Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Best-Practice: How to create dependent has_one relations

What's the best practice to create has_one relations?

For example, if I have a user model, and it must have a profile...

How could I accomplish that?

One solution would be:

# user.rb class User << ActiveRecord::Base   after_create :set_default_association    def set_default_association     self.create_profile   end end 

But that doesn't seem very clean... Any suggestions?

like image 307
BvuRVKyUVlViVIc7 Avatar asked Sep 28 '10 00:09

BvuRVKyUVlViVIc7


People also ask

What is the difference between Has_one and Belongs_to?

They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user . To determine who "has" the other object, look at where the foreign key is.

What is dependent destroy in rails?

Dependent is an option of Rails collection association declaration to cascade the delete action. The :destroy is to cause the associated object to also be destroyed when its owner is destroyed.

Does rails have one relationship?

A has_one association indicates that one other model has a reference to this model. That model can be fetched through this association. This relation can be bi-directional when used in combination with belongs_to on the other model.


1 Answers

Best practice to create has_one relation is to use the ActiveRecord callback before_create rather than after_create. Or use an even earlier callback and deal with the issues (if any) of the child not passing its own validation step.

Because:

  • with good coding, you have the opportunity for the child record's validations to be shown to the user if the validations fail
  • it's cleaner and explicitly supported by ActiveRecord -- AR automagically fills in the foreign key in the child record after it saves the parent record (on create). AR then saves the child record as part of creating the parent record.

How to do it:

# in your User model... has_one :profile before_create :build_default_profile  private def build_default_profile   # build default profile instance. Will use default params.   # The foreign key to the owning User model is set automatically   build_profile   true # Always return true in callbacks as the normal 'continue' state        # Assumes that the default_profile can **always** be created.        # or        # Check the validation of the profile. If it is not valid, then        # return false from the callback. Best to use a before_validation         # if doing this. View code should check the errors of the child.        # Or add the child's errors to the User model's error array of the :base        # error item end 
like image 186
Larry K Avatar answered Sep 16 '22 15:09

Larry K