उलटा क्या करता है? एसक्यूएल क्या उत्पन्न करता है?


143

मैं अपना सिर इधर inverse_of- उधर करने की कोशिश कर रहा हूं और मुझे नहीं मिला।

उत्पन्न वर्ग क्या दिखता है, यदि कोई हो?

करता है inverse_ofविकल्प समान व्यवहार करता है, तो के साथ प्रयोग किया प्रदर्शन :has_many, :belongs_toऔर :has_many_and_belongs_to?

क्षमा करें यदि यह एक ऐसा मूल प्रश्न है।

मैंने यह उदाहरण देखा:

class Player < ActiveRecord::Base
  has_many :cards, :inverse_of => :player
end

class Card < ActiveRecord::Base
  belongs_to :player, :inverse_of => :cards
end

जवाबों:


125

से प्रलेखन , ऐसा लगता है जैसे :inverse_ofविकल्प एसक्यूएल प्रश्नों से बचने के लिए, उन्हें पैदा नहीं करने के लिए एक विधि है। यह ActiveRecord के लिए एक संकेत है कि पहले से ही लोड किए गए डेटा का उपयोग करने के बजाय इसे फिर से एक रिश्ते के माध्यम से लाने के लिए।

उनका उदाहरण:

class Dungeon < ActiveRecord::Base
  has_many :traps, :inverse_of => :dungeon
  has_one :evil_wizard, :inverse_of => :dungeon
end

class Trap < ActiveRecord::Base
  belongs_to :dungeon, :inverse_of => :traps
end

class EvilWizard < ActiveRecord::Base
  belongs_to :dungeon, :inverse_of => :evil_wizard
end

इस मामले में, कॉलिंग dungeon.traps.first.dungeonको dungeonएक नया लोड करने के बजाय मूल वस्तु को वापस करना चाहिए क्योंकि डिफ़ॉल्ट रूप से यह मामला होगा।


5
क्या आप दस्तावेज़ में टिप्पणी को समझते हैं: "rel_to संघों के लिए has_many उलटा संघों की उपेक्षा की गई है।" और फिर भी डॉक्टर उस सटीक उदाहरण का उपयोग करता है। मुझे यहां क्या समझ नहीं आ रहा है?
dynex

50
यह सब मेरे लिए बहुत अजीब है, क्योंकि यह मुझे लगता है कि आप हमेशा इस व्यवहार को डिफ़ॉल्ट रूप से चाहते हैं, और केवल तब उपयोग करने की आवश्यकता होती है: व्युत्क्रम_of जब एसोसिएशन का नाम पता नहीं लगाया जा सकता है। इसके अलावा परिभाषा में विसंगतियां परेशान हैं, लेकिन इसने मुझे कुछ मामलों में मदद की है। किसी भी कारण से मुझे बस हर जगह नहीं रहना चाहिए?
इब्राहिम

18
@ इब्राहिम ने इसकी जाँच की, इसे 23 दिन पहले मिला दिया गया था! github.com/rails/rails/pull/9522
Hut8

6
इसका मतलब यह है कि एक Rel_to एसोसिएशन के व्युत्क्रम को नजरअंदाज किया जा सकता है क्योंकि एक रिकॉर्ड A के माता-पिता के रिकॉर्ड के बच्चे को रिकॉर्ड A होने की गारंटी नहीं है - यह रिकॉर्ड A का एक भाई हो सकता है। , रिकॉर्ड ए होने की गारंटी है
डेविड एल्ड्रिज

2
भविष्य के पाठक को इस ब्लॉग से मदद मिल सकती है ...: D
Arup Rakshit

42

मुझे लगता :inverse_ofहै कि सबसे अधिक उपयोगी है जब आप ऐसे संघों के साथ काम कर रहे हैं जो अभी तक कायम नहीं हैं। उदाहरण के लिए:

class Project < ActiveRecord::Base
  has_many :tasks, :inverse_of=>:project
end

class Task < ActiveRecord::Base
  belongs_to :project, :inverse_of=>:tasks
end

अब, कंसोल में:

irb> p = Project.new
=> #<Project id: nil, name: nil, ...>
irb> t = p.tasks.build
=> #<Task id: nil, project_id: nil, ...>
irb> t.project
=> #<Project id: nil, name: nil, ...>

:inverse_ofतर्कों के बिना , t.projectवापस आ जाएगा nil, क्योंकि यह एक sql क्वेरी को ट्रिगर करता है और डेटा अभी तक संग्रहीत नहीं है। :inverse_ofतर्कों के साथ , डेटा को मेमोरी से पुनर्प्राप्त किया जाता है।


1
मुझे ac_sested_attributes_for के साथ एक समस्या थी। डिफ़ॉल्ट रूप से, मौजूदा संबद्ध ऑब्जेक्ट शो (कार्रवाई संपादित करें) के लिए केवल नेस्टेड विशेषताएँ। यदि, उदाहरण के लिए, आप किसी ऑब्जेक्ट को 3 संबंधित ऑब्जेक्ट के साथ बनाना चाहते हैं, तो आपको अपने मॉडल में Model.new (नई क्रिया) और: inverse_of होना चाहिए।
विक्टर मार्कोनी

