はじめに
ツイートにタグ付け機能を付与する際、多対多、一対多のどちらで実装するかでそれぞれのメリットが存在するかと思います。
・多対多のメリット:タグ一覧ページ、タグの詳細ページを実装しやすい。
・一対多のメリット:create,updateが実装しやすい。中間テーブルを作る必要が無い。
今回は一対多での実装の際にネックとなる、tags_controllerにおけるindex action, show actionの作成について投稿させていただきます。
多くの参考記事で多対多による実装が載っていますが、この点さえクリアできれば、一対多の方が簡単に実装できると感じています。)
コード
class CreateTags < ActiveRecord::Migration
def change
create_table :tags do |t|
t.string :name, index: true
t.references :tweet, foreign_key: true
end
end
end
class Tweet < ActiveRecord::Base
has_many :tags, dependent: :destroy
end
class Tag < ActiveRecord::Base
belongs_to :tweet
end
class TagsController < ApplicationController
def index
@tags = []
Tag.order("name ASC").each do |tag|
i = 0
@tags.each do |t|
if tag.name != t.name
i += 1
end
end
if i == @tags.length
@tags << tag
end
end
end
def show
@tag = Tag.find(params[:id])
@tweets = []
Tweet.all.each do |tweet|
tweet.tags.each do |tag|
if tag.name == @tag.name
@tweets << tweet
break
end
end
end
end
end
終わりに
indexのviewページでは、作成されたタグの一覧を表示、showのviewページでは、該当のtagが付けられたツイートの一覧を表示します。
それぞれ、@tags、@tweetsを用いることで、タグ,ツイートを被らせることなく表示することを実現できます。
(なお、配列から重複を取り除く際、rubyではuniqというメソッドが存在しますが、配列の中身がハッシュの際に上手く使用できないようなので、今回は上記のようなコードを書きました。また、本記事はgem:acts-as-taggable-onを使用しないことを前提としています。)
以上、内容に不備がございましたら、コメントいただけますと幸いです。