2011-03-16 47 views
5

Theo tài liệu của ActiveRecord::Base:ActiveRecord bình đẳng đối tượng

== (comparison_object) Trả về true nếu comparison_object là như nhau đối tượng chính xác , hoặc comparison_object là của cùng loại và tự có một ID và nó là bằng compare_object.id.

Lưu ý rằng các bản ghi mới khác nhau từ bất kỳ bản ghi nào khác theo định nghĩa, trừ khi bản ghi khác là bản thân số . Ngoài ra, nếu bạn tìm nạp hồ sơ hiện có với chọn và để lại ID, bạn đang ở chế độ riêng của mình, vị từ này sẽ trả về false.

Cũng lưu ý rằng việc hủy hồ sơ sẽ giữ ID của mẫu đó trong mẫu , do đó, các mô hình đã xóa vẫn còn so sánh được.

Nhưng quan sát của tôi cho thấy rằng nó chỉ so sánh instaces, không ids để sau là đúng:

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 

Câu hỏi đặt ra là 2 AR trường hợp được coi là khác nhau trong khi các tài liệu một cách rõ ràng nói rằng những nên bằng nhau?

CẬP NHẬT: Bình đẳng LÀM VIỆC như mong đợi. Mẫu mã trên không liên quan. Xem câu trả lời của tôi dưới đây.

+0

Lưu ý: Phiên bản hiện tại của liên kết doc trên là tại http://api.rubyonrails.org/classes/ActiveRecord/Core.html#method -i-3D-3D – DreadPirateShawn

Trả lời

5

Trả lời câu hỏi của riêng tôi (câu hỏi này không liên quan).

Tất cả kiểm tra bình đẳng DO hoạt động như mong đợi (và được mô tả trong tài liệu).
Tôi cho rằng lý do nó không hiệu quả đối với tôi là tôi chạy autotest và một số thứ có thể được lưu vào bộ nhớ cache hoặc một số lý do thần thoại khác mà tôi không thể giải thích ngay bây giờ.

Nói tóm lại, tất cả các khẳng định sau đây được thực sự đi qua:

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) 
+0

+1 để đề cập đến tự động và lưu vào bộ nhớ cache, giải thích vấn đề tôi gặp phải với watchr. Cám ơn! – rdamborsky

4

Xem xét kỹ hơn định nghĩa: Lưu ý rằng các bản ghi mới khác với các bản ghi khác theo định nghĩa.

Trong trường hợp này, vì AR thường thực hiện kiểm tra bình đẳng cho cột nhận dạng, bạn có thể so sánh hai đối tượng bằng cách so sánh kết quả của những gì #attributes trả lại cho mỗi đối tượng.

+0

2 bản ghi khác nhau. Nhưng 2 đối tượng có cùng ID là hợp lý bằng nhau (theo 'ID .. bằng với compare_object.id'). Nếu điều đó là đúng, tôi không hiểu tại sao 'a == b' là' false' bởi vì nó phải giống như 'a.id == b.id' (tức là' true'). Hoặc tôi đang thiếu một cái gì đó? –

+0

Bạn đúng, nhưng đây là trường hợp đặc biệt vì biến a chứa một bản ghi mới và theo định nghĩa thì sẽ không bằng bất kỳ bản ghi nào khác. Nếu bạn đã sử dụng User.find (: email ..) == User.find (: email ..) .. Nó sẽ trả về true bởi vì không chỉ chúng là cùng một bản ghi mà cả hai đều không phải là mới. –

+0

Không. Cả hai 'a' và' b' đều KHÔNG phải là bản ghi mới. 'a.new_record?' và 'b.new_records?' là 'false'. Chúng chỉ là 2 vật thể khác nhau.Không có gì để làm với 'User.find (..) == User.find (..)'. Ngoài ra, ngay bây giờ thông số kỹ thuật của tôi thực sự * làm việc như các tài liệu nói * và tôi có thể sử dụng 'a == b'. Tôi đoán có vấn đề ở một nơi khác. Điều này có nghĩa là câu hỏi của tôi đã lỗi thời và (như tôi mong đợi) 'a == b' luôn đúng với điều kiện chúng có cùng ID. –

Các vấn đề liên quan