2012-01-05 9 views
5

मेरे पास दो ActiveRecord मॉडल हैं जिनमें एचएबीटीएम एसोसिएशन है।एक habtm एसोसिएशन की द्वीप तालिका कैसे प्राप्त करें?

मैं एरल का उपयोग करके अनाथ रिकॉर्ड प्राप्त करने के लिए scope लिखना चाहता हूं।

मेरी समस्या यह है कि मुझे एसोसिएशन के arel_table को पुनर्प्राप्त करने का कोई तरीका नहीं मिला। चूंकि संबंध एचएबीटीएम है, इसलिए arel_table पर कॉल करने के लिए कोई मॉडल नहीं है।

मेरे पास अब निम्नलिखित है (जो काम करता है), लेकिन मैं जॉइन टेबल के नाम के साथ एक नई आईएलएल टेबल बनाता हूं (reflect_on_association विधि का उपयोग कर पुनर्प्राप्त)।

SELECT `teachers`.* 
FROM `teachers`  
WHERE (`teachers`.`id` NOT IN (SELECT `groups_teachers`.`teacher_id` 
           FROM `groups_teachers`)) 

तो वहाँ arel_table को पुनः प्राप्त करने के बजाय एक नया एक बनाने किसी भी बेहतर तरीका है:

scope :orphans, lambda { 
    teachers = arel_table 
    join_table = Arel::Table.new(reflect_on_association(:groups).options[:join_table]) 

    join_table_condition = join_table.project(join_table[:teacher_id]) 
    where(teachers[:id].not_in(join_table_condition)) 
} 

यह निम्नलिखित एसक्यूएल उत्पादन होता है?

+0

नोट, मुझे लगता है कि ऐसा करने के लिए एक क्लीनर तरीका है, नीचे मेरा जवाब देखें। – Andrew

उत्तर

3

दुर्भाग्य से, मेरा मानना ​​है कि अपने समाधान काफी साफ वहाँ अभी है और जब instantiated क्या संघ ही आंतरिक रूप से करता है वास्तव में, है, है:

https://github.com/rails/rails/blob/46492949b8c09f99db78b9f7a02d039e7bc6a702/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb#L7

मैं reflection.join_table मानना ​​है कि वे बनाम प्रतिबिंब। विकल्प [: join_table] केवल मास्टर में अभी है।

2

आप संघ का नाम जानते हैं और इसलिए मेज, जो इस मामले में ऐसा लगता है कि आप ऐसा करेंगे, तो आप कॉल करने के लिए सक्षम होना चाहिए लग रहा है में शामिल होते हैं:

Arel::Table.new(:groups_teachers) 

मेरी परीक्षण है कि अरेल तालिका रिटर्न में एक habtm संघ। मुझे यह इंगित करने के लिए this answer पर धन्यवाद।

+0

कम से कम अब तक (एआरएल 3.0.2 और एआर 3.2 देख रहे हैं) आप कुछ बदसूरत एथलेटिक्स जैसे 'Groups.reflect_on_association (: शिक्षकों) .through_reflection.klass.arel_table' कर सकते हैं, जो आपको एक उचित बाध्य वस्तु देनी चाहिए। – Nicos

+0

अगर कोई उलझन में है तो त्वरित उदाहरण! 'उपयोगकर्ता। Joins (: खेल)। कहीं (Arel :: table.new (: sports_users) [: sport_id] .eq (SPORT_ID))' – Marrs

संबंधित मुद्दे