Rails 3: finding a record by name in multilingual app

Hello,

I upgraded my application from Rails 2 to Rails 3 and ran into a problem. In rails 2 I could use the english name of the record to find it like: Page.find_by_name("Welcome") even though the user chose German as the language (which of course showed the German welcome page.

Eversince I switched to Rails 3 (default_locale still :en) I can't find anything by giving the English name which sucks cause apparently when the user uses German it'd need to use find_by_name("Willkommen") but when the user uses English it'd need to use find_by_name("Welcome").

I don't really know the id of each page so I can't use that. How can I solve this problem?

Thanks

can you be more specific?

Well, I have been using Page.find_by_name("Welcome") in my code all the time when I was on Rails 2 (and globalize2, of course) and no matter what language was selected by the user it was always possible to load the welcome page with this command: Page.find_by_name("Welcome")

Eversince I switched to Rails 3 Page.find_by_name("Welcome") doesn't work anymore if there's another language selected but English which sucks cause I'd need to wrap an if clause checking for the language and then do one of these: Page.find_by_name("Welcome") for English Page.find_by_name("Willkommen") for German Page.find_by_name("Bienvenido") for Spanish which is very stupid but I hope you're catching my drift.

The problem is that I can't use the id but have to use the name which is multilingual.

What that not specific enough? I really don't know how to proceed right now cause there's no proper way to avoid name.

This is my latest approach which I don't like at all but well... Page.find(Fixtures.identify(:welcome)) Works for every language but not so nice. Anyone else got a better solution?

This is completely fishy. Rails is not supposed to translate strings behind your back. Are you any extensions (gems, plugins) that may try to be helpful in the wrong way?

Out of the box, #find_by_name behaves exactly the same as #find_by_foobar, which is to say, it executes an SQL statement containing a comparison of column "name" with the string you provide. It looks like a call to I18n.translate has been slipped in somewhere.

Do you get the same result for Page.where(:name => 'Welcome').first?

In order to find the real cause, your best bet is to use the debugger and step into the misbehaving statement.

Michael

This is completely fishy. Rails is not supposed to translate strings behind your back. Are you any extensions (gems, plugins) that may try to be helpful in the wrong way?

Well, I used globalize2 when I used Rails 2.3.8 and everything worked perfectly fine but no new gems or anything eversince. Must be globalize3 or something...

Out of the box, #find_by_name behaves exactly the same as #find_by_foobar, which is to say, it executes an SQL statement containing a comparison of column "name" with the string you provide. It looks like a call to I18n.translate has been slipped in somewhere.

Do you get the same result for Page.where(:name => 'Welcome').first?

where doesn't work because it's in a different table: Page.where(:name => 'Willkommen') ActiveRecord::StatementInvalid: Mysql::BadFieldError: Unknown column 'pages.name' in 'where clause': SELECT `pages`.* FROM `pages` WHERE (`pages`.`name` = 'Willkommen')

In order to find the real cause, your best bet is to use the debugger and step into the misbehaving statement.

I guess I have no other choice...

Just to make my problem a bit more clear: irb(main):030:0> I18n.locale = :de => :de irb(main):031:0> Page.find_by_name("Welcome") => irb(main):032:0> Page.find_by_name("Willkommen") => [#<Page id: 93372675, text: "blah blah", created_at: "2010-09-12 12:55:41", updated_at: "2010-09-12 12:55:41">] irb(main):033:0> I18n.locale = :en => :en irb(main):034:0> Page.find_by_name("Welcome") => [#<Page id: 93372675, text: "blah blah", created_at: "2010-09-12 12:55:41", updated_at: "2010-09-12 12:55:41">] irb(main):035:0> Page.find_by_name("Willkommen") =>

Before I upgraded to Rails 3 all four queries returned the same result.

sorry for not answering busy.

yes i understand what you say now, but it seems that is a problem with the gem. I dont know globalize2 ill read on it and try to help.

yes i understand what you say now, but it seems that is a problem with the gem. I dont know globalize2 ill read on it and try to help.

Thanks in advance I do appreciate but I'm using globalize3 and not 2 anymore :slight_smile:

so is it working?

Nope not yet but you said you'll try to help and appreciate it.

Well, after looking at the globalize3 code (specifically lib/globalize/active_record/class_methods.rb), I see *why* you get the result you do. The code is actually quite ingenious (or flabberghastly, depending on how you look at it).

Anyway, I think(!) you get what you want, if you simply write

with_locale(:en) {   Page.find_by_name('Welcome') }

For more details, have a look at the tests that come with globalize3.

Michael

Michael Schuerig wrote:

with_locale(:en) {   Page.find_by_name('Welcome') }

Thanks, but there's a little something that makes me not being able to use it. I got another field called content which has the actually content of the page. When I use it with with_locale I get the english content as well. I though of adding a "key" field so I can always find it by it's key, rename "name" to "title" and everything should, work if I do find_by_key().