我的模型中有一个before_save,可以将逗号转换为点正常工作。但不知怎的,它破了。示例:用户输入1,22和值无条件存储,如1.00
我需要将值存储为小数,即使用户键入逗号而不是点。因为我住的地方逗号是分隔符。
before_save { self.price.to_s.gsub(',', '.').to_f }
我也试过改变这个:
before_save :convert_comma
private
def convert_comma
self.price = self.price.to_s.gsub(',', '.').to_f
end
我在控制台中对上面的逗号替换进行了测试并且它可以正常工作,但是对于before_save,数据的存储舍入为1.00
Rails控制台:
2.3.4 :001 > p = Ticket.new("driver_id"=>"3", "origin_id"=>"AP", "origin_city_id"=>"Amapá", "destination_id"=>"GO", "destination_city_id"=>"Abadia de Goiás", "start_date"=>"29/12/2017 19:28", "return_date"=>"29/12/2017 19:28", "annotation"=>"1", "rate"=>"1", "price"=>"1233,22", "status"=>"Aberto")
=> # <Ticket id: nil, start_date: "2017-12-29 19:28:00", return_date: "2017-12-29 19:28:00", rate: #<BigDecimal:68e22a8,'0.1E1',9(18)>, price: #<BigDecimal:68e21e0,'0.1233E4',9(18)>, annotation: "1", status: "Aberto", department_id: nil, origin_id: "AP", destination_id: "GO", driver_id: 3, created_at: nil, updated_at: nil, origin_city_id: "Amapá", destination_city_id: "Abadia de Goiás", manager: nil, day: nil, user_id: nil, deleted_at: nil>
2.3.4 :002 > p.save
(0.2ms) SAVEPOINT active_record_1
SQL (0.6ms) INSERT INTO "tickets" ("start_date", "return_date", "rate", "price", "annotation", "status", "origin_id", "destination_id", "driver_id", "created_at", "updated_at", "origin_city_id", "destination_city_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["start_date", "2017-12-29 19:28:00"], ["return_date", "2017-12-29 19:28:00"], ["rate", 1.0], ["price", 1233.0], ["annotation", "1"], ["status", "Aberto"], ["origin_id", "AP"], ["destination_id", "GO"], ["driver_id", 3], ["created_at", "2017-12-29 21:55:22.119679"], ["updated_at", "2017-12-29 21:55:22.119679"], ["origin_city_id", "Amapá"], ["destination_city_id", "Abadia de Goiás"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
这真的很奇怪。知道会发生什么事吗? 谢谢!
答案 0 :(得分:2)
这里的问题是,只要在初始化程序(Ticket.new)中写入属性,活动记录就会将字符串强制转换为BigDecimal。请注意,在控制台输出中,您的实例为price属性保存BigDecimal,值为“0.1233E4”,而不是“0.123322e4”。这意味着当你的:convert_comma方法运行时:
self.price.to_s #=> '1233.0'
一种可能的解决方案是覆盖模型中的属性writer,在ticket.rb文件中编写以下实例方法:
def price=(new_price)
super(BigDecimal.new(new_price.to_s.gsub(',', '.')))
end
答案 1 :(得分:1)
我不确定是否理解了您的问题,我认为该错误正在尝试转换','in'。'在一个数字类型。您可以在视图中使用NumberHelper方法更改其打印方式,例如:
<%= number_with_delimiter(@product.price, delimiter: ",", separator: ".") %>
分隔符是千位和分隔符的小数,如果货币可能是更好的number_to_currency方法
<%= number_to_currency(@product.price, delimiter: ".", separator: ",", unit: "€") %>
修改强> a link to ActionView::Helpers::NumberHelper references
再次编辑 由于你需要允许用户使用数字逗号作为分隔符,我建议你自己查找或写一个18n文件放入你的config / locales文件夹,对于巴西它应该是br.yml。在语音“number:”处,您可以设置货币和格式,并设置分隔符和分隔符。 要在默认情况下设置此文件,请在config / application.rb上添加以下行:
module YourApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.i18n.default_locale = :br
end
end
然后你的number_field需要有正确的步骤选项:
<%= f.number_field :price, step: 0.01 %>
这应该有效并且还允许您翻译系统消息:)
答案 2 :(得分:1)
我在https://stackoverflow.com/a/11585385/2188585找到了解决方法并修改为:
before_save :pricecomma
def pricecomma
price
end
def pricecomma=(price)
self.price = price.gsub(',', '.') unless price.blank?
end
将表单更改为:
<%= f.text_field :pricecomma %>
仍然没有得到正在发生的事情。我尝试了没有此虚拟属性的相同代码,并且没有获得替换。但这种方式很好。