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
Related
I have an trackers table and applications tables
application.rb
has_many :trackers
tracker.rb
belongs_to :application
What I trying to do is update the check_in_date in the trackers table to be query to begin_date in the applications tables only for those records which have check_in_date is equal to "2019-05-30".
I am trying to run the command below but I am getting an error.
Tracker.joins(:application).where("check_in_date = ?", "2019-05-30").update_all("tracker.check_in_date = application.begin_date")
error
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: missing FROM-clause entry for table "application")
Any idea where i am going wrong.
Maybe try this:
Note I have no idea if this will work so don't do it in production unless you can confirm
Tracker.where(check_in_date: "2019-05-30")
.update_all("check_in_date = (#{
Application.select(:begin_date)
.where('applications.id = trackers.application_id').to_sql})"
)
The theory is that this should result in the following SQL
UPDATE trackers
SET check_in_date = (
SELECT
begin_date
FROM
applications
WHERE
applications.id = trackers.application_id
)
WHERE
trackers.check_in_date = "2019-05-30"
There seems some typo
if check_in_date is date type then convert is "2019-05-30" in date
my_check_in_date = "2019-05-30".to_date
While using any attribute in the query model name should always be plural
Tracker.joins(:application)
.where("trackers.check_in_date= ?", my_check_in_date)
.update_all("trackers.check_in_date = applications.begin_date")
.references(:application)
I have a Property model that has_many :photos. I want to count the number of properties that have one or more photo.
How do I do that?
I have tried the simple:
> Property.where('properties.photos.count > ?', 0).count
(3.1ms) SELECT COUNT(*) FROM "properties" WHERE (properties.photos.count > 1)
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "photos"
LINE 1: SELECT COUNT(*) FROM "properties" WHERE (properties.photos....
^
: SELECT COUNT(*) FROM "properties" WHERE (properties.photos.count > 0)
from /ruby-2.3.0#myproject/gems/activerecord-3.2.22.5/lib/active_record/connection_adapters/postgresql_adapter.rb:1163:in `async_exec'
Caused by PG::UndefinedTable: ERROR: missing FROM-clause entry for table "photos"
LINE 1: SELECT COUNT(*) FROM "properties" WHERE (properties.photos....
to:
> Property.joins(:photos).where('photos.count > ?', 0).count
(3.7ms) SELECT COUNT(*) FROM "properties" INNER JOIN "photos" ON "photos"."property_id" = "properties"."id" WHERE (photos.count > 0)
ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: aggregate functions are not allowed in WHERE
LINE 1: ..."photos"."property_id" = "properties"."id" WHERE (photos.cou...
^
: SELECT COUNT(*) FROM "properties" INNER JOIN "photos" ON "photos"."property_id" = "properties"."id" WHERE (photos.count > 0)
from ruby-2.3.0#myproject/gems/activerecord-3.2.22.5/lib/active_record/connection_adapters/postgresql_adapter.rb:1163:in `async_exec'
Caused by PG::GroupingError: ERROR: aggregate functions are not allowed in WHERE
LINE 1: ..."photos"."property_id" = "properties"."id" WHERE (photos.cou...
to the more advanced:
>Property.includes(:photos).group(['property.id', 'photos.id']).order('COUNT(photos.id) DESC').count
(0.6ms) SELECT COUNT(DISTINCT "properties"."id") AS count_id, property.id AS property_id, photos.id AS photos_id FROM "properties" LEFT OUTER JOIN "photos" ON "photos"."property_id" = "properties"."id" GROUP BY property.id, photos.id ORDER BY COUNT(photos.id) DESC
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "property"
LINE 1: ...CT COUNT(DISTINCT "properties"."id") AS count_id, property.i...
^
: SELECT COUNT(DISTINCT "properties"."id") AS count_id, property.id AS property_id, photos.id AS photos_id FROM "properties" LEFT OUTER JOIN "photos" ON "photos"."property_id" = "properties"."id" GROUP BY property.id, photos.id ORDER BY COUNT(photos.id) DESC
from ruby-2.3.0#myproject/gems/activerecord-3.2.22.5/lib/active_record/connection_adapters/postgresql_adapter.rb:1163:in `async_exec'
Caused by PG::UndefinedTable: ERROR: missing FROM-clause entry for table "property"
LINE 1: ...CT COUNT(DISTINCT "properties"."id") AS count_id, property.i...
and a few other variations, and they all produce similar errors.
What am I doing wrong?
Note: All I want is the count of properties that have photos.count > 0. I don't want a hash of all the properties and the count of photos. In other words, if there are 5000 properties in my db, I want to build a scope that returns just the properties that actually have photos.
Since all you want is the Propertys with Photos then an INNER JOIN is all you need.
Property.joins(:photos)
That is it. If you want a scope then
class Property < ActiveRecord::Base
scope :with_photos, -> {joins(:photos)}
end
To get the count using rails 3.2
Property.with_photos.count(distinct: true)
You could also use: in rails 3.2
Property.count(joins: :photos, distinct: true)
ActiveRecord::Calculations#count Doc
This will execute
SELECT
COUNT(DISTINCT properties.id)
FROM
properties
INNER JOIN photos ON photos.property_id = properties.id
EDIT:
Property.joins(:photos).group('photos.property_id').having('count(photos.property_id) > 1').count
#=> {1234=>2} # 1234 is property id 2 is count of photos
You will get the property_ids with the number of associated photos with it.
Old Answer:
You can get the properties with atleast one photos associated with it
Property.includes(:photos).where.not(photos: { property_id: nil })
As you are using rails 3.2 .not will not work you have to use
Property.includes(:photos).where("property_id IS NOT null")
Property.includes(:photos).where("SELECT count(photos.id) > 0 FROM photos WHERE property_id = properties.id")
As a scope:
scope :with_photos, -> { where("SELECT count(photos.id) > 0 FROM photos WHERE property_id = properties.id") }
You can try like this, I have done in my projects,
Photo.group(:property_id).count
You will get property id with photos count
results = { 3314=>3, 2033=>3, 3532=>2, 3565=>6, 3510=>1, 3022=>7, 648=>2, 570=>3, 4678=>3, 3540=>1, 3489=>4, 536=>1, 1715=>4 }
Give this a go:
class Property < ApplicationRecord
has_many :photos
def self.with_photos
self.all.reject { |p| p.photos.empty? }
end
end
Property.with_photos.count
Source
More Efficient (Rails 4+):
Property.joins(:photos).uniq.count
Source
More Efficient (Rails 5.1+):
Property.joins(:photos).distinct.count
Source
According to your requirement you can try this
1) A simple count of the number of properties that have 1 or more
photo
To just get the number of properties which have one or more photo you can do this
Property.joins(:photos).distinct.count
As we are not using group the distinct or uniq is necessary. distinct will return ActiveRecord_Relation and uniq will return Array.
2) I would like that set of properties returned so I can
create a scope of just those properties. Also, I do have lots of
properties with more than 1 photo.
To get all the property objects which have one or more than one photo you can use the same query:
Property.joins(:photos).distinct
or you can use the group_by clause:
Property.joins(:photos).group('properties.id')
The difference will be that when you will use size method on the group query it will return a hash with the property_id as key and number of photos on the property as value.
Performance Update:
If you always require the count of associated object and you want to fetch it efficiently you may use counter_cache like this:
class Photo < ApplicationRecord
belongs_to :property, counter_cache: true
end
class Property < ApplicationRecord
has_many :photos
end
And then you will have to add a column in the properties table named photos_count and Rails will automatically update the column each time a new photo record is added or a exisisting photo record is removed. And then you can also query directly:
Property.where('photos_count > ?', 1)
This is optional and you can do this if you are facing performance issues with the data fetch.
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
How can I find the relationships where the start node or the end node is in the list.
ids = ProcessingRun.last.nodes.pluck(:id)
#rels = Relationship.where(:end_node_id => ids) + Relationship.where(:start_node_id => ids)
I've tried lots of variations on OR
rels_in_id_array = Relationship.where("start_node_id in #{ids} OR end_node_id in#{ids}")
Relationship Load (0.9ms) SELECT "relationships".* FROM "relationships" WHERE (start_node_id in [35752, 35726, 35728, 35729, 35731, 35735, 35736, 35738, 35742, 35745, 35750, 35751, 35723, 35725, 35739, 35740, 35749, 35724, 35722, 35733, 35734, 35737, 35741, 35743, 35732, 35746, 35747, 35721, 35730, 35727, 35744, 35748, 35753] OR end_node_id in[35752, 35726, 35728, 35729, 35731, 35735, 35736, 35738, 35742, 35745, 35750, 35751, 35723, 35725, 35739, 35740, 35749, 35724, 35722, 35733, 35734, 35737, 35741, 35743, 35732, 35746, 35747, 35721, 35730, 35727, 35744, 35748, 35753])
PG::SyntaxError: ERROR: syntax error at or near "["
LINE 1: ...".* FROM "relationships" WHERE (start_node_id in [35752, 35...
and it's not working....
so that's why I thought I'd add 2 arrays together. But it turns out they are arrays, not ActiveRecord relations, so I can't do things with them that you can do with AR relations.
Relationship.where("start_node_id IN (?) OR end_node_id IN (?)", ids, ids)
Relationship.where('end_node_id IN (?) OR start_node_id IN (?)', ids, ids)
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.