1

ここに私のモデルがあります:

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

これを説明するものは何ですか?どうすればこれを機能させることができますか?

4

2 に答える 2

0
s1.flight.equal? s2.flight
=> true

とがまったく同じ Ruby オブジェクトを参照しているためs1.flight、上記は true になります。s2.flight

s1.flight.equal? s3.flight

ここでは、さまざまな Ruby オブジェクトs1.flights3.flight参照します。どちらも同じレコード データ(同じ値を含む)を含んでいます。:id

問題は、Railsやコンパレータequal?を使用する必要があるときに、Ruby のメソッドを使用していることです。==eql?

Ruby docs for (およびとしてエイリアス化)からObject== eql?equal?

等価 — オブジェクト レベルでは、== は obj と other が同じオブジェクトである場合にのみ true を返します。通常、このメソッドは下位クラスでオーバーライドされ、クラス固有の意味を提供します。

残念ながら、equal?バリエーションはでオーバーライドされませんActiveRecord::BaseRails docs for == (aliased as eql?)から:

comparison_object がまったく同じオブジェクトである場合、または comparison_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
于 2013-04-20T06:43:21.227 に答える