Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Using join with custom-named associations

I have the following model

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

end

The association is actually made to the TestStructure model, but the association name is examination. There is no examination table.

The problem arises when I'm querying using join. The following query

Measurement.joins(:examination).where(examination: { year: 2016, month: 5 })

fails, with this error

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...

So clearly, the examinations table doesn't exists, but I can't find a way to tell ActiveRecord I'm using a named association instead of the default one.

Any insights?

like image 348
Sebastialonso Avatar asked Aug 29 '17 19:08

Sebastialonso


3 Answers

where expects the actual table name, it just inserts it in SQL:

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

So you may use:

Measurement.joins(:examination).where(test_structures: { year: 2016, month: 5 })

But it's not good

Then you depend on table name while Model should abstract such things. You could use merge:

Measurement.joins(:examination).merge(TestStructure.where(year: 2016, month: 5))
like image 175
Danil Speransky Avatar answered Nov 14 '22 23:11

Danil Speransky


For joins you use the association name, but for where you need to use the table name

Measurement.joins(:examination).where(test_structures: { year: 2016, month: 5 })

or

Measurement.joins(:examination).where('test_structures.year': 2016, 'test_structures.month': 5 )
like image 38
Grzegorz Avatar answered Nov 14 '22 22:11

Grzegorz


In this example table name examinations should be provided instead of an association name examination in the where method.

Measurement.jons(:examination).where(examinations: { year: 2016, month: 5 })
like image 28
potashin Avatar answered Nov 15 '22 00:11

potashin