search
LoginSignup
0

More than 1 year has passed since last update.

posted at

【Rails】Form Objectを使ったログイン機能のサンプル

Form Objectとは

Formで使うためのモデルみたいなやつ。

Railsのフォームは基本的にActiveRecordのモデルに依存している。
1つのフォームで複数モデルの操作をしたいときにForm Objectを使うと、処理がすっきりかける。

またログインに関する処理など、既存のモデルが使えない処理もForm Objectに書くと良い場合がある。

あんまり使わない方が良いって意見もある。

ログイン機能にform_objectを使う場合のサンプル

Railsチュートリアルとかで解説されてる、bcrypt等を使ったログイン機能にForm Objectをいれることを想定。

form_object

$ mkdir app/forms
$ touch app/forms/login.rb
app/forms/login.rb
class Login
    include ActiveModel::Model 

    attr_accessor :email, :password #使うカラム

    validates :email, presence: true 
    validates :password, presence: true 

    def save 
        return false if invalid?
        true
    end 
end

controller

app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def new
    @login = Login.new
  end

  def create 
    @login = Login.new(login_params)
    if @login.save && (@user = User.find_by(email: @login.email)) && @user.authenticate(@login.password)
      login @user
      redirect_to users_path
    else 
      render :new 
    end 
  end 

  private

  def login_params
    params.require(:login).permit(%i[email password])
  end
end

view

app/views/sessions/new.html.erb
<%= form_with model: @login, url: login_path, local: true do |f| %>
  <%= f.text_field :email %>
  <%= f.password_field :password %>
  <%= f.submit "ログイン" %>
<% end %>

locale

$ touch config/locales/models/login.ja.yml
config/locales/models/login.ja.yml
ja:
  activemodel:
    attributes:
      login:
        email: メールアドレス
        password: パスワード

カスタムバリデーションを追加

app/forms/login.rb
class Login
    include ActiveModel::Model 

    attr_accessor :email, :password

    validates :email, presence: true 
    validates :password, presence: true 
    validate :valid_combination

   # ユーザーが見つからない、またはパスワードに誤りがある場合にエラーを返す
   def valid_combination
      @user = User.find_by(email: email)
      errors.add(:base, 'メールアドレスとパスワードの組み合わせが正しくありません。') unless @user&.authenticate(password)
   end

    def save 
        return false if invalid?
        true
    end 
end

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0