Ruby
MySQL
RubyOnRails

Ruby on Rails 5 + MySQLで中間テーブルをつくる

Ruby on Railsで中間テーブルを作ろうと思います。

例としてBlogというプロジェクトにArticleとTagモデルを作り、
Article_tagsモデルを作ります。
(多対多の関係です。
複数の記事に複数のタグをつけることができる、タグは複数の記事をもつことができる。)

scaffoldと、migrationを使用して作成します。

実装すること

タグの詳細ページ(localhost:3000/tags/{tagのid}/)
にそのタグが関連づいている記事(article)を表示するようにします。

手順

scaffoldコマンドでArticle,Tagを作成します。
id(pkey),updated_at,created_atは特にしていなくてもDBのカラムとして作られます。

rails generate scaffold Article title:string body:string
rails generate scaffold Tag name:string

マイグレーションを実行します。

bundle exec rake db:migrate

中間テーブル用のモデルを作成します。

 rails generate model ArticleTags article:references tag:references

もういちどマイグレーションを実行します。

完成したマイグレーションファイルを以下のように変更します。

class CreateArticleTags < ActiveRecord::Migration[5.2]                           
  def change                                                                     
    create_table :article_tags do |t|                                            
      t.references :article, foreign_key: true                                   
      t.references :tag, foreign_key: true                                       

      t.timestamps                                                                                             
    end                                                                          
  end                                                                            
end                                                                                                                                                                                            

マイグレーションを実行します。

bundle exec rake db:migrate

モデルの編集

app/models/article_tag.rb

belongs_to :article
belongs_to :tag

app/models/article.rb
app/models/tag.rb
それぞれに

has_many :article_tags

を追記します。

ビューの編集

app/views/tags/show.html.erb
を編集することにします。

<% @tag.article_tags.each do |article_tag| %>                                                                         
    <%= article_tag.article.title %>
    <%= article_tag.article.body%>
<% end %>

これで中間テーブルを設定して、異なるモデルの情報を取得することができました。