Rails - 使用与自定义命名关联的连接

Seb*_*nso 3 ruby postgresql activerecord ruby-on-rails ruby-on-rails-5

我有以下型号

class Measurement < ApplicationRecord
  belongs_to :examination, class_name: "TestStructure", foreign_key: "examination_id"

end
Run Code Online (Sandbox Code Playgroud)

该关联实际上是对TestStructure模型进行的,但关联名称是检查.没有检查表.

当我查询使用时出现问题join.以下查询

Measurement.joins(:examination).where(examination: { year: 2016, month: 5 })
Run Code Online (Sandbox Code Playgroud)

失败,出现此错误

ActiveRecord::StatementInvalid:
   PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "examination"
   LINE 1: ...d" = "measurements"."examination_id" WHERE "examinati...
# --- Caused by: ---
 # PG::UndefinedTable:
 #   ERROR:  missing FROM-clause entry for table "examination"
 #   LINE 1: ...d" = "measurements"."examination_id" WHERE "examinati...
Run Code Online (Sandbox Code Playgroud)

很明显,该examinations表不存在,但我找不到告诉ActiveRecord我使用命名关联而不是默认关联的方法.

任何见解?

Dan*_*sky 6

where 期望实际的表名,它只是在SQL中插入它:

Article.where(whatever: {you: 'want'}).to_sql
=> "SELECT `articles`.* FROM `articles` WHERE `whatever`.`you` = 'want'"
Run Code Online (Sandbox Code Playgroud)

所以你可以使用:

Measurement.joins(:examination).where(test_structures: { year: 2016, month: 5 })
Run Code Online (Sandbox Code Playgroud)

但这并不好

然后你依赖于表名,而Model应该抽象这样的东西.你可以使用merge:

Measurement.joins(:examination).merge(TestStructure.where(year: 2016, month: 5))
Run Code Online (Sandbox Code Playgroud)

  • @Sebastialonso你选择不是最好的解决方案:然后你依赖于表名而不是依赖于应该抽象的东西的模型 (3认同)

Grz*_*orz 5

对于联接,您使用关联名称,但是对于需要使用表名称的位置

Measurement.joins(:examination).where(test_structures: { year: 2016, month: 5 })
Run Code Online (Sandbox Code Playgroud)

要么

Measurement.joins(:examination).where('test_structures.year': 2016, 'test_structures.month': 5 )
Run Code Online (Sandbox Code Playgroud)