我有一个使用Postgres和Active Record的Rails应用程序,并且无法理解我的模型之间最有效的关联。
我有一个名为Article的模型。文章需要有格式和2/3 类型。
我需要能够按格式列出文章,即http://myapp.com/format/format-id/article-id
我还需要按流派列出文章,所以:myapp.com/genre/genre-name/article-id
我认为类型和格式本身就是模型本身与has_many_and_belongs_to与文章的关联。每篇文章都有多种类型和1种格式,但每种类型都有多篇文章。
我知道这应该很简单,但我无法找到实现这一目标的最有效途径。
答案 0 :(得分:0)
有一个旧的Railscasts插曲通过两种方式与Rails进行多对多关联 - 你应该看一下:http://railscasts.com/episodes/47-two-many-to-many。它已经过时但仍然很重要。
所以,你有文章,格式和流派。由于每篇文章只有一种格式,因此您不需要has_and_belongs_to_many
关系。文章belongs_to
格式和格式has_many
文章。
文章表格中的每一行都有一个format_id
字段,用于指明它所属的格式。
流派和文章之间的关系是多对多的,这有点棘手。在数据库级别,这需要一个联接表'。您的联接表将被称为articles_genres
,并且每行代表一个特定文章所具有的一种类型。因此,它有一个genre_id
列和一个article_id
列。
就rails而言,有两种方法可以做到这一点:
articles_genres
表提供自己的模型。在这种情况下,您可能还希望为表格提供一个不同的名称,以表明它本身就是一个模型,而不仅仅是一个连接表。你可以称之为genreizations
或articles_genres
表自己的模型,并让rails处理它。我通常更喜欢第一种方式 - 我感觉更有控制力,并且为未来留下更灵活的东西。但是,要么会奏效。我链接的railscasts剧集描述了这两种方式。
如果你采取第一种方式,这就是你将拥有的模型:
class Article < ActiveRecord::Base
has_many :genreizations
has_many :genres, through: :genreizations
belongs_to :format
end
class Format < ActiveRecord::Base
has_many :articles
end
class Genreization < ActiveRecord::Base
belongs_to :article
belongs_to :genre
end
class Genre < ActiveRecord::Base
has_many :genreizations
has_many :articles, through: :genreizations
end
在第二种方式中,这就是您将拥有的模型:
class Article < ActiveRecord::Base
has_and_belongs_to_many :genres
belongs_to :format
end
class Format < ActiveRecord::Base
has_many :articles
end
class Genre < ActiveRecord::Base
has_and_belongs_to_many :articles
end