Rails:在n个关联级别上创建多个模型表单

时间:2009-04-01 12:18:40

标签: ruby-on-rails forms webforms

任何人都可以告诉我为什么这个问题末尾的表格不能正常运作吗?

  • 保存不起作用
  • select-helper不选择 根据对象@kid
  • 的值

整个事情是基于Rails 2.2.2而不是,升级到Rails 2.3来解决这个问题不是一个选择。 : - )

我使用this recipe来构建多个模型表单。

# CLASS GRANDPARENT
class Grandparent < ActiveRecord::Base
  has_many :parents 
end

# CLASS PARENT
class Parent < ActiveRecord::Base
  belongs_to :grandparent, :class_name => "Grandparent", :foreign_key => "grandparent_id"
  has_many :kids
end

# CLASS KID
class Kid < ActiveRecord::Base
  belongs_to :parent, :class_name => "Parent", :foreign_key => "parent_id"

  # Virtual attribute setter for new self.parent.grandparent (Grandparent) attributes
  def new_grandparent_attributes=(_gp_attributes)
    self.parent.build_grandparent(_gp_attributes)
  end

  # Virtual attribute setter for existing self.parent.grandparent (Grandparent) attributes
  def existing_grandparent_attributes=(_gp_attributes)
    unless self.parent.grandparent.new_record?
      attributes = _gp_attributes[self.parent.grandparent.id.to_s]
      if attributes
        self.parent.grandparent.attributes = attributes
      else
        self.parent.grandparent.delete(grandparent)
      end
    end
  end

end

# CONTROLLER KIDS
class KidsController < ApplicationController
  def new
    @kid = Kid.new
  end

  def edit
    @kid = Kid.find(params[:id])
  end

  def create
    params[:kid][:new_grandparent_attributes] ||= {}
    @kid = Kid.new(params[:kid])
  end

  def update
    params[:kid][:existing_grandparent_attributes] ||= {}
    @kid = Kid.find(params[:id])
  end

end


# THIS IS THE MULTI-MODEL FORM USED IN THE VIEW

<% form_for(@kid) do |f| %>
    <p>
        <% new_or_existing = @kid.parent.grandparent.new_record? ? 'new' : 'existing' %>
        <% prefix = "kid[#{new_or_existing}_grandparent_attributes][]" %>

        <% fields_for prefix, @kid.parent.grandparent do |g_f| -%>
            <p>
              <%= g_f.label :, 'Grandparent Name' %><br />
              <!-- THE FOLLOWING FORM DOESN'T CHANGE ACCORDING TO EXISTING @child -->
              <%= @grandparents = Entity.find(:all, :order => :name)
                g_f.collection_select(:name ,@grandparents, :id, :name) 
                %>
            </p>
        <% end %>
    </p>
    <p>
        <%= f.label :name, "Kid Name" %><br />
        <%= f.text_field :name %>
    </p>
    <%= submit_tag 'Go' %>
<% end %>

1 个答案:

答案 0 :(得分:1)

好吧,如果我错了,请纠正我,但看起来你实际上并没有将对象保存在任何地方。在您的创建和更新操作中,您正在调用new,然后不保存它。

要纠正这个问题,你可以这样做:

def create
  params[:kid][:new_grandparent_attributes] ||= {}
  @kid = Kid.new(params[:kid])
  if @kid.save
    # successful save logic here
  else
    #failed save logic here
  end
end

def update
  params[:kid][:existing_grandparent_attributes] ||= {}
  @kid = Kid.find(params[:id])
  if @kid.update_attributes(params[:kid])
    #successful save logic here
  else
    #failed save logic here
  end
end

然后在您的选择框中,您尝试查找Entity的每条记录,而不是{@ 1}}与@kid相关的字段。为了做到这一点,你必须建立一个孩子和祖父母之间的关系。

Entity

通过这种方式,您可以通过# CLASS GRANDPARENT class Grandparent < ActiveRecord::Base has_many :parents has_many :grand_kids, :through => :parents end # CLASS PARENT class Parent < ActiveRecord::Base belongs_to :grandparent, :class_name => "Grandparent", :foreign_key => "grandparent_id" has_many :kids end # CLASS KID class Kid < ActiveRecord::Base belongs_to :parent, :class_name => "Parent", :foreign_key => "parent_id" belongs_to :grandparent # ... 访问孩子的祖父母。然后,您可以生成选择字段:

@kid.grandparents