Как использовать вложенные атрибуты с помощью модели разработки

У меня такая же проблема, как Создание дополнительной связанной модели с Devise (у которой нет ответа).

Я переопределил представление для создания нового пользователя и добавил название компании, я изменил модель на использование accepts_nested_attributes_for

Ошибок нет, но не добавляет вложенную запись, и у меня нет контроллера, где я могу изменить запрос.

У меня есть следующее (сокращенное, чтобы сделать его читаемым):

routes.rb

map.devise_for :users
map.resources :users, :has_many => :companies

user.rb

has_many :companies
accepts_nested_attributes_for :companies
devise :registerable ... etc

company.rb

belongs_to :user

new.html.erb

...
<% form_for resource_name, resource, :url => registration_path(resource_name) do |f| %>
...
  <% f.fields_for :company do |company_form| %>
    <p><%= company_form.label :name %></p>
    <p><%= company_form.text_field :name %></p>
  <% end %>
...

UPDATE: Я не добавил: компания в список attr_accessible в модели User.

Ответ 1

Возможно, вы пытаетесь присвоить некоторую защищенную переменную массой, иначе вы не сможете сохранить действительную запись. Убедитесь, что запись фактически сохраняется в db.

Ответ 2

Вы можете добавить в модель пользователя следующий метод:

user.rb

def with_company
  self.companies.build
  self
end

И измените представление:

new.html.erb

...
<% form_for [resource_name, resource.with_company], :url => registration_path(resource_name) do |f| %>
...
  <% f.fields_for :company do |company_form| %>
  ...
  <% end %>

Таким образом, у вас будет вложенная форма для добавления одной компании к пользователю. Чтобы динамически добавить несколько пользователей к пользователю, отметьте Railcast # 197 Райана Бейтса. Убедитесь, что вы передаете пару ресурсов в виде массива, в противном случае вы получите такую ​​ошибку: "неправильное количество аргументов (3 для 2)".

Ответ 3

Я понял, что это очень старый поток, но поскольку я нашел лучшее решение, отсюда и ответ.

Просто измените new.html.erb следующим образом:

<% form_for(resource, :as => resource_name,:url => registration_path(resource_name) do |f| %>
    ...
    <% prefix = "user[company_attributes]"%>
    <% fields_for prefix, @user.company do |company_form| %>
    ...
    <% end %>
<% end %>

Таким образом, когда вызывается @user.save, он запускает company.save тоже со всеми проверками, которые могут быть у вас в модели компании.

У меня нет много опыта RoR, но я думаю, что это лучшее решение. Как вы думаете?