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().