2010-12-03 16 views
5

私はユーザが入力するフォームフィールドがあります。Rails Way:モデルに設定する前に値を書式設定しますか?

  • パーセント:50.5%
  • お金:$144.99
  • 日付:Wednesday, Jan 12th, 2010

...

percentmoneyをタイプ属性はdecimalフィールドとして保存されますActiveRecordで、日付はdatetimeまたはdateフィールドです。

javascriptでフォーマットを変換するのは簡単ですし、理論的にはactiverecordの許容フォーマットonsubmitに変換することもできますが、それはまともな解決策ではありません。

私はActiveRecordのアクセサをオーバーライドするようにしたいので、設定されていると、任意の文字列から適切な形式に変換されますが、それはベストではありません。私はしたくない何

は、コントローラにこのような何かを必要とする別のプロセッサオブジェクトを介して、それらを実行する必要がある。

def create 
    # params == {:product => {:price => "$144.99", :date => "Wednesday, Jan 12, 2011", :percent => "12.9%"}} 
    formatted_params = Product.format_params(params[:product]) 
    # format_params == {:product => {:price => 144.99, :date => Wed, 12 Jan 2011, :percent => 12.90}} 
    @product = Product.new(format_params) 
    @product.save 
    # ... 
end 

、それは完全に透明にするために私がしたいと思います。私はこれを行うことができますので、ActiveRecordのフックはどこですかRails Way

更新

私は今のためにこれをやっている:https://gist.github.com/727494

class Product < ActiveRecord::Base 
    format :price, :except => /\$/ 
end 

product = Product.new(:price => "$199.99") 
product.price #=> #<BigDecimal:10b001ef8,'0.19999E3',18(18)> 
+1

アプリで再びこの値を編集する場合はあなたが行うどんなプロセス例えば、このプロセスは双方向にするために、この作品 –

答えて

10

あなたは、このようなbefore_validation

class Product < ActiveRecord::Base 

    before_validation :format_params 


     ..... 


    def format_params 
     self.price = price.gsub(/[^0-9\.]/, "") 
     .... 
    end 
+2

必要がありますない「attribute_normalizer」という名前の宝石がありますbefore_validationゲッターをオーバーライドして逆にする必要があります。 –

+1

のこの質問に対するiainの答えを参照してください。上記のように、priceはデータベースの数値であると仮定します。意味のあるユーザー入力 "1ab23cd45"は、format_paramsを見る前にto_f処理を1にします。長い日の後、私はself.price = price_before_type_cast.gsub([/ [^ 0-9 \。] /、 '')でなければならないことを知っている。自動生成された* _before_type_castアクセサの使用は重要な秘密である。 – elc

+1

さらなる補足:実際には、ファクトナンが価格を割り振るときに、「フィックスナムのための未知のメソッドgsub」型のエラーが発生するため、price_before_type_cast.to_s.gsub(...)が必要です。 – elc

29

としてあなたのparamsを正常化するために、検証フックの前に使用することができますセッターまたはゲッターをオーバーライドする可能性があります。

class Product < ActiveRecord::Base 
    def price=(price) 
    self[:price] = price.to_s.gsub(/[^0-9\.]/, '') 
    end 
end 

ゲッターをオーバーライド:

セッターをオーバーライド

class Product < ActiveRecord::Base 
    def price 
    self[:price].to_s.gsub(/[^0-9\.]/, '')) 
    end 
end 

違いは、後者の方法はまだ、ユーザが入力したものを格納することであるが、それは、フォーマット取得最初のもの一方、フォーマットされたバージョンを格納します。解析番号のあなたがなどProduct.new(...)update_attributesを呼び出すときにこれらのメソッドが使用されます

...

+0

これは受け入れられる回答である必要があります。 – Erowlin

関連する問題