Ruby on Rails belongs_to vs. has_one associations - clarification requested - ruby-on-rails

In the following instance, what would the difference be between using belongs_to :mother and has_one :mother for the Chlid class? I've been reading the Rails documentation on this and I can't see how either one would make a difference apart from the semantics involved with reading it.
From what I can tell, the various associations add extra methods to each class, but I haven't been able to find the documentation to list per association what the methods are and what they do.
class BiologicalMother < ActiveRecord::Base
has_many :children
end
class Child < ActiveRecord::Base
belongs_to :biological_mother
end

In your case the has_many belongs_to is the right approach not just semantically but as how rails works. The foreign key is always stored in the belongs_to part of the association.
A valid has_one scenario could be like having a Purchase model which has_one BillingAddress.
example:
class Purchase
has_one :billing_address
end
class BillingAddress
belongs_to :purchase #this holds the foreign key - purchase_id
end
Regarding your case, you cant use has_many in one side and has_one at the other side of the association because the belongs_to part holds the foreign key always.
Let me know if this works for you.

At this point, it's almost purely semantics. With mongoid, I know that the foreign key is stored on the model with the belongs_to, so there might be something like that with ActiveRecord too.

Related

Rails STI design issue

I am working a side project where a user can have multiple clients. Those client can be of type Person or Business.
I was leaning toward the idea to using STI but I am not sure whether this is the right way to go since my models will not share the same attributes.
For instance a Business has a legal_form where a Person might have a marital_status.
Is it ok to use STI in this particular case or (2nd question) is there any way to allow rails to use separate tables for each types.
STI is like inheritance in ruby. You can use it if you have parent and children and they share a lot of attributes and data. If Person and Business share a lot you can use it. Otherwise I'd recommend you use Polymorphic Associations
A slightly more advanced twist on associations is the polymorphic
association. With polymorphic associations, a model can belong to more
than one other model, on a single association. For example, you might
have a picture model that belongs to either an employee model or a
product model. Here's how this could be declared:
class Picture < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
class Employee < ActiveRecord::Base
has_many :pictures, as: :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, as: :imageable
end
I don't really like STI and I'd recommend you try to use Polymorphic Associations.
A common problem with STI
A common problem with STI is that, over time, more types get added to
that table, and it grows more and more columns, and the records in the
table have less and less in common with one another. Each type of
record uses some subset of the table’s columns, and none uses all of
them, so you end up with a very sparsely populated table. Those types
create costs for one another: when you query for articles, you must
remember to filter out all the other types of values and to only
select columns relevant to articles, or else pay a huge performance
cost. You reproduce a lot of work the database would do for you, if
you only had each data type in its own table.
Assuming I would go for the polymorphic association would this be correct
class Client < ActiveRecord::Base
belongs_to :cliental, polymorphic: true
end
class Business < ActionRecord::Base
# Here I am using has_one because I do not want to have duplicates
has_one :client, as: :cliental
end
class Person < ActionRecord::Base
# Here I am using has_one because I do not want to have duplicates
has_one :client, as: :cliental
end
And later I would like to do the following
class User < ActiveRecord::Base
has_many clients
has_many businesses, through: :client
has_many people, through: :client
end

Reason for belongs_to and has_many associations in ruby-on-rails

I don't get why need both these associations?
Surely if you define one, it would naturally imply the other. Therefore making one of them redundant.
Is there ever a situation where you would have one and not the other?
For example if I define:
class Post < ActiveRecord::Base
has_many :comments
end
why do I then need to define:
class Comment < ActiveRecord::Base
belongs_to :post
end
Surely the above could be implied, and therefore use convention over configuration.
I'm just curious what the thinking was behind this! I'm sure there must be a good reason.
It's not that straight forward. For example if you have a belongs_to relation, the other end could represent a has_one or a has_many.
Secondly, sometimes you don't want the inverse association as it clogs up your model on the other end of the association. For example, you have a lot of classes referencing user but you don't need to know that a user has_many backorder_refirbished_car_parts
First for this code it should be belongs_to if i understand right, as has_one will search at Post for comment_id and i don't think its the case for you and comment who has post_id defined on it
class Comment < ActiveRecord::Base
# has_one :post
belongs_to :post
end
Second: if you don't want to define it, then You can do it but you will not be able to say:
Comment.first.post
so if you don't need it don't write it.
Its not like needed. If you want only belongs_to or has_many association you could. There is not a dependency, If you followed convention of foreign key.

