In countries such as France, Germany and Italy, a comma is used to separate the integral and fractional parts of a float (2.99 becomes 2,99). Still Rails stubbornly uses a dot as the decimal separator when displaying and processing text fields for float values, and there is little in the I18n API to help.
Fortunately we discovered a small hack to make decimal columns of ActiveRecord models accept the comma as the separator. Copy the following as comma_as_decimal_separator.rb
into the config/initializers
folder of your Rails application:
ActiveRecord::Base.class_eval do
def convert_number_column_value_with_comma_separator(value)
value = convert_number_column_value_without_comma_separator(value)
if value.is_a?(String)
value = value.gsub(',', '.')
end
value
end
alias_method_chain :convert_number_column_value, :comma_separator
end
ActiveRecord::ConnectionAdapters::Column.class_eval do
def type_cast_with_comma_separator(value)
if type == :decimal && value.is_a?(String)
value = value.gsub(',', '.')
end
type_cast_without_comma_separator(value)
end
alias_method_chain :type_cast, :comma_separator
end
Remember to restart your server so the initializer gets loaded.
Now any decimal column will accept a string with a comma as the separator. The string will then automagically be converted to the correct value:
>> article = Article.new
=> #<Article id: nil, price: nil>
>> article.price = "5,2"
=> "5,2"
>> article.price
=> #<BigDecimal:b6e9c4f4,'0.52E1',8(8)>
>> article.selling_price.to_s
=> "5.2"
Note that this only works for columns of type decimal, not float. Always use decimals and try to avoid floats, which have many issues.
Now that your model can deal with commas, you want your text fields to show decimal values with commas, too! Our favorite solution for this is to define an additional form helper number_field
which can be used in lieu of text_field
to show an input box for decimal values. Copy the following as number_field.rb
into the config/initializers
folder of your Rails application:
ActionView::Helpers::FormBuilder.class_eval do
def number_field(field, options = {})
value = object.send(field).to_s
value.gsub!('.', ',') unless value.blank?
options[:value] = value
options[:class] = "#{options[:class]} number_field"
text_field(field, options)
end
end
Remember to restart your server so the initializer gets loaded.
Now you can have your views display a number field with commas:
<% form_for @article do |form| %>
<%= form.number_field :price %>
<%= form.submit %>
<% end %>
Because the number_field
helper creates a text field with the CSS class number_field
, you can style those inputs in your CSS stylesheet. We like to make number fields shorter than regular text fields and right-align its value:
input.number_field {
width: 100px;
text-align: right;
}
Was this post helpful to you? Then let us know!