首先,这个:
def format_values
self.profit.to_s.delete!('^0-9') unless self.profit.nil?
end
和这个差不多:
def format_values
return if(self.profit.nil?)
p = self.profit
s = p.to_s
s.delete!('^0-9')
end
因此,没有理由期望您的format_values
方法对self.profit
.
您当然可以更改format_values
以将处理后的字符串分配给,self.profit
但这无济于事,因为您的清理逻辑位于错误的位置,它将在变成零后执行。 '$1,000'
当你给一个属性赋值时,ActiveRecord 会沿途应用一些类型转换。当您尝试转换'$1,000'
为数字时会发生什么?你当然得到零。如果您在控制台中玩耍,您可以看到这种情况发生:
> a = M.find(id)
> puts a.some_number
11
> a.some_number = 'pancakes'
=> "pancakes"
> puts a.some_number
0
> a.some_number = '$1,000'
=> "1,000"
> puts a.some_number
0
> a.some_number = '1000'
=> "1000"
> puts a.some_number
1000
因此,您的数据清理必须在数据进入模型实例之前进行,因为一旦 AR 掌握了价值,您就会'$1,000'
变成0
一切,一切都将丢失。我将逻辑放在控制器中,控制器的工作是在外部世界和模型之间进行调解,数据格式化和修改当然算作调解。所以你可以在你的控制器中有这样的东西:
def some_controller
fix_numbers_in(:profit)
# assign from params as usual...
end
private
def fix_numbers_in(*which)
which.select { |p| params.has_key?(p) }.each do |p|
params[p] = params[p].gsub(/\D/, '') # Or whatever works for you
end
end
然后,在 ActiveRecord 弄脏你的数据并把事情弄得一团糟之前,一切都会变得干净。
您可以通过覆盖profit=
模型中的方法来做类似的事情,但这实际上不是模型的工作。