2012-07-19 18 views
14

मेरे पास कुछ विशेषताओं और वर्चुअल विशेषता वाला मॉडल है। इस वर्चुअल विशेषता का निर्माण सृजन फ़ॉर्म में चेकबॉक्स बनाने के लिए किया जाता है।टाइप करें एक ActiveRecord मॉडल आभासी विशेषता

class Thing < ActiveRecord::Base 
    attr_accessor :foo 
    attr_accessible :foo 
end 

क्षेत्र के बाद से के रूप में एक चेकबॉक्स, foo विशेषता मान के रूप '0' या '1' प्राप्त होगा। मैं इसे निम्नलिखित कोड की वजह से एक बूलियन होना चाहते हैं:

class Thing < ActiveRecord::Base 
    attr_accessor :foo 
    attr_accessible :foo 

    before_validation :set_default_bar 

    private 

    def set_default_bar 
    self.bar = 'Hello' if foo 
    end 
end 

समस्या है कि यहाँ हालत सच हो जाएगा तब भी जब foo'0' है। मैं ActiveRecord प्रकार कास्टिंग तंत्र लेकिन केवल मैं इसे पीछा कर रहा है क्या करने के लिए मिल गया उपयोग करना चाहते हैं:

class Thing < ActiveRecord::Base 
    attr_reader :foo 
    attr_accessible :foo 

    before_validation :set_default_bar 

    def foo=(value) 
    @foo = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value) 
    end 


    private 

    def set_default_bar 
    self.bar = 'Hello' if foo 
    end 
end 

लेकिन मैं इसे इस तरह से कर रही है गंदा लग रहा है। क्या रूपांतरण विधि को फिर से लिखने के बिना कोई बेहतर विकल्प है?

धन्यवाद

उत्तर

14

मूल पोस्ट से आपका समाधान मेरे लिए सबसे अच्छा समाधान दिखता है।

class Thing < ActiveRecord::Base 
    attr_reader :foo 
    def foo=(value) 
    @foo = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value) 
    end 
end 

आप थोड़ा चीजों को साफ करना चाहता था, तो आप हमेशा एक सहायक विधि है कि आप value_to_boolean प्रयोग करने के लिए अपने foo= लेखक पद्धति निर्धारित करता है बना सकते हैं।

मैं शायद एक विधि bool_attr_accessor कहा जाता है के साथ एक मॉड्यूल बनाना होगा, ताकि आप इस तरह देखने के लिए अपने मॉडल को आसान बनाने में कर सकते हैं:

class Thing < ActiveRecord::Base 
    bool_attr_accessor :foo 
end 

ऐसा लगता है कि ActiveModel चाहिए हमारे लिए कुछ इस तरह प्रदान करते हैं ताकि आभासी विशेषताओं अधिनियम "असली" (ActiveRecord- persisted) विशेषताओं की तरह। इस प्रकार कास्ट आवश्यक है जब भी आपके पास एक बूलियन आभासी विशेषता है जो किसी फ़ॉर्म से सबमिट हो जाती है।

हो सकता है कि हम प्रस्तुत करना चाहिए रेल के लिए एक पैच ...

0

तुमने ऐसा क्यों नहीं है:

def foo=(value) 
    @foo = value 
    @bar = 'Hello' if value == "1" 
end 
+0

क्योंकि मानों को 'सत्य' और 'झूठी' में बदल दिया जा सकता है और इसे अभी भी काम करना चाहिए। रेल ठीक है लेकिन गलत जगह आईएमएचओ में। – Happynoff

+0

'foo =' में @bar को सेट करने के बारे में मुझे लगता है कि यह करने की जगह नहीं है, एक जिम्मेदारी सिद्धांत और सब कुछ। और, मेरे वास्तविक उपयोग-मामले में, इसे पहले_विधीकरण में रखने का अर्थ है;) – Happynoff

+0

आप सही हैं। आपके पास यह समाधान है: https://gist.github.com/2000623 लेकिन मुझे नहीं लगता कि यह एक बेहतर समाधान है। यह मूल रूप से रेल की तुलना में एक ही बात है। स्रोत देखें: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/column.rb – Dougui

1

validates_acceptance_of कोड पर देखो (क्लिक करें दिखाएँ स्रोत)। उन्होंने इसे "0" की तुलना में लागू किया।

मैं पंजीकरण रूपों में यह उपयोग कर रहा हूँ इस तरह से:

class User < ActiveRecord::Base 
    validates_acceptance_of :terms_of_service 
    attr_accessible :terms_of_service 
end 

तुम सच में स्ट्रिंग से डाली चाहते हैं आदि आप इस का उपयोग कर सकते हैं:

def foo=(value) 
    self.foo=(value == true || value==1 || value =~ (/(true|t|yes|y|1)$/i)) ? true:false 
end 

या समान किरदार विधि जोड़ें String कक्षा के लिए और इसे मॉडल में उपयोग करें:

class String 
def to_bool 
    return true if self == true || self =~ (/(true|t|yes|y|1)$/i) 
    return false if self == false || self.blank? || self =~ (/(false|f|no|n|0)$/i) 
    raise ArgumentError.new("invalid value for Boolean: \"#{self}\"") 
end 
end 
+0

हाँ शायद, लेकिन मुझे यह थोड़ा गंदा करने का तरीका मिल गया है। मैं एक असली बूलियन का उपयोग करना पसंद करूंगा। क्या होगा यदि कोड के किसी अन्य भाग भाग में मैं 'Thing.new (foo: true) लिखता हूं? – Happynoff

+0

मुझे स्ट्रिंग # to_bool को साफ और सहायक होने के लिए मिला। धन्यवाद। – linojon

2

रेल में 5 आप attribute विधि का उपयोग कर सकते हैं। यह विधि इस मॉडल पर एक प्रकार के साथ एक विशेषता को परिभाषित करती है। यदि आवश्यक हो तो यह मौजूदा विशेषताओं के प्रकार को ओवरराइड कर देगा।

class Thing < ActiveRecord::Base 
    attribute :foo, :boolean 
end 

सावधानी: वहाँ रेल 5.0.0 डाटाबेस से लोड मॉडल पर इस attribute सुविधा के गलत व्यवहार है। इसलिए रेल 5.0.1 या उच्चतर रेल का उपयोग करें।

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