क्या इस ActiveRecord :: ReadOnlyRecord त्रुटि उत्पन्न कर रहा है?

वोट
198

यह इस प्रकार है इस से पहले सवाल है, जो उत्तर दिया गया था। मैं वास्तव में, मैं एक है कि क्वेरी से शामिल होने को दूर कर सकता है की खोज की तो अब काम कर रहे क्वेरी है

start_cards = DeckCard.find :all, :joins => [:card], :conditions => [deck_cards.deck_id = ? and cards.start_card = ?, @game.deck.id, true]  

यह काम करने के लिए प्रकट होता है। हालांकि, जब मैं एक और संघ में इन DeckCards ले जाने की कोशिश, मैं ActiveRecord :: ReadOnlyRecord त्रुटि मिलती है।

कोड यह

for player in @game.players 
  player.tableau = Tableau.new
  start_card = start_cards.pop 
  start_card.draw_pile = false
  player.tableau.deck_cards << start_card  # the error occurs on this line
end

और प्रासंगिक मॉडल (झांकी मेज पर खिलाड़ियों कार्ड हैं)

class Player < ActiveRecord::Base
  belongs_to :game
  belongs_to :user
  has_one :hand
  has_one :tableau
end

class Tableau < ActiveRecord::Base
  belongs_to :player
  has_many :deck_cards
end  

class DeckCard < ActiveRecord::Base
  belongs_to :card
  belongs_to :deck  
end

मैं तो बस इस कोड के बाद एक इसी तरह की कार्रवाई कर रहा हूँ, जोड़ने DeckCardsखिलाड़ियों हाथ करने के लिए, और है कि कोड ठीक काम कर रहा है। मैं अगर मैं जरूरत सोचा belongs_to :tableauDeckCard मॉडल में, लेकिन यह खिलाड़ी के हाथ में जोड़ने के लिए ठीक काम करता है। मैं एक है tableau_idऔर hand_idDeckCard तालिका में कॉलम।

मैं रेल एपीआई में ReadOnlyRecord ऊपर देखा, और यह बहुत वर्णन से परे नहीं कहना है।

12/03/2009 को 16:28
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


6 जवाब

वोट
275

से ActiveRecord CHANGELOG(v1.12.0, 16 अक्टूबर, 2005) :

केवल पढ़ने के रिकॉर्ड का परिचय दें। आप object.readonly को कॉल करते हैं! तो यह वस्तु के रूप में चिह्नित केवल पढ़ने के लिए और बढ़ा ReadOnlyRecord अगर आप object.save कॉल करेंगे। object.readonly? रिपोर्ट है कि क्या वस्तु केवल पढ़ने के लिए। पासिंग: किसी भी खोजक विधि की केवल पढ़ने के => true केवल पढ़ने के रूप में रिकॉर्ड लौटे का प्रतीक होगा। : अब विकल्प मिलती है का अर्थ है: केवल पढ़ने के लिए, इसलिए यदि आप इस विकल्प का उपयोग, एक ही रिकॉर्ड बचत अब असफल हो जायेगी। आस-पास काम करने के लिए find_by_sql का प्रयोग करें।

का उपयोग find_by_sqlनहीं वास्तव में एक विकल्प के रूप में यह कच्चे पंक्ति / स्तंभ डेटा देता है, नहीं है ActiveRecords। आपके पास दो विकल्प:

  1. उदाहरण चर के लिए मजबूर @readonlyरिकॉर्ड में गलत पर (हैक)
  2. का प्रयोग करें :include => :cardबजाय:join => :card

सितं, 2010 अद्यतन

इसके बाद के संस्करण में से अधिकांश नहीं रह गया है सच है। इस प्रकार, रेल 2.3.4 में और 3.0.0:

  • का उपयोग कर Record.find_by_sql रहा है एक व्यवहार्य विकल्प
  • :readonly => trueस्वचालित रूप से मान लिया जाता है केवल अगर :joinsनिर्दिष्ट किया गया था बिना किसी स्पष्ट :select है और न ही कोई स्पष्ट (या खोजक-गुंजाइश-विरासत में मिला है) :readonlyविकल्प (के कार्यान्वयन को देखने set_readonly_option!में active_record/base.rbरेल 2.3.4 के लिए, या के कार्यान्वयन to_aमें active_record/relation.rbऔर की custom_join_sqlमें active_record/relation/query_methods.rbरेल 3.0.0 के लिए)
  • हालांकि, :readonly => trueहमेशा स्वचालित रूप से में मान लिया जाता है has_and_belongs_to_many, तो में शामिल होने तालिका में दो विदेशी कुंजी स्तंभों से भी अधिक है और :joinsएक स्पष्ट बिना निर्दिष्ट किया गया था :select(यानी उपयोगकर्ता के आपूर्ति :readonlyमूल्यों अनदेखी कर रहे हैं - यह देखने finding_with_ambiguous_select?में active_record/associations/has_and_belongs_to_many_association.rb।)
  • अंत में, जब तक कि एक विशेष के साथ काम कर तालिका में शामिल होने और has_and_belongs_to_many, फिर @aaronrustadकी जवाब रेल 2.3.4 और 3.0.0 में ठीक लागू होता है।
  • करते नहीं का उपयोग :includesकरता है, तो आप एक हासिल करना चाहते हैं INNER JOIN( :includesएक का अर्थ है LEFT OUTER JOIN, जो कम चयनात्मक और कम से कम कुशल है INNER JOIN।)
12/03/2009 को 19:15
का स्रोत उपयोगकर्ता

वोट
168

या फिर रेल 3 में आप केवल पढ़ने के लिए विधि का उपयोग कर सकते हैं (अपनी शर्तों के साथ बदलें "..."):

( Deck.joins(:card) & Card.where('...') ).readonly(false)
10/08/2010 को 00:50
का स्रोत उपयोगकर्ता

वोट
43

यह रेल की हाल ही में रिलीज में परिवर्तित हो सकता है, लेकिन इस समस्या को हल करने के लिए उचित तरीके से जोड़ने के लिए है : केवल पढ़ने के => झूठी ढूंढ़ने के विकल्प के लिए।

07/06/2009 को 01:32
का स्रोत उपयोगकर्ता

वोट
15

का चयन करें ( '*') रेल 3.2 में इसे ठीक करने लगता है:

> Contact.select('*').joins(:slugs).where('slugs.slug' => 'the-slug').first.readonly?
=> false

बस सत्यापित करने के लिए, को छोड़ते हुए चयन करें ( '*') एक केवल पढ़ने के लिए रिकॉर्ड उत्पादन करता है:

> Contact.joins(:slugs).where('slugs.slug' => 'the-slug').first.readonly?
=> true

कह नहीं सकते मैं औचित्य समझते हैं लेकिन कम से कम यह एक त्वरित और स्वच्छ वैकल्पिक हल है।

01/03/2013 को 23:17
का स्रोत उपयोगकर्ता

वोट
5

find_by_sql के बजाय, आप एक निर्दिष्ट कर सकते हैं: खोजक और सब कुछ खुश फिर से का चयन करें ...

start_cards = DeckCard.find :all, :select => 'deck_cards.*', :joins => [:card], :conditions => ["deck_cards.deck_id = ? and cards.start_card = ?", @game.deck.id, true]

27/03/2009 को 01:32
का स्रोत उपयोगकर्ता

वोट
3

यह निष्क्रिय करने के लिए ...

module DeactivateImplicitReadonly
  def custom_join_sql(*args)
    result = super
    @implicit_readonly = false
    result
  end
end
ActiveRecord::Relation.send :include, DeactivateImplicitReadonly
10/08/2012 को 23:31
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more