ассоциации рельсов - Как бы вы представили эти отношения?

Я пытаюсь найти лучший способ представить следующие отношения.

Newspaper has_many Articles
Newspaper has_many Subscribers

Подписчики могут сохранять статьи для своей личной страницы.

Два вопроса:

1) Как будут выглядеть отношения в рельсах? Как будет выглядеть действие «сохранить»?

Следующее использование has_many мне кажется неправильным:

class ArticleController < ApplicationController
  def save
    a = Article.find(101)
    @user.saved_articles << a
  end
end

2) Нужна ли мне таблица соединения Saved_Articles, которая выглядела бы так?

Saved_Articles
----------------
user_id, article_id

person truthSeekr    schedule 06.03.2011    source источник


Ответы (3)


То, что вы описываете, - это отношения «многие ко многим». С точки зрения ассоциаций Rails, это один из способов определить это:

class Newspaper
  has_many :articles
  has_many :subscribers
end

class Subscriber
  belongs_to :newspaper
  has_and_belongs_to_many :articles
end

class Article
  belongs_to :newspaper
  has_and_belongs_to_many :subscribers
end

При использовании has_and_belongs_to_many вам понадобится таблица соединений, но она должна называться articles_subscribers и иметь поля subscriber_id и article_id:

articles_subscribers
--------------------
article_id
subscriber_id

Тогда ваше действие save будет выглядеть примерно так, если предположить, что @user является экземпляром Subscriber:

class ArticlesController < ApplicationController
  def save
    @user.articles << Article.find(params[:id])

    # handle the response - render or redirect
  end
end

См. http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many для получения дополнительной информации о has_and_belongs_to_many

person dnch    schedule 06.03.2011
comment
Спасибо за такой подробный ответ. - person truthSeekr; 06.03.2011

Ответьте на вопрос №1:

в models/newspaper.rb: has_many :статьи has_many :подписчики

в контроллерах/newspapers_controller.rb

def create
  @newspaper = NewsPaper.new(params[:newspaper])
  if @newspaper.save
    redirect_to 
  else
    render :new
  end
end
person RubyFanatic    schedule 06.03.2011

Ответ на вопрос №2: для этого вам не нужна таблица соединений. Было бы достаточно 3 отдельных таблиц (газеты, статьи и подписчики). Внешние ключи длягазета_id будут в статьях и подписчиках.

person RubyFanatic    schedule 06.03.2011