I'd like to setup an advanced search of a Rails resource (i.e Product) where I can perform both positive and negative searches. For example:
- Product is a phone
- Product is not made by Apple
- Product was made in the last 16 months
I can pass multiple parameters to a page but is there a way to chain queries?
@results = Product.where("lower(type) LIKE ?", "%#{search_term.downcase}%").where(....
I'd like to use a combination of where and where.not:
def search
word1 = params[:word_1]
word2 = params[:word_2]
if word1.starts_with?('not')
chain1 = where.not("lower(tags) LIKE ?", "%#{word1.downcase}%")
else
chain1 = where("lower(tags) LIKE ?", "%#{word1.downcase}%")
end
if word2.starts_with?('not')
chain2 = where.not("lower(tags) LIKE ?", "%#{word2.downcase}%")
else
chain2 = where("lower(tags) LIKE ?", "%#{word2.downcase}%")
end
@products = Product.chain1.chain2
end
but I get the following error:
undefined method
where' for #ProductsController:0x0000000000ac58`
CodePudding user response:
You can chain where
like this
Product.
where(type: "phone").
where.not(factory: "Apple").
where(manufactered_at: 16.months.ago..)
Also rails 7 introduces invert_where
(it inverts all condtions before it) so you can
Product.
where(factory: "Apple").invert_where.
where(type: "phone").
where(manufactered_at: 16.months.ago..)
You can use scopes
class Product < ApplicationRecord
scope :phone, -> where(type: "phone")
scope :apple, -> where(factory: "Apple")
scope :manufacatured_last, ->(period) { where(manufactered_at: period.ago..) }
end
Product.apple.invert_where.phone.manufacatured_last(16.months)