रेल 4 और बाद में व्यवहार पर सहमत, लेकिन यह v3 में ठीक काम किया (कुछ बाद के अवतार को छोड़कर, हालांकि पुराने वाक्यविन्यास v3.2.13 में फिर से काम करता है)। और शामिल होने के मॉडल में ध्यान दें, आईडी के किसी और की उपस्थिति को मान्य नहीं कर सकता - केवल मॉडल-ऑब्जेक्ट। लगता है कि आप इसके लिए एक आईडी के बिना एक संघ हो सकता है, v4 'तर्क' में।
जोसेफ

वास्तव में .. :inverse_ofनए माता-पिता और बाल संस्थाओं को एक ही रूप में बनाते समय मेरे लिए एक मुद्दा हल किया।
WM

16

इसके बाद अधिकांश मामलों में pr ( https://github.com/rails/rails/pull/9522 ) व्युत्क्रम की आवश्यकता नहीं होती है।

सक्रिय रिकॉर्ड मानक नामों के साथ अधिकांश संघों के लिए स्वचालित पहचान का समर्थन करता है। हालाँकि, सक्रिय रिकॉर्ड स्वचालित रूप से द्वि-दिशात्मक संघों की पहचान नहीं करेगा जिसमें निम्न विकल्प शामिल हैं:

  • :के माध्यम से
  • :विदेशी कुंजी
class Author < ApplicationRecord
  has_many :books, inverse_of: 'writer'
end

class Book < ApplicationRecord
  belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
end

a = Author.first
b = a.books.first
a.first_name == b.writer.first_name # => true
a.first_name = 'David'
a.first_name == b.writer.first_name # => true

उपरोक्त उदाहरण में, उसी ऑब्जेक्ट का एक संदर्भ चर aऔर विशेषता में संग्रहीत है writer


मैं रेल्स 5 का उपयोग कर रहा हूं, और या तो आप जोड़ते हैं inverse_ofया नहीं, इसके लिए परिणाम a.first_name == b.author.first_nameहमेशा कठिन होता है।
अरसलान अली

@ अर्सलानअली महान टिप्पणी के लिए धन्यवाद, मैंने जवाब अपडेट किया।
कलामोनोवदेव

5

हर किसी के लिए बस एक अपडेट - हमने बस inverse_ofअपने एक ऐप के साथ एक has_many :throughएसोसिएशन का उपयोग किया है


यह मूल रूप से "मूल" ऑब्जेक्ट "चाइल्ड" ऑब्जेक्ट को उपलब्ध कराता है

इसलिए यदि आप रेल के उदाहरण का उपयोग कर रहे हैं:

class Dungeon < ActiveRecord::Base
  has_many :traps, :inverse_of => :dungeon
  has_one :evil_wizard, :inverse_of => :dungeon
end

class Trap < ActiveRecord::Base
  belongs_to :dungeon, :inverse_of => :traps
  validates :id,
      :presence => { :message => "Dungeon ID Required", :unless => :draft? }

  private
  def draft?
      self.dungeon.draft
  end 
end

class EvilWizard < ActiveRecord::Base
  belongs_to :dungeon, :inverse_of => :evil_wizard
end

उपयोग :inverse_ofकरने से आप डेटा ऑब्जेक्ट तक पहुंच सकते हैं, जो इसके विपरीत है, बिना किसी और एसक्यूएल प्रश्नों का प्रदर्शन किए


5

जब हमारे पास has_many और अंतर्गत_ संबंध के साथ 2 मॉडल हैं, तो हमेशा inverse_of का उपयोग करना बेहतर होता है जो ActiveRecod को सूचित करता है कि वे एसोसिएशन के एक ही पक्ष के हैं। इसलिए यदि एक तरफ से एक क्वेरी ट्रिगर की जाती है, तो यह कैश और कैश से काम करेगा यदि यह विपरीत दिशा से ट्रिगर होता है। जो प्रदर्शन में सुधार करता है। रेल से 4.1, उलटा_ऑफ स्वचालित रूप से सेट हो जाएगा, अगर हम विदेशी_की का उपयोग करते हैं या वर्ग के नाम में परिवर्तन करते हैं, तो हमें स्पष्ट रूप से सेट करने की आवश्यकता है।

विवरण और उदाहरण के लिए सर्वश्रेष्ठ लेख।

http://viget.com/extend/exploring-the-inverse-of-option-on-rails-model-associations



3

यदि आपके पास has_many_throughदो मॉडल, उपयोगकर्ता और भूमिका के बीच संबंध है, और गैर-मौजूदा या अमान्य प्रविष्टियों के खिलाफ कनेक्टिंग मॉडल असाइनमेंट को मान्य करना चाहते हैं validates_presence of :user_id, :role_id, तो यह उपयोगी है। आप अभी भी उसके सहयोग से एक उपयोगकर्ता @user उत्पन्न कर सकते हैं @user.role(params[:role_id])ताकि उपयोगकर्ता को बचाने के लिए असाइनमेंट मॉडल का विफल सत्यापन न हो।


-1

कृपया एक नज़र डालें 2 दो उपयोगी संसाधन

और कुछ सीमाएँ याद रखें inverse_of:

साथ काम नहीं करता है: संघों के माध्यम से।

के साथ काम नहीं करता है: बहुरूपी संघों।

rel_to संघों के लिए has_many व्युत्क्रम संघों को अनदेखा किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.