如何在ActiveRecord中执行嵌套查询?

时间:2014-05-13 16:21:52

标签: ruby-on-rails activerecord

模型A has_many model_bs。

模型B belongs_to model_a和model_c。

模型C has_many model_bs,可以是blackwhite类型。

我想拉出模型A的所有记录,这些记录具有模型B,属于类型black的模型C.到目前为止,我可以提取模型B的所有记录,它们属于black类型的模型C,如下所示:

ModelB.joins(:model_c).where("model_c.type = 'black'")

这会返回ActiveRecord::Relation::ActiveRecord_Relation_ModelB,但现在我需要这样的内容:

records = ModelB.joins(:model_c).where("model_c.type = 'black'")
Model_A.where model_b: records

由于显而易见的原因而无效。

我尝试的另一件事是:

Model_A.includes(:model_bs).includes(model_c).where("model_c.type = 'black'")

但这会产生错误:

ActiveRecord::ConfigurationError:
       Association named 'model_c' was not found on ModelA; perhaps you misspelled it?

那我该怎么做?我还想了解查询的原理,当你有很多链式模型并希望根据模型Y的属性检索模型X的记录时,模型Y与模型X相距n级。

3 个答案:

答案 0 :(得分:3)

我认为您需要joins而不是includes,因为您只需要一个模型。

Model_A.joins(model_bs: :model_c).where("model_cs.type = 'black'").references(:model_cs)

因为modelA有很多型号 和modelC有很多型号

答案 1 :(得分:1)

您输错了:includes(model_c)应为includes(:model_c),这就是错误Association named 'model_c' was not found on ModelA的来源。

获取查询的一种方法可能是:

Model_A.includes(:model_bs, :model_cs).where("model_cs.type = 'black'").references(:model_cs)

同样在您的模型中,您可以通过以下方式直接链接Model_A和Model_C:

在Model_A中

has_many :model_cs, :through => :model_bs

在Model_C

has_many :model_as, : through => :model_bs

答案 2 :(得分:0)

仅仅是为了记录 - 因为我不断得到错误,模型A上没有定义model_c属性,我认为在ModelA.includes(:model_bs).includes(:model_c)中它会搜索ModelA和ModelC之间的直接关系。所以我这样做了 - ModelA和ModelC之间的共同实体是ModelB,因此:

ModelB.includes(:model_a).included(:model_c).where("my_string_criteria")

虽然这会返回ModelB的实例而不是ModelA的实例,正如我原先想要的那样,这不是问题,因为我只需要ModelA的一个字段中的值,并且无论如何都会使用pluck。所以我在上面提到的关系中使用了pluck而仍然得到了我想要的东西。但xlembouras更准确,更有效率,所以我提出了他的建议。