Rails belongs_to relationship with multiple possibilities

I'm trying to make a relationship where a model, Information, belongs_to either a User or a Client.
I thought about putting in my Information.rb
belongs_to :user
belongs_to :client
and in User.rb and Client.rb
has_one :information
But that makes it so that an information could belong_to both a User and a Client.
Is there a way to make it so that it can only belong to either or without just leaving one of the fields blank?
P.S. If it is needed I'm using Rails 4.2, Ruby 2.2.1, and Devise for my account authentication.
Thanks!
This sounds like an unusual association but it's a good fit for Polymorphic Association. In this case, you would declare a name for this association
class Information < ActiveRecord::Base
belongs_to :informational, polymorphic: true #or something like it
class User < ActiveRecord::Base
has_many informations, as :informational
class Client < ActiveRecord::Base
has_many informations, as :informational
And you would also need to add two columns to Information
informational_id, :integer and informational_type, :string
and Client and User need a integer called informational_id that is indexed.

Modelling Many Rails Associations

I'm trying to wrap my head around how I should model my database for a parent model with many has_one associations (20+). I have one model called House which is the parent model of all the other models:
class House < ActiveRecord::Base
has_one :kitchen
has_one :basement
has_one :garage
has_one :common_room
#... Many other child models
end
All the child models contain unique properties specific to their own class. I've thought about STI, but there isn't really any shared functionality or inputs that I can use across models. I've also thought of making one 'super model', but that doesn't really follow Rails best practices, plus it would contain over 200 columns. Is there another design pattern or structure that I can use to model this efficiently so that I can reduce database calls?
class House
has_many :rooms
Room::TYPES.each do |room_type|
has_one room_type, -> { where(room_type: room_type) }, class_name: "Room"
end
class Room
belongs_to :house
TYPES = %i/kitchen basement garage common_room etc/.freeze
end
In your migration make sure to add_index :rooms, [:type, :house_id], unique: true. Unless a house can have more than 1 type of room. If that is the case, I think a different approach is needed.
To your second question, it depends really, what type of database are you using? If its PostgreSQL you could use hstore and store those as a properties hash. Or you could serialize you db to take that as a hash. Or you could have another model that room has many of. For instance has_many :properties and make a property model that would store that information. Really depends on what else you want to do with the information
Why not using Polymorphism in Rails? It would be much simpler
class House < ActiveRecord::Base
has_many :properties, as: :property_house
end
class Kitchen < ActiveRecord::Base
belongs_to :property_house, polymorphic: true
end
class Garage < ActiveRecord::Base
belongs_to :property_house, polymorphic: true
end
For more information, go here: http://terenceponce.com/blog/2012/03/02/polymorphic-associations-in-rails-32/

Rails - Polymorphic association join table

I am currently trying to set up a model structure that seems quite simple, but I haven't quite got it down.
I have a model payment that can belong to either a customer or a supplier (which can both have many payments).
My question is simply whether I need to manually create an interface table to allow this, or if declaring the polymorphic associations will do this for me?
e.g. I have:
class Payment < ActiveRecord::Base
belongs_to :payment_originator, :polymorphic => true
end
class Customer < ActiveRecord::Base
has_many :payments, :as => :payment_originator
end
class Supplier < ActiveRecord::Base
has_many :payments, :as => :payment_originator
end
Is this enough, or do I also need to use a generator to manually create the payment_originator model?
Thanks!
As far as the models go, this is good enough. You just need to migrate a :payment_originator_type and :payment_originator_id to the payments table. The associations you defined above will automatically fill these in for you.

Resources