2012-01-17 14 views
5

Chcę, aby atrybuty mojego modelu UserPrice były domyślne na 0, jeśli są puste lub jeśli nie sprawdzają poprawności numerycznej. Te atrybuty to tax_rate, shipping_cost i price.Ustaw domyślne atrybuty na 0, jeśli puste lub jeśli nie sprawdzanie poprawności numerycznej

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 

Najpierw kładę :default => 0 wewnątrz tabeli dla wszystkich 3 kolumn, ale nie chciałem, bo to już pól wypełnionych i chcę użyć zastępczych. Oto mój model 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 

ODPOWIEDŹ

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 

Odpowiedz

3

W tym przypadku prawdopodobnie set: default => 0: nil => false w migracji db.

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 

użyć atrybutu Normalizer przy konieczności wykonywania bardziej zaawansowanych rzeczy jak formatowanie numeru telefonu https://github.com/mdeering/attribute_normalizer. Atrybut normalizer jest naprawdę dobry do zapewnienia formatu danych.

# 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 
5

Można chyba tylko umieścić go w akcji before_validation cyklem:

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 

Nie trzeba sprawdzić, czy wejście jest ciągiem od Rails domyślnie na 0 w tym scenariuszu jakikolwiek . Jeśli potrzebujesz tylko tej walidacji podczas akcji create, możesz ją zmienić na:

before_validation :default_to_zero_if_necessary, :on => :create 
Powiązane problemy