2017-03-01 65 views
0

我试图重构,有很多的has_many的型号范围:通过涉及在连接表的条件协会Rails的避免重复加入对已加入和合并

class Assignment 
    has_many :assignment_reviewers 
    has_many :preferred_assignment_reviewers, -> { preferred } 
    # more of these for different types of reviewers 

    has_many :reviewers, through: :assignment_reviewers 
    has_many :preferred_reviewers, through: :preferred_assignment_reviewers 
    # more of these 

我添加了以下范围在审阅

class Reviewer 
    scope :preferred, -> do 
    joins(:assignment_reviewers).merge(AssignmentReviewer.preferred) 

,这样我可以做

assignment.reviewers.preferred 

,而不是使用的has_many

assignment.preferred_reviewers 

但是,在重复INNER前者结果JOIN

INNER JOIN `assignment_reviewers` `assignment_reviewers_reviewers` 
ON `assignment_reviewers_reviewers`.`reviewer_id` = `reviewers`.`id` 
INNER JOIN `assignment_reviewers` 
ON `reviewers`.`id` = `assignment_reviewers`.`reviewer_id` 

看来我有三种选择:

  1. 保持定义has_manys和的has_many:得来的每一个(缺点:很多在已经是神级的模型上的特定关联)
  2. 使用范围(下侧:重复连接)
  3. 使用合并直接

    assignment.reviewers.merge(AssignmentReviewer.preferred) 
    

    (缺点:不是能言善辩)

我倾向于选择选项2,因为更清晰的代码,我猜测额外的加入不会对绩效有重大影响。

任何建议/有没有更好的选择,我错过了?

回答

0

我想通了,我喜欢比三我列出更好的解决方案:

我添加了一个扩展块到我的has_many:通过声明

has_many :reviewers, through: :assignment_reviewers do 
    def preferred 
    merge(AssignmentReviewer.preferred) 
    end 
end 

虽然我仍然不得不宣布大​​量的扩展,这是一个比每个has_many声明has_many和has_many都要简洁得多,因为我需要