2013-01-22 45 views
9

के साथ 'कहां' खंड के बाद `प्लक` का उपयोग नहीं कर सकता है मेरे पास एक ऐप है जिसमें Post मॉडल हैं, जिनमें से प्रत्येक belongs_toUser मॉडल है। जब ये पोस्ट प्रकाशित होते हैं, तो PublishedPost मॉडल बनाया गया है जो belongs_to प्रासंगिक Post मॉडल है।ActiveRecord: उत्सुक लोड किए गए एसोसिएशन

मैं प्रकाशित पोस्ट है कि एक उपयोगकर्ता नाम से मेल खोजने के लिए एक ActiveRecord क्वेरी बनाने, तो उन प्रकाशित पदों की आईडी प्राप्त करने के लिए जब मैं eager- के बाद pluck विधि का उपयोग करने की कोशिश की कोशिश कर रहा हूँ, लेकिन मैं एक त्रुटि हो रही है मेरे संगठनों को लोड करना और उन्हें where विधि से खोजना।

यहाँ (का हिस्सा) मेरी नियंत्रक है:

class PublishedPostsController < ApplicationController 

    def index 
    ar_query = PublishedPost.order("published_posts.created_at DESC") 

     if params[:searchQuery].present? 
     search_query = params[:searchQuery] 
     ar_query = ar_query.includes(:post => :user) 
          .where("users.name like ?", "%#{search_query}%") 
     end 

    @found_ids = ar_query.pluck(:id) 

    ... 

    end 

end 

जब pluck विधि कहा जाता है, मैं इस:

ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'users.name' in 'where clause': SELECT id FROM `published_posts` WHERE (users.name like '%Andrew%') ORDER BY published_posts.created_at DESC 

मैं परिणाम मैं

साथ की तलाश में हूँ कर सकते हैं
@found_ids = ar_query.select(:id).map{|r| r.id} 

लेकिन मैं pluck का उपयोग करता हूं क्योंकि यह जाने के लिए क्लीनर तरीका जैसा लगता है। मैं यह नहीं समझ सकता कि यह क्यों काम नहीं कर रहा है। कोई विचार?

उत्तर

10

आपको includes के बजाय joins की आवश्यकता है और करना चाहिए।

दो कार्य बहुत समान हैं सिवाय इसके कि joins से डेटा क्वेरी के परिणाम में वापस नहीं किया गया है जबकि includes में डेटा है।

उस संबंध में, includes और pluck एंटीथेटिकल हैं। एक मुझे उन सभी डेटा को वापस करने के लिए कहता है जो आप संभवतः कर सकते हैं, जबकि दूसरे ने मुझे केवल इतना ही दिया है।

चूंकि आप केवल थोड़ी सी मात्रा चाहते हैं, तो आप joins करना चाहते हैं। (अजीब select भी कुछ हद तक विरोधात्मक लगता है जो अभी भी काम करता है, लेकिन आप इस मामले में id से अधिक अस्पष्टता को दूर करने की आवश्यकता होगी।)

कंसोल में इसे आजमाएँ और आप देखेंगे कि includes एक प्रश्न है कि एक तरह से लग रहा है का कारण बनता है इस तरह: SELECT "posts"."id" as t0_ro, "posts"."text" as t0_r1, "users"."id" as t1_r0, "users"."name" as t1_r1 ... जब आप pluck कथन पर काम करते हैं तो उन सभी पागल tx_ry कॉलम दूर जाते हैं और जो कुछ भी आपने निर्दिष्ट किया है उसे प्रतिस्थापित कर दिया जाता है।

मुझे उम्मीद है कि मदद करता है, लेकिन यदि यह रेलवेस्ट नहीं हो सकता है। यह 5 मिनट के निशान के आसपास समझाया गया है।

http://railscasts.com/episodes/181-include-vs-joins

9

आप यहाँ खोज कर देता है तो "रेल अस्पष्ट स्तंभ बांधना", आप को पता है तुम बस के साथ query.pluck(:id) जगह ले सकता है चाहते हो सकता है:

query.pluck("table_name.id") 
+0

येसएसएस! मुझे नहीं पता कि यह दस्तावेज़ों में क्यों नहीं है? कम से कम मैंने इसे नहीं देखा। – FireDragon

0

आपकी क्वेरी के रूप में यह है कार्य नहीं करेगा प्लक कॉल के बिना भी लिखा है।

कारण, आपके WHERE खंड में उपयोगकर्ता तालिका का संदर्भ देने वाले शाब्दिक एसक्यूएल शामिल हैं जो रेल नोटिस नहीं देखता है और कई प्रश्नों का उपयोग करने का निर्णय लेता है और डेटाबेस स्तर में शामिल होने के बजाय स्मृति (.preload()) में शामिल होता है।eager_load()):

SELECT * from published_posts WHERE users.name like "pattern" ORDER BY published_posts.created_at DESC 
SELECT * from posts WHERE id IN (a_list_of_all_post_ids_in_publised_posts_returned_above) 
SELECT * from users WHERE id IN (a_list_of_all_user_ids_in_posts_returned_above) 

3 प्रश्नों में से पहला विफल रहता है और यह आपको मिली त्रुटि है।

रेलों को मजबूर करने के लिए यहां एक जॉइन का उपयोग करें, आपको या तो .inager() के बजाय स्पष्ट .eager_load() का उपयोग करना चाहिए, या एक .references() खंड जोड़ें।

इसके अलावा, @Geoff का उत्तर क्या है, आपको वास्तव में शामिल करने की ज़रूरत नहीं है। (यहां), बल्कि एक .joins()।