2012-11-13 6 views
9

मान लीजिए कि मैं कोड सारण कर रहा हूं, और ऑब्जेक्ट एक्स के कॉलम नामों के माध्यम से लूपिंग कर रहा हूं, यह पता लगाने का सबसे अच्छा तरीका क्या है कि कोई कॉलम एक एसोसिएशन है या नहीं?रेल/एक्टिव रिकार्ड: पता लगाएं कि कोई कॉलम एक एसोसिएशन है या नहीं

मैं जानता हूँ कि मैं यह कर सकता है, लेकिन अगर वहाँ एक बेहतर तरीका है मैं सोच रहा हूँ:

@user = User.first 
    @user.attributes.keys.each do |column| 
    if column[-3..-1] == "_id" && @user.respond_to?(column[0..-4].to_sym) 
     puts "#{column} is an association/relation." 
    else 
     puts "#{column} is not an assocation/relation." 
    end 
    end 
end 

किसी भी में निर्मित रेल तरीकों या सहायकों संघों का पता लगाने के लिए? उपरोक्त कोड न तो सुंदर और न ही मूर्ख प्रमाण है। धन्यवाद!

उत्तर

15

एक तरह से यह करने के लिए उस वर्ग के लिए सभी संगठनों पर चिंतन करने के होगा:

associations = class_goes_here.reflect_on_all_associations 

और फिर बस belongs_to लोगों को खोजने के लिए, के बाद से उन _id क्षेत्र होगा:

associations = associations.select { |a| a.macro == :belongs_to } 

फिर आप इन एसोसिएशनों पर यह कर कर विदेशी कुंजी पा सकते हैं:

association_foreign_keys = associations.map(&:foreign_key) 

मैं गुण प्राप्त करने के लिए @user.attributes का उपयोग नहीं करता और फिर कॉलम नाम प्राप्त करने के लिए keys का उपयोग नहीं करता। कॉलम नाम प्राप्त करने के लिए मैं User.column_names का उपयोग करूंगा।

इसलिए, सभी कि समझाया साथ, आप तो अपने कोड इस लिए इसे और अधिक सरल बनाने के लिए होने के लिए बदल सकते हैं:

associations = User.reflect_on_all_associations 
associations = associations.select { |a| a.macro == :belongs_to } 
association_foreign_keys = associations.map(&:foreign_key) 
User.column_names.each do |column| 
    if association_foreign_keys.include?(column) 
    puts "#{column} is an association/relation." 
    else 
    puts "#{column} is not an assocation/relation." 
    end 
end 
+0

रेल के रूप में 1.1.1 आप मैक्रो तुरंत आधार पर फ़िल्टर कर सकते हैं: 'संघों = User.reflect_on_all_associations (: belongs_to) 'और कोड की दूसरी पंक्ति को बचाओ। – ToniTornado

1

मुझे यकीन है कि चयनित समाधान बेहतर है हूँ, लेकिन आप "आदर्श में रहते हैं, तो दुनिया ", जहां हर कोई रेल कन्वेंशन का पालन करें, मुझे लगता है आप this पर भरोसा कर सकते हैं:

2,2 स्कीमा कन्वेंशनों सक्रिय रिकॉर्ड, डेटाबेस तालिकाओं में स्तंभों के लिए नामकरण रिवाजों का उपयोग करता है पर निर्भर करता है इन कॉलम का उद्देश्य।

विदेशी कुंजी - इन फ़ील्ड का नाम पैटर्न singularized_table_name_id (उदा।, Item_id, order_id) के नाम पर रखा जाना चाहिए। ये फ़ील्ड्स हैं जो आपके मॉडल के बीच एसोसिएशन बनाते समय सक्रिय रिकॉर्ड देखेंगे।

तो बस स्तंभ नाम के अंत में _ id प्रत्यय के लिए देखो:

Model.column_names.select{|cn| cn.include?("_id")} 
+0

मुझे व्यक्तिगत रूप से लगता है कि यह एक त्रुटि-प्रवण दृष्टिकोण है क्योंकि लोग (दुर्भाग्य से) उन सम्मेलन नियमों को तोड़ते हैं .. –

+0

यही कारण है कि मैंने सम्मेलनों का उल्लेख किया। –

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