I've added an Advance Search to my Book App using this tutorial. Everything works fine, but now I am trying to find a Book by its Tags.
I got the advance search to work if the user enters one Tag into the :keywords text_field.
Is there a way to search various tags by splitting the keyword string with commas?
(ex: fun, kid stories, action)
Would allow me to search books with fun OR kids stories OR actions.
How can I search multiple tags via a comma separated string?
Note: I created a search method that I think could help, but I am not sure how to combine it with the single keyword search.
MODEL
class Book < ActiveRecord::Base
has_many :book_mappings
has_many :tags, through: :book_mappings
end
class BookMapping < ActiveRecord::Base
belongs_to :book
belongs_to :tag
end
class Tag < ActiveRecord::Base
has_many :book_mappings
has_many :books, through: :book_mappings
end
class Search < ActiveRecord::Base
def books
@books ||= find_books
end
def find_books
books = Book.order(:name)
###This works for a single word but NOT if I have multiple tags separated by commas
books = books.joins(:tags).where("tags.name like ?", "%#{keywords}%") if keywords.present?
books
end
def search(keywords)
return [] if keywords.blank?
cond_text = keywords.split(', ').map{|w| "name LIKE ? "}.join(" OR ")
cond_values = keywords.split(', ').map{|w| "%#{w}%"}
all(:conditions => (keywords ? [cond_text, *cond_values] : []))
end
end
VIEWS
<%= form_for @search do |f| %>
<div class="field">
<%= f.label :keywords %><br />
<%= f.text_field :keywords %>
</div>
<% end %>
Here is a simple solution. Just add a like
statement for each keyword.
To filter books with all the tags
if keywords.present?
books = books.joins(:tags)
keywords.tr(' ','').split(',').each do |keyword|
books = books.where("tags.name like ?", "%#{keyword}%")
end
end
To filter books with any of the tags
if keywords.present?
books = books.joins(:tags)
keyword_names = keywords.split(', ')
cond_text = keyword_names.map{|w| "tags.name like ?"}.join(" OR ")
cond_values = keyword_names.map{|w| "%#{w}%"}
books = books.where(cond_text, *cond_values)
end