Last active
October 25, 2018 05:54
-
-
Save msievers/e9421cee6479294f5af5c1eedc1c8f79 to your computer and use it in GitHub Desktop.
A simple, sql only, multi model search
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The idea is, to have models adhere to a convention, which stats, that there has to be a field "searchable_tokens", | |
which includes searchable tokens. Now, we can simply have a (virtual) model/table `search_results`, which can be | |
unioned with "casted selects" of each model we want to search. The casted selects make the columns of each model to fit | |
into the schema of the search result. | |
Mixed with ActiveRecord's polymorphic associations, the result is an ActiveRecord relation with elements, which points to | |
their respective subject. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# db/migrate/20170317064203_create_search_results.rb | |
# | |
# This table is not meant to have any rows, it's more like a virtual table | |
# | |
class CreateSearchResults < ActiveRecord::Migration[5.0] | |
def change | |
create_table :search_results do |t| | |
t.integer :subject_id | |
t.string :subject_type | |
t.text :searchable_tokens | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/search_result.rb | |
# | |
class SearchResult < ApplicationRecord | |
belongs_to :subject, polymorphic: true | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# - the selects force the results in a schema that can be unioned with the search_results table | |
# - because we declared the model to be polymorphic associated to a subject, the actual hit can be accessed via `subject` | |
# If your search_results table has timestamps, than you have to select created_at, updated_at, too | |
companies = Company.where("searchable_tokens LIKE '%micha%'").select("NULL as id, id AS subject_id, 'Company' AS subject_type, searchable_tokens") | |
users = User.where("searchable_tokens LIKE '%micha%'").select("NULL as id, id AS subject_id, 'User' AS subject_type, searchable_tokens") | |
saerch_result = SearchResult.all.union(companies).union(users) | |
search_result.first.subject # => Company | |
search_result.second.subject # => User |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment