如何使用globalize按翻译字段排序查询

时间:2010-08-29 21:09:42

标签: ruby-on-rails activerecord

我正在尝试使用通过globalize2翻译的字段来订购查询。问题是,由于存储在数据库和协会中,我遇到了很多问题。

  • category_translations.name执行翻译和排序的包含不起作用。
  • 我尝试了一个default_scope,但因为它不允许使用lambda或块来处理条件,所以除非我将这个补丁用于ActiveRecord http://gist.github.com/81187
  • ,否则我无法使用它
  • 我尝试过使用globalize2中定义的with_translations,但是我收到了一个错误,即使没有订购也无法让它工作。

我有类似的东西

class Category < ActiveRecord::Base
  validates_presence_of :name
  validates_uniqueness_of :name
  has_many :products, :dependent => :destroy

  translates :name
end

问题是,如何按翻译名称订购?

3 个答案:

答案 0 :(得分:13)

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

答案 1 :(得分:1)

我使用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

答案 2 :(得分:1)

我假设任何名为Category的模型如果不是更少的话,最多会有数百条记录。也许你可以考虑在获取结果后将结果排序在内存中。

@categories = Category.all # or whatever else to retrieve what you want
@categories.sort! { |a,b| a.name <=> b.name }

要小心。如果categories表包含数千条记录,这将是一个坏主意。