2012-03-13 8 views
10

したがって、ユーザーが価格を入力できるフォームがあります。私は、データを正規化するbefore_validationを作成しようとしています。ユーザーがそれを置くと$がクリッピングされます。ユーザー入力を整数に変換する

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

データ型はレールが.to_i前に私before_validationに実行し、すべてをクリッピングされる整数であるため、ユーザが入力$ 50は、ユーザ入力50 $場合、このコードは私に0を与えている、このコードは私に50を与える私が考える場合$の後に。データ型が文字列の場合、この同じコードは正常に機能します。

誰かが整数データ型を保つソリューションをお持ちですか?あなたが@model.price = whateverを行う際

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

だから、それはこの方法の代わりに、レールのデフォルト属性のライターに行きます:

答えて

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

小数点マイsoluction colum価格タイプはありがとうございます。私はいつもbefore_validationを使うのはかなり不器用だと思っていました。これは間違いなくよりエレガントです。 –

3

私は、仮想属性を定義し、あなたは意志でgetterとsetterの両方をフォーマットしたり変更したりできるようにそこに私の操作を行います:

class Model < ActiveRecord::Base 

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

    def foo_price 
    "$#{price}" 
    end 

あなたはまた、それを注意することが必要になることがあります。

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

ありがとう、私はこれも試してみましょう。私は最初に彼のコメントを試したので、私は他の答えを与えた。また、.00キャッチのおかげで、私は正規表現を更新します。 – Robert

+0

Np。私はそのアプローチを提案しました。なぜなら、コントローラーの追加ロジックのファンではなく、一見するとdbフィールドと一致するフィールドをオーバーライドしていないので、明快さがあるからです。文字列が正しいデータ型ではないと推測しています。 ) – offbyjuan

+0

ここでロジックをフォーマットするための追加のプレゼンタークラスを作成します –

0

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]) 
関連する問題