0
0

Deviseを使用した複数モデル間のアクセス制御

Posted at

はじめに

この記事では、Ruby on Railsの人気認証ライブラリであるDeviseを使用して、異なるユーザーモデル間でのアクセス制御を実装する方法を解説します。特に、Company モデルがログインしている状態から、ログインせずに Staff モデルを編集する方法に焦点を当てます。

実装の試みと課題

初めに、Staffs::RegistrationsController を使ったアプローチを試みましたが、どうしてもログイン画面に遷移してしまい原因がわからないという問題に直面しました。

最終的な解決策

この問題を解決するために、StaffsController を利用して、Company モデルが Staff モデルのデータを安全に編集できるようにしました。以下はその具体的な実装です。

1. コントローラの設定

class StaffsController < ApplicationController
  before_action :authenticate_company_or_staff!, only: %i(edit update destroy)
  before_action :set_staff, only: %i[show edit update]

  def edit
  end

  def update
    if @staff.update(staff_params)
      redirect_to staff_path(@staff), notice: 'スタッフ情報が更新されました。'
    else
      render :edit
    end
  end

  private

  def set_staff
    @staff = Staff.find(params[:id])
  end

  # 以下で認証確認
  def authenticate_company_or_staff!
    unless company_signed_in? || staff_signed_in?
      redirect_to new_company_session_path, alert: 'ログインが必要です。'
    end
  end

  def staff_params
    params.require(:staff).permit(:company_id,
        :name,
        :email,
        :position,
        :telephone,
        :postal_code,
        :prefecture,
        :city,
        :street_address,
        :description,
        :password,
        :password_confirmation,
        :current_password,
        service_ids: [])
  end

  def parse_date
    @date = params[:date].present? ? Date.parse(params[:date]) : Date.today # パラメータが存在する場合のみDateオブジェクトを作成
  end
end

2. ビューファイルの編集フォーム

<div class="container mt-4">
  <h2>スタッフ更新</h2>
  <%= render 'form', staff: @staff %>
</div>

3. フォームの部分テンプレート

フォームは、_form.html.erb に分けて、スタッフの情報を更新できるようにフィールドを配置しました。このフォームは、current_company が存在する場合に限り、会社IDを隠しフィールドとして送信します。

知見

  • Deviseで異なるモデル間のアクセス制御を行う際には、RegistrationControllerではうまく制御できず、ログイン画面に遷移させられることがある。
  • 上記の場合、自身でコントローラを作成して制御することで対応可能(StaffsControllerなど)
  • CanCanCanを使用することで、誰がどのリソースにアクセスできるかを細かく制御可能。
0
0
0

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
  3. You can use dark theme
What you can do with signing up
0
0