I found this scope on a blog post...
scope :search_by_title, -> (title) { where("(title like ?) OR title in (?)", "%#{title}%", title.split) }
... and I'm trying to figure out the second half of the OR pair.
If the query was "banana cake",
it seems to me like the scope would work like this
scope :search_by_title, -> ("banana cake") { where("(title like ?) OR title in (?)", "%banana cake%", ["banana","cake"]) }
and this doesn't seem useful at all.
Anyone got an example that demonstrates how this scope would work?
Thanks
The first part of the scope (before OR) will work when your title includes "banana cake".
The second part of the scope (after OR) will work when your query is either "banana" or "cake".
So, it is useful because you can search for either "banana cake" or "banana" or "cake".
If you don't have that title.split part in there, then your search for either "banana" or "cake" would not work. It will only for "banana cake".
Related
I have a model Deployment, it has following relations:
belongs_to :user
belongs_to :user_group, optional: true
I want to be able to define scope for easier filtering. I can easily filter by user, something like this:
scope :by_owner, -> (ow) { joins(:user).where("users.name like ?", "%#{ow}%") }
But what I really want to use user_group first if association exists and if it doesn't, then fall back on user. Logic would work like this:
If this deployment belongs to at least one user_group
scope :by_owner, -> (ow) { joins(:user_group).where("user_groups.name like ?", "%#{ow}%") }
else
scope :by_owner, -> (ow) { joins(:user).where("users.name like ?", "%#{ow}%") }
end
I am guessing that I have to achieve it somehow with an SQL query, but I can't seem to figure it out. Any suggestions?
Thanks!
Update
I got a bit closer with the following query:
scope :by_owner, -> (ow) { joins(:user, :user_group).where("(users.display_name like ?) OR (user_groups.name like ?)", "%#{ow}%", "%#{ow}%") }
But it's still not it because 1st of all the records that don't have user_groups association are ignored in the response and also it searches by user even if user_group is defined. Still looking for suggestions if there are any.
When using array or string conditions inside Rails query, for example:
Scope in Location model:
scope :name_like, ->(keyword) {where("name ilike ?", keyword)}
It will have problem when using it with join table who also has column name. It is like:
Location.joins(:users).name_like('main')
It will report ambiguous column name conflicts at name.
How should I address this issue, thanks!
Change your name_like scope to use explicit name of locations. I suggest to change it as below:
scope :name_like, -> (keyword) { where("locations.name ilike ?", keyword) }
You need to use like this
scope :by_name, -> { joins(:users).where("users.name like '%?%'",'FirstName' ) }
Refer this link below.
https://apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/scope
I have an array of arrays like [["2","3"], ["3","1"], ["6", "1"]]. The first element of each sub-array is the user ID and the second one is the number of seats the user reserved for an event.
I want to allow each user to view his reservations by finding his ID in the array. Suppose that I have two models: User and Event. In the User controller, I want to use a scope like #mybooking = Event.mybooking(current_user.id) and the problem is how to write the proper scope in the Event model?
And, if the user is found, I want to use its second element, too.
I tried different solutions but didn't work! Let me know if you think it's not possible using the scope and if you have another kind of solution.
Edit:
As I'm still waiting for a solution that works, I should mention that I'm looking for something like this:
scope :mybookings, ->(id){where("reservations.to_enum.map{|n,m| n} ?", id)}
or
scope :mybookings, ->(id) { where("reservations.map(&:first) ?", id) }
These two don't work because of the error I get related to "...." part.
And, below solution isn't true because I'm calling the Event's scope from User controller and it's not possible to use reservations in that controller because this variable is for the Event controller.
class Event
scope :mybooking, ->(user_ids) { where(user_id: user_ids) }
end
Now it is possible to do in controller:
reservations = [["2","3"], ["3","1"], ["6", "1"]]
Event.mybooking(reservations.map(&:first))
How do I create a scope that basically says this:
scope :filtered, where('status != one string, another string, yet another, yep, even more')
So basically saying "status does not equal any of the following strings."
And that list of strings will expand over time.
Note, I'm using PostgreSQL.
Try this: (Not tested)
scope :filtered, where(["status <> ALL ( ARRAY[?, ?] )", 'string_1', 'string_2'])
You can use this:
scope :filtered, where(["status NOT IN (?)", ["string1", "string2", "string3"]])
I am currently using scopes in my model to perform searches within a database. I can stack these scopes and it will output results matching all parameters.
scope :search_between, lambda{|begin_date, end_date|
where "sub.date BETWEEN ? AND ?", begin_date, end_date
}
What I am having trouble with is integrating a keywords search that will search the entire database and output the results that contain the sum of the keywords. I would like to do something like this (displayed for simplicity):
scope :keywords, lambda{|search|
search.chomp.split(/,\s*/) do |item|
where "date like ? or city like ? or state like ?", "%#{item}%" and
where "date like ? or city like ? or state like ?", "%#{item}%" and
where "date like ? or city like ? or state like ?", "%#{item}%"
end
}
I am currently using something like this to take care of searching multiple columns:
scope :keywords, lambda{|search|
search.chomp.split(/,\s*/) do |item|
where(Sub.column_names.map {|cn| "#{cn} like ?" }.join("or "), "%#{item}%"] Sub.column_names.size)).join(' AND ')
end
}
My problem is that I want to do multiple "where()'s" in the scope. Is it possible and if so, how?
Just turn it into a method that returns a scope:def self.keywords(search)
scope = self.scoped
search.chomp.split(/,\s*/).each do |item|
scope = scope.where(["date like ? or
city like ? or
state like ?", "%#{item}%","%#{item}%","%#{item}%"])
end
scope
end
The drawback is that you can't chain keywords off of other scopes, but you can chain other scopes off of keywords.
I think you will be hitting the limit with using the database for full text search.
Have you looked into using Solr or Sphinx for your full text searches? There's also IndexTank if you want to use a 3rd party service.
For solr, there are rubygems available to help you: sunspot, solrsan(i'm the author)
Sunspot is definitely more full-featured and solrsan is a barebones layer.