使用嵌套属性轻松以形式选择关联



我正在尝试创建一个嵌套属性表单,以创建一个模型,该模型主要是其他两个模型之间的关联"连接器"。就我而言,模型代表booksawards和"连接器"模型book_awards。当我编辑一本书时,我希望能够快速选择它赢得的奖项。

我一直在使用http://railscasts.com/episodes/196-nested-model-form-part-1 为了帮助我开始,但恐怕我会卡住。

另一个似乎相似的问题是Accepts_nested_attributes_for find_or_create?不幸的是,这也不是我正在做的事情,我无法改编它。

我的模型看起来像这样。每个模型都有其他属性和验证等,但是我已将其删除为了清楚。

class Book < ActiveRecord::Base
  has_many :book_awards
  accepts_nested_attributes_for :book_awards, :allow_destroy => true
end
class Award < ActiveRecord::Base
  has_many :book_awards
end
class BookAward < ActiveRecord::Base
  belongs_to :book, :award
end

在我的编辑和新的书本控制器方法中,以及创建和更新的故障案例,我有一行@awards = Award.all

在我看来,我想查看所有奖项的清单,并旁边的复选框。当我提交时,我想更新,创建或破坏book_award模型。如果选择了复选框,我想更新现有模型或创建新模型(如果不存在)。如果未选择复选框,那么我想销毁现有模型,或者如果奖励不存在,则无需做任何事情。我有一个book_awards的部分。我不确定复选框选择器是否应该在此部分中。

我认为我的复选框将是:_destroy的钩子,但其极性反转。我认为这样的事情基本上会做到:

= f.check_box :_destroy, {}, 0, 1

目前,我有一个部分,但我不确定它真正属于哪里。

接下来是我目前不起作用的观点,但也许这将有助于演示我要做的事情。我循环遍历awards,并使用fields_for为已存在的任何事物设置嵌套属性。这太丑陋了,但我认为这有点有效。但是,我真的不知道如何开始使用其他情况。

= f.label :awards
- @awards.each do |a|
  - if f.object.awards && f.object.awards.include?(a)
    = f.fields_for :book_awards, f.object.book_award.select{|bas| bas.award == a } do |ba|
      = render 'book_awards', :f => ba, :a => a
  - else
    = fields_for :book_awards do |ba|
      = render 'book_awards', :f => ba, :a => a

我希望每次都以相同的顺序列出奖项(控制器中的@awards分配可能会指定订单),而不是首先列出现有奖项。

我讨厌回答自己的问题,但我终于找出了有效的东西。我需要做的第一件事是根据Railscast中包含的疯狂对象更新"新"案例。接下来,我需要手动设置:child_index。最后,我需要适当地手动设置:_destroy复选框。

.field
  = f.label :awards
  - @awards.each_with_index do |a,i|
    - if exists = (f.object.awards && f.object.awards.include?(a))
      - new_ba = f.object.book_awards.select{|s| s.award == a}
    - else
      - new_ba = f.object.class.reflect_on_association(:book_awards).klass.new
    = f.fields_for :book_awards, new_ba, :child_index => i do |ba|
      = render 'book_awards', :f => ba, :a => a, :existing => exists

我的部分看起来像这样:

.field
  = f.check_box :_destroy, {:checked => existing}, 0, 1
  = f.label a.name
  = f.hidden_field :award_id, :value => a.id
  = f.label :year
  = f.number_field :year

这并不是很漂亮,但是它似乎确实做了我想要的。

相关内容

  • 没有找到相关文章

最新更新