如果空白或未验证数值,则将属性默认设置为0

Lea*_*RoR 5 ruby ruby-on-rails ruby-on-rails-3

我希望我的UserPrice模型的属性默认为0,如果它们是空的或者它没有验证数字.这些属性是tax_rate,shipping_cost和price.

class CreateUserPrices < ActiveRecord::Migration
  def self.up
    create_table :user_prices do |t|
      t.decimal :price, :precision => 8, :scale => 2
      t.decimal :tax_rate, :precision => 8, :scale => 2
      t.decimal :shipping_cost, :precision => 8, :scale => 2
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

起初,我把:default => 0所有3列放在表的内部,但我不想这样,因为它已经填充了字段,我想使用占位符.这是我的UserPrice模型:

class UserPrice < ActiveRecord::Base
  attr_accessible :price, :tax_rate, :shipping_cost
  validates_numericality_of :price, :tax_rate, :shipping_cost
  validates_presence_of :price
end
Run Code Online (Sandbox Code Playgroud)

回答

before_validation :default_to_zero_if_necessary, :on => :create

private 

def default_to_zero_if_necessary
    self.price = 0 if self.price.blank?
    self.tax_rate = 0 if self.tax_rate.blank?
    self.shipping_cost = 0 if self.shipping_cost.blank?
end
Run Code Online (Sandbox Code Playgroud)

iwa*_*bed 5

您可以将其置于before_validation生命周期操作中:

before_validation :default_to_zero_if_necessary

private
  def default_to_zero_if_necessary
    price = 0 if price.blank?
    tax_rate = 0 if tax_rate.blank?
    shipping_cost = 0 if shipping_cost.blank?
  end
Run Code Online (Sandbox Code Playgroud)

您无需检查输入是否为字符串,因为Rails会在该方案中将其默认为0.如果您在create操作期间只需要此验证,则可以将其更改为:

before_validation :default_to_zero_if_necessary, :on => :create
Run Code Online (Sandbox Code Playgroud)


sun*_*ity 3

在这种情况下,我可能会在数据库迁移中设置 :default => 0, :nil => false。

class CreateUserPrices < ActiveRecord::Migration
  def self.up
    create_table :user_prices do |t|
      t.decimal :price, :precision => 8, :scale => 2, :default => 0, :nil => false
      t.decimal :tax_rate, :precision => 8, :scale => 2, :default => 0, :nil => false
      t.decimal :shipping_cost, :precision => 8, :scale => 2, :default => 0, :nil => false
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

当必须执行更高级的操作(例如格式化电话号码https://github.com/mdeering/attribute_normalizer )时,我会使用属性规范化器。属性规范化器对于确保数据格式非常有用。

# here I format a phone number to MSISDN format (004670000000)
normalize_attribute :phone_number do |value|
  PhoneNumberTools.format(value)
end

# use this (can have weird side effects)
normalize_attribute :price do |value|
  value.to_i
end

# or this.
normalize_attribute :price do |value|
  0 if value.blank?
end
Run Code Online (Sandbox Code Playgroud)