Равенство объектов ActiveRecord - PullRequest
5 голосов
/ 16 марта 2011

В соответствии с документами ActiveRecord :: Base :

== (сравнение_объекта) Возвращает истину, если объект сравнения_объекта является точно таким же точным объектом или объект сравнения_объекта того же типа иУ self есть идентификатор, и он равняется Сравнение_объекта.

Обратите внимание, что новые записи отличаются от любой другой записи по определению, если только другая запись не является самим получателем.Кроме того, если вы извлекаете существующие записи с помощью select и пропускаете идентификатор, вы сами по себе, этот предикат вернет false.

Обратите внимание также, что при удалении записи сохраняется ее идентификатор в экземпляре модели, поэтому он был удаленмодели по-прежнему сопоставимы.

Но мои наблюдения показывают, что сравниваются только инстакты, а не идентификаторы, поэтому справедливо следующее:

a = Factory.create(:user)
b = User.find_by_email(a.email) # b is logically same as a

a.id.should == b.id # All good
a.should == b # FAILS: Contradicts the docs
a.should_not == b # Contradicts the docs
a.should_not eql b # Contradicts the docs

Вопрос состоит в том, что рассматриваются 2 случая ARотличаться, в то время как документы прямо говорят, что они должны быть равны?

ОБНОВЛЕНИЕ: Равенство РАБОТАЕТ как ожидалось . Пример кода выше не имеет значения .Смотрите мой ответ ниже.

Ответы [ 2 ]

5 голосов
/ 17 марта 2011

Отвечая на мой собственный вопрос (который не имеет значения).

Все проверки на равенство ДОЛЖНЫ работать как положено (и описано в документации).
Я предполагаю, что это не сработало для меня в том, чтоЯ запускаю autotest, и что-то может быть кэшировано или какая-то другая мифическая причина, которую я сейчас не могу объяснить.

Подводя итог, все следующие утверждения действительно проходят:

a = Factory.create(:user)
b = User.find_by_email(a.email) # b is logically same as a

a.id.should == b.id
a.should == b
a.should eql b
User.find_by_email(a.email).should == User.find_by_email(a.email)
a.should == User.find_by_email(a.email)
b.should == User.find_by_email(a.email)
4 голосов
/ 16 марта 2011

Присмотритесь к определению: Обратите внимание, что новые записи отличаются от любой другой записи по определению .

В этом случае, поскольку AR обычно просто проверяет равенство в столбце идентификаторов,Вы можете сравнить два объекта, сравнив результат того, что #attributes возвращает для каждого.

...