Find 'homeless families' in many-to-many relation - ruby-on-rails

I have 2 models and one linking them in many-to-many relation.
Like this:
class Family < ActiveRecord::Base
has_many :family_in_house
end
class House < ActiveRecord::Base
has_many :family_in_house
end
class FamilyInHouse < ActiveRecord::Base
belongs_to :family
belongs_to :house
end
And I need to have a separate scope for families that are not associated with any house.
I'm realtively new to RoR and couldn't find the solution myself. I use Rails 3.2.9 if it's necessary.
Thanks in advance!

class Family < ActiveRecord::Base
has_many :family_in_houses
scope :without_house, includes(:family_in_houses).where( :family_in_houses => {:house_id=>nil} )
end

Related

how to connect two table that has no relation in rails

I have a table called foods and categories, but this table has no relation, I want to connect them through another table called food_category. And I want to make one-to-one relation between food and category maybe the diagram looks like this
class Food < ApplicationRecord
has_one :category
end
class Category < ApplicationRecord
has_one :food
end
class FoodCategory < ApplicationRecord
belongs_to :category
belongs_to :food
end
Is it possible to do this?
Yes, this is possible. You just need to do
has_one :category, through: :food_categories
as discussed in the Rails docs here.
However, this is a long-winded way to go about this kind of association. If it's going to be one-to-one, why not just add a foreign key to Category from Food? And presumably, you would actually want Category to contain many Food records? Seems like the below would make more sense:
class Food < ApplicationRecord
belongs_to :category
end
class Category < ApplicationRecord
has_many :food
end
class Food < ApplicationRecord
has_one :food_category
has_one :category, through: :food_categories
end
In rails console, you can access like this
Food.find(:id).categories

has_and_belongs_to_many STI, restrict to be unique by types

I'm using STI models with has_and_belongs_to_many relations.
So I have User with many Templates of different types, like MainTemplate < Template; NotSoMainTemplate < Template; etc.
Is there a way to limit each user to have only one MainTemplate and only one NotSoMainTemplate, and so on for all types?
Let me reiterate the problem statement as I have understood it.
You want User to have at most one kind of each template. i.e.
1 MainTemplate, 1 NotSoMainTemplate, etc.
You don't need a direct relation with Template (parent table)
Each template may be used by more than one user
Based on the above assumption, I would suggest you to do the following:
Remove existing habtm association between User and Template
Add migrations to add main_template_id, not_so_main_template_id to User
Add the following associations:
class MainTemplate < Template
has_many :users
end
class NotSoMainTemplate < Templete
has_many :users
end
class class User < ActiveRecord::Base
belongs_to :main_template
belongs_to :not_so_main_template
end
Since you are already using STI, you can try has_one.
class Template < ActiveRecord::Base
has_many :users, through: template_choice
...
end
class MainTemplate < Template
...
end
class TemplateChoice < ActiveRecord::Base
belongs_to :template_choice
belongs_to :user
end
class User < ActiveRecord::Base
has_one :main_template, through: :template_choice
has_one :not_so_main_template, through: :template_choice
...
end

How to define my DB relationships

We have the following (part) models.
User
Booking
Apartment
Villa
Bed_Breakfast
Boutique_hotel
The user can have many bookings and a booking can have many villas, apartments, B&B or boutique hotels.
This is my idea to set up the relationships.
class User
has_many: bookings
end
class booking
belons_to :user
end
class Apartment
belongs_to :booking
end
class Villa
belongs_to :booking
end
Is this the right way to do it?
Thanks...
remco
I think, your approach is not good. Seems you are looking for has_many :through association in your tables. you can have a look into Rails has_many :through Docs. you should go like this:
class User
has_many :apartments, through: bookings
end
class booking
belongs_to :user
belongs_to :apartment
end
class Apartment
belongs_to :user
has_one :booking
end
Hope it will help. Thanks.
Yeah everything looks good and add this
class booking
belongs_to :user
has_many :villas
has_many :apartments
...
end
Villa and Apartment seem to be the same thing. Are they not both a Property? You could have a Property to keep yourself DRY (don't repeat yourself) which would eliminate writing the same code for each of the Apartments/Villas. My recommendation is this:
class Villa < Property < ActiveRecord::Base
end
class Apartment < Property < ActiveRecord::Base
end
Alternatively you could use a Polymorphic Design and have a property type.

Rails order by associated data

Is it possible to order the results of school.classrooms by the teacher's name? I want to do this directly in the association, and not a separate call.
class School < ActiveRecord::Base
has_many :classrooms
end
class Classroom < ActiveRecord::Base
belongs_to :school
belongs_to :teacher
end
class Teacher < ActiveRecord::Base
has_one :classroom
end
This should work if you are using rails 3.x
school.classrooms.includes(:teacher).order("teachers.name")

Relation between two single-table inheritance models

I have the following two models
class ContactField < ActiveRecord::Base
end
class Address < ContactField
end
class Phone < ContactField
end
and
class Contact < ActiveRecord::Base
end
class Company < Contact
end
class Person < Contact
end
I want one contact, no matter is it Company or Person, to have many ContactFields(Addresses and Phones)... So where should I put those has many and belongs to?
Thanks
You already said it in plain english :-)
I want one contact, no matter is it Company or Person, to have many ContactFields(Addresses and Phones)... So where should I put those has many and belongs to? Thanks
class Contact < ActiveRecord::Base
has_many :contact_fields
end
class ContactField < ActiveRecord::Base
belongs_to :contact
end
This Relationship will be inherited by both address and phone
Looks like you're describing a belongs to relationship. The associations should be defined in the parent class, so they can be inherited by the subclasses.
class ContactField < ActiveRecord::Base
belongs_to :contact
belongs_to :company, :foreign_key => :contact_id
belongs_to :person, :foreign_key => :contact_id
end
class Contact < ActiveRecord::Base
has_many :contact_fields
has_many :addresses
has_many :phones
end
However #contact.contact_fields will just return ContactField records. If you need the methods defined in any of the sub classes you can always use the becomes method. There are a few ways around that. Such adding the extra associations, like I did. Or using ActiveRecord::Base#becomes

Resources