Ransack search and translations

2019-09-09 21:41发布

问题:

I´m trying to make ransack work on a model that has an association with a translation table.

Translations are managed by globalize gem.

The problem is when I try to search with ransack in model table in :name column, it shows nothing because the :name information is stored in another table.

Any clues how can I make ransack search in the association translation table? I know there is the possibility of using ransackers, but I have no idea which code to put in them.

回答1:

Globalize gives you a class method of with_translations like:

User.with_translations('en')

And so you can set up your own scope on your model that takes advantage of this like:

def self.with_translated_name(name_string)
  with_translations(I18n.locale).where('user_translations.name' => name_string)
end

Then you can expose this scope in your ransackable_scopes array in the model in question, like:

private

def self.ransackable_scopes   
  %i(with_translated_name) 
end

With that in place you should be able to do:

User.ransack({ with_translated_name: "John" }) 


回答2:

While @rlarcombe his answer works in this specific situation, you loose all predicates that ransack provides (eq, cont, etc.) and are basically writing the search query yourself.

Globalize adds the translation table as an association and ransack provides the ability to search on associated tables by prefixing the searchable attribute with the associated table name.

For your situation this would work and would still allow you to use all of ransack's predicates.

User.with_translations(I18n.locale).ransack(translations_name_eq: 'John')

You can use other predicates like cont (contains) for ILIKE matching by just replacing the predicate suffix:

User.with_translations(I18n.locale).ransack(translations_name_cont: 'John')