Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails commonly used strings (for notices and error messages and the like)

About a year ago I decided to make sure that every flash notice that had text that wasn't unique would get the text from a method in a module. My initial reason for doing this was to avoid typing out the same string over and over. If I wanted to change the wording I could do so easily in one spot and the likelihood of typos from repeating the same thing over and over would be decreased.

What I ended up with was this:

module Messages
    def format_error_messages(errors)
        errors.map {|attribute, message| "Error: #{attribute.to_s.titleize} #{message}.<br />"}
    end

    def error_message_could_not_find(object_name)
        "Error: Unable to find the specified " + object_name + "!"
    end

    def error_message_could_not_create(object_name)
        "Error: Unable to create the " + object_name + "!"
    end

    def error_message_could_not_save(object_name)
        "Error: Unable to save " + object_name + " to database!"
    end

    def error_message_could_not_update(object_name)
        "Error: Unable to update " + object_name + "!"
    end

    def error_message_could_not_destory(object_name)
        "Error: Unable to destroy " + object_name + "!"
    end

    def notice_message_created(object_name)
        object_name.capitalize + " has been created!"
    end

    def notice_message_updated(object_name)
        object_name.capitalize + " has been updated!"
    end

    def notice_message_destroyed(object_name)
        object_name.capitalize + " has been deleted!"
    end
end

In my controllers when I'm setting up the flash I can do something like:

flash[:notice] = notice_message_created("post")

That way all successfully created objects generate similar messages.

I'm redoing one of my projects now and am going over all of this and I have this nagging feeling that this is just not the best way to go about doing this. I mean, it works, and it's served me well so far, but I've never seen anyone else do this and I'm starting to think there's a reason. Having to add a new method every time I need a new string seems almost silly. But then how else would I go about being able to insert contextual text into the string (like the name of the type of object we're dealing with)?

Is there a Rails community standard when it comes to dealing with common strings of text? Especially ones that need to have additional text inserted into them at runtime?

I've been reading up on Rails' internationalization since it would be nice to have my projects localized into more than one language and I like the idea of having all my strings of text in nice YAML files which would kill two birds with one stone. But I don't see how I could do that and keep the same sort of functionality I've already got and need (unless I'm horribly mistaken and I don't need it because there's a better way).

I'm pretty much open to any ideas, suggestions, or relevant reading on this issue.

like image 498
seaneshbaugh Avatar asked Jun 20 '11 12:06

seaneshbaugh


1 Answers

You could use as an alternative approach the Rails Internationalization API. Then you could fill your locale file with the strings you want to use. Any parameter you want to give can be included like in the example ins section 4.2 in the tutorial.

I18n.backend.store_translations :en, :thanks => 'Thanks %{name}!'
I18n.translate :thanks, :name => 'Jeremy'
# => 'Thanks Jeremy!'

So do the following steps:

  1. Visit the file config/locales/en.yml

  2. Insert there your localization:

    en: created: "#{name} has been created!"

  3. Call instead of notice_message_created(object_name) the following: t(:created, object_name.capitalize)

At the end, everything should work as before, you have get rid of a lot of simple methods, and you are able to internationalize your application by including the locale, and adding locale files to config/locales.

like image 167
mliebelt Avatar answered Sep 19 '22 14:09

mliebelt