LoginSignup
0
0

More than 1 year has passed since last update.

formオブジェクト(ActiveModel)を用いたタグ機能(編集、削除編)

Posted at

説明

自分は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)
  end

  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

  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受け取った投稿の中身を一つ一つ入れています。

tweets_controller.rb
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]が追加されている点です。

tweets_controller.rb
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メソッドを使用する点です。

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_tag.rb
    @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モデルにだけツイート内容を更新する作業を行います。

tweets_tag.rb
    if tag_list != []
      old_relations = TweetTagRelation.where(tweet_id: tweet)
      old_relations.destroy_all
    end

重要なのはここからで、変数として受け取ったtag_listがからでなければ、old_relationsに編集前に設定されていたタグの情報を全て入れて、削除する記述をします。

tweets_tag.rb
 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オブジェクトでのタグ編集、削除の解説となります。この後フロント、タグ関連の投稿一覧、タグの検索の記事を投稿していこうと思います。閲覧ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0