Rails 3.1 has_many:通过表单

时间:2012-01-18 21:52:40

标签: ruby-on-rails ruby-on-rails-3.1

我有以下模型:

class Dog < ActiveRecord::Base
  validates :registration, :uniqueness => true
  belongs_to :breed
  has_many :shows, :through => :show_entries
  has_many :show_entries
end

class Show < ActiveRecord::Base
  belongs_to :event
  has_many :dogs, :through => :show_entries
  has_many :show_entries
  after_save :update_event
end

class ShowEntry < ActiveRecord::Base
  belongs_to :show
  belongs_to :dog
  belongs_to :entry_class
  #DB has a bunch of other fields
end

我现在有一个显示一堆复选框的表单:

<% for show in @shows %>
    <%= check_box_tag "dog[show_ids][]", show.id, @dog.shows.include?(show), {:id => "dogs_show_"}%>
    <%= show.name %>
<% end %>

虽然我无法弄清楚在POST控制器操作中该怎么做。如何获取值并更新ShowEntry表以创建或删除?

谢谢, d。

更新:我忘了提到ShowEntry表还有其他字符串字段。如何在表单中表示它们,并在POST控制器操作中处理它们?

这是我想到的形式(伪HTML),假设我有3个节目,我可能会与狗关联:

<div>
  check_box for Show1
  dropdownlist for entry_class
  input text for property1
  input text for property2
</div>
<div>
  check_box for Show2
  dropdownlist for entry_class
  input text for property1
  input text for property2
</div>
<div>
  check_box for Show3
  dropdownlist for entry_class
  input text for property1
  input text for property2
</div>

当然,它的样式很好,每个隐藏或显示的最后四行取决于每个check_box的检查状态。

2 个答案:

答案 0 :(得分:1)

如果您希望在控制器中创建狗和节目之间的关联。

dog = Dog.find(params[:id])    
dog.show_ids =  params(dog[show_ids]) # where show_ids is the array of show_ids
dog.save #I think this is optional, 

答案 1 :(得分:1)

如果我正确阅读,看起来你需要在Dog模型上使用'accepts_nested_attributes_for:show_entries'。然后在表单中,您需要为每个show entry / attribute组合使用'dog [show_entry] [some unique int] [some attribute name]'。 unique int用于将属性组合在一起。它与show entry模型的id无关。

然后你应该能够在创建动作中说'Dog.new params [:dog]',它应该自动构建节目条目和关联。

更新:抱歉,我昨晚在手机上,因此很难写出一堆代码。但基本的想法是在Dog表单中获取格式正确的ShowEntry数据。

<%= form_for @dog do |form| %>
  <%= form.fields_for :show_entries do |se_form| %>
     <%# Build form elements for existing show entries %>  
  <% end %>
  <%# These shows should either be pre-filtered down to the ones not already associated to the dog or you should add that check in the loop below %>
  <% @shows.each do |show| %>
    <%= form.fields_for :show_entries, ShowEntry.new(:show => show, :dog => @dog) do |new_se| %>
      <%# Build form elements for new show entries %>
    <% end %>
  <% end %>
  <%= form.submit %>
<% end %>

这将允许您在更新狗记录时创建新的ShowEntry记录。您应该能够将params[:dog]直接传递给控制器​​操作中的update_attributes

如果您希望能够销毁节目条目,则需要将:allow_destroy => true添加到accepts_nested_attributes_for声明中。然后,通过在:_destroy格式中传递名为ShowEntry的输入,其中包含特定update_attributes的真值,将自动删除ShowEntry模型。

您可能希望将:_destroy用作隐藏字段设置为true,然后将复选框设置为false。这样,当选中复选框时,记录将不会被销毁,新数据将生效。取消选中该复选框时,:_destroy将为真,并且记录将被销毁或未保存到数据库中。您可以使用JavaScript启用和禁用与ShowEntry关联的表单字段,以防止用户输入无法保存的数据。