Search code examples
ruby-on-rails-3ransack

Ransack gem choose predicate and custom predicate names


I'm a bit confused with using an advanced ransack search. I'm trying do make a custom search where not all table names can be selected as search terms and not all predicates are used. I used railscast as a tutorial for this but I can't find anything how to limit the number of predicates. Is there also a possibility to use the names of preicates and table fields in different language (just labels)?

My search form

= search_form_for @q, :url => search_offers_path, :html => { :method => :post } do |f|
  = f.condition_fields do |c|
    .field
      = f.attribute_fields do |a|
        = a.attribute_select
      = f.predicate_select 
      = f.value_fields do |v|
        = v.text_field :value
      = link_to "#{t :destroy}", '#', class: "remove_fields"

    = link_to_add_fields "#{t :add}", f, :condition

  .field
    = t :sort
    = f.sort_fields do |s|
      = s.sort_select

  = f.submit "#{t :search}"

My controller

def index
  select_offers = Offer.where { (user_id != id) & (ended == false) & ((created_at + life_time ) > DateTime.now) }
  @q = select_offers.search(params[:q])
  @offers = @q.result(:distinct => true).page(params[:page])
  @q.build_condition
  @q.build_sort if @q.sorts.empty?
end

Solution

  • I have found a solution. To change predicate labels I used i18n.

    en.yml
    
    ransack:
      asc: "ascending"
      desc: "descending"
      predicates:
        cont: "contains"
        not_cont: "not contains"
        start: "starts with"
        end: "ends with"
        gt: "greater than"
        lt: "less than"
        ...
    

    There is also a possibility to change the names of attribute fields

    attributes:
      model_name:
        model_field1: "field name1"
        model_field2: "field name2"
        ...
    

    To limit the search predicates instead of

    = f.predicate_select 
    

    I used

    = f.attribute_fields do |a|
      = a.attribute_select
    = f.select :p, { 'custom predicate name1' => :predicate1, 'custom predicate name2' => :predicate2 }
    

    To limit table search fields I added to model

    UNRANSACKABLE_ATTRIBUTES = ["id", "published", "created_at"]
    
    def self.ransackable_attributes auth_object = nil
      (column_names - UNRANSACKABLE_ATTRIBUTES) + _ransackers.keys
    end