Ruby on Railsでdeviseとscaffoldを組み合わせた際に調べたことをまとめてみた。


はじめに

Ruby on Railsでdeviseとscaffoldを使って簡易アプリを作っているときに分からないコードなど、調べたことを自分用にまとめてみました。

環境


MacOS Catalina version 10.15.7
Rails 6.0.3.4
devise 4.7.3

前提


$ rails new アプリ名でアプリができている状態

deviseの導入


以下のurlのページを参考にdeviseでログイン機能等を作成する。
rails g devise:installでファイルの作成を終えた後、下のコードを記述する。
config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

こちらのページ⇨ https://qiita.com/Orangina1050/items/a16e655519a60f35b394

scaffoldの導入

既に作ってあるアプリにディレクトリを移動した後、以下の形式でscaffoldを実行する。

$ rails g scaffold モデル名 カラム1:データ型1 カラム2:データ型2

自分は自己紹介をする簡易アプリなので以下のカラムを持たせた。

$ rails g scaffold intro name:string hometown:string text:content

scaffold実行後以下を行う。

$ rails db:migrate

カラムをつけ忘れて追加したい場合

rails g migration 行なう処理Toテーブル名 カラム名:データ型の形式で実行する。カラムを加えるなら、AddColumnToテーブル名というように書く。

自分は、user_idのカラムをつけ忘れたため、

$ rails g migration AddColumnToIntros user_id:integer

を行った。rails db:migrateも忘れずに。

コントローラーに設定を加える

scaffoldによってできたコントローラー(intros_controller.rb)の一番上に、
before_action :authenticate_user!を記入する。

before_action :authenticate_user!とは

authenticate_user!はdeviseを入れる事で使えるようになるヘルパーの一つで、
コントローラーに設定してログイン済ユーザーのみにアクセスを許可する。
参考 https://qiita.com/ryuuuuuuuuuu/items/bf7e2ea18ef29254b3dd

次に、newアクション内に下記を追加する。

app/controllers/intros_controller.rb
@intro = Intro.find_or_create_by(:user_id => current_user.id)

find_or_create_byとは

は引数の条件に該当するデータがあればそれを返しfind_by(attributes)、なければ新規作成create(attributes, &block)します。今回は、user_idがcurrent_user.idの場合、それを取得、なければ作成を行っている。
参考 https://qiita.com/taimuzu/items/0a21738d018f475d63ae

自己紹介を既に作成しているユーザーが新規作成のボタンを押したときに編集ページにとんでほしいのでnewアクションに

app/controllers/intros_controller.rb
redirect_to edit_intro_url(@intro)

を追記する。これはredirect_to edit_intro_url(@user.id)と同じことをやっている。
参考 https://qiita.com/Kawanji01/items/96fff507ed2f75403ecb

redirect_toのパス確認

さっき指定したリダイレクト先は、以下のコマンドを打つと様々なパスが出てくるので、そこから対象のものを探す。edit_intro_urlの部分。

$ rails routes

最後に、editアクションにidがcurrent_user.idかそうでないか分岐する処理を書く。

app/controllers/intros_controller.rb
 if @intro.user_id != current_user.id 
    flash[:notice] = "他のユーザーの編集はできません。"
    redirect_to intros_path
 end

その際に、もとからindex.html.erbとshow.html.erbに書かれている、<p id="notice"><%= notice %></p>をコメントアウトすることで、flash[:notice]の内容を表示することができる。