测试ActiveRecord :: Relation的相等性

sto*_*elj 3 ruby-on-rails

我有两个ActiveRecord:Relation对象:

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>]>
Run Code Online (Sandbox Code Playgroud)

每个包含一条记录,这些记录通过==测试,

actual.size #=> 1
expected.size #=> 1
actual.first == expected.first #=> true
Run Code Online (Sandbox Code Playgroud)

但是ActiveRecord::Relation对象没有:

actual == expected #=> false
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么两个ActiveRecord::Relation对象没有通过==测试.谁能帮我理解为什么?

spi*_*ann 5

值得注意的是,ActiveRecord::Relation只是定义了一个数据库查询.它只保存有关信息where的条件,limit,joins等条款.但是在实际请求结果之前不会执行该查询.

因此,在一定条件下最终返回相同结果的两个关系不被视为相等是有道理的.因为在另一个条件下运行两个查询可能会返回不同的结果:可能是因为它们返回时间戳或返回是随机排序的.

一旦需要结果就执行查询:当您打电话eachall例如.或者在你的例子中:sizefirst.查询运行后,将返回实际结果(而不再是Relation对象).因此所有后来的比较都会回归true.

  • 调用 .to_sql 后,我发现获取两个活动关系的 sql 确实不同。因此,我对每个对象进行了完整切片(制作活动记录数组)并比较了两个数组,这有效。可能还有更优雅的东西,但它就在那里。 (2认同)