4

我需要一些关于我正在使用 rails 3 进行的 Rails 开发的帮助。这个应用程序是在几个月前刚开始的​​时候给我的,从那以后我变得相当喜欢 Ruby。

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

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

如果用户已从项目中分配和取消分配,并且在以后将他们分配回项目中,而不是重写结束日期,我想在 Teams 表中创建一个新条目,以便能够跟踪资源分配给某个项目的日期。

所以我的问题是,是否可以通过关联在 :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
4

1 回答 1

0

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

您的代码正在查找现有团队并设置取消关联,而不是添加新团队(我认为最好命名为 TeamMembership)

我想你只想做这样的事情:

  1. 为活动成员添加一个 assoc(但在此使用 uniq: => 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
    

更少的代码,更多的惯用语。此外,代码现在更明确地反映了业务建模

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

于 2011-08-22T06:21:53.067 回答