2012-03-13 13 views
10

में कनवर्ट करें तो मेरे पास एक ऐसा फॉर्म है जहां उपयोगकर्ता मूल्य इनपुट कर सकते हैं। मैं पहले_विधीकरण करने की कोशिश कर रहा हूं जो डेटा को सामान्य करता है, अगर उपयोगकर्ता इसे डालता है तो $ क्लिपिंग करता है।उपयोगकर्ता इनपुट को पूर्णांक

before_validation do 
unless self.price.blank? then self.price= self.price.to_s.gsub(/\D/, '').to_i end 
end 

तो उपयोगकर्ता इनपुट $ 50 इस कोड को उपयोगकर्ता इनपुट $ 50 के लिए इस कोड मुझे 50. देता है मुझे 0. दे रहा है मुझे लगता है कि जब से डेटा प्रकार पूर्णांक कि रेल मेरी before_validation से पहले .to_i चल रहा है और सब कुछ कतरन है $ के बाद। डेटा प्रकार एक स्ट्रिंग है तो यह वही कोड ठीक काम करता है।

किसी को भी एक समाधान मुझे पूर्णांक डेटाप्रकार रखने देंगे है?

def price=(val) 
    write_attribute :price, val.to_s.gsub(/\D/, '').to_i 
end 

तो जब आप @model.price = whatever करते हैं, यह पटरियों डिफ़ॉल्ट विशेषता लेखक के बजाय इस विधि के लिए जाना जाएगा:

उत्तर

20

एक तरह से मॉडल पर तंत्र है जो मूल्य सेट, इस तरह ओवरराइड करने के लिए है। फिर आप वास्तविक लेखन करने के लिए संख्या को परिवर्तित कर सकते हैं और write_attribute का उपयोग कर सकते हैं (आपको इसे इस तरह से करना है क्योंकि मानक price= अब यह विधि है!)।

मैं इस विधि सबसे ज्यादा पसंद है, लेकिन संदर्भ एक और तरीका है करने के लिए यह मॉडल करने के लिए इसे असाइन करने से पहले अपने नियंत्रक में है। पैरामीटर एक स्ट्रिंग के रूप में आता है, लेकिन मॉडल उस स्ट्रिंग को एक संख्या में परिवर्तित कर रहा है, इसलिए सीधे पैरामीटर के साथ काम करें। (सिर्फ अपने नियंत्रक कोड के अनुकूल) कुछ इस तरह:

def create 
    @model = Model.new(params[:model]) 
    @model.price = params[:model][:price].gsub(/\D/, '').to_i 
    @model.save 
end 

या तो समाधान के लिए, कि before_validation को हटा दें।

+0

धन्यवाद। मैंने हमेशा सोचा था कि पहले_विधीकरण का उपयोग करना बहुत बेकार है। यह निश्चित रूप से अधिक सुरुचिपूर्ण है। –

3

मैं एक आभासी प्रत्येक का उपयोग करता है और वहाँ प्रारूपण और होगा पर दोनों गेटर और सेटर को संशोधित करने के लिए अनुमति मेरी हेरफेर करना होगा:

"$50.00".gsub(/\D/, '').to_i #=> 5000 
+0

धन्यवाद, मैं इसे भी आज़मा दूंगा। मैंने दूसरा जवाब दिया क्योंकि मैंने पहले अपनी टिप्पणी की कोशिश की थी। इसके अलावा, .00 पकड़ के लिए धन्यवाद, मैं अपने regex अद्यतन करेंगे। – Robert

+0

एनपी। मैंने सुझाव दिया कि दृष्टिकोण क्योंकि मैं नियंत्रक में अतिरिक्त तर्क का प्रशंसक नहीं हूं और स्पष्टता है क्योंकि आप किसी क्षेत्र को ओवरराइड नहीं कर रहे हैं कि पहली नज़र में डीबी फ़ील्ड से मेल खाना चाहिए और मुझे लगता है कि एक स्ट्रिंग सही डेटा प्रकार नहीं है:) – offbyjuan

+0

मैं यहां तर्क स्वरूपण के लिए अतिरिक्त प्रस्तुति वर्ग बनाउंगा –

0
:

class Model < ActiveRecord::Base 

    def foo_price=(price) 
    self.price = price... #=> Mods to string here 
    end 

    def foo_price 
    "$#{price}" 
    end 

तुम भी ध्यान दें कि चाहते हो सकता है

मेरे soluction colum मूल्य प्रकार दशमलव

t.decimal :price, precision: 12, scale: 6 

# app/concern/sanitize_fields.rb 
    module SanitizeFields 
     extend ActiveSupport::Concern 

     def clear_decimal(field) 
     return (field.to_s.gsub(/[^\d]/, '').to_d/100.to_d) unless field.blank? 

     end 

     def clear_integer(field) 
     field.to_s.strip.gsub(/[^\d]/, '') unless field.blank? 
     end 

     # module ClassMethods 
     # def filter(filtering_params) 
     #  results = self.where(nil) 
     #  filtering_params.each do |key, value| 
     #  results = results.public_send(key, value) if value.present? 
     #  end 
     #  results 
     # end 
     # 
     # #use 
     # #def index 
     # # @products = Product.filter(params.slice(:status, :location, :starts_with)) 
     # #end 
     # 
     # end 

    end 

#app/controllers/products_controller.rb 

include SanitizeFields 

params[:product][:price] = clear_decimal(params[:product][:price]) 
संबंधित मुद्दे