我有带变量的模型(许多模型类:多态关系),以及变量之间的约束(变量不一定在同一模型中。
我尝试进行查询以查找与模型列表相关联的所有约束(所有变量都与列表中的模型相关联,而我真的不知道该怎么做。
我的模特看起来像这样。
class Model1 < ApplicationRecord
has_many :vars, as: :model
end
class Model2 < ApplicationRecord
has_many :vars, as: :model
end
class Var < ApplicationRecord
belongs_to :model, polymorphic: true
# model_type and model_id in vars table
has_many :cns_vars
has_many :constraints, through: :cns_vars
end
class_CnsVar < ApplicationRecord
belongs_to :var
belongs_to :constraint
end
class Constraint < ApplicationRecord
has_many :cns_vars
has_many :vars, through: :cns_vars
end
要找到与一个模型有关的约束,我有这个查询:
Constraint.includes(:vars).where(active: true, vars: {model_id: model.id, model_type: model.class.to_s})
此查询为我提供了至少有一个与模型关联的变量的约束。我需要与模型列表关联的all vars约束。
是否可以进行相同的查询,但是所有变量都与模型相关联?有没有一种方法可以进行相同的查询,但所有变量都与模型列表相关联?
Constraint.includes(:vars).where(active: true, vars: {*[var.model_type, var.model_id] in my models list*})
是否有一种解决方案可以通过一个查询来执行此操作?还是我必须用另一种方式做?
感谢您的帮助。
(红宝石:2.6.0 /滑轨:5.2.3)
编辑:为了给出更好的解释,请看一下此函数,该函数返回我需要的内容,但是这样做会产生太多查询!
def constraints_for_models_list(models)
all_vars = models.flat_map(&:vars)
all_constraints = all_vars.flat_map(&:constraints)
all_constraints.uniq!
constraints = []
all_constraints.each do |constraint|
next unless constraint.vars.included_in?(all_vars)
constraints << constraint
end
return constraints
end
Constraint.includes(:vars).where(active: true).where.not(vars: { model: nil })
当然,如果我正确理解了您要尝试的内容。
关于您在评论中的要求:Constraint.includes(:vars).where(active: true).where('vars.model_type IN
?', ['Model1',Model2'])
您可以使用INNER JOIN子句,通过其外键(我猜是constraint_id),添加joins
以确保约束表中的每一行都与cns_vars表中的行匹配:
Constraint
.joins(:vars)
.includes(:vars)
.where(active: true, vars: { model_id: model.id, model_type: model.class.to_s })