count with has_many in rails - ruby-on-rails

I've got an Order and Orderdetails
Orderdetails belongs_to Order
Order has_many Orderdetails
I am trying to convert the following query to ActiveRecord count function
select Count(*)
from orderdetails A, orders B
where A.prodid='6' and A.orderid= B.id and B.custid='11'
I tried:
#count = Orderdetail.count(:conditions => "prodid = 6 and order.custid = 11")
However, this gives error:
PGError: ERROR: syntax error at or near "order"
LINE 1: ...unt_all FROM "orderdetails" WHERE (prodid = 6 and order.cust...
Edit
I changed to orders
but now i get this error:
ActiveRecord::StatementInvalid:
PGError: ERROR: missing FROM-clause
entry for table "orders" LINE 1:
...unt_all FROM "orderdetails" WHERE
(prodid = 6 and orders.cus...

You need to add :joins => :order', because your condition contains element from orders table (that's why you get error missing FROM-clause), try:
#count = Orderdetail.count(:joins => :order, :conditions => "prodid = 6 and orders.custid = 11")
Also it better (safer) to use array in conditions:
#count = Orderdetail.count(:joins => :order, :conditions => ["prodid = ? and orders.custid = ?", 6, 11])

I think you should thoroughly read some docs on how associations work in rails. Try this guide.
You don't need to write any SQL in :conditions to do what you need.

Related

Mysql2::Error: Unknown column in where clause Rails

I receive an error of
Mysql2::Error: Unknown column 'requests.access_level_id' in 'where clause':
SELECT `requests`.*
FROM `requests` LEFT OUTER JOIN `users` ON `users`.`id` = `requests`.`from_id`
WHERE `requests`.`access_level_id` = 1
ORDER BY id DESC
Model
class Request < ApplicationRecord
belongs_to :user, foreign_key: :from_id
end
Controller
#req = Request.left_outer_joins(:user).where(access_level_id: 1).order('id DESC')
How can I remove requests from the WHERE clause requests.access_level_id = 1? I just want access_level_id = 1 to be in the where statement.
As you requested, you can add where clause without requests as,
#req = Request.left_outer_joins(:user).where('access_level_id = ?', 1).order('id DESC')
But its good to keep relative aliasing for access_level_id. If its users then please use it like,
#req = Request.left_outer_joins(:user).where(users: { access_level_id: 1 }).order('id DESC')
Assuming that access_level_id is field for user, you can replace your query with following:
#req = Request.left_outer_joins(:user).where('users.access_level_id = ?', 1).order('id DESC')
By default the fields in where conditions are considered to be belonging to Request method in your query.
Hope this helps you.
Please let me know if you face any issue.

Active Record doesn't update collection when there is joins and includes in query

Hello I've a problem with my query.
There are my models below:
class Owner
has_many :busiensses
has_many :adverts
end
class Business
belongs_to :owner
end
class Advert
belongs_to :owner
end
When I make this query everything is okay and it returns right collection full of needed objects:
Owner.joins(:adverts).includes(:businesses)
.where(businesses: {owner_id: nil})
But when I add to query update it raises error
Owner.joins(:adverts).includes(:businesses)
.where(businesses: {owner_id: nil})
.update_all(status: 'sth')
Error:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "businesses"
Where is the problem? I bet this error from SQL and it raised when you forget add sth to FROM statement and that sth needed in further conditions, but where in AR i forgot to add it?
Owner.joins(:adverts)
.includes(:businesses)
.where(businesses: {owner_id: 1})
.update_all(name: "blaaaaa")
This statement translates into this query:
UPDATE "owners"
SET "name" = 'blaaaaa'
FROM "businesses" /* missed this */
WHERE "owners"."id" IN
(SELECT "owners"."id" FROM "owners"
INNER JOIN "adverts"
ON "adverts"."owner_id" = "owners"."id"
WHERE "businesses"."owner_id" = 1)
You miss the "FROM 'bussinesses'" which causes the error:
missing FROM-clause entry for table "businesses"
My solution is to use joins instead of using includes. It works fine in my machine.
Owner.joins(:adverts)
.joins(:businesses)
.where(businesses: {owner_id: 1})
.update_all(name: "blaaaaa")
=> 1

Rails transforming Query from Rails 3.2.12 to 4.0.0 Errors

Hi I've got some problems convertigs Querys from My 3.2.12 Rails app to the new converted 4.2.0 version.
I got this:
#data[:weekday] ||= Xyz.count(:include => [:membership],
:conditions => ["xyz.done_at IS NOT NULL AND xyz.course_id = ?", #course_id],
:group => "WEEKDAY(xyz.done_at)").collect {| val | [val[0].to_i, val[1]]}
I've made this new one, is this the same?
#data[:weekday] = Xyz.where("done_at IS NOT NULL AND memberships.course_id = ?", #course_id).joins(:membership).group("WEEKDAY(done_at)").count()
And the I got this one:
#data[:xyz_per_hours] ||= Xyz.count(:include => [:membership],
:conditions => ["xyz.done_at IS NOT NULL AND memberships.course_id = ?", #course_id],
:group => "TIMESTAMPDIFF(HOUR, xyz.created_at, xyz.done_at)").to_a.select do | val |
val[0].to_i < 120
end
I've converted it to:
#data[:xyz_per_hours] = Xyz.where("done_at IS NOT NULL AND course_id = ?", #course_id).joins(:membership).group("TIMESTAMPDIFF(HOUR, created_at, done_at)").count().to_a.select do | val |
val[0].to_i < 120
end
But I got this error:
Mysql2::Error: Column 'created_at' in field list is ambiguous: SELECT COUNT(*) AS count_all, TIMESTAMPDIFF(HOUR, created_at, done_at) AS timestampdiff_hour_created_at_done_at FROM `xyz` INNER JOIN `memberships` ON `memberships`.`id` = `xyz`.`membership_id` WHERE (done_at IS NOT NULL AND course_id = 44) GROUP BY TIMESTAMPDIFF(HOUR, created_at, done_at)
Whats wrong?
In group clause
"TIMESTAMPDIFF(HOUR, created_at, done_at)"
you need to specify a table for column created_at like it was in the original expression - xyz.created_at
And your first question
I've made this new one, is this the same?
There is only one difference between both expressions - in the first one you use :include => [:membership] what means LEFT OUTER JOINs operation (documentation) but in the second one you use joins(:membership) which means INNER JOIN operation
That last issue is occurring in your #group statement. Because youre joining on membership, and both membership and xyz have created_at attributes, the query doesnt know which created_at to order by.

ActiveRecord and map in RoR

I make select
m_repeats = Event.where(:repeat => 'monthly').where("schedule < ?", date.end_of_month)
Then I need change the shedule (it is date field) in each element.
I try to do:
m_repeats.map{ |elem| elem.schedule.year = date.today.year, elem.schedule.month = date.today.month }
But I get the errors:
Mysql2::Error: Unknown column 'schedule' in 'where clause': SELECT `events`.* FROM `events` WHERE `events`.`repeat` = 'monthly' AND (schedule < '2013-04-30')
or
undefined method `schedule' for #
What is correct way to do it?
Try to use only one where statement like
m_repeats = Event.where('events.repeat = ? AND events.schedule < ?', 'monthly', date.end_of_month)
or explicitly name the table of your query on the schedule column like
m_repeats = Event.where(:repeat => 'monthly').where("events.schedule < ?", date.end_of_month)
I don't think that your map method is causing the problem, because the select of the Events takes place at the call of the map method and there you get a clear problem in your select query.
it was really grammar error :) 'schedule' instead of 'shedule'

Rails 3 how to do a query with a habtm association

I need to dump a set of Awards into a instance variable:
#corp = Award.find(:all, :conditions => ["award.category_id = ?", "2" ])
Award <= => AwardsCategories <= => Categories
I am trying to find All the Awards that have a Category of X
The interesting piece I am noticing is that my Award.category_id is nil but the AwardsCategory.category_id and award_id are both set.
The error is returning is:
ActiveRecord::StatementInvalid in PagesController#award_cat
PGError: ERROR: missing FROM-clause entry for table "award"
LINE 1: SELECT "awards".* FROM "awards" WHERE (award.category_id = ...
^
: SELECT "awards".* FROM "awards" WHERE (award.category_id = '2')
Any ideas and merry christmas
With a habm award doesn't need a category_id (after all, if it was used, how could an award have multiple categories?)
You need to join the award_categories table and put conditions on award_categories.category_id. Obviously if you have an actual category handy, you can just do
category.awards

Resources