投稿編集機能

内容

投稿編集機能の実装

投稿編集機能

1. MVCの設定

ルーティングを設定し、ビューは新規投稿のものを使い回し
投稿が編集できたらユーザーのマイページに遷移するようコントローラーを編集する
posts_controller.rb

def edit
  @post = Post.find(params[:id])
end

def update
  @post = Post.find(params[:id])
  if @post.update(post_params)
    redirect_to user_path(current_user.id)
  else
    render :edit
  end
end

2. 編集ページへ遷移するボタンをjQueryで導入

ユーザーのマイページから投稿編集ページへ遷移できるよう、マウスオーバーするとドロップボタンが出てくるように実装
前回はJavaScriptを使用したが、jQueryの方が簡単に実装できるためこちらを用いる
まずはjQueryのインストール
ターミナル

% yarn add jquery

Rails5以前はjquery-railsというGemをインストールするのが普通だったらしい、Rails6から標準装備されているWebpackerで管理する際はyarnコマンドを使用してインストールする→簡単に導入できる

次にWebpackの設定ファイルでjQueryを管理下として認定
config/webpack/environment.js

const { environment } = require('@rails/webpacker')
// 以下追記
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
// ここまで
module.exports = environment

application.jsでjQueryを呼び出せるようにする
application.js

// 追記
require('jquery')

以上で導入完了

jsファイルにjQueryのコードを記述
最初以下のように記述していたが、これだとクリックしたclass要素すべてに対してtoggleの表示/非表示が実行されてしまった

$(document).on("click", '.leader', function() {
  $('.leader-lists').toggle();
});

よってthisを入れてクリックした1つだけに対して動作するように修正

$(document).on("click", '.leader', function() {
  $('.leader-lists', this).toggle();
});

以上のようにjQueryを用いると簡潔にコードが書けるようになる

3. rubocop

次回

投稿削除機能から

参考

1. FontAwesomeの使用

FontAwesomeでアイコンを使用したかったが、なぜかサイトに表示できず
FontAwesomeのver.が6になっていてHTMLの表記方法が変わっていた
→自分のkitコードの最新バージョンがver.5であったため、ver.5のHTML表記で書かないといけない = まだ6に対応していない? or kitコードを何らかの手段で最新にアップデートする必要がある?

2. 部分テンプレートに変数を渡す時の注意点

部分テンプレートを呼び出す際、partialを省略できることは知っていたので、以下のように記述していた

render 'shared/post', locals: { post: @post }

しかしこれではうまく変数を渡せなかった
→partialを省略したらlocalsも省略する必要があるらしい

render 'shared/post', post: @post

3. jQueryでonしたクリックが効かない

onメソッドの基本的な記述方法は以下の通り

$(".btn").on("click", function(){
  console.log("効かない");
});

上記の記述は正しいが、ページ読み込み後に生成された要素には効かないらしい
jQueryで後から追加した要素等がそれに該当
そういう時は引数にセレクタを指定する

$(document).on("click", ".btn", function(){
  console.log("効いた");
});