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 は、false に設定できる :uniq オプションを使用します。ドキュメントに記載されているように、:through rel'ns に特に役立ちます。

あなたのコードは、新しいチームを追加するのではなく、既存のチームを見つけて関連付けを解除しています(TeamMembershipという名前の方が良いと思います)

次のようなことをしたいだけだと思います:

  1. アクティブなメンバーシップの関連付けを追加します (ただし、この例では 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
    

コードがはるかに少なくなり、より慣用的になります。また、コードはビジネス モデリングをより明確に反映するようになりました。

警告: 私はこのためのテスト アプリを作成していません。コードには詳細が 1 つまたは 2 つ欠けている可能性があります

于 2011-08-22T06:21:53.067 に答える