проблемы с параметрами сборки для acceptpts_nested_attributes_for - PullRequest
3 голосов
/ 27 апреля 2010

Я пытаюсь добавить user_id к вложенному атрибуту, который создается родительским контроллером, но, похоже, он не дает желаемого эффекта?

Т.е.. У меня есть модель под названием Place.rb, которая accepts_nested_attributes_for :reviews и has_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 'для 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 голосов
/ 27 апреля 2010

Попробуйте это:

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]
1 голос
/ 01 октября 2010

Вы можете или не можете добавить скрытое поле в форму, которая включает в себя user_id. Тогда хэш params уже будет иметь значение. Если вы беспокоитесь о фальсификации, вы можете сравнить ее с current_user.id. Опять же, может быть, именно поэтому вы пытаетесь начать с этого?

1 голос
/ 27 апреля 2010

Если у вас есть params[:review] в качестве хэша атрибутов, вам нужно сделать merge!:

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

Редактировать: Я также предполагаю, что вы будете использоватьэто метод create.

Edit # 2: Он не будет работать с методом new, потому что, как вы можете найти на railsapi.com ,метод построения

"работает только в том случае, если связанный объект уже существует, а не если он равен nil!"

Edit # 3: I'mне уверен, что это лучший способ, но я проверил здесь, и это сработало ...

У вас есть следующие параметры:

{"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"
}}
0 голосов
/ 03 октября 2010

Возможно, вы используете form_for с плохим синтаксисом. Я прекратил использование hidden_fields после просмотра этого: http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for

и этот комментарий: (Благословит тебя Бог, начокаб!)

начокаб - 2 ноября 2008 г. params хеш автоматически получает идентификатор модели

Хэш параметров получает автоматически заполнен идентификатором каждой модели это передается в form_for. Если мы создавали песню внутри существующий альбом:

URL: / альбомы / 209 / песни / новый form_for [@album, @song] do | f | ... f.submit "Добавить" конец

Хэш параметров будет:

params = {"commit" => "Добавить", "Authenticity_token" => "...", "Album_id" => "209", "Песня" => { "song_attributes" => {...}} }

Итак, в song_controller вы можете используйте этот album_id в before_filter:

before_filter: find_album
защищенный def find_album @album = Album.find (params [: album_id]) end

Если бы ты только сделал это:

form_for @song do | f |

Вы получите хэш этого параметра:

params = {"commit" => "Добавить", "Authenticity_token" => "...", "Песня" => { "song_attributes" => {...}} }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...