ActiveRecord not using counter_cache? - ruby

I have two simple models:
class Push < ActiveRecord::Base
has_many :opened_pushes
end
class OpenedPush < ActiveRecord::Base
belongs_to :push, :counter_cache => true
end
However, if I do
a_push.opened_pushes.count
It queries the db, rather than using opened_push_count column present in Push. I thought it was smart enought to do that...is this how it's suppose to be?

Needed to call size, as opposed to length or count which will generate a query.

Related

Query an ActiveRecord on several tables?

Sorry to ask this question but I'm really newbie with Ruby and I need help to update several records on my database.
I'm using ActiveRecord to query the database. Let say I have a table Product that contains SubProduct that also contains SubSubProduct. Now I would like to write a simple query to get all SubSubProduct of Product.
To get a list of SubSubProduct I usually do this
ssp = SubSubProduct.where(sub_sub_type: "example")
Now to use a where clause on relational element how can I do
ssp = SubSubProduct.where(sub_sub_type: "example", SubProduct.Product.type: "sample")
Set up ActiveRecord associations in your models:
#app/models/product.rb:
class Product < ActiveRecord::Base
has_many :sub_products
end
#app/models/sub_product.rb:
class SubProduct < ActiveRecord::Base
belongs_to :product
end
#app/models/sub_sub_product.rb:
class SubSubProduct < ActiveRecord::Base
belongs_to :sub_product
end
What you wanted:
ssp = SubSubProduct.where(sub_sub_type: "example", SubProduct.Product.my_type: "sample")
The correct syntax:
ssp = SubSubProduct.includes(sub_product: :product).where(sub_sub_type:"example", products: {my_type: "toto"})
This is performed via associations.
class SubSubProduct
has_many :products
end
Then you can do things like
sub_product.products
and it will product all the products associated with them.
Try a nested includes:
`Product.includes(subproducts: :subsubproducts)'
For this, you'll want to set up ActiveRecord associations in your models:
In product.rb:
class Product < ActiveRecord::Base
has_many :sub_products
has_many :sub_sub_products, through: :sub_products
end
In sub_product.rb:
class SubProduct < ActiveRecord::Base
belongs_to :product
has_many :sub_sub_products
end
In sub_sub_product.rb:
class SubSubProduct < ActiveRecord::Base
belongs_to :sub_product
end
Then, if you have a Product and want its SubSubProducts, you can use:
# p is a Product object
p.sub_sub_products

Issues with Polymorphic/STI in Ruby

We're having a problem with polymorphism & STI in Ruby
Our database has two tables: 'account' and 'list'. 'list' has columns 'account_id', 'type', 'description'.
Our classes look like so:
class Account < ActiveRecord::Base
has_many :lists
has_many :subscription_lists
has_many :email_lists
end
class List < ActiveRecord::Base
belongs_to :account
end
class SubscriptionList < List
end
class EmailList < List
end
Inside Account, methods email_lists and subscription_lists work exactly as expected. Our goal is we want to be able to call lists which will return an array of all lists. Currently, that doesn't work, nor does self.lists
Oddly, Account.find(self.id).lists DOES give us an array of all the lists associated.
What gives? How do we fix this?
You can use List.all which will return an ActiveRecord::Relation of all List objects, regardless of type.
Additionally, you can use #instance_variable.lists on any instance variable of Account
What's more, you could use a query on a class method to accomplish the job, like so, which will also return an ActiveRecord::Relation:
List.where('account_id = ?', id)
Lastly, your Account association with List should not include the children of List:
class Account < ActiveRecord::Base
has_many :lists, inverse_of: :account, dependent: :destroy
end

Activerecord checking if association exist

I have two ActiveRecord models:
class Class < ActiveRecord::Base
(...)
has_many :class_to_teacher, dependent: :destroy
end
class Teacher < ActiveRecord::Base
has_many :classes,
through: :class_to_teacher
end
class ClassToTeacher < ActiveRecord::Base
belongs_to :klass
belongs_to :teacher
end
When I remove Class I don't remove it completly only I remove record from ClassToTeacher record. I need to keep this data:
def leave(class, teacher)
teacher.klasses.delete(class)
end
Now I have to get all associated classes (classes which contains record in ClassToTeacher). How to do this the best? Thanks for all answers.
You should try something like that:
Class.includes(:class_to_teacher).where('class_to_teacher.id is not null').references(:class_to_teacher).all
Assuming that you have an 'id' field in your database for the ClassToTeacher
I guess there's a lot of ways to get there but the simplest one is probably this:
Klass.where(id: KlassToTeacher.select(:klass_id))
This will result in a single query with a sub-query. Note that I changed the names of the models because Class is already defined in Ruby and you're just asking for trouble.

ActiveRecord - Finding all records with x number of classifications

I'm trying to figure out how to write an ActiveRecord method that will return all Boats with more than three classifications.
class Boat < ActiveRecord::Base
belongs_to :captain
has_many :boat_classifications
has_many :classifications, through: :boat_classifications
end
class Classification < ActiveRecord::Base
has_many :boat_classifications
has_many :boats, through: :boat_classifications
end
class BoatClassifications < ActiveRecord::Base
belongs_to :boat
belongs_to :classification
end
In general, I'm having trouble finding resources for writing queries on join models in AR. If anyone knows any good resources to help learn complex AR queries, that would be really helpful.
Fist JOIN the boats with the classifications. Then you need to GROUP BY boats.id so then you can COUNT how many rows you have grouped for every different boat. Using the HAVING allows you to apply that condition over the grouped records. At the end, selects the boats as you want.
Boat.joins(:classifications).group("boats.id").having("COUNT(*) > 3").select("boats.*")

Ruby on Rails 3: How can I sort ActiveRecords by an attribute of another table?

I need to query a database table and get the rows ordered by a count of an association. Is there a Rails (like Active Record Query) way to do this?
My models and their associations are as follows:
class User < ActiveRecord::Base
has_one :business
end
class Business < ActiveRecord::Base
has_many :postulations
end
class Postulation < ActiveRecord::Base
belongs_to :business
end
I need to get a number of Users ordered by the amount of Postulations that their Business has. Is there a clean way to do this or do I just have to query with find_by_sql?
Thank you.
User.includes(:business => :postulations).group("users.id").order("count(postulations.id) desc").limit(20)
This will probably work

Resources