Active Record, count of grandchild association record - ruby-on-rails

Let's say I've got:
class Town < ActiveRecord::Base
has_many :citizens
end
class Citizen < ActiveRecord::Base
belongs_to :town
has_many :cars
end
class Car < ActiveRecord::Base
belongs_to :citizen
end
Using ActiveRecord, what is the simplest way I can get a count of cars in the town?

In your models you can define a through association.
class Town < ActiveRecord::Base
has_many :citizens
has_many :cars , :through => :citizens
end
And query like this.
#town.cars.count
or
Town.find("town id").cars.count

Related

Rails - search through has_many association

I have these models:
class Car < ActiveRecord::Base
has_many :car_services
end
class CarService < ActiveRecord::Base
belongs_to :car
belongs_to :car_service_definition
end
class CarServiceDefinition < ActiveRecord::Base
has_many :car_services
end
I am trying to find out if the currently selected car has a certain service - trying to do it this way:
airbag = car.car_services.car_service_definitions.where('service_type = "Airbag"').first
But this query doesn't work because of the wrong using model associations.
How do I find out, if the current car has some airbags?
Thank you in advance.
Assuming your migrations are fine
class Car < ActiveRecord::Base
has_many :car_services
end
class CarService < ActiveRecord::Base
belongs_to :car
belongs_to :car_service_list
has_and_belongs_to_many :car_service_definitions
end
class CarServiceDefinition < ActiveRecord::Base
end
airbag = car.car_services.car_service_definitions.where(service_type: 'AirBag').first
Well, from the look of the relationships, I assume that car_services is the rich join table of cars and car_service_definitions
What you can do is to set up has_many :through relationship on both car and car_service_definition
class Car < ActiveRecord::Base
has_many :car_services
has_many :car_service_definitions, through: :car_services
end
class CarService < ActiveRecord::Base
belongs_to :car
belongs_to :car_service_definition
end
class CarServiceDefinition < ActiveRecord::Base
has_many :car_services
has_many :cars, through: :car_services
end
And then if you want to find airbag, it would be like this
airbag = car.car_service_definitions.where("car_service_definitions.service_type" => 'AirBag').first
But if you want to check if the car has air_bag, could just write a method like this
class Car < ActiveRecord::Base
def has_air_bag?
car_service_definitions.where("car_service_definitions.service_type" => 'AirBag').count > 0
end
end

Rails type of relation between models

I have 3 models: User, Order and Car and I have question because I don't know what relationships between these models will be the best. Only requirement is that only one car per user in order.
A user can have many orders, and therefore, many cars through those orders.
class User < ActiveRecord::Base
has_many :orders
has_many :cars, through: :orders
end
An order belongs to a user and a car.
class Order < ActiveRecord::Base
belongs_to :user
belongs_to :car
end
A car has one order.
class Car < ActiveRecord::Base
has_one :order
end
So you need one on one relationship between order and car and then back to order and customer one relationship. Something below should do the trick.
class Car < ActiveRecord::Base
has_one :order
has_one :customer, through: :order
end
class Order < ActiveRecord::Base
belongs_to :car
belongs_to :customer
end
class Customer < ActiveRecord::Base
has_one :order
has_one :car , through: :order
end
But i will suggest the has_many relationship by the looks of the model name, but you know better your problem than me.

has_many and has_many relation

I have Country, City, Shop models
class Country < ActiveRecord::Base
has_many :cities
end
class City < ActiveRecord::Base
belongs_to :country
has_many :shops
end
class Shop < ActiveRecord::Base
belongs_to :city
end
How can I get country.shops in activerecord? (get all shops in country)
I usually use Country.cities.collect { |c| c.shops }
but this is not activerecord object.
I have considered add country_id on shop model and set has_many relation but I think it's not best way.
In Country, add a has_many :through relation:
class Country < ActiveRecord::Base
has_many :cities
has_many :shops, through: :cities
end
Now you can write country.shops and receive an appropriate ActiveRecord relation where you can say stuff like country.shops.where name:"Nieman Marcus" and other such queries.
you can def a method in Class Country
def all_shops
self.cities.collect { |c| c.shops }
end
you alse can use Mongoid::Tree
def all_shops
Shop.where(:parent_ids => self.id)
end

Associations two-many-to-many

I don't fully understand how associations work.
I have 3 models:
Movie (:about, :title, :url, :actors, :uploader)
Actor (:birth, :name)
Relationships (:actor_id, :film_id)
Relationships is the association between Movies and Actors, so "which actor play in which movie". My teacher told me I can make it easier with http://railscasts.com/episodes/47-two-many-to-many but I don't know how to use that, any idea?
I would imagine you want something like:
class Movie < ActiveRecord::Base
has_many :actors, :through => :relationships
end
class Relationship < ActiveRecord::Base
belongs_to :movie
belongs_to :actor
end
class Actor < ActiveRecord::Base
has_many :movies, :through => :relationships
end
http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association
Or alternatively, if you don't feel you have to define the relationship class explicitly, you can simply use has_and_belongs_to_many:
class Movie < ActiveRecord::Base
has_and_belongs_to_many :actors
end
class Actor < ActiveRecord::Base
has_and_belongs_to_many :movies
end

Rails/Active Record polymorphic association needed?

I have 3 models, a School which has many Teachers and Students. The problem is that Students can belong to either a School or a Teacher, so theoretically they always belong to a School through association. How would I deal with this type of data structure in Rails/Active Record?
class School < AR::Base
has_many :teachers
has_many :students
end
class Teacher < AR::Base
belongs_to :school
has_many :students
end
class Student < AR::Base
belongs_to ???
end
This solution should work, but you I have a doubt about your introduction ; you say that "a teacher have many student". This sentences implies "a student has ONE teacher".
Maybe you should set an has_and_belongs_to_many association.
class School < AR::Base
has_many :teachers
has_many :students, :through => :teachers
end
class Teacher < AR::Base
belongs_to :school
has_many :students
end
class Student < AR::Base
belongs_to :teacher
belongs_to :school, :through => :teacher
end
Clearly you need polymarphic association, can be done as
class School < AR::Base
has_many :teachers
has_many :students, :as => :studentable
end
class Teacher < AR::Base
belongs_to :school
has_many :students
end
class Student < AR::Base
belongs_to :studentable
end
don't forget to add studentable_id and studentable_type to student model.

Resources