通过关联在 :has_many 中包含多个条目

发布于 2024-11-30 12:02:13 字数 1610 浏览 4 评论 0原文

我正在使用 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

I need some help with a rails development that I'm working on, using rails 3.
This app was given to me a few months ago just after it's inception and I have since become rather fond of Ruby.

I have a set of Projects that can have resources assigned through a teams table.

A team record has a start date and a end date(i.e. when a resource was assigned and de-assigned from the project).

If a user has been assigned and deassigned from a project and at a later date they are to be assigned back onto the project,
instead of over writting the end date, I want to create a new entry in the Teams table, to be able to keep a track of the dates that a resource was assigned to a certain project.

So my question is, is it possible to have multiple entries in a :has_many through association?

Here's my associations:

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

I also have the following function in 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

Bonjour°[大白 2024-12-07 12:02:13

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

您的代码是找到一个现有的团队并设置解除关联,而不是添加一个新的团队(我认为最好将其命名为 TeamMembership)

我认为您只想做这样的事情:

  1. 为活跃成员资格添加一个关联(但是在这个中使用 uniq: => true:

    has_many :团队
    has_many :资源, :through => :团队,:uniq =>错误的
    has_many :活动资源, 
             :通过=> :团队, 
             :类名=> '资源', 
             :条件=> {:解除关联=>零},
             :uniq =>真的
    
  2. 添加时,如果 active_resources 不存在,则将其添加到其中,并“取消关联”任何团队已被删除:

    member_ids.each do |id|
      resource = Resource.find(id) #您可能希望通过包含或预取进行优化
      活动资​​源<<资源 # let :uniq =>真正的手柄对我们来说是独一无二的
    结尾
    
    团队。每个人都做|团队|
      team.解除关联! except member_ids.include?(team.resource.id) # 将任何解除关联的逻辑封装到一个方法中
    结尾
    

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

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

Sure, you can have multiple associations. has_many takes a :uniq option, which you can set to false, and as the documentation notes, it is particularly useful for :through rel'ns.

Your code is finding an existing team and setting deassociated though, rather than adding a new Team (which would be better named TeamMembership I think)

I think you want to just do something like this:

  1. add an assoc for active memberships (but in this one use 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. when adding, add to the active_resources if it doesn't exist, and "deassociate" any teams that have been removed:

    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
    

much less code, and much more idiomatic. Also the code now more explicitly reflects the business modelling

caveat: i did not write a test app for this, code may be missing a detail or two

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文