Rails Active记录多个关联

时间:2014-10-10 22:37:13

标签: ruby-on-rails postgresql activerecord associations

我有一个使用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种格式,但每种类型都有多篇文章。

我知道这应该很简单,但我无法找到实现这一目标的最有效途径。

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而言,有两种方法可以做到这一点:

  1. articles_genres表提供自己的模型。在这种情况下,您可能还希望为表格提供一个不同的名称,以表明它本身就是一个模型,而不仅仅是一个连接表。你可以称之为genreizations
  2. 不要给articles_genres表自己的模型,并让rails处理它。
  3. 我通常更喜欢第一种方式 - 我感觉更有控制力,并且为未来留下更灵活的东西。但是,要么会奏效。我链接的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