Rails 記事とタグを管理する

Rails で記事とタグを管理したい場合は、どうしたらよいのか?


解決策

1つの記事に複数のタグがあり、1つのタグに複数の記事があるので、多対多の関連を表現する仕組みのhas_and_belongs_to_manyを使います。

次のステップで処理します。

  1. 記事モデルを作成する
  2. タグモデルを作成する
  3. 記事とタグの関連テーブルを作成する
  4. 記事モデルにタグモデルを関連付ける
  5. タグモデルに記事モデルを関連付ける

補足:別の方法として、has_many :throughを使った方法もあります。


ステップ1. 記事モデルを作成する

Articleモデルを生成します。

$ rails generate model Article

マイグレーションファイルに、titleカラムとcontentカラム付きのarticlesテーブルを定義します。

# db/migrate/xxx_create_articles.rb
class CreateArticles < ActiveRecord::Migration
 def change
  create_table :articles do |t|
   t.string :title, null: false
   t.text :content
   t.timestamps null: false
  end
 end
end

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

$ rake db:migrate

ステップ2. タグモデルを作成する

Tagモデルを作成します。

$ rails generate model Tag

マイグレーションファイルに、nameカラム付きのtagsテーブルを定義します。

# db/migrate/xxx_create_tags.rb
class CreateTags < ActiveRecord::Migration
 def change
  create_table :tags do |t|
   t.string :name, null: false
   t.timestamps null: false
  end
 end
end

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

$ rake db:migrate

ステップ3. 記事とタグの関連テーブルを作成する

空のマイグレーションファイルを作ります。名前はArticlesテーブルとTagsテーブルの関連テーブルなので、CreateArticlesTagsTableとします。

$ rails generate migration CreateArticlesTagsTable

マイグレーションファイルに、記事テーブルID用のarticle_idカラムと、タグテーブルID用のtag_idカラム付きのarticles_tagsテーブルを定義します。

テーブルの名前は、二つのテーブル名をアンダースコア(_)で区切ったものにします。主キーは不要なので、:id => falseとしています。

# db/migrate/xxx_create_artilces_tags_table.rb
class CreateArticlesTagsTable < ActiveRecord::Migration
 def change
  create_table :articles_tags, :id => false do |t|
   t.integer :article_id, null: false
   t.integer :tag_id, null: false
  end
 end
end

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

$ rake db:migrate

 


ステップ4. 記事モデルにタグモデルを関連付ける

記事モデルファイルを開き、has_and_belongs_to_manyによって、タグモデルとの多対多の関連を宣言します。モデル名は複数形にするようです。

# app/models/article.rb
class Article < ActiveRecord::Base
 has_and_belongs_to_many :tags
end

ステップ5. タグモデルに記事モデルを関連付ける

タグモデルファイルを開き、has_and_belongs_to_manyによって、記事モデルとの多対多の関連を宣言します。モデル名は複数形にするようです。

# app/models/tag.rb
class Tag < ActiveRecord::Base
 has_and_belongs_to_many :articles
end

これでモデル周りの作成は完了です。

 


使い方1. 記事とタグを作る

※ ここまでのステップが全て行われていれば、Railsコンソールで実行できます。

$ rails console

記事1, 2 を作ります。

> article1 = Article.create title:"記事1", content:"内容1"
> article2 = Article.create title:"記事2", content:"内容2"

タグ1, 2 を作ります。

> tag1 = Tag.create name:"タグ1"
> tag2 = Tag.create name:"タグ2"

使い方2. 記事にタグを付ける

使い方1の続き。

記事1にタグ1 と タグ2を付けます。

> article1.tags << tag1
> article1.tags << tag2

!補足注意:同じ記事に対して同じタグを何度でも重複して付けられるので、すでにタグが付いているかを確認した方がベストです。

記事1にタグ1が付いているかを確認するには次のようにします。

> article1.tags.exists? tag1

タグ1がすでに付いていれば true が返ります。付いていないなら false です。


使い方3. 記事に付いてるタグ一覧を取得する

使い方2の続き。

記事1に付いているタグ一覧を取得します。

> article1.tags

タグ名のみ取得するなら次のようにします。

> article1.tags.each do |tag|
>  p tag.name
> end

使い方4. タグが付いてる記事一覧を取得する

使い方3の続き。

タグ1が付いている記事一覧を取得します。

> tag1.articles

使い方5. 記事からタグを1件外す

使い方4の続き。

記事1に付いているタグ1を外します。

> article1.tags.delete tag1

使い方6. 記事からタグを全て外す

使い方5の続き。

記事1に付いているタグを全て外します。

> article1.tags.clear