【问题标题】:problems with build params for accepts_nested_attributes_forAccepts_nested_attributes_for 的构建参数问题
【发布时间】:2010-04-27 13:48:59
【问题描述】:

我正在尝试将 user_id 添加到由父控制器构建的嵌套属性中,但它似乎没有达到预期的效果?

即。我有一个名为 Place.rb 的模型,其中 accepts_nested_attributes_for :reviewshas_many :reviews, :as => :reviewable, :dependent => :destroy

嵌套属性工作正常,我在 Places 控制器中构建它,就像这样......

新动作

@review = @place.reviews.build(:user_id => current_user.id)

创建动作

params[:place].merge(:user_id => current_user.id)
params[:place][:reviews_attributes].merge!(:user_id => current_user.id)* bad
@place = Place.new(params[:place])

这是原始的,用于地方模型获取 user_id,现在我也需要嵌套评论模型的 user_id。地方和评论都有 user_ids 可能看起来很奇怪,但人们可以为同一个地方添加新评论...

可能像这样但不起作用:

@place = Place.new(params[:place].merge(:user_id => current_user.id, :reviews_attributes => { :user_id => current_user.id } ))

得到错误:undefined method with_indifferent_access' for 3:Fixnum`

@place = Place.new(params[:place].merge(:user_id => current_user.id, :reviews_attributes => { "0" =>  { :user_id => current_user.id }}))

添加了正确的 user_id 但将评论的内容替换为 NULL ;-(

我之前是通过表单添加用户,但想通过控制器来完成,这样它只会在创建时添加 user_id,因为特定评论可能会被其他人更新,而我不希望更新更改原始作者的 user_id...

有效的旧方法:

<%= e.label :content, "Review" %><br />
<%= e.text_area :content, :rows => 20, :class => 'jquery_ckeditor' %><br />
<%= e.hidden_field :user_id, :value => current_user.id %> #want to remove this line

但是通过控制器,带有选项的构建方法没有效果?有任何想法吗?我不能通过构建来做到这一点吗?

日志中的输出:

    Parameters: {"commit"=>"Submit", "action"=>"create", "city_id"=>"prague",
 "controller"=>"places", "place"=>{"address"=>"fsdfsdf", "name"=>"sdfsdfsd",
 "reviews_attributes"=>{"0"=>{"content"=>"<p>\r\n\tsdfsdfsdfsdfsdfsdfsdf sdfsdfsdf</p>\r
\n"}}, "website"=>"", "city_id"=>"1036", "place_type"=>"1"}}

【问题讨论】:

  • 我不是很了解。您在控制器中添加了user_id,但它不起作用,对吗?你之前是如何在控制器中构建review 的?
  • 我一直在通过地方控制器构建评论,它工作正常,除了在我通过视图添加 user_id 进行评论之前......我包括在内,现在我是尝试直接在构建方法中执行此操作。即在它只是@place.reviews.build 之前,现在我尝试使用@place.reviews.build(:user_id => current_user.id) 这似乎可以从控制台工作。

标签: ruby-on-rails modeling nested-forms nested-attributes


【解决方案1】:

试试这个:

params[:place][:user_id] = current_user.id
params[:place][:reviews_attributes].each do |key, review|
  review[:user_id] = current_user.id
end if params[:place][:reviews_attributes]

【讨论】:

    【解决方案2】:

    假设你有params[:review] 作为属性的哈希,你需要做一个merge!

    params[:review].merge!(:user_id => current_user.id)
    @review = @place.reviews.build(params[:review])
    

    编辑: 我还假设您将在 create 方法上使用它。

    编辑#2: 它不适用于 new 方法,因为您可以在 railsapi.com 找到 build 方法

    "仅在关联对象时有效 已经存在,如果它是 nil 则不是!”

    编辑#3: 我不确定这是否是最好的方法,但我在这里进行了测试并且它有效......

    你有这个参数:

    {"commit"=>"Submit", "action"=>"create", "city_id"=>"prague",
       "controller"=>"places", "place"=>{"address"=>"fsdfsdf", "name"=>"sdfsdfsd",
       "reviews_attributes"=>{"0"=>{"content"=>"<p>\r\n\tsdfsdfsdfsdfsdfsdfsdf 
       sdfsdfsdf</p>\r\n"}}, "website"=>"", "city_id"=>"1036", "place_type"=>"1"}}
    

    因此您可以通过以下方式访问评论的属性:params[:place][:reviews_attributes],并且要合并 user_id 属性,您可以这样做:

    params[:place][:reviews_attributes].each_value {
       |v| v.merge!(:user_id => current_user.id) 
    }
    

    现在params[:place][:reviews_attributes] 看起来像这个例子:

    {"0"=>{
       "user_id"=>"1",
       "content"=>"<p>\r\n\tsdfsdfsdfsdfsdfsdfsdf sdfsdfsdf</p>\r\n"
    }}
    

    【讨论】:

    • 这太难看了,所以我将上面的内容添加到问题中,并带有特定的 new 和 create 操作。
    • 我很高兴在创建时这样做,但我不确定如何合并嵌套属性...见上文。 :reviews_attributes => { :user_id => current_user.id } 不起作用。
    • 它是params[:reviews_attributes].merge!(:user_id =&gt; current_user.id)
    • 这样我得到“未定义的方法`合并!'对于 nil:NilClass",尝试了 params[:place][:reviews_attributes].merge!(:user_id => current_user.id),得到无所谓的访问错误。在上面添加了我的日志。
    【解决方案3】:

    您可能希望也可能不希望在包含 user_id 的表单中添加隐藏字段。然后 params 哈希将已经具有该值。如果您担心篡改,可以将其与 current_user.id 进行比较。话又说回来,也许这就是你一开始就这样尝试的原因?

    【讨论】:

      【解决方案4】:

      也许您使用的 form_for 语法很差。看了这个之后我已经放弃使用 hidden_​​fields:http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for

      还有这条评论:(上帝保佑你,nachocab!)

      nachocab - 2008 年 11 月 2 日参数 hash 自动获取模型 id

      参数哈希自动获取 填充了每个模型的 id 传递给 form_for。要是我们 在里面创作一首歌 现有专辑:

      网址:/albums/209/songs/new form_for [@album, @song] 做 |f| ... f.提交“添加”结束

      参数哈希是:

      参数 = {“提交”=>“添加”, "authenticity_token"=>"...", "专辑编号"=>"209", “歌曲”=>{“歌曲属性”=>{...}} }

      所以,在songs_controller 中你可以 在 before_filter 中使用此专辑 ID:

      before_filter :find_album
      受保护的 def find_album @album = Album.find(params[:album_id]) 结束

      如果你只是这样做:

      form_for @song do |f|

      你会得到这个参数哈希:

      参数 = {“提交”=>“添加”, "authenticity_token"=>"...", “歌曲”=>{“歌曲属性”=>{...}} }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-27
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        相关资源
        最近更新 更多