I have two models: Author and Book, where
class Book< ApplicationRecord
belongs_to :author
end
class Author< ApplicationRecord
has_many :books
end
Author has a name:string
Book has title:string and author_id as index
I'm interested in finding all authors that have books that contain some given strings
eg if the terms are ['wizard', 'one hundred', 'two cities'] I want to return the authors whose books contain the terms in the title ( one book title containing 'wizard' AND one book containing 'one hundred' AND...)
I could go with something like
class Post
scope :including_all_title, -> (titles) { where(matching_tag_query(titles, 'AND')) }
private
def matching_tag_query(titles, condition_separator = 'AND')
titles.map { |t| "(title LIKE '%#{t}%')" }.join(" #{condition_separator} ")
end
end
( Author.joins(:books).merge(Books.including_all_title... ) but doesn't seem great as the number of terms increases.
I've seen responses that contain Postgres's '@> ' ( eg Postgres: check if array field contains value?)
but so far I couldn't make it work( probably syntax isn't good, I don't get an error but no results )
I'm wondering how could I achieve that with Active Record ( or another solution better than my own)
Edit: I realise I might have been unclear, what I'm trying to do is:
If Author(name:'John')
has books Book(title: 'The wonderful Wizard of Oz')
Book(title: 'Fantastic beasts')
Book(title: 'Some other work')
Book(title: 'Another book')
and I query by ["%wizard%", "%fantastic%"]
I would want to find the author whose books , match ALL of the keywords, so in this case John would be a match( because "wizard" matches one book, and "fantastic" matches another, even if some are unmatched- I'm interested in my keywords)