我有这样一种深层次的关系:
>> @document.template_variables.first.master.box.stack
=> #<Stack id: 6, name: "Contact information", direction: "down", x: 145.0, y: 145.0, template_id: 28, width: 55, page: 1, html_box: "column_right">
Master不是完全正常的Rails关系,它在TemplateVariable
中定义如下:
def master
TemplateVariable.find(master_id) if master_id.present?
end
所以它有点指的是它自己的另一个实例,但正如你从顶部的日志输出中看到它可以正常工作。
我的问题是,我需要所有 TemplateVariables
,其父Stack
与框名称匹配,如下所示:
scope :by_box, -> (b) { where('box.stack.html_box' => b) }
但无论我尝试什么,即使在控制台中,我都无法正确查询。
>> @document.template_variables.where(master.box.stack.html_box != nil)
!! #<NameError: undefined local variable or method `master' for #<#<Class:0x007fd287cd9888>:0x007fd28bb11ee8>>
并且范围返回此错误:
ActiveRecord::StatementInvalid - PG::UndefinedTable: ERROR: missing FROM-clause entry for table "box"
LINE 1: ...WHERE "template_variables"."document_id" = $1 AND "box"."sta...
有任何帮助吗?我错过了什么?
答案 0 :(得分:1)
我想我应该在这里创建一个答案。您的范围引发了错误,因为您没有在where子句boxes
之前加入表stacks
和where('box.stack.html_box' => b)
。 Rails会将其转换为SQL查询
SELECT "template_variables".* FROM "template_variables" WHERE "box"."stack.html_box" = ...
如您所见,此查询不知道where子句。哪个是"box"
表?这是"stack.html_box"
列?
所以你要做的就是首先加入boxes
和stacks
,然后where子句是where(stacks: { html_box: b })
或where('stacks.html_box' => b })
(stacks
是复数,因为它是表名),它被转换为SQL查询
SELECT "template_variables".* FROM "template_variables" INNER JOIN "boxes" ON "boxes"."id" = "template_variables"."box_id" INNER JOIN "stacks" ON "stacks"."id" = "boxes"."stack_id" WHERE "stacks"."html_box" = ...
它会运作良好。
另一个建议是,您应该将master
定义为belongs_to
关联,例如
belongs_to :master, class_name: 'TemplateVariable', foreign_key: :master_id
希望得到这个帮助。