Rails Application Helper Didn't Support Chinese Characters

Ruby method to remove accents from UTF-8 international characters

I generally use I18n to handle this:

1.9.3p392 :001 > require "i18n"
=> true
1.9.3p392 :002 > I18n.transliterate("Hé les mecs!")
=> "He les mecs!"

How to show nested form validation errors after the validation errors for the parent model?

Update 1:

I discovered that the answer by februaryInk was very close to correct if you don't need to worry about i18n and translation of your application text. If you put the has_many :child_model underneath all your validations, the validations will appear in the correct order. However, full_messages doesn't appear to translate model or attribute names using the locale files, so if you require the error messages to be translated (which I do), my answer still seems like a decent solution.

Update 2:

Just realized after posting the first update that I could simplify my code that generates the messages list a lot by removing the part that does the ordering using the discovery in update 1, and just keep the part that does the translation. So here is my new solution, which is a combination of my update 1 and my original solution. All other information about the config/locales/xx.yml and config/application.rb files is still the same for this updated solution as it was for the original.

app/models/parent_model.rb

...

validates :name, # validations hash
validates :description, # validations hash
validates :others, # validations hash

has_many :child_models
accepts_nested_attributes_for :child_models

...

app/models/child_model.rb

...

validates :nested_1, # validations hash
validates :nested_2, # validations hash

...

app/helpers/application_helper.rb

messages = resource.errors.messages.keys.map {|value| error_message_attribute(resource, value) + I18n.t('space') + resource.errors.messages[value].first}.map { |msg| content_tag(:li, msg) }.join

private
def error_message_attribute(resource, symbol)
if symbol.to_s.split(".").length > 1
model_name, attribute_name = symbol.to_s.split(".")
model_class = model_name.singularize.camelize.constantize
model_class.model_name.human + I18n.t('space') + model_class.human_attribute_name(attribute_name).downcase
else
resource.class.human_attribute_name(symbol)
end
end

End of Update

I made a few changes to my error_messages function in application_helper.rb and now have everything working the way I wanted: main form validation errors are on the top, nested form validation errors are under those, the order of the errors does not change except moving the nested form errors under the main form errors.

My solution was to change the messages = line in error_messages as shown below and to add a private helper method. (This should probably be broken down into parts to make it easier to read and understand, but I built it up in the console to get what I wanted and just pasted it directly from there).

app/helpers/application_helper.rb

messages = Hash[resource.errors.messages.keys.map.with_index(1) { |attribute, index| [attribute, [index, attribute.match(/\./) ? 1 : 0]] }].sort_by {|attribute, data| [data[1], data[0]]}.collect { |attributes| attributes[0]}.map {|value| error_message_attribute_name(resource, value) + I18n.t('space') + resource.errors.messages[value].first}.map { |msg| content_tag(:li, msg) }.join

private
def error_message_attribute_name(resource, symbol)
if symbol.to_s.split(".").length > 1
model_name, attribute_name = symbol.to_s.split(".")
model_class = model_name.singularize.camelize.constantize
model_class.model_name.human + I18n.t('space') + model_class.human_attribute_name(attribute_name).downcase
else
resource.class.human_attribute_name(symbol)
end
end

This solution should also work for other other locales, since I used I18n to get all the names. You will have to add the following also:

config/locales/en.yml

en:
space: " "

This is so the model and attribute names will be handled correctly in languages that either have or don't have spaces between words (the first locale I need to support is Chinese, which doesn't have spaces between the words). If you did need to support Chinese, for example, you would use this:

config/locales/zh.yml

zh:
space: ""

If you don't have to support this case, all instances of I18n.t('space') can be replaced with " ". The model and attribute names can also be translated as, but again if you don't need to support locales beyond English you don't need to do anything (although you can use the en.yml file to change the names of the model or attributes that are displayed).

As an example using en.yml to change the names displayed using the common Authors/Books example:

config/locales/en.yml

en:
activerecord:
models:
author: "writer"
book: "manuscript"
attributes:
author:
name: "non de plume"
book:
name: "title"
published: "year"

In this example the default, without the above additions to en.yml, would be:

  • Name can't be blank.
  • Book name can't be blank.
  • Book published can't be blank.

But with the above additions to en.yml it would be:

  • Nom de plume can't be blank.
  • Manuscript title can't be blank.
  • Manuscript year can't be blank.

And of course, if you have a zh.yml file with the appropriate translations, whatever you have in those would show up instead.

If you do need to support multiple locales, don't forget to add the following to config/application.rb (this part was only tested superficially, and may need some additional configuration):

config/application.rb

config.i18n.available_locales = [:zh, :en]
config.i18n.default_locale = :en

Create a helper or something for haml with ruby on rails

You can use haml_tag too

def content_box
haml_tag :div, :class => "holder" do
haml_tag :div, :class => "top"
haml_tag :div, :class => "content" do
yield
haml_tag :div, :class => "bottom"
end
end

and in haml

%html
%head
%body
Maybee some content here.
= content_box do
Content that goes in the content_box like news or stuff

Rails controller fails with TypeError - Error during failsafe response?

It turns out that the problem was that the line

token=RegistrationManager.get_instance.get_auth_token(params)

which refers to a helper class called RegistrationManager that I had in the helpers subdirectory. For reasons I still dont understand, if you refer to a class rather than module that lives in the helpers directory, Rails is unhappy. Why it fails at line 1, I'm not really sure, but moving the class out of helpers into controllers/concerns solved the problem. I wish the error messaging referred to the location of the bad call rather than at line 1, could have saved me and Mr. Adel a lot of time!



Related Topics



Leave a reply



Submit