render メソッド

renderメソッドは、部分テンプレートを呼び出す際に利用するメソッド

 partial オプション

renderメソッドで使用できるオプション。 partialというオプションを付けることで、明示的に部分テンプレート名を指定し、部分テンプレートを表示することができます。
下の例では、_sample.html.erbという部分テンプレートを呼び出しています。

【例】

<% render partial: "sample" %>

 

 locals オプション

renderメソッドで使用できるオプションです。 localsというオプションを付けることで、部分テンプレート内でその変数を使えるようになります。

【例】

<% render partial: "sample", locals: { post: "hello!" } %>

えっ

 

これで部分テンプレート内においてhello!という文字列の代入されたpostという変数が使えるようになります。

では、renderメソッドを利用して_post.html.erbを呼び出す

index.html.erbを以下のように編集

app/views/posts/index.html.erb

<% @posts.each do |post| %>

  <%= render partial: "post", locals: { post: post } %>

<% end %>

 

部分テンプレートを使うメリット2こ

・繰り返し書くコードを一回で済ます

・修正するときに修正箇所が少なく済む

アソシエーションによるテーブルの関係

アソシエーションによりテーブルを紐付けると

userテーブル    postsテーブル

user_id          ⇨  id        nickname

1     ⇨          1            1さん

2     ⇨         2            2さん

3     ↘          2            2さん

「post.user.nickname」でpostsテーブルのuser_idと紐付いているusersテーブルのレコードからnicknameを取得できる

 

アソシエーションによってモデル同士を紐付けたことにより

「post.user.nickname」みたいなのでpostsテーブルのuser_idと紐付いているusersテーブルのレコードからnicknameを取得することができる

そうすることによってviewに「nickname」が表示されるようになった。でも、投稿からユーザーの情報を呼び出す際にN+1問題という状態が発生する

 N+1問題

アソシエーションを組んだことによって、データを1度呼び出し、さらにそれに紐付く別テーブルのデータを呼ぶ際に、紐付くデータを呼ぶためのSQLを毎回発行してしまう状態のことをN+1問題と言います。

 モデルを利用してデータベースの情報にアクセスする際に発行される命令文です。SQLが発行されるたびにデータベースに対して通信が走るので、SQLが大量に発行されれば処理が重くなります。

 

configure_permitted_parameters メソッド

deviseでは初期状態でサインアップ時にメールアドレスとパスワードのみを受け取るようにストロングパラメーターが設定してあるので、追加したキー(つまりnickname)のパラメーターは許可されていない。

追加のパラメーターを許可したい場合は、application_controller.rbにおいてbefore_actionconfigure_permitted_parametersメソッドを設定する

 

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end

Rails g migration AddNicknameToUsers nickname:string

ユーザーテーブルにニックネームカラムをstring型で追加してください

Rails db:migrate

データベースに適用

mysqlのuserテーブル見たら一番右端にnicknameカラムができてる

  def post_params

    params.require(:post).permit(:title, :content).merge(user_id: current_user.id)

  end

mergeメソッドを利用して、postというハッシュの中に、user_idというキーを結合して、user_idをpostsテーブルに登録できるようになる

user_idは、ログイン中のユーザーidが必要なため、current_user.idと記述することで取得が可能