Примером этого исключаемого исключения является: Когда вы пытаетесь проверить что-то, это null.
Например:
string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)
if (testString.Length == 0) // Throws a nullreferenceexception
{
//Do something
}
Время выполнения .NET исключение NullReferenceException при попытке выполнить действие над чем-то, что не было инстанцировано, т.е. код выше.
По сравнению с ArgumentNullException, которое обычно выбрано как защитная мера, если метод ожидает, что то, что происходит
Дополнительная информация находится в C # NullReferenceException и Null Parameter .
Один из способов - переопределить механизм модели, задающей цену, например:
def price=(val)
write_attribute :price, val.to_s.gsub(/\D/, '').to_i
end
Итак, когда вы делаете @model.price = whatever
, он перейдет к этому методу вместо рельсов по умолчанию автор атрибутов. Затем вы можете преобразовать число и использовать write_attribute
для выполнения собственно записи (вы должны сделать это так, потому что стандартный price=
теперь этот метод!).
Мне нравится этот метод лучше всего, но для справки другой способ сделать это находится в вашем контроллере, прежде чем назначать его модели. Параметр вводится как строка, но модель преобразует эту строку в число, поэтому работайте с параметром напрямую. Что-то вроде этого (просто адаптируйте его к вашему коду контроллера):
def create
@model = Model.new(params[:model])
@model.price = params[:model][:price].gsub(/\D/, '').to_i
@model.save
end
Для любого решения удалите это before_validation
.
Мой столбец решения тип цены десятичный
t.decimal :price, precision: 12, scale: 6
# app/concern/sanitize_fields.rb
module SanitizeFields
extend ActiveSupport::Concern
def clear_decimal(field)
return (field.to_s.gsub(/[^\d]/, '').to_d / 100.to_d) unless field.blank?
end
def clear_integer(field)
field.to_s.strip.gsub(/[^\d]/, '') unless field.blank?
end
# module ClassMethods
# def filter(filtering_params)
# results = self.where(nil)
# filtering_params.each do |key, value|
# results = results.public_send(key, value) if value.present?
# end
# results
# end
#
# #use
# #def index
# # @products = Product.filter(params.slice(:status, :location, :starts_with))
# #end
#
# end
end
#app/controllers/products_controller.rb
include SanitizeFields
params[:product][:price] = clear_decimal(params[:product][:price])
Я бы определил виртуальный атрибут и выполнил свою манипуляцию, позволяя вам форматировать и изменять как getter, так и setter по своему усмотрению:
class Model < ActiveRecord::Base
def foo_price=(price)
self.price = price... #=> Mods to string here
end
def foo_price
"$#{price}"
end
Также вы можете заметить, что:
"$50.00".gsub(/\D/, '').to_i #=> 5000