Rails形成三个模型和命名空间

时间:2009-09-15 23:09:04

标签: ruby-on-rails forms namespaces associations multiple-models

长时间对着这个人猛烈抨击我。在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散列似乎正在传递给控制器​​(基于浏览器中的回溯日志,但是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

>> []

现在,我无法弄清楚如何让视图将params传递给每个对象并让控制器将这些参数保存到db。

我的问题:A)这是一个使用nested_attributes_for的好地方,如果是这样,我如何用命名空间声明? B)有更简单,更容易理解的方法吗?

将params传递给三个模型对我来说非常具有挑战性,无论我阅读多少文档,我都无法绕过它(#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

我不确定命名空间模型如何转换为其符号标识符。谢谢!

1 个答案:

答案 0 :(得分: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_forkids_attributes=方法正在寻找一个对象数组,因此我需要手动指定表单中的数组关联,并告诉fields_for要使用哪种类型的模型。

希望这有帮助。