использование построения в отношении has_many в действии create приводит к ошибке массового назначения

У меня есть ошибка массового назначения, которую я могу исправить только с помощью УЖЕСТВЕННОГО кода. Я, должно быть, делаю что-то не так. Позволь мне объяснить:

У моих клиентов приложения rails много контактов. На странице «Клиент» отображается список контактов, принадлежащих этому клиенту. Я хочу иметь возможность добавлять новый контакт в список. Итак, я передаю клиента контроллеру контактов, используя ...

<%= link_to('new contact', new_contact_path(client_id: @client)) %> 

В ContactsController ....

def new
 client=Client.find(params[:client_id])
 @contact=client.contacts.new
end


def create
  @client = Client.find(params[:contact][:client_id])
  @contact= @client.contacts.build(params[:contact])
      if @contact.save
 ...

«Сохранить» приводит к неудивительной ошибке:

Невозможно массово назначить защищенные атрибуты: client_id

потому что параметры контакта включают client_id, которого нет (и не должно быть) attr_accessible в модели контакта

Единственный способ, которым я знаю, как решить эту проблему, - установить каждый параметр индивидуально (за исключением client_id) следующим образом:

@contact= @client.contacts.build(first_name: params[:contact][:first_name], last_name:     params[:contact][:first_name], email: params[:contact][:email])

Этот подход работает, но все кажется неправильным. Конечно, это более элегантная альтернатива. Любая помощь приветствуется. (да, я новичок в рельсах)


person zambacan    schedule 08.04.2013    source источник


Ответы (1)


Чтобы пропустить часть, в которой рассказывается, как вы должны исправить свою ошибку, я хотел бы рассказать вам, как вы должны делать кодирование в первую очередь :) Поправьте, если я ошибаюсь.

В Routes.rb вы должны были вставить (если это еще не так):

resources :client do
    resources : contacts
end

Затем, во-вторых, в вашем view файле вы должны поместить что-то вроде этого:

<%= link_to('new contact', new_client_contact_path(@client)) %> 

Таким образом, вам не нужно ничего делать в вашем действии create, rails будет управлять всем остальным. Вот как это должно быть сделано

Редактировать:

просто чтобы было понятнее. В действии new в вашем contacts контроллере вы должны указать:

user= user.find(params[:user_id])
#2nd you build a new one
@contact= user.contacts.build

И в вашем create действии в contacts контроллере вы должны указать:

user = User.find(params[:user_id])
#2nd you create the contact with arguments in params[:contact ]
@contact = user.contact.create(params[:contact ])
response .....
person Aleks    schedule 08.04.2013
comment
спасибо ... Я был почти уверен, что пытался обойти проблему неправильно. Похоже на довольно распространенный сценарий - person zambacan; 08.04.2013
comment
Да, это так. Я добавил код для новых и создания действий (я сделал это без тестирования, поэтому что-то может быть не так, если просто скопировать-вставить). Но да, это обычное дело. Если вы хотите больше осмотреться, поищите nested resources и узнайте, как их использовать. Рад, что помог. Спасибо - person Aleks; 08.04.2013
comment
Позже я узнал о acceptpts_nested_attributes_for и нашел гораздо лучший способ создания контактов. - person zambacan; 27.04.2013