2015-12-28 19 views
5

Trong các mô hình của tôi, tôi có người dùng (User) và các câu chuyện (Story), với quan hệ: user has_many stories.Ruby on Rails: #any? trả về giá trị sai

tôi đã nhận thấy một cái gì đó kỳ lạ trong vỏ của tôi:

(dev) user.stories.any? 
=> true 

(dev) user.stories 
    Story Load (1.6ms) SELECT "stories".* FROM "stories" WHERE "stories"."user_id" = 703 ORDER BY created_at ASC [["user_id", 703]] 
=> [] 

(dev) user.stories.any? 
=> false 

làm việc như thế này? Đây có phải là do mã của tôi hay là lỗi của một số loại trong Rails và cách nó truy vấn cơ sở dữ liệu?

+0

@sawa những gì bạn có nghĩa là dấu chấm câu tiếng Anh không? Bạn có thể chính xác hơn không? Tôi rõ ràng không phải là một người bản ngữ và đôi khi tôi chỉ đơn giản là không nhìn thấy sai lầm ở đâu. – Mat

+1

OK. Sau đó, các quy tắc là các ngôn ngữ khác nhau. Trong tiếng Pháp, chúng tôi sử dụng dấu cách trước và sau khi dấu câu được tạo thành từ hai phần. – Mat

+0

lỗi có thể có trong mối quan hệ hoạt động của đường ray? xem nguồn cho http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-any-3F gọi http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method- i-empty-3F và trả về true 'nếu limit_value == 0' - có thể là một tối ưu hóa để tránh nhấn cơ sở dữ liệu nhiều lần? Tôi tự hỏi nếu nó hoạt động giống nhau trong môi trường RAIN đường ray? – house9

Trả lời

0

Một workaround tôi thấy (nhờ @ house9) là sử dụng:

user.stories.to_a.any? 
user.stories.to_a.empty? # also works with empty? 

Bằng cách này, Rails buộc phải thực hiện truy vấn. Và chi phí là khá thấp kể từ khi thực hiện to_a.any? nhiều lần chỉ thực hiện truy vấn một lần.

Hoặc tốt hơn, như @Jordan gợi ý, sử dụng:

user.stories.exists? 
+0

Điều đó sẽ tải tất cả các câu chuyện của người dùng vào bộ nhớ. Nếu bạn không cần sử dụng thông tin câu chuyện, chỉ cần sử dụng 'user.stories.count> 0'. Nó sẽ thực hiện một phép tính đơn giản trên db, thay vì chọn tất cả các trường của nó và tuần tự hóa chúng thành một mảng ruby. –

+1

Không sử dụng 'count', sử dụng [' exist? '] (Http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F). Đó là những gì nó cho. –

+0

@Jordan Thậm chí tốt hơn. –

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