4

これは非常にばかげた質問なので、単純なものが欠けているに違いないと感じています。フィールドのあるフォームがありquantityます。人々は数量を入力するときにカンマを入力し続けるので (たとえば、12,000を示すために入力します)、データベースの整数列に12,000数量 (例) を保存する前にカンマを削除したいと思います。12000

これまでのところ、2つの方法を試しました。このSOの質問で提案されているセッターメソッドをオーバーライドする

  def quantity=(num)
    num.gsub!(',', '') if num.is_a?(String)
    self[:quantity] = num.to_i
  end

これはある意味で機能します。12,000数量フィールドに入力してフォームを送信する12000と、データベースに入ります。quantity問題は、すべての検証もバイパスすることです。たとえば、数量の値の存在を検証できなくなりました。これは良くない。

また、(セッターをオーバーライドする代わりに) 検証前のコールバックを使用しようとしました。

  before_validation :sanitize_quantity

  def sanitize_quantity
    # Doesn't wok because quantity.to_i already called by this point.
  end

数量がコールバック メソッドに到達するまでに、Rails は既にそれを呼び出しているため、これは機能しませんto_i。これは、コールバックに到達するまでに12,000切り捨てられることを意味します。12繰り返しますが、良くありません。

クライアント側でコンマを削除する以外に、他に何を試すことができますか?

最後に、特定の国ではピリオドとコンマの使い方が異なるため、これは本質的にばかげたことだと認識しています。とにかくやるしかない。

4

3 に答える 3

10

型強制を使用する

私があなたの質問を正しく理解していれば、文字列を数値に強制しようとしています。その場合は、次のように明示的なキャストを使用できます。

validates :quantity, presence: true, numericality: true

def quantity=(num)
  self[:quantity] = num.to_s.scan(/\b-?[\d.]+/).join.to_f
end

テストと例

これがどのように機能するかを確認してください。コンソールで次のことを試すことができます。

# String as input.
number = '12,956.05'
number.to_s.scan(/\b-?[\d.]+/).join.to_f
=> 12956.05

# Float as input.
number = 12956.05
number.to_s.scan(/\b-?[\d.]+/).join.to_f
=> 12956.05

# Using an ActiveRecord object.
q = Quantity.new quantity: '12,956.05'
=> #<Quantity id: nil, quantity: 12956.05, created_at: nil, updated_at: nil>
q.save
=> true
于 2012-07-20T19:08:30.943 に答える
9

質問を読んでいるときに、実際にこれを理解しました。

重要なのは、仮想属性を使用することです。

class Job < ActiveRecord::Base
  def flexible_quantity
    quantity
  end

  def flexible_quantity=(quantity)
    self.quantity = quantity.gsub(',', '') unless quantity.blank?
  end
 end

次に、フォームで virtual 属性を使用します。

<%= f.text_field :flexible_quantity %>

代わりに、flexible_quantity 値の存在を検証します。

class Job < ActiveRecord::Base
  validates :flexible_quantity, presence: true

  # The cool this is that we can leave the numericality validation on the quantity field.
  validates :quantity, presence: true, numericality: { only_integer: true }
end
于 2012-07-20T18:56:53.837 に答える
0

で数量を取得しますparams[:quanity]。ヘルパー メソッド (たとえば、コントローラーで定義) を呼び出して文字列を修正し、それをモデルに渡すことができます。

# YourController.rb
def create # or whatever
    quantity = sanitize_quantity(params[:quantity])
    YourModel.create!(:quantity => quantity)
end

private

    def sanitize_quantity(num)
        num.gsub!(',', '') if num.is_a?(String)
        return num.to_i
    end

そのため、モデルに渡す前にサニタイズして、引き続き検証を行うことができます。

于 2012-07-20T18:45:44.193 に答える