मैं यह समझने की कोशिश कर रहा हूं कि has_many :through
इसका क्या और कब उपयोग करना है (और कैसे)। हालांकि, मुझे यह नहीं मिल रहा है। मैं शुरुआती रेल 3 पढ़ रहा हूं और मैंने Googling की कोशिश की, लेकिन मैं समझ नहीं पा रहा हूं।
मैं यह समझने की कोशिश कर रहा हूं कि has_many :through
इसका क्या और कब उपयोग करना है (और कैसे)। हालांकि, मुझे यह नहीं मिल रहा है। मैं शुरुआती रेल 3 पढ़ रहा हूं और मैंने Googling की कोशिश की, लेकिन मैं समझ नहीं पा रहा हूं।
जवाबों:
मान लें कि आपके पास दो मॉडल हैं: User
औरGroup
।
यदि आप चाहते थे कि उपयोगकर्ता समूहों से संबंधित हों, तो आप कुछ इस तरह से कर सकते हैं:
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
यदि आप एसोसिएशन के आसपास अतिरिक्त मेटाडेटा ट्रैक करना चाहते हैं तो क्या होगा? उदाहरण के लिए, जब उपयोगकर्ता समूह में शामिल हुआ, या शायद उपयोगकर्ता की समूह में क्या भूमिका है?
यह वह जगह है जहाँ आप एसोसिएशन को एक प्रथम श्रेणी वस्तु बनाते हैं:
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# has attributes for date_joined and role
end
यह एक नई तालिका पेश करता है, और group_id
उपयोगकर्ता की तालिका से कॉलम को समाप्त करता है ।
इस कोड के साथ समस्या यह है कि आपको हर उस जगह को अपडेट करना होगा जहां आप उपयोगकर्ता वर्ग का उपयोग करते हैं और इसे बदलते हैं:
user.groups.first.name
# becomes
user.group_memberships.first.group.name
इस प्रकार का कोड बेकार है, और यह इस दर्दनाक की तरह परिवर्तन शुरू करता है।
has_many :through
आपको दोनों दुनिया का सर्वश्रेष्ठ देता है:
class User < ActiveRecord::Base
has_many :groups, :through => :group_memberships # Edit :needs to be plural same as the has_many relationship
has_many :group_memberships
end
अब आप इसे सामान्य की तरह मान सकते हैं has_many
, लेकिन जरूरत पड़ने पर एसोसिएशन मॉडल का लाभ उठा सकते हैं।
ध्यान दें कि आप भी ऐसा कर सकते हैं has_one
।
संपादित करें: उपयोगकर्ता को समूह में जोड़ना आसान बनाता है
def add_group(group, role = "member")
self.group_associations.build(:group => group, :role => role)
end
user.groups << group
? या सब कुछ इस संघ द्वारा संभाला जाता है?
कहो कि आपके पास ये मॉडल हैं:
Car
Engine
Piston
एक कार has_one :engine
एक इंजन belongs_to :car
एक इंजनhas_many :pistons
पिस्टनbelongs_to :engine
एक गाडी has_many :pistons, through: :engine
पिस्टनhas_one :car, through: :engine
अनिवार्य रूप से आप एक मॉडल रिश्ते को दूसरे मॉडल में सौंप रहे हैं, इसलिए कॉल करने के बजाय car.engine.pistons
, आप बस कर सकते हैंcar.pistons
has_many :through
और has_and_belongs_to_many
रिश्तों में शामिल होने की मेज के माध्यम से कार्य , जो एक मध्यवर्ती तालिका है जो अन्य तालिकाओं के बीच संबंधों का प्रतिनिधित्व करती है। JOIN क्वेरी के विपरीत, डेटा वास्तव में एक तालिका में संग्रहीत किया जाता है।
इसके साथ has_and_belongs_to_many
, आपको एक प्राथमिक कुंजी की आवश्यकता नहीं है, और आप ActiveRecord मॉडल के बजाय ActiveRecord संबंधों के माध्यम से रिकॉर्ड एक्सेस करते हैं। आप आमतौर पर HABTM का उपयोग तब करते हैं जब आप दो मॉडलों को कई-कई संबंधों से जोड़ना चाहते हैं।
आप एक का उपयोग करें has_many :through
संबंध का तब करते हैं जब आप एक रैल मॉडल के रूप में ज्वाइन टेबल के साथ बातचीत करना चाहते हैं, प्राथमिक कुंजियों के साथ पूर्ण होते हैं और जुड़ने वाले डेटा में कस्टम कॉलम जोड़ने की क्षमता होती है। उत्तरार्द्ध विशेष रूप से उन डेटा के लिए महत्वपूर्ण है जो सम्मिलित पंक्तियों के लिए प्रासंगिक है, लेकिन वास्तव में संबंधित मॉडल से संबंधित नहीं है - उदाहरण के लिए, सम्मिलित पंक्ति में फ़ील्ड से प्राप्त परिकलित मान संग्रहीत करना।
में सक्रिय रिकॉर्ड संघों के लिए एक गाइड , सिफारिश पर लिखा है:
अंगूठे का सबसे सरल नियम यह है कि आपको एक has_many सेट करना चाहिए: यदि आपको एक स्वतंत्र इकाई के रूप में संबंध मॉडल के साथ काम करने की आवश्यकता है, तो संबंध के माध्यम से। यदि आपको रिलेशनशिप मॉडल के साथ कुछ करने की आवश्यकता नहीं है, तो has_and_belongs_to_many संबंध स्थापित करना आसान हो सकता है (हालाँकि आपको डेटाबेस में शामिल होने वाली तालिका बनाने के लिए याद रखने की आवश्यकता होगी)।
आपको has_many का उपयोग करना चाहिए: यदि आपको जुड़ने वाले मॉडल पर सत्यापन, कॉलबैक या अतिरिक्त विशेषताओं की आवश्यकता है।
user
समूह को जोड़ने के लिए मॉडल पर एक विधि जोड़ूंगा। मेरे द्वारा किए गए संपादन जैसा कुछ। उम्मीद है की यह मदद करेगा।