以下是我的模特:
class Flight < ActiveRecord::Base
has_many :seats, dependent: :destroy, inverse_of: :flight
end
class Seat < ActiveRecord::Base
belongs_to :flight, inverse_of: :seats
end
似乎inverse_of
效果很好,但是当我使用条件时它不起作用:
f1 = Flight.first
s1 = f1.seats.first
s2 = f1.seats.second
s3 = f1.seats.where(id: 0..1000000).third
s1.flight.equal? s2.flight
=> true
s1.flight.equal? s3.flight
=> false
这解释了什么?我怎样才能做到这一点?
答案 0 :(得分:0)
s1.flight.equal? s2.flight
=> true
以上结果为真,因为s1.flight
和s2.flight
引用完全相同的Ruby对象。
s1.flight.equal? s3.flight
此处,s1.flight
和s3.flight
引用不同的Ruby对象。它们都包含相同的记录数据(包括相同的:id
值)
当你应该使用Rails的==
或eql?
比较器时,问题是你正在使用Ruby的equal?
方法。
来自 the Ruby Object
docs for ==
(aliased as eql?
and equal?
)
Equality - 在Object级别,只有当obj和other是同一个对象时,==才返回true。 通常,在子类中重写此方法以提供特定于类的含义。
不幸的是,equal?
是ActiveRecord::Base
中覆盖的变种不。来自 the Rails docs for ==
(aliased as eql?
) :
如果comparison_object是完全相同的对象,或者compare_object属于同一类型且self具有ID并且它等于comparison_object.id,则返回true。
你会发现这与:inverse_of
无关。您可以尝试一个简单的例子
f1 = Flight.all.first
f2 = Flight.all.first
f1.eql? f2
=> true
f1 == f2
=> true
f1.equal? f2 # Direct Object comparison (skips ActiveRecord::Base)
=> false
答案 1 :(得分:0)
Inverse_of
选项不适用于条件,这就是s1.flight
和s3.flight
不相等的原因 - ActiveRecord
只是在您执行时从数据库重新加载对象{{ 1}}。这似乎是记录在案的行为,请参阅https://github.com/rails/rails/issues/23693#issuecomment-184438933