More than one ActiveRecord query at once? - ruby-on-rails

Here's an action in my controller. What it currently does is display all Guides that have a least any spelling of the word 'abyss' in it. What I'd like to do is display all guides that have either any spelling of 'abyss' or any spelling of 'cat' in it as well.
I've tried all sorts of '%cat%' combinations, but can't find the right place to put it.
How do I make this work?
def abyss
t = Guide.arel_table
#guides = Guide.where(t[:title].matches('%abyss%'))
end

Try with or as follows:
def abyss
t = Guide.arel_table
#guides = Guide.where(t[:title].matches('%abyss%').or(t[:title].matches('%cat%')))
end

You can use find_by_sql to simplify such queries:
def abyss
#guides = Guide.find_by_sql(["select * from guides where title LIKE ? OR title LIKE ?", '%abyss%', '%cat%'])
end

Related

Search for item name from multiple fields on Ruby on Rails

I'm trying to enable a search for an item, and then have that item listed if the search is completed. I can get it to work for both instances, but not at the same time. My code:
def search
#results=0
if !params[:searchinput].empty?
#results=1
#searchinput = params[:searchinput]
#searchcriteria="%#{params[:searchinput]}%"
#productlist = Product.where("productname like ? OR description like ?", #searchcriteria)
end
end
I get the following error:
Is the formatting with the productlist statement wrong?
The problem is you have to pass in two variables. If that is #searchcriteria then pass that in.
def search
#results=0
if !params[:searchinput].empty?
#results=1
#searchinput = params[:searchinput]
#searchcriteria="%#{params[:searchinput]}%"
#productlist = Product.where("productname like ? OR description like ?", #searchcriteria, #second_variable)
end
end
the productlist statement should look like the following:
#productlist = Product.where("productname like ? OR description like ?", #searchcriteria, #searchcriteria)

How to combining two search parameters in Rails

I am just getting into Rails and want to preform a simple search FROM destination TO destination. I have the basic search functionality working and connected to the database but when I choose FROM and TWO the output is combined and I get all transports FROM the specific text and all transports TO the specific text. I want to filter them and only have the ones that go FROM TO.
Here is what I have so far.
class Transport < ApplicationRecord
def self.searchfrom(searchfrom)
where("strtloc LIKE ?", "%#{searchfrom}%")
end
def self.searchto(searchto)
where("endloc LIKE ?", "%#{searchto}%")
end
end
I basically want to add AND in between the two parameters but I am stuck.
This is my transports_controller.rb
if params[:searchfrom]
#transports = Transport.searchfrom(params[:searchfrom])
else
#transports = Transport.all
end
if params[:searchto]
#transports = Transport.searchto(params[:searchto])
else
#transports = Transport.all
end
I also want the ability to only select FROM. So I cant really do a simple AND statement. But one at a time.
Any help apreciated!
Please check this answer:
Ruby on Rails: Search Form - multiple search fields
You should find this is related to you problem.
You can do either of the following:
#transports = Transport.where("strtloc LIKE ? AND endloc LIKE ?", "#{params[:searchfrom]}%", "#{params[:searchto]}%")
It'll do an AND operations between the two parameters.
or
#transports = Transport.where("strtloc LIKE ?", "#{params[:searchfrom]}%")
# first search for start locations
#transports = #transports.where("endloc LIKE ?", "#{params[:searchto]}%")
# then search for end locations in the result of start location.
Also check: HERE

Rails: outputting data where record has more votes

