2

こんにちは、私は初心者のプログラマーで、おそらく私の質問はばかげていますが、ネット (およびこのサイト) を検索していて、答えが見つかりませんでした (おそらく、適切に質問しなかったのでしょう)。

問題は、アプリに 3 種類のユーザー (患者、医師、管理者) がいて、それぞれが (ログインすると) 一部のページだけを表示できるようにすることです。たとえば、医師はそのプロファイルと一部の患者データ ページにのみアクセスでき、患者は自分のデータのあるページにのみアクセスでき、管理者は管理ページにのみアクセスできる必要があります。

ユーザーのタイプに応じてページへのアクセスをフィルタリングするにはどうすればよいですか?

事前にどうもありがとうございました。

4

1 に答える 1

1

ユーザーが Devise や Clearance などで認証されている場合、サインインしているユーザーはcurrent_userメソッドを介して利用できます。すべての呼び出しを現在のユーザーにスコープするだけです。

class PatientsController < ApplicationController
  def index
    @patients = current_user.patients
  end

  def show
    # Will raise an ActiveRecord::RecordNotFound exception
    # if there is not patient with given id or the patient 
    # is not associated with the current_user
    # Renders a 404 error in production
    @patient = current_user.patients.find(params[:id])
  end
end

Rails のベスト プラクティスの例:

class PostsController < ApplicationController
  def edit
    # raise RecordNotFound exception (404 error) if not found
    @post = current_user.posts.find(params[:id])
  end
end

そのため、投稿が current_user によって所有されていることを約束できる current_user.posts でのみ投稿を見つけます。そうでない場合は、404 エラーが発生します。所有者と current_user を比較する必要はありません。スコープ アクセスを使用してパーミッション チェックを簡単にします。

class User < AR::B
  has_many :patients
  has_many :reports, through: :patients
end

class Patient < AR::B
  belongs_to :user
  has_many :reports
end

class Report < AR::B
  belongs_to :patient
end

# config/routes.rb
resources :patients

class PatientsController < ApplicationController
  # Ensure that a user is signed in (via Devise)
  before_action :authenticate_user! # before_filter in Rails 3

  # Load the patient before certain actions
  before_action :load_patient, only: [:show, :edit, :update, :destroy]

  def index
    # Scoping to the current_user ensures that a doctor can only see his patients 
    @patients = current_user.patients
  end

  def show
  end

  def new
    @patient = current_user.patients.build
  end

  def create
    @patient = current_user.patients.build(patient_params)
    if @patient.save
      redirect_to @patient, notice: 'Patient has been created.'
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @patient.save
      redirect_to @patient, notice: 'Patient has been updated.'
    else
      render :edit
    end
  end

  def destroy
    @patient.destroy
    redirect_to patients_path, notice: 'Patient has been destroyed.'
  end

  private

  def load_patient
    @patient = current_user.patients.find(params[:id])
  end

  def patient_params
    params.require(:patient).permit(:first_name, :last_name)
  end
end

スコーピングにより、ユーザーは自分のレコードと関連付けられているレコードのみを編集できるようになります。

よりきめ細かいアクセス ロジックが必要な場合 (たとえば、医師がメッセージを受信したい場合にのみ、患者は医師にメッセージを送信できます)、Punditを調べることをお勧めします。

お役に立てれば!

于 2013-08-07T08:54:58.013 に答える