Within my rails app, I have a Book model and a User model.
I'm using the acts_as_votable gem to allow voting on the books model.
In one of my views, I am currently rendering a list of all books that the current user has not voted for and then grabbing a single random book from that list:
@books = Book.where.not(id: current_user.find_voted_items.map(&:id))
@book = @books.sample
I have now added categories to both users and books, using the acts-as-taggable-on gem.
A book or a user can have up to 9 predefined categories(tags) selected, as part of the tag_list.
tag_list = "math, science, history, design, art, film, music, philosophy, poetry"
Books and users share these same 9 categories/tags.
I'm trying to retrieve a list of all books that share any similar tags to what the current user has selected under their settings, excluding all books that the user has already voted for, and excluding all books that belong to the current user (book.user != current_user).
Lastly I'm trying to select one single random book from this list.
How would I go about doing this?
Something like the following code should work. It feels pretty hacky, though.
Book.tagged_with(current_user.tags, any: true).
where.not(user: current_user).
where.not(id: current_user.find_voted_items.map(&:id)).
sample
If you find you are using parts of this query in other places, I'd suggest extracting them into class methods. Since you will need to pass in the current user as an argument, note that the preferred way (According to Rails Guides) is to use a class method instead of a scope.