Right now I have this
def index
#trips = Trip.all
end
And I'm outputting data like so:
- #trips.order('created_at desc').first(4).each do |trip|
- trip.trip_images.first(1).each do |image|
= trip.title_name.titleize
However, I have a votable table (from acts_as_votable gem) associated to trips. I was wondering if I can only output trips where trips have a certain amount of votes?
I can get the votes like this:
- #trips.order('created_at desc').first(4).each do |trip|
= trip.get_likes.size #this is where I can get the likes
- trip.trip_images.first(1).each do |image|
= trip.title_name.titleize
EDIT
If I do this instead:
def index
#votes = ActsAsVotable::Vote.where(votable_type: 'Trip').group(:votable_id).count
#trips = Trip.where(#votes)
end
#votes gives me something like this:
{195=>1, 106=>1, 120=>1, 227=>1, 247=>1, 264=>1, 410=>1}
How do I get it where trip will only get the ids?
EDIT 2
I think I figured it out...
def index
#votes = ActsAsVotable::Vote.where(votable_type: 'Trip').group(:votable_id).count
#trips = Trip.where(id: #votes.keys)
end
I got some kind of output. Is there a better way?
Yesterday I answered similar question.
This is how you could get the id(s) of trip with certain amount of votes (you can use =, >, <= and so on):
trip_ids = ActsAsVotable::Vote
.where(votable_type: 'Trip')
.group(:votable_id)
.having('count(votable_id) > 1') #any number of votes
.pluck(:votable_id)
.uniq
Trip.where(id: trip_ids)
Have you considered making this a method in your Trip model?
Something like,
def popular_trip_images
Trip.select(:trip_images).where("likes > ?", 200)
end
Then use it something like,
...
trip.popular_trip_images.each do |image|
...
Edit:
However, I have a votable table (from acts_as_votable gem) associated to trips. I was wondering if I can only output trips where trips have a certain amount of votes?
Sorry, missed this part. The gem has a find_liked_items method but don't see offhand how to set something like liked > 400 etc.
I've been trying to work through the comments, but right now, I've gotten this code to work:
def index
#votes = ActsAsVotable::Vote.where(votable_type: 'Trip').group(:votable_id).count
#votes = #votes.select {|k,v| v > 1}
#trips = Trip.where(id: #votes.keys)
end
If someone else can come up with a better solution! I'll mark as correct.

append data to an array rails 4

I need to append data to a variable
#celebrity = Celebrity.includes(:category).where('category_id = ?', params[:id])
test =[]
#celebrity.each do |celeb|
#vote = Vote.where('celebrity_id = ?', celeb).count
test << {vote_count:#vote}
end
when i debug 'test',
abort test.inspect
I am getting the result of
[{:vote_count=>2}, {:vote_count=>1}, {:vote_count=>0}]
but, my question is how can I append vote_count to #celebrity , can anyone please help me out
You should not do it this way, its terrible in terms of performance.
If you setup a counter_cache properly (see ref), you'd have data right away in your model instances as expected
#celebrity.each do |celeb|
celeb["vote_count"] = celeb.votes.count
end
+apneadiving is right. use counter_caches

Rails 3 multiple parameter filtering using scopes

Trying to do a basic filter in rails 3 using the url params. I'd like to have a white list of params that can be filtered by, and return all the items that match. I've set up some scopes (with many more to come):
# in the model:
scope :budget_min, lambda {|min| where("budget > ?", min)}
scope :budget_max, lambda {|max| where("budget < ?", max)}
...but what's the best way to use some, none, or all of these scopes based on the present params[]? I've gotten this far, but it doesn't extend to multiple options. Looking for a sort of "chain if present" type operation.
#jobs = Job.all
#jobs = Job.budget_min(params[:budget_min]) if params[:budget_min]
I think you are close. Something like this won't extend to multiple options?
query = Job.scoped
query = query.budget_min(params[:budget_min]) if params[:budget_min]
query = query.budget_max(params[:budget_max]) if params[:budget_max]
#jobs = query.all
Generally, I'd prefer hand-made solutions but, for this kind of problem, a code base could become a mess very quickly. So I would go for a gem like meta_search.
One way would be to put your conditionals into the scopes:
scope :budget_max, lambda { |max| where("budget < ?", max) unless max.nil? }
That would still become rather cumbersome since you'd end up with:
Job.budget_min(params[:budget_min]).budget_max(params[:budget_max]) ...
A slightly different approach would be using something like the following inside your model (based on code from here:
class << self
def search(q)
whitelisted_params = {
:budget_max => "budget > ?",
:budget_min => "budget < ?"
}
whitelisted_params.keys.inject(scoped) do |combined_scope, param|
if q[param].nil?
combined_scope
else
combined_scope.where(whitelisted_params[param], q[param])
end
end
end
end
You can then use that method as follows and it should use the whitelisted filters if they're present in params:
MyModel.search(params)

Resources