# Search

Finding what you're looking for fast is essential. That's why Avo leverages ransack's (opens new window) powerful query language.

First you need to add ransack as a dependency to your app (breaking change from 1.10.0).

# Gemfile
gem 'ransack'

# Enable search for a resource

To enable search for a resource, you need to add the search_query class variable to the resource file.



 
 
 




class UserResource < Avo::BaseResource
  self.title = :name
  self.search_query = ->(params:) do
    scope.ransack(id_eq: params[:q], first_name_cont: params[:q], last_name_cont: params[:q], m: "or").result(distinct: false)
  end

  # fields go here
end

The search_query block passes over the params object that holds the q param, the actual query string. It also provides the scope variable on which you run the query. That ensures that the authorization scopes have been appropriately applied.

In this block, you may configure the search however strict or loose you need it. Check out ransack's search matchers (opens new window) to compose the query better.

# Configure the search result

# Label

By default, the search results will be displayed as text. The text label will be the title column you previously configured.

Blank search

You may configure that to be something more complex using the as_label option. That will take the final value of that field and display it as the label of the search result.









 
 
 


class PostResource < Avo::BaseResource
  self.title = :name
  self.search_query = ->(params:) do
    scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
  end

  field :id, as: :id
  field :name, as: :text, required: true, as_label: true
  field :complex_name, as: :text, hide_on: :all, as_label: true do |model|
    "[#{model.id}]#{model.name}"
  end
end
Search label

Notice the hide_on: :all option used to hide the computed complex_name attribute from the rest of the views. That is because you may or may not want to show that attribute in other views.

# Description

Search Description is a pro feature

You might want to show more than just the title in the search result. Avo provides the as_description option to add some more information.












 
 
 
 
 


class PostResource < Avo::BaseResource
  self.title = :name
  self.search_query = ->(params:) do
    scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
  end

  field :id, as: :id
  field :name, as: :text, required: true, as_label: true
  field :complex_name, as: :text, hide_on: :all, as_label: true do |model|
    "[#{model.id}]#{model.name}"
  end
  field :excerpt, as: :text, as_description: true do |model|
    ActionView::Base.full_sanitizer.sanitize(model.body).truncate 130
  rescue
    ""
  end
end
Search description

# Avatar

You may improve the results listing by adding an avatar to each search result. You do that by using the as_avatar attribute. This attribute has three options :square, :rounded or :circle. This influences the final roundness of the avatar.

















 


class PostResource < Avo::BaseResource
  self.title = :name
  self.search_query = ->(params:) do
    scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
  end

  field :id, as: :id
  field :name, as: :text, required: true, as_label: true
  field :complex_name, as: :text, hide_on: :all, as_label: true do |model|
    "[#{model.id}]#{model.name}"
  end
  field :excerpt, as: :text, as_description: true do |model|
    ActionView::Base.full_sanitizer.sanitize(model.body).truncate 130
  rescue
    ""
  end
  field :cover_photo, as: :file, is_image: true, as_avatar: :rounded
end
Search avatar

# Header Help Text

You may improve the results listing header by adding a text highlighting the fields you are looking for or any other instruction for the user. You do that by using the search_query_help attribute. This attribute takes a string and appends it to the title of the resource.

Search Header Help





 




class PostResource < Avo::BaseResource
  self.title = :name
  self.search_query = ->(params:) do
    scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
  end
  self.search_query_help = "- search by id"

  field :id, as: :id
end

When a resource has the search_query attribute, you will see a new search input in the Index view. You can use that to search that particular resource.

Resource search
Global search is a pro feature

Avo also has a global search feature. It will search through all the resources that have the search_query attribute present.

You open the global search input by clicking the trigger on the navbar or by using the CMD + K keyboard shortcut (Ctrl + K on windows).

Global search trigger

If you, by any chance want to hide the global search you can do so using this setting 👇



 


# config/initializers/avo.rb
Avo.configure do |config|
  config.disabled_features = [:global_search]
end

You might have a resource that you'd like to be able to perform a search on when on its Index page but not have it present in the global search. You can hide it using hide_from_global_search = true.








 






class TeamMembershipResource < Avo::BaseResource
  self.title = :id
  self.includes = [:user, :team]
  self.visible_on_sidebar = false
  self.search_query = ->(params:) do
    scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
  end
  self.hide_from_global_search = true

  field :id, as: :id
  field :user, as: :belongs_to
  field :team, as: :belongs_to
end

# Scope out global or resource searches

You may want to perform different searches on the global search from the resource search. You may use the params[:global] flag to figure that out.








 




class OrderResource < Avo::BaseResource
  self.search_query = ->(params:) do
    if params[:global]
      # Perform global search
      scope.ransack(id_eq: params[:q], m: "or").result(distinct: false)
    else
      # Perform resource search
      scope.ransack(id_eq: params[:q], details_cont: params[:q], m: "or").result(distinct: false)
    end
  end
end