Bạn đang thấy một tạo phẩm sử dụng irb
để điều tra mọi thứ.
Khi bạn nói điều này:
> Product.first.title
#=> nil
bạn method_missing
sẽ được gọi để lười biếng nạp phương pháp title
và bạn nhận nil
.
Khi bạn nói điều này:
> Product.first
Bạn đang có hiệu quả làm điều này:
> p = Product.first; puts p.inspect
Thể hiện sản phẩm đầu tiên sẽ được nạp và sau đó irb
sẽ gọi inspect
vào nó và AR sẽ thêm phương pháp truy cập trên đường đi. Kết quả là Sản phẩm sẽ có phương thức title
. Do đó, làm điều này:
> Product.first
> Product.first.title
sẽ không gọi method_missing
của bạn tại tất cả như sẽ có một phương pháp thực title
cho Product.first.title
để gọi.
Nếu bạn cố gắng một lần nữa như thế này:
> Product.first; nil
> Product.first.title
Bạn sẽ thấy hai nil
s.
Theo như chuỗi đi, ActiveRecord không thực sự phát hiện kết thúc, nó chỉ là một số phương pháp gọi tự nhiên yêu cầu dữ liệu thực từ cơ sở dữ liệu và một số thì không.
Nếu bạn gọi where
, order
hoặc bất kỳ phương pháp truy vấn nào khác, bạn sẽ nhận được cá thể ActiveRecord::Relation và bạn có thể chuỗi các phương pháp truy vấn và phạm vi khác trên đối tượng quan hệ đó. Ví dụ, where
(mà ActiveRecord :: Quan hệ được bằng cách bao gồm ActiveRecord::QueryMethods) trông như thế này:
def where(opts, *rest)
return self if opts.blank?
relation = clone
relation.where_values += build_where(opts, rest)
relation
end
nên nó chỉ làm cho một bản sao của truy vấn hiện tại, bổ sung một số điều cần bản sao, và cung cấp cho bạn các bản sao trở lại.
Nếu bạn gọi first
, last
, to_a
, all
, bất kỳ Enumerable phương pháp (ví dụ: bạn gọi each
), ...sau đó bạn hỏi về các trường hợp cụ thể và ActiveRecord sẽ phải thực hiện truy vấn để nhận ra (các) cá thể mô hình được đề cập. Ví dụ, ActiveRecord::Relation#to_a
trông như thế này:
def to_a
logging_query_plan do
exec_queries
end
end
và all
là ít hơn một wrapper xung quanh to_a
. ActiveNecord không thực sự biết nơi mà kết thúc của chuỗi, nó chỉ không tải bất cứ điều gì từ cơ sở dữ liệu cho đến khi nó có để bạn nói với nó nơi chuỗi kết thúc bằng cách nói đi ra và lấy cho tôi một số dữ liệu.
tôi nghĩ rằng nó phát hiện sự kết thúc của chuỗi: đó là nơi bạn không lấy lại đối tượng proxy tìm kiếm! – phoet
Đây không phải là câu hỏi. Câu hỏi đặt ra là tại sao '' 'Product.first.title''' trả về' '' nil''' cho đến khi '' 'Product.first''' được gọi, khi' '' method_missing''' được sử dụng bên trong một mô hình. Khi bạn đã gọi '' 'Product.first''' title trả về' '' My sample blog'''. – user544941
@ user544941: Ah, tôi thấy những gì anh ta hỏi về: cái gì thay thế hoặc bỏ qua 'phương thức_missing' của anh ta. –