以前の記事ではrailsチュートリアルのアプリにフォロワー通知機能を追加する方法について説明しました。
以前の記事
Railsチュートリアルの追加機能~フォロワー通知 Vol.1~
Railsチュートリアルの追加機能~フォロワー通知 Vol.2~
今回も全2回で返信機能の実装について説明していきたいと思います。
目次
実装した機能詳細
- idと名前を組み合わせてユーザー名(@id-username)とする
- マイクロポストの内容がユーザー名ではじまる場合、返信として処理する
- 自分へのリプライはできない
- 受信者と送信者のフィードにのみ表示
micropostテーブルにカラムとインデックスを追加する
以下のコマンドを実行して、マイグレートファイルを作成します。
rails g migration Add_In_Reply_To_Column_To_Microposts in_reply_to:integer
生成されたマイグレーションファイル(/db/migrate/日付_add_in_reply_to_column_to_microposts.rb)を開き、以下のコードを追加します。
class AddInReplyToColumnToMicroposts < ActiveRecord::Migration[7.0]
def change
add_column :microposts, :in_reply_to, :integer, default:0, foreign_key:{ to_table: :users }
add_index :microposts, [:in_reply_to, :created_at]
end
end
これにより、返信先のユーザーのIDを格納することができるようになります。
追加するscopeを使うためのfeedメソッドを記述する
app/models/user.rbにファイルに以下のコードを追加します。
def feed
part_of_feed = "relationships.follower_id = :id or microposts.user_id = :id"
Micropost.including_replies(id)
.left_outer_joins(user: :followers)
.where(part_of_feed, { id: id }).distinct
.includes(:user, image_attachment: :blob)
end
scopeの追加
引数をとるscopeはクラスメソッドで定義することが推奨されているため、クラスメソッドで定義することにします。
app/models/micropost.rbファイルに以下のコードを追加します。
def Micropost.including_replies(id)
where(in_reply_to: [id, 0]).or(Micropost.where(user_id: id))
end
in_reply_toが0または自分のIDであるまたはuser_idが自分のIDであるものさがしています。
つまり、返信先の指定がないまたは返信先が自分、自分が投稿者であるものをとってくるようにしています。
次の記事ではバリデーションの設定などについて説明していきたいと思います。
参考