a:has_many中的多个条目通过关联

时间:2011-08-22 06:05:03

标签: ruby-on-rails model-associations

我需要一些帮助,我正在使用rails 3进行rails开发。 这个应用程序是在几个月前刚刚发布之后给我的,后来我变得非常喜欢Ruby。

我有一组可以通过团队表分配资源的项目。

团队记录具有开始日期和结束日期(即,从项目中分配和取消分配资源时)。

如果已为项目分配和取消分配用户,并且稍后将其分配回项目, 我希望在Teams表中创建一个新条目,而不是过度写入结束日期,以便能够跟踪资源分配给某个项目的日期。

所以我的问题是,是否可以在a:has_many中通过关联创建多个条目?

这是我的联想:

class Resource < ActiveRecord::Base
  has_many :teams
  has_many :projects, :through => :teams 
end

class Project < ActiveRecord::Base
  has_many :teams
  has_many :resources, :through => :teams
end

class Team < ActiveRecord::Base
  belongs_to :project
  belongs_to :resource
end

我在Project.rb中也有以下功能:

after_save  :update_team_and_job

private
  def update_team_and_job

    # self.member_ids is the selected resource ids for a project

    if self.member_ids.blank?
      self.teams.each do |team|
        unless team.deassociated
          team.deassociated = Week.current.id + 1
          team.save
        end
      end
    else
      self.teams.each do |team|

        #assigning/re-assigning a resource

        if self.member_ids.include?(team.resource_id.to_s)
          if team.deassociated != nil
            team.deassociated = nil
            team.save
          end
        else

          #de-assigning a resource

          if team.deassociated == nil
            team.deassociated = Week.current.id + 1
            team.save
          end
        end
      end

      y = self.member_ids - self.resource_ids
      self.resource_ids = self.resource_ids.concat(y)

      self.member_ids = nil
    end
  end
end

1 个答案:

答案 0 :(得分:0)

当然,您可以拥有多个关联。 has_many采用:uniq选项,您可以将其设置为false,并且如文档所述,它对于:通过rel'ns特别有用。

您的代码是找到一个现有的团队并设置取消关联,而不是添加一个新的团队(我认为这会更好地命名为TeamMembership)

我想你想做这样的事情:

  1. 为活动成员资格添加一个关联(但在此使用uniq:=&gt; true:

    has_many :teams
    has_many :resources, :through => :teams, :uniq => false
    has_many :active_resources, 
             :through => :teams, 
             :class_name => 'Resource', 
             :conditions => {:deassociated => nil},
             :uniq => true
    
  2. 添加时,如果不存在则添加到active_resources,并“取消关联”已删除的任何团队:

    member_ids.each do |id|
      resource = Resource.find(id) #you'll probably want to optimize with an include or pre-fetch
      active_resources << resource # let :uniq => true handle uniquing for us
    end
    
    teams.each do |team|
      team.deassociate! unless member_ids.include?(team.resource.id) # encapsulate whatever the deassociate logic is into a method
    end
    
  3. 更少的代码,更加惯用。此外,代码现在更明确地反映了业务建模

    警告:我没有为此编写测试应用程序,代码可能缺少一两个细节