Rails 4 作用域联接以查找非此即彼的关系



我有一个带有许多关系的rails 4.2.8应用程序。我的相互作用模型具有并且属于许多基因(特别是相互作用可以有2个基因,而一个基因可以属于任意数量的相互作用(,而基因模型又有许多药物和疾病。

我试图允许用户根据其一个或另一个基因是否具有与之相关的药物和/或疾病来过滤相互作用。如果选择了药物或疾病"过滤器",则下面的代码按要求工作,因为显示与至少一个具有至少其中一个关联的基因的所有相互作用。

但是,当检查两个过滤器时,我只显示一个或两个基因至少具有一种药物至少一种疾病相关的相互作用。我还想展示一个基因有药物但没有疾病,另一个基因有疾病但没有药物相关的相互作用。

模型

class Interaction < ActiveRecord::Base
has_and_belongs_to_many :genes
...
scope :disease_associated, -> { joins(genes: :diseases) }
scope :drug_target, -> { joins(genes: :drugs) }
...
end
class Gene < ActiveRecord::Base
has_and_belongs_to_many :interactions
has_and_belongs_to_many :drugs
...
end
class Drug < ActiveRecord::Base
has_and_belongs_to_many :genes
end
class Disease < ActiveRecord::Base
has_and_belongs_to_many :genes
end

交互控制器

class InteractionsController < ApplicationController
...
@interactions = @interactions.disease_associated() if params[:filter_disease].present?
@interactions = @interactions.drug_target() if params[:filter_druggable].present?
...

我没有找到任何明显解决此问题的方法/问题,尽管这可能是由于我无法找到足够简洁地解决问题以有效搜索的单词。

提前感谢!

在 Rails 4 中,我可以提出两个选项:

1. 身份证件列表

ids = []
ids |= Interaction.disease_associated.pluck(:id) if params[:filter_disease].present?
ids |= Interaction.drug_target.pluck(:id) if params[:filter_druggable].present?
interactions = Interaction.where(id: ids)

清除,但如果数据库中有许多交互,则不好。

2. 联盟

Gem active_record_union gem 为 Rails 提供 SQLUNION支持。

interactions = Interaction.none
interactions = interactions.union(Interaction.disease_associated) if params[:filter_disease].present?
interactions = interactions.union(Interaction.drug_target) if params[:filter_druggable].present?

附言:通过常见查询而不是按域设计数据库。

最新更新