Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

has_one, :through => model VS simple method?

I have some issues using has_one, through => model. The best is to show you my case.

class Category
  has_many :articles
end

class Article
  has_many :comments
  belongs_to :category
end

class Comment
  belongs_to :article
  has_one :category, :through => :articles
end

Everthing works fine. I can do comment.category. The problem is when I create a new comment and set up its article, I have so save the comment to make the association works. Example :

 >> comment = Comment.new
 >> comment.article = Article.last
 >> comment.category
     -> nil
 >> comment.article.category
     -> the category
 >> comment.save
 >> comment.category
     -> nil
 >> comment.reload
 >> comment.category
     -> the category

has_one, through => model anyway do not set up, build constructor and create method. So, I want to replace my comment model by :

class Comment
  belongs_to :article
  def category
    article.category
  end
end

Sounds a good idea ?

like image 790
Hartator Avatar asked May 20 '11 09:05

Hartator


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 Has_and_belongs_to_many?

As far as I can remember, has_and_belongs_to_many gives you a simple lookup table which references your two models. For example, Stories can belong to many categories. Categories can have many stories.

What is has_ many?

A has_many association is similar to has_one , but indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a belongs_to association. This association indicates that each instance of the model has zero or more instances of another model.


1 Answers

Nothing wrong with your idea. I can't see many situations in which has_one :category, :through => :articles would be the obvious better choice (unless eager-loading with Comment.all(:include => :category) ).

A hint on delegate:

class Comment
  belongs_to :article
  delegate :category, :to => :article

A different approach:

class Comment
  belongs_to :article
  has_one :category, :through => :article

  def category_with_delegation
    new_record? ? article.try(:category) : category_without_delegation
  end

  alias_method_chain :category, :delegation
like image 176
Marcel Jackwerth Avatar answered Sep 28 '22 04:09

Marcel Jackwerth