0

I am trying to create a custom search method for a project I'm working on. Ideally I'd like to be able to have the user input and unlimited number of keywords to filter the results by, but I'm willing to settle for a just a couple. I have my code working for just one keyword. Here is the code in my model:

class Food < ActiveRecord::Base
  has_many :meal_items, inverse_of: :food_for_meal, foreign_key: 'food_for_meal_id'
  has_many :user_meals, through: :meal_items

  def self.search (key)
    Food.where("description LIKE ?", "%#{key}%")
  end
end

Here is one attempt I have made to use multiple keywords:

class Food < ActiveRecord::Base
  has_many :meal_items, inverse_of: :food_for_meal, foreign_key: 'food_for_meal_id'
  has_many :user_meals, through: :meal_items

  def self.search (key)
    keys = key.split('+')
    Food.where("description LIKE ?", "%#{keys[0]}%") 
          AND ("description LIKE ?", "%#{keys[1]}%")
  end
end

I have tried moving things in and out of parens and quotes and so forth, but can't seem to nail down the correct syntax. Any help would be appreciated.

3
  • 1
    Looks like you may want to explore full text search. Are you using PG or MySQL? Commented Jun 14, 2016 at 20:43
  • @mmichael PG. Not familiar with full text search. Commented Jun 14, 2016 at 20:50
  • 1
    Take a look at the Textacular gem Commented Jun 14, 2016 at 21:01

1 Answer 1

2

.where takes SQL fragments, so just put the AND inside.

Food.where("description LIKE ? OR description LIKE ?", "%#{keys[0]}%", "%#{keys[1]}%")

You could do something like for n, keys:

Food.where((['description LIKE ?'] * keys.size).join(' OR '), *keys.map{ |key| "%#{key}%" })

EDIT: You probably want OR as pointed out by a commenter in my answer.

Sign up to request clarification or add additional context in comments.

4 Comments

I think you want OR not AND
You are right, I got caught on the original question.
@Leito what does the asterisk here indicate? *keys.map{ |key| "%#{key}%" }
@Atache, less than 10 years later still counts? For other readers, it's Ruby's splat operator. it destructures an array, so instead of the array being passed as the second argument to the where, the elements of the array are passed as second, third, fourth, etc. For example: abc=[a, b, c]; Foo.bar(*abc) # == Foo.bar(a,b,c)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.