[has_many]关系在[类型,标识]列表中进行滚动查询

问题描述 投票:0回答:1

我有带变量的模型(许多模型类:多态关系),以及变量之间的约束(变量不一定在同一模型中。

我尝试进行查询以查找与模型列表相关联的所有约束(所有变量都与列表中的模型相关联,而我真的不知道该怎么做。

我的模特看起来像这样。

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
mysql ruby-on-rails ruby-on-rails-5
1个回答
1
投票

Constraint.includes(:vars).where(active: true).where.not(vars: { model: nil })当然,如果我正确理解了您要尝试的内容。

关于您在评论中的要求:Constraint.includes(:vars).where(active: true).where('vars.model_type IN ?', ['Model1',Model2'])


0
投票

您可以使用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 })
© www.soinside.com 2019 - 2024. All rights reserved.