Как заказать запрос в переводе с использованием globalize
Я пытаюсь заказать запрос, используя поле, которое переводится с помощью globalize2. Проблема в том, что, поскольку она хранится в базе данных и в ассоциации, у меня много проблем.
- Выполнение перевода и упорядочения с помощью
category_translations.name
не работает.
- Я попробовал default_scope, но поскольку он не позволяет использовать лямбда или блок для условий, я не могу заставить его работать, если я не использую этот патч для ActiveRecord http://gist.github.com/81187
- Я пробовал с
with_translations
, определенным в globalize2, однако я получаю сообщение об ошибке, и я не мог заставить его работать даже без упорядочения.
У меня что-то вроде этого
class Category < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
has_many :products, :dependent => :destroy
translates :name
end
Вопрос в том, как я могу заказать переведенное имя?
Ответы
Ответ 1
Метод with_translations
, по-видимому, подходит:
Category.with_translations(I18n.locale).order('category_translations.name')
Кроме того, если вы используете PostgreSQL, вы можете добавить к нему регистр, нечувствительный к этому:
Category.with_translations(I18n.locale).order("LOWER(category_translations.name) ASC")
Подробнее об этом здесь:
https://github.com/globalize/globalize#scoping-objects-by-those-with-translations
Ответ 2
Я тестировал это с помощью sqlite3, и он работает.
class Category < ActiveRecord::Base
...
named_scope :ordered, lambda {|locale|
{
#:select => "categories.*, categories.name sort_name",
# For MySQL
#:select => "categories.*, IF(category_translations.name IS NULL, categories.name, category_translations.name) sort_name",
# For sqlite3
:select => "categories.*, (CASE WHEN category_translations.name IS NULL THEN categories.name ELSE category_translations.name END) sort_name",
:joins => ActiveRecord::Base.sanitize_sql_array([
"LEFT JOIN category_translations on category_translations.category_id = categories.id AND category_translations.locale = ?", locale]),
:order => "sort_name"
}
}
...
end
Category.ordered(some_locale).all # Returns all records, sorted by translated name
Ответ 3
Я предполагаю, что любая модель под названием Category
будет иметь не более сотни записей, если не меньше. Возможно, вы можете рассмотреть возможность сортировки результатов в памяти после их загрузки.
@categories = Category.all # or whatever else to retrieve what you want
@categories.sort! { |a,b| a.name <=> b.name }
Остерегайтесь. Это станет плохой идеей, если таблица categories
содержит более тысячи записей.