n対nの関連
Railsでn対n関連を実装します。
現在1対nの関連を持ったTagテーブルとArticleテーブルをn対nの関連に変更します。
ここでは中間テーブルを作成しない方法で実装します。
has_and_belongs_to_many
各モデルにhas_and_belongs_to_manyを追加します。
class Article < ActiveRecord::Base has_and_belongs_to_many :tags end class Tag < ActiveRecord::Base has_and_belongs_to_many :articles end
関連付け
関連付けはマイグレーションファイルで行います。
キー指定は必要なくなるのでarticle_idとtag_idは必要なくなります。ですので削除します。
$ rails g migration remove_article_id_from_tags article_id:integer $ rails g migration remove_tag_id_from_articles tag_id:integer
以下のコマンドでマイグレーションファイルを生成します。
$ rails g migration create_articles_tags
こんな感じでActiveRecord::Associations::CollectionProxyクラスのオブジェクトとして関連付けが形成されます。
irb(main):001:0> Article.first.tags Article Load (0.4ms) SELECT `articles`.* FROM `articles` ORDER BY `articles`.`id` ASC LIMIT 1 Tag Load (0.4ms) SELECT `tags`.* FROM `tags` INNER JOIN `articles_tags` ON `tags`.`id` = `articles_tags`.`tag_id` WHERE `articles_tags`.`article_id` = 1 => #<ActiveRecord::Associations::CollectionProxy [#<Tag id: 1, name: nil, description: nil, created_at: "2016-04-04 05:05:54", updated_at: "2016-04-04 05:05:54", article_id: nil>]>
出たエラー
マイグレーションファイルでの関連付けを忘れていて以下のエラーが出ました
irb(main):008:0* Article.first.tags Article Load (0.9ms) SELECT `articles`.* FROM `articles` ORDER BY `articles`.`id` ASC LIMIT 1 Mysql2::Error: Table 'development.articles_tags' doesn't exist: SHOW FULL FIELDS FROM `articles_tags` ActiveRecord::StatementInvalid: Mysql2::Error: Table 'development.articles_tags' doesn't exist: SHOW FULL FIELDS FROM `articles_tags`