stoebelj
stoebelj

Reputation: 1598

Testing equality for ActiveRecord::Relation

I have two ActiveRecord:Relation objects:

actual
#=> #<ActiveRecord::Relation [#<AdmTep id: 587730567, Student_Bnum: "145919559", Program_ProgCode: "750600237", BannerTerm_BannerTerm: 201511, Attempt: 1, GPA: 2.75, GPA_last30: 3.0, EarnedCredits: 30, PortfolioPass: nil, TEPAdmit: true, TEPAdmitDate: nil, Notes: nil, letter_file_name: "letter.docx", letter_content_type: nil, letter_file_size: nil, letter_updated_at: nil>]>
expected
#=> #<ActiveRecord::Relation [#<AdmTep id: 587730567, Student_Bnum: "145919559", Program_ProgCode: "750600237", BannerTerm_BannerTerm: 201511, Attempt: 1, GPA: 2.75, GPA_last30: 3.0, EarnedCredits: 30, PortfolioPass: nil, TEPAdmit: true, TEPAdmitDate: nil, Notes: nil, letter_file_name: "letter.docx", letter_content_type: nil, letter_file_size: nil, letter_updated_at: nil>]>

Each contains a single record, and those records pass an == test,

actual.size #=> 1
expected.size #=> 1
actual.first == expected.first #=> true

but the ActiveRecord::Relation objects do not:

actual == expected #=> false

I am having trouble understanding why two ActiveRecord::Relation objects do not pass an == test. Can anyone help me understand why?

Upvotes: 5

Views: 1928

Answers (1)

spickermann
spickermann

Reputation: 106792

It is worth noting that an ActiveRecord::Relation just defines a database query. It only holds information about where conditions, limit, joins etc. clauses. But that query is not performed until a result is actually requested.

Therefore it makes sense that two relations that would end up returning the same result under a certain condition are not treated as equal. Because running both queries under another condition might return different results: Maybe because they return timestamps or the return is randomly ordered.

The query is performed once a result is needed: When you call each or all for example. Or in your example: size or first. Once the query ran the actual result is returned (and not a Relation object anymore). Therefore all later comparisons return true.

Upvotes: 6

Related Questions