5

Profitフィールドを持つユーザーモデルがあります。利益フィールドはDECIMAL(11,0)タイプです。フォームにマスクされた入力があり、ユーザーは$1,000のようなものを入力できます。その値をフォーマットし、数値以外のすべてを削除して、1000を保存したいと思います。これが私がこれまでに持っているものです:

class User < ActiveRecord::Base
  before_save :format_values

  private

  def format_values
    self.profit.to_s.delete!('^0-9') unless self.profit.nil?
  end
end

しかし、それはデータベースに0を保存し続けます。フォーマット機能の前に10進数に変換しているようです。

4

6 に答える 6

8

これを試して:

def profit=(new_profit)
  self[:profit] = new_profit.gsub(/[^0-9]/, '')
end
于 2012-04-18T17:54:23.863 に答える
6

まず第一に、これ:

def format_values
  self.profit.to_s.delete!('^0-9') unless self.profit.nil?
end

これとほとんど同じです:

def format_values
    return if(self.profit.nil?)
    p = self.profit
    s = p.to_s
    s.delete!('^0-9')
end

format_valuesしたがって、メソッドが に何らかの影響を与えると期待する理由はありませんself.profit

format_valuesもちろん、処理された文字列を割り当てるように変更することもできますがself.profit、クレンジング ロジックが間違った場所にあり、ゼロに変わった後に実行されるため、それは役に立ちません。 '$1,000'

プロパティに値を代入すると、ActiveRecord は途中でいくつかの型変換を適用します。数値に変換しようとするとどうなります'$1,000'か? もちろんゼロになります。コンソールで遊んでみると、これが起こっているのを見ることができます:

> a = M.find(id)
> puts a.some_number
11
> a.some_number = 'pancakes'
 => "pancakes"
> puts a.some_number
0
> a.some_number = '$1,000'
 => "1,000"
> puts a.some_number
0
> a.some_number = '1000'
 => "1000"
> puts a.some_number
1000

したがって、データがモデル インスタンスに入るにデータのクリーンアップを行う必要があります。AR が値を取得するとすぐに'$1,000'0すべてが失われるからです。コントローラーにロジックを入れます。コントローラーの仕事は、外界とモデルの間を仲介することであり、データのフォーマットとマングリングは確かに仲介としてカウントされます。したがって、コントローラーに次のようなものを含めることができます。

def some_controller
    fix_numbers_in(:profit)
    # assign from params as usual...
end

private

def fix_numbers_in(*which)
    which.select { |p| params.has_key?(p) }.each do |p|
        params[p] = params[p].gsub(/\D/, '') # Or whatever works for you
    end
end

そうすれば、ActiveRecord が汚れたデータを手に入れて混乱を招く前に、すべてがクリーンになります。

モデルのメソッドをオーバーライドすることで同様のことを行うことができますprofit=が、それは実際にはモデルの仕事ではありません。

于 2012-04-18T20:02:45.973 に答える
0
  def format_values
    self.profit.to_d!
  end
于 2012-04-18T17:48:05.837 に答える
0

この特定のインスタンス変数 @profit のカスタム セッターを作成することをお勧めします。

class User
  attr_accessor :profit

  def profit= value    
    @profit = value.gsub(/\D/,'')
  end
end

u = User.new
u.profit = "$1,000"
p u.profit # => "1000"
于 2012-04-18T17:56:14.697 に答える
0

number の Rails ヘルパーを正確に使用することをお勧めします。以下はいくつかのコードです。

一般的な例:

number_with_precision(111.2345, :precision => 1, :significant => true)     # => 100

Rails コードの例:

def profit=(new_profit)
  number_with_precision(self[:profit], :precision => 1, :significant => true)
end
于 2012-04-18T18:48:56.707 に答える
0
class User < ActiveRecord::Base
  before_save :format_values

  private

  def format_values
    self.profit = profit.to_s.gsub(/\D/,'') if profit
  end
end
于 2012-04-18T19:29:11.340 に答える