プロフィール機能を実装する
次に、ログインユーザー向けに名前や自己紹介文などを登録する「プロフィール機能」を追加します。
現状usersテーブルではemail、passwordの情報を管理していますが、ここではusersテーブルとは別にユーザー情報を管理するprofileテーブルを作成します。もちろん同じusersテーブルに名前や自己紹介文などのカラムを追加し、これらの情報を管理することも可能ですが、ひとつのテーブルが大きくなりすぎると扱いづらくなってしまうため、ここではuserとprofileのテーブルを分けておきます。
ただし2つのテーブルには関連がありますから、アソシエーションを定義しておくデータの取り扱いが楽になりそうです。アソシエーション は下記の通りの設定してください。
1)userはprofileをひとつ持っている →User has_one Profile
2)profileはuserに紐づく →Profile belongs_to User
早速profileテーブルおよびmodelを作成しましょう。profileテーブルでは以下の情報を管理します。
・名前(first_nameとlast_nameの2つにカラムを分ける)
・説明文(description)
・プロフィール写真(image)
アソシエーションのために、profileテーブルではuser_idを管理するためのカラムも必要です。忘れずに設定しましょう
profileのcrudを作成
ここではprofileページを以下のように作成します。
1)showページを準備せず、登録情報は「editページ」で確認や修正ができるようにする。
2)newページも省略。editページに遷移した際、もしログインユーザーがprofileを登録済みであればそのデータを表示し、
なければ新規作成できるようにする。
1)はリンク先を調整することで実現可能ですね。
2)に関しては少し工夫が必要です。editページで登録済みのprofileデータがあれば@profile
で受け渡しを行いますが、もし存在しなければProfile modelのインスタンスを生成する必要があります。
has_one, belogns_toの関係の関係において、親(User)から子(Proflile)のインスタンスを生成する際に使うのが、build_※※※※
で、※※※※
にはモデル名(先頭は小文字)を入れます。今回はログインしているユーザーに対してProfile modelのインスタンスを生成するため、current_user.build_profile
とします。
@profile = current_user.profile || current_user.build_profile
current_user.profile:
profileを登録済みのユーザーに対する処理。current_userに紐づくprofileレコードをアソシエーション で呼び出しています。
current_user.build_profile:
profileにまだ登録していないユーザーに対する処理。current_userに対してProfile modelのインスタンスを生成しています。
||
は「もし||
以前がnil
であれば、||
以降を実行する」という意味です。profileに登録済か未登録かはcurrent_user.profile
に値が入るかどうかで判定できます。
ProfilesController < ApplicationController
before_action :set_profile, only: [:edit, :update]
def edit
end
def create
@profile = current_user.build_profile(profile_params)
if @profile.save
redirect_to edit_login_profile_path, notice: 'Your profile has been successfully saved.'
else
render 'edit'
end
end
def update
if @profile.update(profile_params)
redirect_to edit_login_profile_path, notice: 'Your profile has been successfully saved.'
else
render 'edit'
end
end
private
def set_profile
@profile = current_user.profile || current_user.build_profile
end
def profile_params
params.require(:profile).permit(
:first_name,
:last_name,
:introduction,
:image,
:remove_image
)
end
end