ActiveRecord - Finding all records with x number of classifications - ruby

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.*")

Related

searching for records based off of results from other results

I have four kinds of records. Teams. Coaches. Players. and Families.
Teams have a one to many association with Coaches.
Coaches have a one to one association with Players.
Players have a many to one association with Families.
What I need to find are specific families that are associated with certain Teams. However due to their separation i can't just go Team.last.family.
Is there a way to leap over the Players and Coaches and do a query from the clinics straight to the family?
Most likely you will need to make use of the joins method.
If you provide more details of your model code and schema we could provide more details, but it will be something along the lines of.
Family.joins(some_join_object).where(some_sql_search_string)
Once you have a join table that includes all the columns you want, specify the conditions you would like to filter on.
Family.joins(:players, :coaches, :teams).where("families.name='Wesley' and teams.name='Crushers'")
Here is an example from the provided link.
class Category < ApplicationRecord
has_many :articles
end
class Article < ApplicationRecord
belongs_to :category
has_many :comments
has_many :tags
end
class Comment < ApplicationRecord
belongs_to :article
has_one :guest
end
class Guest < ApplicationRecord
belongs_to :comment
end
class Tag < ApplicationRecord
belongs_to :article
end
12.1.3.2 Joining Nested Associations (Multiple Level)
Category.joins(articles: [{ comments: :guest }, :tags])
This produces:
SELECT categories.* FROM categories INNER JOIN articles ON
articles.category_id = categories.id INNER JOIN comments ON
comments.article_id = articles.id INNER JOIN guests ON
guests.comment_id = comments.id INNER JOIN tags ON tags.article_id =
articles.id
Or, in English: "return all categories that have articles, where those
articles have a comment made by a guest, and where those articles also
have a tag."

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

How to load parent-child-parent associations in Rails 4?

this is my first question on StackOverflow :)
I'm building a Rails 4 app, having trouble to figure out a good way to load records from mutilple data models. I could hard code SQL statements like an inner join, but wondering if there's any better way. Searched in existing questions on SO, but didn't find a match.
Here are my models:
class Person < ActiveRecord::Base
has_many :addresses
end
class Address < ActiveRecord::Base
belongs_to :person
belongs_to :city
end
class City < ActiveRecord::Base
has_many :addresses
end
Question: given a person Id, how should I load its associated addresses with the city information?
Address.includes(:persons,:cities).where(person_id: person.id)
this is one of many ways.

ActiveRecord not using counter_cache?

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.

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