Ruby on rails Rails:具有多态关联和自定义类名的嵌套联接查询

Ruby on rails Rails:具有多态关联和自定义类名的嵌套联接查询,ruby-on-rails,postgresql,activerecord,Ruby On Rails,Postgresql,Activerecord,考虑以下一个学校的例子。有一个教室(选择“类”一词以避免任何语法混乱)。每个教室都有许多学生和一位级长,他是这些学生中的一位。下面是我如何编写模型的: 课堂 有很多:学生,相反的::教室 所属:级长,班名:“学生”,与::教室相反 终止 班级学生 属于:教室,与学生相反 属于:house,与::成员相反 终止 班房 有很多:成员,班名:“学生”,倒数::房子,外键:“房子id” has_one:address,as::addressable 终止 班级地址 #属性city::string 属于:

考虑以下一个学校的例子。有一个教室(选择“类”一词以避免任何语法混乱)。每个教室都有许多学生和一位级长,他是这些学生中的一位。下面是我如何编写模型的:

课堂
有很多:学生,相反的::教室
所属:级长,班名:“学生”,与::教室相反
终止
班级学生
属于:教室,与学生相反
属于:house,与::成员相反
终止
班房
有很多:成员,班名:“学生”,倒数::房子,外键:“房子id”
has_one:address,as::addressable
终止
班级地址
#属性city::string
属于:可寻址,多态:true
终止
house的目的是跟踪来自同一家的学生。每个房子都有一个地址,地址的属性之一是城市。当然,为了简洁起见,我没有提到每个模型中的其他属性<例如,代码>地址,属于此处未列出的其他模型,因此存在多态关联

目标

我的目标是得到一份来自某个城市的级长名单。我知道在Ruby中有很多方法可以解决这个问题,但是如何使用ActiveRecord/SQL查询来实现呢?我正在使用Rails 5.0和Postgres 9.6

我尝试过的

我已经尝试了两种方法,都是通过将表格连接起来。然而,我面临的问题是,由于非常规名称,AR无法生成apt查询。以下是我尝试的最有希望的变化:

classification.joins(级长:{house::address})。其中(级长:{house:{address:{city:“巴塞罗那”})
连接似乎工作正常。但是,
where
位变得疯狂,因为perfict的底层表是
students
。运行它的结果只是一个ActiveRecord关系对象。但是在上面运行
。\u a
,我会得到以下结果:

ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "address"
我成功地检索到了其级长有特定名字的教室,如下所示:

教室。加入(级长:{house::address})。其中(学生:{first_name:“Juliana”})
但这是我最好的了。当嵌套出现时,我无法应用相同的逻辑:

教室.连接(级长:{house::address}).where(学生:{house:{address:{city:“巴塞罗那”})
运行此操作将导致以下错误:

NoMethodError: undefined method `_reflect_on_association' for nil:NilClass
from /home/vagrant/.rvm/gems/ruby-2.3.1@school/gems/activerecord-5.0.0.1/lib/active_record/table_metadata.rb:47:in `associated_table'
你知道我应该在这里做什么吗

Classroom.joins(prefect: {house: :address}).where(prefects: { houses: { addresses: { city: "Barcelona"}}})
旁注:我认为您过度使用了
:与
相反的内容。从导轨上

活动记录支持大多数关联的自动识别 用标准的名字。但是,活动记录不会自动恢复 确定包含以下任何一项的双向关联 选项:

  • :条件

  • :通过

  • :多态

  • :类名

  • :外键


我终于找到了对我有用的东西,它比我最初尝试的要简单得多:

school.joins(级长:{house::address})。其中(“address.city=?”,“巴塞罗那”)

这是一个很好的问题,但我认为它需要一个更好的标题来描述情况,以便其他有类似问题的人可以找到它。类似于“Rails:具有多态关联的嵌套连接查询”的内容哦,是的!好建议。我会继续改变的。@m-simon-borg我还在争论什么是更好的联系。从一个角度来看,学生档案中应该知道自己是否是一名级长。但另一方面,这些细节与课堂密切相关,而不是与学生密切相关。这就是我选择当前方法的原因。@Jerry但是教室能在没有外键匹配的情况下找到它的完美吗?噢!看起来我在原始片段中犯了一个错误。老实说,这些模型不是我真正拥有的。它们只是我选择的等价物,我刚刚意识到这可能不是最好的类比。我现在已经更新了代码片段。课堂中的关联是
属于:perfect…
,我知道这在课堂环境中是没有意义的,但它是我的模型的一个相同的表示形式,而这种关联实际上是有意义的。好的,答案顶部的更新查询现在起作用了吗@杰瑞
class Author < ApplicationRecord
  has_many :books, inverse_of: 'writer'
end

class Book < ApplicationRecord
  belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
end
class Classroom
  has_many :students
  belongs_to :prefect, class_name: "Student"
end

class Student
  belongs_to :classroom
  belongs_to :house, inverse_of: :members
end

class House
  has_many :members, class_name: "Student", foreign_key: "house_id"
  has_one :address, as: :addressable
end

class Address
  belongs_to :addressable, polymorphic: true
end