【问题标题】:Ruby on rails. Passing params from view to controller红宝石在铁轨上。将参数从视图传递到控制器
【发布时间】:2016-02-04 12:11:39
【问题描述】:

我有我认为一定是一个简单的问题,但我就是想不通。我正在尝试在创建另一个模型时更新一个模型中的属性。

在我看来:

<%= link_to 'Click here to rate this user', new_user_review_path(:user_id => request.user.id, :gigid => request.gig.id), remote: true %>

通过参数:gigid:user_id

比我的控制器:

def new
    @review = Review.new
    @gig = Gig.find(params[:gigid])
end

  def create
    @review = @user.reviews.new review_params
    @review.reviewed_id = current_user.id
       if @review.save
        @gig.update(reviewed: true)
        respond_to do |format|
          format.html {redirect_to session.delete(:return_to), flash[:notice] = "Thankyou for your rating!"}
          format.js 
        end
    else
      render 'new'
    end
  end

但我得到undefined method 'update'for nil:NilCLass:

我知道参数正在传递,“Gig”可以更新为:

def new
    @review = Review.new
    Gig.find(params[:gigid]).update(reviewed: true)
end

可以正常更新属性,但是当我点击“新评论”时,不会在实际创建评论时。

添加:

def create
    @review = @user.reviews.new review_params
    @review.reviewed_id = current_user.id
      if @review.save
        Gig.find(params[:gigid]).update(reviewed: true) 

etc etc etc 

给我同样的undefined method 'update'for nil:NilCLass:

我尝试过使用find_by_id 而不是find,这没什么区别。

编辑:

def create
@gig = Gig.find params[:gigid] 
@review = @user.reviews.new review_params
    @review.reviewed_id = current_user.id
       if @review.save
         @gig.update(reviewed: true)
    etc etc etc

也不行。我没有收到任何错误,但演出 ID 仍然是“nil”。

参数传递给“新建”操作,而不是“创建”操作。我觉得这应该很容易,但我现在还没有看到。

【问题讨论】:

  • 你得到那个错误是因为 Gig.find(params[:gigid]) 返回 Nil。确保 params[:gigid] 是 db 中存在的有效 id,以便它可以找到它。在尝试调用更新方法之前应该可能做一个不为零的检查。
  • 那么我很困惑。您的“新”操作不会呈现模板或任何内容?你怎么称呼“创造”?您的 link_to 会生成一个指向您的“新”操作的链接。
  • 我是通过 ajax 进行的,但没有 javascript,我会被重定向到呈现部分表单的“新”评论页面。然后我填写并保存/创建评论。我希望属性在保存/创建时更新。

标签: ruby-on-rails controller params link-to


【解决方案1】:

但我得到未定义的方法'update'for nil:NilCLass:

错误是您没有在create 操作中定义@gig

由于 Rails 是基于 HTTP 和 HTTP is stateless 构建的,因此您必须为每个新请求设置“实例”变量:

def new
  @review = Review.new
  @gig    = Gig.find params[:gigid]
end

def create
 @gig    = Gig.find params[:gigid]
 @review = @user.reviews.new review_params

对你来说很多更好的模式是在你的Review 模型中使用after_create 回调:

#app/models/review.rb
class Review < ActiveRecord::Base
   belongs_to :gig #-> I presume
   after_create :set_gig

   private

   def set_gig
      self.gig.update(reviewed: true)
   end
end

--

如果您想在当前设置中更新 Gig,最好通过请求(而不是链接)发送 gig_id 参数:

#app/views/reviews/new.html.erb
<%= form_for [@user, @review] do |f| %>
   <%= f.hidden_field :gig_id, @gig.id %> #-> params[:reviews][:gig_id]
   ...
<% end %>

这将使params[:review][:gig_id]create 操作中可用,您可以在代码中使用它。

【讨论】:

  • 由于我需要其他条件,我使用了最后一种方法。使用隐藏字段和 params[:review][:gig_id] 它可以正常工作。不知道为什么我错过了。谢谢。
【解决方案2】:

问题是,您从未在 create 方法中为 @gig 赋值。我看不到你的表单,但你的 create 方法中需要这样的东西:

@gig = Gig.find params[:gigid]

假设您将参数 :gigid 传递给 #create

在您展示的第二个示例中,我不确定发生了什么,但您应该在 find() 上收到 ActiveRecord::RecordNotFound 异常。

【讨论】:

  • 我试过@gig = Gig.find params[:gigid] 然后@gig.update(reviewed: true) 这也不起作用,ID = NIL。它仅适用于“新建”操作。我使用的是 link_to,而不是表单。我的链接是我问题中的第一段代码。
【解决方案3】:

尝试下面的代码进行更新操作。

gig_record = Gig.find_by_id(params[:gigid])
gig_record.update_attribute(reviewed: true) unless gig_record.blank?

【讨论】:

  • 这也为我提供了 nil:NilClass 的未定义方法 'update_attribute'。
猜你喜欢
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
  • 1970-01-01
相关资源
最近更新 更多