1

Я ударяю головой об этом один в течение длительного времени. On 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 действия, чтобы создать экземпляр новых экземпляров всех трех моделей с указанными ассоциациями. Однако, хотя кажется, что хэш-код params передается контроллеру, как он должен (на основе журналов backtrace в браузере, когда он взрывается), объект Goat::Kid не собирает параметры.

irb (irb session - это просто псевэ-представление того, что я пытаюсь выполнить, если он не вызывает #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 

>> [] 

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

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

Прохождение параметров к трем моделям было очень сложным для меня, и независимо от того, сколько документов я читаю, я не могу обмотать его вокруг (и #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 

Я не знаю, как перевести с пространствами имен моделей с их идентификаторами символов. Благодаря!

+0

Ну, не уверен, что это было слишком ясно. Вот как я хотел бы свою форму, чтобы посмотреть:
Person Имя:
Person Фамилия:
Коза Имя:
Коза Цвет:
Козье :: Kid Ник:
Козье :: Kid Возраст:
Таким образом, это одна форма будет создать три новые модели с соответствующими ассоциациями и соображениями пространства имен. еек. – 2009-09-15 23:16:20

+0

коз? WTF? lol – JRL

+0

Да, это для предстоящего приложения Goatr. Нет, эти модели фиктивны для защиты невинных. Это был единственный пример, который я мог бы придумать для использования пространства имен - это имеет смысл, хотя верно! – 2009-09-15 23:58:24

ответ

2

Ну, это мой первый раз, играя с 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_for. Метод kids_attributes= искал массив объектов, поэтому мне нужно было указать ассоциацию массива в форме вручную и сообщить fields_for, какую модель использовать.

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

+0

Хейя, Майкл, я ценю ваше предложение, но реализация бросила мне NoMethodError, который я не совсем понял - любые идеи? Я очень ценю это. (Я оставил комментарий ниже, потому что у меня возникли проблемы с входом в эту учетную запись) – 2009-09-28 16:32:45