/ / रेल पर रूबी: रिलेशनशिप या एसोसिएशन को बदलने का सबसे अच्छा तरीका - एसक्यूएल, रूबी-ऑन-रेल, रूबी, डेटाबेस, एक्टिव्रेकॉर्ड

रेल पर रूबी: रिलेशनशिप या एसोसिएशन को बदलने का सबसे अच्छा तरीका - एसक्यूएल, रूबी-ऑन-रेल, रूबी, डेटाबेस, एक्टिव्रेकॉर्ड

मैं इसे देखता हूं। जहां कथन बहुत से अनुरोध करता है कैच उपयोगकर्ता लोड एसोसिएशन से संदेश। क्या यह सही है या नहीं?

इस मामले में मुझे एक मिलता है ActiveRecord_Relation:

@dogs = Dog.where(user_id: current_user.id).order("created_at DESC")

इस मामले में, मुझे एक मिलता है ActiveRecord_Associations_CollectionProxy:

@dogs = current_user.dogs.order("created_at DESC")

जब मैं दृश्य में पुन: प्रयास करता हूं

<% @dogs.each do |dog| %>
<div><%= dog.name %></div>
<% end %>

मुझे अपने कंसोल लॉग में अलग संदेश मिलता है:

ActiveRecord_Relation:

User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]

ActiveRecord_Associations_CollectionProxy:

User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 15], ["LIMIT", 1]]
Dog Load (0.6ms)  SELECT "dogs".* FROM "dogs" WHERE "dogs"."user_id" = ? ORDER BY "dogs"."created_at" DESC  [["user_id", 15]]

क्या बेहतर तरीका है? आपका बहुत बहुत धन्यवाद।

उत्तर:

उत्तर № 1 के लिए 4

यह दोनों मामलों में लगता है current_user केवल एक बार बुलाया जाना चाहिए। संभवतः current_user विधि इस तरह एक कार्यान्वयन है:

def current_user
# read some cookies or something
User.find_by([...])
end

यह मुझे स्पष्ट नहीं है क्यों User.find_by में कई बार बुलाया जाएगा"ActiveRecord_Relation" संस्करण, लेकिन ऐसा लगता है कि यह हो रहा है कि क्या हो रहा है। रेल इस क्वेरी के परिणाम को कैश कर रहे हैं, इसलिए पहली बार जब आप गर्म कैश दबाते हैं।

इसे रद्द करने के लिए, आप कर सकते हैं memoize #current_user। इसे पहले आमंत्रण के बाद क्वेरी को देखने वाले प्रत्येक से सक्रिय रिकॉर्ड को रोकना चाहिए current_user.