首页 文章

Rails 3数据建模帮助 - 有许多,属于嵌套属性

提问于
浏览
2

我正在开展一个涉及三个模型(收件人,奖励,播音员)的项目,并且当播音员向多个收件人发放奖励时需要具有嵌套属性 . 举个例子,奖励表格需要有能力做三件事:

  • 可以添加多个收件人(即"add recipient","remove recipient") - 嵌套属性

  • 创建新奖项后,该奖项将发布到收件人的 Profiles 中 .

  • 启用@ recipient.awards和@ announcer.awards的未来轮询

在如何巧妙地解决这个问题方面真的很挣扎 . 以下数据结构有意义,但不能在奖励表单中执行“accepts_nested_attributes_for:recipients” . 你能帮我吗?提前谢谢了 .

class Recipient <ActiveRecord :: Base

  • has_many:奖励

  • has_many:播音员,:通过=>:奖励

结束

class Announcer <ActiveRecord :: Base

  • has_many:奖励

  • has_many:收件人,:通过=>:奖励

结束

class Award <ActiveRecord :: Base

  • belongs_to:播音员

  • belongs_to:收件人

结束

1 回答

  • 3

    你就在那里 . 主要问题是您尝试在表单中创建收件人对象,而不是仅仅创建奖励与另一个对象(用户)之间的关系 . 你可以这样做:

    class User < ActiveRecord::Base
      has_many :recipients
      has_many :awards, :through => :recipients
    end
    
    # this is your relationship between an award and a user
    class Recipient < ActiveRecord::Base
      belongs_to :user
      belongs_to :award
    end
    
    class Award < ActiveRecord::Base
      has_many :recipients
      has_many :users, :through => :recipients
      belongs_to :announcer
    
      accepts_nested_attributes_for :recipients, :allow_destroy => true
    end
    
    class Announcer < ActiveRecord::Base
      has_many :awards
      has_many :recipients, :through => :awards
    end
    

    然后你只需要一个嵌套的表单来构建recipients_attributes数组:

    <%= form_for @award do |f| %>
    
      <%= f.text_field :name %>
    
      <div id="recipients">
        <% @award.recipients.each do |recipient| %>
    
         <%= render :partial => '/recipients/new', :locals => {:recipient => recipient, :f => f} %>
    
        <% end %>
      </div>
      <%= link_to_function 'add recipient', "jQuery('#recipients').append(#{render(:partial => '/recipients/new').to_json})" %>
    
    <% end %>
    

    并且,为了保持干燥,只需将嵌套部分推入部分:

    # app/views/recipients/_new.html.erb
    <% recipient ||= Recipient.new %>
    <%= f.fields_for 'recipients_attributes[]', recipient do |rf| %>
      <%= rf.select :user_id, User.all %>
      <%= fr.check_box '_delete' %>
      <%= fr.label '_delete', 'remove' %>
    <% end %>
    

    显然User.all调用并不理想,所以可能会自动完成 .

相关问题