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?
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?
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.
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:
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.
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().
containing a comparison of column “name” with the string you
(pages.name = ‘Willkommen’)
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.