sk

開発で得たこと

ユーザープロフィールの作成

この記事で行うこと

ユーザーが現在のパスワード(current_password)なしでプロフィールを登録・編集できるようにする。 f:id:sksksksksk:20180729031314p:plain

使うもの

前提

予約機能の作成 - さがえもん まで完了していること。

現場では?

ユーザープロフィールには登録される項目が多いため、別テーブルで切り分けて保存します。

実装手順

プロフィールテーブルの作成

userテーブルとは別にprofileテーブルを作成します。 userとprofileテーブルは以下のような関連性を持ちます。 f:id:sksksksksk:20180729023437p:plain

  • profileの作成
$ rails g model Users::Profile

app/models/users/profile.rb

class Users::Profile < ApplicationRecord
  # -------------------------------------------------------------------------------
  # Relations
  # -------------------------------------------------------------------------------
  belongs_to :user
end

app/models/user.rb

  # -------------------------------------------------------------------------------
  # Relations
  # -------------------------------------------------------------------------------
  has_many :deliveries, dependent: :destroy
  has_one :profile, class_name: 'Users::Profile', dependent: :destroy
  accepts_nested_attributes_for :profile

profileはmodel/users/profile.rbのようにmodel直下にはないので class_name で指定します。 accepts_nested_attributes_for でuserを編集する時に一緒にprofile(子レコード)を保存・更新することができるようになります。

db/migrate/20180728140656_create_users_profiles.rb

class CreateUsersProfiles < ActiveRecord::Migration[5.1]
  def change
    create_table :users_profiles do |t|
      t.belongs_to :user, foreign_key: true
      t.integer :gender
      t.timestamps
    end
  end
end

データを作成しましょう。

$ rails db:migrate

プロフィール入力フォームの作成

プロフィール変更ページにgender(性別)用のフォームを作成します。

性別は男性・女性どちらかをgenderカラムに持ちます。 この際genderはbooleanでもいいのですが、enumという便利な機能があるのでこちらを使っていきます。

enumの詳細は enumまとめ - さがえもん を読んでみてください。

app/models/users/profile.rb

  belongs_to :user
  # -------------------------------------------------------------------------------
  # Enumerables
  # -------------------------------------------------------------------------------
  enum gender: {
    woman:  1000,
    man:    2000
  }

プロフィール画面へ遷移する前にprofileをbuildさせてあげます。 buildしてあげないと field_for のフォームが表示されません。

app/controllers/users/registrations_controller.rb

  def edit
    resource.build_profile if resource.profile.nil?
    super
  end

フォームは以下のように書くことでシンプルに表現することができます。 app/views/users/registrations/edit.html.haml

    ・・・・・
    .form-group
      = f.label :password_confirmation, class: 'col-sm-2 control-label'
      .col-sm-10= f.password_field :password_confirmation, class: 'form-control', autocomplete: 'off'
    // プロフィール
    = f.fields_for :profile do |profile_f|
      .form-group
        = profile_f.label :gender, class: 'col-sm-2 control-label'
        .col-sm-9.col-xs-12
          - Users::Profile.genders_i18n.invert.each do |key_i18n, value|
            %label.radio-inline
              = profile_f.radio_button :gender, value
              = key_i18n
    .form-group
      = f.label :current_password, class: 'col-sm-2 control-label'
   ・・・・・

f:id:sksksksksk:20180729024719p:plain

  • current_passwordなしで登録できるように変更する

こちらは railsのdeviseまとめ - 現場の開発 で説明しています。ご覧ください。

app/views/users/registrations/edit.html.haml

  .form-group # 削除
    = f.label :current_password, class: 'col-sm-2 control-label' # 削除
    .col-sm-10= f.password_field :current_password, class: 'form-control', autocomplete: 'off' #削除

参考

github.com

ソースコード

github.com

質疑応答

コメントしてください。 こんなコード見たいというような要望あれば記事にしますのでそちらもコメントかメッセージください。

ProgateやRailsチュートリアル、プログラミングスクールを通い終えたが現場のコードはかけない、

一体どうやって書くの?と思っているエンジニアのみなさんのためのチュートリアルを公開しています。

チュートリアル