has_one , : через => модель ПРОТИВ простого метода?

#ruby-on-rails #ruby #ruby-on-rails-3 #activerecord #model

#ruby-on-rails #ruby #ruby-on-rails-3 #activerecord #Модель

Вопрос:

У меня возникли некоторые проблемы с использованием has_one, through => model . Лучше всего показать вам мой случай.

 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
  

Все работает нормально. Я могу сделать comment.category . Проблема в том, что когда я создаю новый комментарий и настраиваю его статью, мне приходится сохранять комментарий, чтобы заставить ассоциацию работать. Пример :

  >> 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 в любом случае не настраивайте конструктор сборки и не создавайте метод. Итак, я хочу заменить свою модель комментариев на :

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

Звучит неплохо?

Комментарии:

1. кто-нибудь? ни у кого нет хороших мнений?

Ответ №1:

В вашей идее нет ничего плохого. Я не вижу многих ситуаций, в которых has_one :category, :through => :articles был бы очевидный лучший выбор (если только не требуется загрузка с помощью Comment.all(:include => :category) ).

Подсказка на delegate :

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

Другой подход:

 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
  

Комментарии:

1. некоторую дополнительную информацию alias_method_chain можно найти здесь

2. Я чувствую, что это то, что Rails должен делать по умолчанию… Вместо того, чтобы всегда запрашивать базу данных, просмотрите объект, который уже есть в памяти!

Ответ №2:

Попробуйте внести изменения в свой класс Category следующим образом:

 class Category
  has_many :articles
  has_many :comments, :through => :articles
end
  

Комментарии:

1. извините, неправильно написал это в stakeoverflow. Проблема не в моем реальном приложении.