# 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.
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
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
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
# Avatar
- Search Avatar is a Pro feature (opens new window).
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
# 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.
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
# Resource search
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.
# Global search
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).
# Hide the global search
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
# Hide a resource from the global search
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