I have a search bar which works fine but it produces a duplicate every time it shows the correct result.
if params[:nav_search]
#art = Art.where(["style_number LIKE ? OR name LIKE ?", "%#{params[:nav_search]}%", "%#{params[:nav_search]}%"]).page(params[:page]).per_page(18)
end
Any clue where I'm going wrong?
Try to the following
#art = Art.where(["style_number LIKE ? OR name LIKE ?", "%#{params[:nav_search]}%", "%#{params[:nav_search]}%"]).distinct.page(params[:page]).per_page(18)
To retrieve objects from the database, Active Record provides several finder methods. Each finder method allows you to pass arguments into it to perform certain queries on your database without writing raw SQL.
You can see this Rails Guide for very well understand
include .uniq
try this,
if params[:nav_search]
#art = Art.where(["style_number LIKE ? OR name LIKE ?", "%#{params[:nav_search]}%", "%#{params[:nav_search]}%"]).uniq.page(params[:page]).per_page(18)
end
Use uniq or distinct to avoid duplicate records. In your case, you should use distinct:
if params[:nav_search]
#art = Art.where(["style_number LIKE ? OR name LIKE ?", "%#{params[:nav_search]}%", "%#{params[:nav_search]}%"]).distinct.page(params[:page]).per_page(18)
end
Related
When we are checking one active record result is empty or not, what will be
way which have more performance.
pc_count = Property.select("id").where('property_category_id = ?', 5).limit(1)
if pc_count.blank?
#
end
if pc_count[0]
#
end
In two ways i have tried this pc_count.blank? or pc_count[0], because i heard that blank will take extra query, but when i tried that in console i couldn't see that any extra call
Try exists
which will be like.
Person.exists?(5)
Person.exists?('5')
Person.exists?(:name => "David")
Person.exists?(['name LIKE ?', "%#{query}%"])
Person.exists?
refer: http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F
No, both your versions do not produce another query.
It depends what you are doing with pc_count:
1.) You are using that id somewhere later, then use either of your methods (i prefer .blank?)
2.) You only need this for the this check. Then I would do
Property.select("id").where('property_category_id = ?', 5).limit(1).count
because there will be no model created and you can just test count == 0
For example if i want to pull all #posts using #posts.all but i dont want to include the very last or latest record from that?
here is what i am trying to do,
#posts = Post.all(Without the very very latest record that was created.)
Basically all record but not the very last record.
I think it is not worth it to try to generate a SQL query that excludes the very last element. Especially a subquery might be slower than just loading all records into an Array and than excluding the last:
#posts = Post.all[0..-2]
Your other example from the comments would look like this:
#contact_prices = #contact.retail_prices.all.order("created_at DESC").load[0..-2]
Another option (depending on the order of your relation) might be to use offset:
#contact_prices = #contact.retail_prices.order("created_at DESC").offset(1)
This is the most direct way I think of doing what you're trying to do:
Post.limit(Post.count - 1)
If you want your query to allow pagination or other LIMIT queries, you could try something like
Post.where("id < ?", Post.last.id)
Lots of answers that will do the trick, but throwing out an additional option:
#posts = Post.where("id != ?", Post.last.id)
One line AR:
Post.where.not(id: Post.last&.id)
I currently have the following in my controller to find the device:
Device.find_by_token(params[:token])
Replacing token with unique_id.
So the new query would be:
Device.find_by_unique_id(params[:unique_id])
For some of older requests, unique_id is not being passed in params and device won't be found.
How can I do something like:
Device.find_by_token_or_unique_id(params[:token], params[:unique_id])
or course this doesn't exist.
Also, I don't want to do:
if params[:token]
Device.find_by_unique_id(params[:unique_id])
else
Device.find_by_token(params[:token])
end
Thanks in advance.
I think this is what you are looking for:
Devise.where("token = ? OR unique_id = ?", params[:token], params[:unique_id]).first
Keeping in mind the previous answer could potentially return you 2 items, you could do this alternative:
user = Device.where(unique_id: params[:unique_id]).first
user ||= Device.where(token: params[:token]).first
Or you could implement Arel Helpers and be able to actual build it as a or query.
https://github.com/camertron/arel-helpers
I prefer to using Arel as it makes your code no longer contain ANY SQL.
Hello I struggle creating a specific query.
I have a searchfield with input parameter "{search}". I want to use this search field to find all tables which have a plate with veggies of a specific flavor or description.
I already got a tricky query which does exactly what it is supposed to do - so this works perfectly fine!
Tables.where(id: Plate.select("plate_id").where(Veggie.select("id").where('description LIKE ? OR flavor LIKE ?', "%#{search}%","%#{search}%")))
Aside from Veggies, suppose there is also a SQL-Table calles Fruits. Now i want to search for all Tables which have Plates which have Veggies OR(!!!) Fruits fitting to the description or flavor of the searchfield input.
I experimented a lot but can not find the right way.
Here is one of my experiments which does not work though:
Tables.where(id: Plate.select("plate_id").where((Veggie.select("id").where('description LIKE ? OR flavor LIKE ?', "%#{search}%","%#{search}%")).or(Fruit.select("id").where('color LIKE ? OR flavor LIKE ?', "%#{search}%","%#{search}%")))
The code above does not work! The problem is, I can not figure out how to combine those 2 subqueries. The or statement does not seem to work. Any help appreciated.
EDIT:
As has been pointed out, i now tried doing it with the UNION command. Unfortunately the .union() option with the Gem active_record_union seems to work only for rails 4+.
So i simulated a union with the following code.
def self.search2(search2)
if search2
if search2.length > 0
#Plate1 = Plate.where(veggie_id: Veggie.select("id").where('description LIKE ? OR color LIKE ?', "%#{search2}%","%#{search2}%"))
#Plate2 = Plate.where(fruit_id: Fruit.select("id").where('description LIKE ? OR color LIKE ? OR flavor LIKE ?', "%#{search2}%","%#{search2}%", "%#{search2}%" ))
#Plate12 = #Plate1+#Plate2
#table_ids = Array.new
#Plate12.each do |plate|
#table_ids.push(plate.table_id)
end
where(id: #table_ids)
else
scoped
end
else
scoped
end
end
Actually, i do believe this is very messy! It DOES work as intended, but i am a fraid it is a bit slow and unperformant. If anyone has a better suggestion i am glad about any help.
I write follow code to get one record from the table webeehs:
webeehs_result = Webeeh.find(:all, :conditions=>["webeeh_project_id=#{project_id}"])
Then I want to get one column value from this record, how could I do?
For example, the column name is webeeh_date.
first of all, never EVER write code like that. Building your own conditions as pure strings can leave you vulnerable to SQL injection exploits. If you must do conditions, then do it like this:
:conditions => ["webeeh_project_id = ?", project_id]
if you have a Project model, you should rename the webeeh_project_id column from your Webeeh model into project_id and have an association in your Project model like has_many :webeehs
Then, you won't need to call that find anymore, just do a p = Project.find(id) and then p.webeehs will return the webeehs you need.
the result will be an array which you can iterate through. And to get your webeeh.webeeh_date member, just call it like this:
result.each do |webeeh|
date = webeeh.webeeh_date
end
webeehs_result = Webeeh.findwebeeh_dates
is enough to get all columnn values.
For a different method and performance issues check the following: http://www.stopdropandrew.com/2010/01/28/finding-ids-fast-with-active-record.html
webeeh_result will usually be an array of results for the database.
You can iterate throughit using
webeehs_result.each do |webeeh|
# use "webeeh.webeeh_date" to access the column_name or do whatever you want with it.
end