3

親コントローラーによって構築されたネストされた属性に 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_id があるのは奇妙に思えるかもしれませんが、人々は同じ場所に新しいレビューを追加できます...

おそらくこのようですが、動作しません:

@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"}}
4

4 に答える 4

4

これを試して:

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]
于 2010-04-27T16:44:38.017 に答える
1

user_idを含むフォームに非表示フィールドを追加する場合としない場合があります。その場合、paramsハッシュにはすでに値があります。改ざんが心配な場合は、current_user.idと比較できます。それでは、そもそもそういうわけで、そもそもこのようにしようとしているのでしょうか。

于 2010-10-01T12:42:54.463 に答える
1

params[:review]属性のハッシュとして持っていると仮定すると、次のことを行う必要がありmerge!ます。

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

編集: これを使用することも想定しています。これはoncreateメソッドです。

編集#2:railsapi.comnewで見つけることができるように、ビルドメソッドがあるため、メソッドでは機能し ません。

「関連付けられたオブジェクトがすでに存在する場合にのみ機能し、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"
}}
于 2010-04-27T14:15:04.013 に答える
0

構文が不十分な form_for を使用している可能性があります。これを見た後、hidden_​​fieldsの使用をやめました: http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for

とこのコメント: (神のご加護を、ナチョキャブ!)

nachocab - 2008 年 11 月 2 日 params ハッシュはモデル ID を自動的に取得します

params ハッシュには、form_for に渡されるすべてのモデルの ID が自動的に入力されます。既存のアルバム内に曲を作成する場合:

URL:/albums/209/songs/new form_for [@albums, @song] do |f| ... f.submit "Add" end

params ハッシュは次のようになります。

params = {"commit"=>"Add", "authenticity_token"=>"...", "album_id"=>"209", "song"=>{"song_attributes"=>{...}} }

したがって、songs_controller では、この album_id を before_filter で使用できます。

before_filter :find_album
protected def find_album @album = Album.find(params[:album_id]) 終了

これだけをした場合:

form_for @song do |f|

この params ハッシュを取得します。

params = {"commit"=>"Add", "authenticity_token"=>"...", "song"=>{"song_attributes"=>{...}} }

于 2010-10-03T03:44:46.500 に答える