Tam*_*iev 5 ruby activerecord ruby-on-rails ruby-on-rails-3
我有一个带有利润字段的用户模型.利润字段是DECIMAL(11,0)类型.我在表单上有一个屏蔽输入,允许用户输入1000美元.我想格式化该值并删除除数字之外的所有内容,因此我将保存1000.这是我到目前为止:
class User < ActiveRecord::Base
before_save :format_values
private
def format_values
self.profit.to_s.delete!('^0-9') unless self.profit.nil?
end
end
Run Code Online (Sandbox Code Playgroud)
但它一直在数据库中保存0.看起来它在我的格式化功能之前将其转换为十进制.
试试这个:
def profit=(new_profit)
self[:profit] = new_profit.gsub(/[^0-9]/, '')
end
Run Code Online (Sandbox Code Playgroud)
首先,这个:
def format_values
self.profit.to_s.delete!('^0-9') unless self.profit.nil?
end
Run Code Online (Sandbox Code Playgroud)
与此基本相同:
def format_values
return if(self.profit.nil?)
p = self.profit
s = p.to_s
s.delete!('^0-9')
end
Run Code Online (Sandbox Code Playgroud)
所以没有理由期望你的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
Run Code Online (Sandbox Code Playgroud)
因此,您的数据清理必须在数据进入模型实例之前进行,因为一旦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
Run Code Online (Sandbox Code Playgroud)
然后一切都会干净,然后ActiveRecord就会对你的数据进行肮脏的小动作并弄乱一些东西.
您可以通过覆盖profit=模型中的方法来执行类似的操作,但这实际上不是模型的工作.
| 归档时间: |
|
| 查看次数: |
4924 次 |
| 最近记录: |