在我的验证发生之前,Rails float列会自动将字母转换为数字

时间:2014-07-26 18:43:10

标签: ruby-on-rails ruby regex validation type-conversion

我的rails项目数据库中有一个浮点列,可以将表单中的百分比保存为浮点数。当用户输入字母和数字的某些组合(如“12jkawd3%”)时,它会转换为浮点数,然后我的验证可以将其排除为无效(它变为有效的浮点数)。我目前正在控制器中使用带有正则表达式的方法来防止这种情况发生并且它可以正常工作,但我觉得必须有更多的rails方法来实现它。我咨询了谷歌并没有发现任何东西。有人可以帮忙吗?

这是我的控制器。如果输入了无效数据,string_to_float方法将阻止它转换为浮点数

class MyProductsNotificationsController < ApplicationController
  def create
    my_product = MyProduct.find(params[:my_product])
    discount = NumberFormatter.string_to_float(params[:my_products_notification][:discount])
    @my_products_notification = MyProductsNotification.new(my_product: my_product, discount: discount)
    if @my_products_notification.save
      redirect_to current_user
    else
      redirect_to current_user, notice: 'Invalid format for discount'
    end
  end
end

NumberFormatter类(注意忽略else 0,因为它是视图的边缘情况。

class NumberFormatter
  class << self
   def string_to_float(discount_string)
      if discount_string =~ /(?<=^| )\d+(\.\d+)?(?=$| )|(?<=^| )\.\d+(?=$| )/
        discount_string
      else
        0
      end
    end

我的模特

class MyProductsNotification < ActiveRecord::Base
  belongs_to :my_product
  before_create :string_to_float
  validates :discount, numericality: { greater_than: 0, less_than_or_equal_to: 100, message: 'is invalid.' }


  private
  def string_to_float
    self.discount = '%.2f' % (self.discount || 0)
  end
end

和表格:

<%= form_for @my_product_notification do |f| %>
        <% if product.my_products_notification %>
          <% discount = product.my_products_notification.discount %>
        <% else %>
          <% discount = '' %>
        <% end %>
        <%= hidden_field_tag :my_product, product.id -%>
        <%= f.label "Percentage discount threshold: %"  %>
        <%= f.text_field :discount, value: discount %>
        <%= f.submit 'Save notification' %>
      <% end -%>

1 个答案:

答案 0 :(得分:1)

当你在变量中输入一些值时,基本上rails会根据数据库列的数据类型转换输入数据。一种方法是使用attr_accessor

您可以将值设置为attr_accessor并检查此变量的验证,然后相应地更新旧的数据库浮点变量。