[Ruby] [Rails] How to search across columns of related models (parent and child) in ransack

2 minute read

What you want to achieve

I want to search up to model columns related (nested) to one model

Specifically, I would like to perform a collective search including not only store names of used clothing stores but also area names (1 to many) and brand names (many to many).

Screenshot 2020-07-11 17.45.47.png

Conclusion

Specify related model name_related model column name in element name of form tag

For example, when you want to use the area name (name) of the area model linked to the shop model as the search condition = f. Form helper: Element name of element name is set as area_name_cont.

When disassembled area → Related model name name → column name of related model cont → predicate that specifies partial match

Will be.

= search_form_for(@q, url: shop_search_path) do |f|
  = f.text_field :area_name_cont
  # Area name of the area model linked to the shop model (name)

For example, when you want to use the brand name (name) of the brands model linked to the shop model as the search condition = f. Form helper: Element name of element name is set to brands_name_cont.

When disassembled brands → related model name *shop has_many: brands, so plural name → column name of related model cont → predicate that specifies partial match

Will be.

= search_form_for(@q, url: shop_search_path) do |f|
  = f.text_field :brands_name_or_genres_name_cont
  The brand name of the brand model linked to the #shop model
  # genre model name associated with the shop model
  # Note that the model name will be plural if there are multiple linked models

By the way, you can search multiple columns by connecting column names with _or_ etc.

For actual usage of ransack, please refer to articles such as Summary of various search form creation methods using [Rails]ransack.

Model-to-model association

*Only relevant parts are listed

Screenshot 2020-07-11 18.17.14.png

shop.rb


# shop model
  belongs_to :area, optional: true
  has_many :shop_genres
  has_many :shop_brands
  has_many :genres, through: :shop_genres
  has_many :brands, through: :shop_brands

area.rb


# area model
  has_many :shops

brand.rb


# brand model
  has_many :shop_brands
  has_many :shops, through: :shop_brands

shop_brand.rb


# shop_brand model
  belongs_to :shop
  belongs_to :brand

shop_genre.rb


# shop_genre model
  belongs_to :shop
  belongs_to :genre

How to find out the association

It is convenient to use the method called ransackable_associations.

1. Rails c in the application directory

terminal


# Run in the corresponding application directory

$ rails c
Running via Spring preloader in process 61541
Loading development environment (Rails 5.0.7.2)
[1] pry(main)>

**2. Execute model name.ransackable_associations **

terminal


# This time I want to investigate the relation with the Shop model, so if I say Shop.ransackable_associations
  The model linked to the Shop model is displayed
[1] pry(main)> Shop.ransackable_associations
=> ["user", "area", "shop_genres", "shop_brands", "genres", "brands"]
[2] pry(main)>

Reference

73 recipes to make search form easily with Ransack -026 related How to search multiple columns in parent table or child table in Ransack