説明
自分はformオブジェクトを用いてタグ機能は実装したのですが、投稿はともかく編集、削除、検索などは記事が少なく、あっても複雑で苦労したのでいくつかに分けて投稿したいと思います。今回は続きの記事になります
前提条件
この記事は一つ前の複数投稿編を閲覧していただいている前提の解説となります。
完成コード
```tweets_controller.rb def edit @form = TweetsTag.new(title: @tweet.title, text: @tweet.text, image: @tweet.image, job_id: @tweet.job_id, status_id: @tweet.status_id) enddef update
@tweet = TweetsTag.new(update_params)
tag_list = params[:tweet][:name].split(',')
if @tweet.valid?
@tweet.update(tag_list)
redirect_to root_path
else
render :edit
end
end
def destroy
@tweet.destroy
redirect_to root_path
end
private
def tweet_params
params.require(:tweets_tag).permit(:title, :image, :text, :job_id, :status_id, :name).merge(user_id: current_user.id)
end
def update_params
params.require(:tweet).permit(:title, :image, :text, :job_id, :status_id, :name).merge(user_id: current_user.id, tweet_id: params[:id])
end
```tweets_tag.rb
def update(tag_list)
@tweet = Tweet.where(id: tweet_id)
tweet = @tweet.update(title: title, text: text, image: image, job_id: job_id, status_id: status_id, user_id: user_id)
if tag_list != []
old_relations = TweetTagRelation.where(tweet_id: tweet)
old_relations.destroy_all
end
tag_list.each do |tag_name|
tag = Tag.where(name: tag_name).first_or_initialize
tag.save
new_relation = TweetTagRelation.new(tweet_id: tweet_id, tag_id: tag.id)
new_relation.save
end
end
コード解説
```tweets_controller.rb def edit @form = TweetsTag.new(title: @tweet.title, text: @tweet.text, image: @tweet.image, job_id: @tweet.job_id, status_id: @tweet.status_id) end ```まずコントローラーのeditアクションにてformオブジェクトでインスタンスを生成し、@formに入れてeditのビューに渡してあげます。各カラムの中身はparams受け取った投稿の中身を一つ一つ入れています。
def update
@tweet = TweetsTag.new(update_params)
tag_list = params[:tweet][:name].split(',')
if @tweet.valid?
@tweet.update(tag_list)
redirect_to root_path
else
render :edit
end
end
private
def tweet_params
params.require(:tweets_tag).permit(:title, :image, :text, :job_id, :status_id, :name).merge(user_id: current_user.id)
end
def update_params
params.require(:tweet).permit(:title, :image, :text, :job_id, :status_id, :name).merge(user_id: current_user.id, tweet_id: params[:id])
end
続いて編集画面から情報を受け取ったupdatesアクションの記述です。ここではまず、privateでいつも使っていたtweets_paramsとは別にupdate_paramsを作ります。tweets_paramsと違う点はrequireでtweetを指定していることと、mergeにてtweet_id: params[:id]が追加されている点です。
def update
@tweet = TweetsTag.new(update_params)
tag_list = params[:tweet][:name].split(',')
if @tweet.valid?
@tweet.update(tag_list)
redirect_to root_path
else
render :edit
end
end
そしてupdateアクションの中身ですが、初めのインスタンス生成でupdate_paramsを指定する以外はcreateアクションとほぼ変わりません。違ってくるのは@tweet.update(tag_list)の部分で普通のアップデートではなくこれからtweets_tag.rbにて新たに作るupdateメソッドを使用する点です。
def update(tag_list)
@tweet = Tweet.where(id: tweet_id)
tweet = @tweet.update(title: title, text: text, image: image, job_id: job_id, status_id: status_id, user_id: user_id)
if tag_list != []
old_relations = TweetTagRelation.where(tweet_id: tweet)
old_relations.destroy_all
end
tag_list.each do |tag_name|
tag = Tag.where(name: tag_name).first_or_initialize
tag.save
new_relation = TweetTagRelation.new(tweet_id: tweet_id, tag_id: tag.id)
new_relation.save
end
end
@tweet = Tweet.where(id: tweet_id)
tweet = @tweet.update(title: title, text: text, image: image, job_id: job_id, status_id: status_id, user_id: user_id)
ここでまず、tweetモデルにだけツイート内容を更新する作業を行います。
if tag_list != []
old_relations = TweetTagRelation.where(tweet_id: tweet)
old_relations.destroy_all
end
重要なのはここからで、変数として受け取ったtag_listがからでなければ、old_relationsに編集前に設定されていたタグの情報を全て入れて、削除する記述をします。
tag_list.each do |tag_name|
tag = Tag.where(name: tag_name).first_or_initialize
tag.save
new_relation = TweetTagRelation.new(tweet_id: tweet_id, tag_id: tag.id)
new_relation.save
end
そして変数に入れられたタグを繰り返すし処理でtagテーブル、中間テーブルにかくじ保存する記述を行い完成です
まとめ
以上がfromオブジェクトでのタグ編集、削除の解説となります。この後フロント、タグ関連の投稿一覧、タグの検索の記事を投稿していこうと思います。閲覧ありがとうございました。