Вопрос

Долго стучал головой об это.На Rails 2.3.2, Ruby 1.9.1.

Попытка использовать одну форму для создания трех объектов, имеющих следующие отношения:

class Person
  has_one :goat
end

class Goat
  belongs_to :person
  has_many :kids
end

class Goat::Kid
  belongs_to :goat
end

Вот краткое изложение схемы:

Person
  first_name
  last_name
Goat
  name
  color
Goat::Kid
  nickname
  age

мне бы хотелось, чтобы мой #create действие для создания новых экземпляров всех трех моделей с указанными ассоциациями.Однако, хотя кажется, что мой хэш параметров передается контроллеру, как и должно (на основе журналов обратной трассировки в браузере, когда он взрывается), Goat::Kid объект не собирает параметры.

irb (сеанс irb — это всего лишь псевдопредставление того, что я пытаюсь выполнить, поэтому, если он не вызывает #save! или любые другие потребности, это не совсем правильно.Я пытаюсь сделать это через браузер/веб-форму.)

a = Person.new :first_name => 'Leopold', :last_name => 'Bloom'
b = Goat.new :name => 'Billy', :color => 'white'
c = Goat::Kid.new :nickname => 'Jr.', :age => 2

a.goat.kids

>> []

Теперь я не могу понять, как заставить представление передавать параметры каждому объекту и заставить контроллер сохранять эти параметры в базе данных.

Мои вопросы:А) хорошее ли это место для использования nested_attributes_for и если да, то как мне объявить это с помощью пространства имен?Б) есть ли более простой и понятный способ сделать это?

Передача параметров трем моделям была для меня очень сложной задачей, и сколько бы документации я ни читал, я не могу уяснить это (#form_for и #fields_for).Пространство имен еще больше усложняет ситуацию.Спасибо за любую помощь!


Приложение:если я в конечном итоге объявлю

accepts_nested_attributes_for

как правильно использовать аргумент символа для модели с пространством имен?

accepts_nested_attributes_for :kids, :through => :goats

или

accepts_nested_attributes_for :goats_kids, :through => :goats

или

accepts_nested_attributes_for :goats::kids, :through => :goats

Я не уверен, как модели с пространством имен преобразуются в их идентификаторы символов.Спасибо!

Это было полезно?

Решение

Ну, я впервые играю с accepts_nested_attributes_for, но, немного поигравшись, мне удалось заставить что-то работать.

Сначала настройка модели:

class Person < ActiveRecord::Base
  has_one :goat
  accepts_nested_attributes_for :goat
end

class Goat < ActiveRecord::Base
  belongs_to :person
  has_many :kids

  accepts_nested_attributes_for :kids
end

class Goat::Kid < ActiveRecord::Base
  belongs_to :goat
end

С помощью простого спокойного контроллера:

ActionController::Routing::Routes.draw do |map|
  map.resources :farm
end

class FarmController < ApplicationController
  def new
  end

  def create
    person = Person.new params[:person]
    person.save
    render :text => person.inspect
  end
end

Затем идет полусложная форма:

Далее настройка формы:

<% form_for :person, :url => farm_index_path do |p| %>
  <%= p.label :first_name %>: <%= p.text_field :first_name %><br />
  <%= p.label :last_name %>: <%= p.text_field :last_name %><br />
  <% p.fields_for :goat_attributes do |g| %>
    <%= g.label :name %>: <%= g.text_field :name %><br />
    <%= g.label :color %>: <%= g.text_field :color %><br />
    <% g.fields_for 'kids_attributes[]', Goat::Kid.new do |k| %>
      <%= k.label :nickname %>: <%= k.text_field :nickname %><br />
      <%= k.label :age %>: <%= k.text_field :age %><br />
    <% end %>
  <% end %>
  <%= p.submit %>
<% end %>

Судя по источнику accepts_nested_attributes_for, похоже, он создаст для вас метод под названием #{attr_name}_attributes=, поэтому мне нужно было настроить fields_for чтобы отразить это (Rails 2.3.3).Далее, получив has_many :kids работать с accepts_nested_attributes_forkids_attributes= метод искал массив объектов, поэтому мне нужно было указать ассоциацию массива в форме вручную и сообщить fields_for какой тип модели использовать.

Надеюсь это поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top