在has_many_through连接模型上设置属性

时间:2013-09-27 11:21:17

标签: ruby-on-rails ruby-on-rails-3 join model has-many-through

我在has_many_throughContributorResource之间存在Contributorship关系。不寻常的是,当我设置关联时,我需要为:

设置contribution_type
model Contributor

  has_many contributorships
  has_many contributors, through: contributorships

end

model Resource

  has_many contributorships
  has_many resources, through: contributorships

end

model Contributorships

  attr_accessible :contribution_type, :contributor, :archive_resource

  belongs_to resources
  belongs_to contributors

end

建立关联涉及:

c = Contributor.create!()
r = Resource.create!()
c.contributorships.create!(resource:r,  contribution_type: :author)

或(如果我不想预先保存):

c = Contributor.new()
r = Resource.new()
cs = Contributorship.new(contributor:c, resource:r,  contribution_type: :author)
c.save!
r.save!
cs.save!

如果我不需要在contribution_type加入模型上设置Contributorship atttribute,我可以做:

c.resources << r

那么有更好的方法吗同时设置属性吗?

2 个答案:

答案 0 :(得分:1)

您可以使用build自动设置实例化对象之间的关联。

contributor = Contributor.new
contributor.contributorships.build(:contribution_type => :author)
contributor.resources.build
contributor.save!

答案 1 :(得分:1)

如果contributor_type的值依赖于其他模型之一的值,我倾向于只在每次创建贡献者时编写一个before_validation回调来设置正确的对应值。即。

model Contributorships

  attr_accessible :contribution_type, :contributor, :archive_resource

  belongs_to resources
  belongs_to contributors

  before_validation :set_contributor_type

  def set_contributor_type
     if self.new_record?
        # Whatever code you need to determine the type value
        self.contributor_type = value
     end
  end

end

如果这是用户定义的值,那么您需要使用accepts_nested_attributes_for,其中模型定义了您的contributor_type,然后在表单中使用fields_for来允许用户在创建记录时设置值。在以下railscast中非常全面且详细地介绍了这一点:http://railscasts.com/episodes/197-nested-model-form-part-2?view=asciicast

<强>即:

<%= form_for(contributor) do |f| %>
   # Whatever fields you want to save for the contributor
   <% contributorship = f.object.contributorships.build %>
   <%= f.fields_for(:contributorships, contributorship) do |new_contributorship| %>
         # Whatever fields you want to save for the contributorship
         <% resource = new_contributorship.object.resources.build %>
         <%= f.fields_for(:resources, resource) do |new_resource| %>
                # Whatever fields you want to save for the resource
         <% end %>
   <% end %>
<% end %>