ActiveRecord विशेषता विधियों को ओवरराइड करें


150

मैं जो बात कर रहा हूँ उसका एक उदाहरण:

class Person < ActiveRecord::Base
  def name=(name)
    super(name.capitalize)
  end
  def name
    super().downcase  # not sure why you'd do this; this is just an example
  end
end

यह काम करने लगता है, लेकिन मुझे सिर्फ ActiveRecord :: Base डॉक्स में विशेषता विधियों को ओवरराइड करने पर अनुभाग पढ़ा गया था , और यह read_attributeऔर write_attributeविधियों का उपयोग करने का सुझाव देता है । मुझे लगा कि ऊपर दिए गए उदाहरण में मैं जो कुछ कर रहा हूं उसमें कुछ गड़बड़ है; अन्यथा, वे इन विधियों को विशेषता विधियों को ओवरराइड करने के "सही तरीके" के रूप में क्यों आशीर्वाद देंगे? वे भी एक बहुत बदसूरत मुहावरा मजबूर कर रहे हैं, तो एक अच्छा कारण होना चाहिए ...

मेरा असली सवाल: क्या इस उदाहरण में कुछ गड़बड़ है?

जवाबों:


211

गारेथ की टिप्पणियों की गूंज ... आपका कोड लिखित रूप में काम नहीं करेगा। इसे इस तरह दोबारा लिखा जाना चाहिए:

def name=(name)
  write_attribute(:name, name.capitalize)
end

def name
  read_attribute(:name).downcase  # No test for nil?
end

बिल्कुल वही जो मुझे चाहिए था। धन्यवाद हारून।
घंटा

18
यह अब सच नहीं है। या तो सुपर या यह अब काम करता है। मैंने हालांकि हैश नोटेशन का परीक्षण नहीं किया है।
हार्टपंक

2
रेल 3 में, एरॉन द्वारा निर्दिष्ट पाठक विधि काम करती है, लेकिन लेखक जो मूल पोस्टर निर्दिष्ट करता है (सुपर को नाम खिलाता है) ठीक काम करता है, और आईएमएचओ उस विशेषता को मैन्युअल रूप से लिखने की तुलना में क्लीनर है जो आरोन सुझाव देता है।
बाटकिंस

1
मैंने नीचे
mipadi

क्या यह सही उत्तर नहीं है? धन्यवाद @Aaron, मेरे लिए भी काम किया।
साक्षी गौतम

94

हारून लॉन्गवेल के उत्तर के विस्तार के रूप में, आप एक्सेसर्स और म्यूटर्स को ओवरराइड करने वाली विशेषताओं तक पहुँचने के लिए "हैश नोटेशन" का उपयोग कर सकते हैं:

def name=(name)
  self[:name] = name.capitalize
end

def name
  self[:name].downcase
end

हैश नोटेशन काम कर सकता है, लेकिन self.attribute3.2.16 को स्टैक को उड़ा देता है।
jhhorn424

इसका यह फायदा है कि यह ||=डिफॉल्ट करने के लिए समर्थन करता है:def name; self[:name] ||= 'anon'; end
पॉल कैंटरेल

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

7

इस विषय पर कुछ बेहतरीन जानकारी http://errtheblog.com/posts/18-accessor-missing पर उपलब्ध है ।

इसका लंबा और छोटा असर यह है कि ActiveRecord विशेषता एक्सेसर्स के लिए ActiveRecord सुपर कॉल्स को सही ढंग से हैंडल करता है।


-1

मेरे पास एक रेल प्लगइन है जो सुपर के साथ विशेषता ओवरराइडिंग कार्य करता है जैसा कि आप उम्मीद करेंगे। आप इसे जीथब पर पा सकते हैं ।

स्थापित करने के लिए:

./script/plugin install git://github.com/chriseppstein/has_overrides.git

काम में लाना:

class Post < ActiveRecord::Base

  has_overrides

  module Overrides
    # put your getter and setter overrides in this module.
    def title=(t)
      super(t.titleize)
    end
  end
end

एक बार जब आप काम पूरा कर लेते हैं तो:

$ ./script/console 
Loading development environment (Rails 2.3.2)
>> post = Post.new(:title => "a simple title")
=> #<Post id: nil, title: "A Simple Title", body: nil, created_at: nil, updated_at: nil>
>> post.title = "another simple title"
=> "another simple title"
>> post.title
=> "Another Simple Title"
>> post.update_attributes(:title => "updated title")
=> true
>> post.title
=> "Updated Title"
>> post.update_attribute(:title, "singly updated title")
=> true
>> post.title
=> "Singly Updated Title"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.