質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • Ruby on Rails 4

    2380questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

CanCanCanで権限設定ができない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 135

koichi8888

score 11

 前提・実現したいこと

CanCanCanを利用し、Admin(すべての権限)とOperator(読み取りのみ)の2つの権限グループを作成し、権限管理をしたいですが、読み取り権限のユーザがログインした際も編集ができてしまいます。
UserDatumというテーブルのauthorityというカラムが1であれば、Admin、2であれば、Operatorとして設定したいです。

↓のページを参考にしました。
https://qiita.com/shimojik/items/2b5f8d1729cbc28b48c2

 発生している問題・エラーメッセージ

エラーメッセージ等はありません。

 該当のソースコード

ability.rb

class Ability
  include CanCan::Ability

 # def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    #   user ||= User.new # guest user (not logged in)
    #   if user.admin?
    #     can :manage, :all
    #   else
    #     can :read, :all
    #   end
    #
    # The first argument to `can` is the action you are giving the user
    # permission to do.
    # If you pass :manage it will apply to every action. Other common actions
    # here are :read, :create, :update and :destroy.
    #
    # The second argument is the resource the user can perform the action on.
    # If you pass :all it will apply to every resource. Otherwise pass a Ruby
    # class of the resource.
    #
    # The third argument is an optional hash of conditions to further filter the
    # objects.
    # For example, here the user can only update published articles.
    #
    #   can :update, Article, :published => true
    #
    # See the wiki for details:
    # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities

 # end

    def initialize(user)
      user ||= UserDatum.new
      if user.authority == 1
        can :manage, :all

      else                                                                                                                           
        can :read, :all
      end
    end


end

users_controller.rb

class UsersController < ApplicationController

# before_action :authenticate_user, {only: [:index, :show, :new, :create, :edit, :update, :destroy, :archive]}
# before_action :forbid_login_user, {only: [:login_form]}

 load_and_authorize_resource

  def index
      # データを降順で表示する
      @users = UserDatum.all.order(created_at: 'desc')
  end

  def show
  end

  def new
    @users = UserDatum.new
  end

  def create
    @user = UserDatum.new(user_params)

    if @user.save
      # redirect
      redirect_to users_path
    else
      # render plain: @user.errors.inspect
      render 'new'
    end
  end


  def edit
    @user = UserDatum.find(params[:id])
  end

  def update
   @user = UserDatum.find(params[:id])
#   pp @item
#   pp item_params

    if @user.update(user_params)
      redirect_to users_path
     else
      render 'edit'
    end
  end

 def destroy
   @user = UserDatum.find(params[:id])
   @user.destroy
   redirect_to users_path
 end

# login_formアクションを追加してください
  def login_form
  end

# loginアクションを追加してください
  def login

    # フォームに入力されたメールアドレスとパスワードに一致するユーザーを取得
    @user = UserDatum.find_by(user_name: params[:user_name], password: params[:password])

    # 一致するユーザーが存在する場合と存在しない場合の処理を追加
    if @user
      session[:user_id] = @user.user_id
      flash[:notice] = "ログインしました"
      redirect_to("/")
    else
     @error_message = "ユーザまたはパスワードが間違っています"
     @user_name = params[:user_name]
     @password = params[:password]
      redirect_to("/login")
     # render("/login")
    end

  end

  def logout
    session[:user_id] = nil
    flash[:notice] = "ログアウトしました"
    redirect_to("/login")
  end

  # 操作履歴一覧
  def archive
    @users = UserDatum.new
  end


  # プライベートメソッド定義

   private
    def user_params
      permits = [
        :user_name,
        :authority,
        :password,
        :comment
      ]
      params.require(:user_datum).permit(permits)
    end



end

application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

# ログイン中のユーザ名取得
  before_action :set_current_user

  def set_current_user
    @current_user = UserDatum.find_by(user_id: session[:user_id])
  end

# ログインしていない場合、ログイン画面にリダイレクト  
  def authenticate_user
    if @current_user == nil
       flash[:notice] = "ログインしてください。"
       redirect_to("/login")
    end
  end

# ログイン済みの場合、ログイン画面へのアクセス禁止、トップページにリダイレクト
  def forbid_login_user
    if @current_user
       flash[:notice] = "ログイン画面にアクセスするにはログアウトする必要があります。"
       redirect_to("/items")
    end
  end






end

 試したこと

・他の権限設定の影響を無くすために、before_actionでログイン状態によってページアクセスを制限するメソッドの読み込みをコメントアウトしました。
・railsサーバでテキストエディタでアクセスしましたが、rails s でサーバ起動をさせたコンソールに↓のデバック箇所のメッセージは何も表示されていないので、設定の読み込みができていないようです。設定ファイルの内容が原因ではなく、設定ファイルの読み込みの記載が問題かと思っています。

def initialize(user)
  pp "cancancan_debug_start"
  pp user
  user ||= UserDatum.new
  pp "cancancan_debug_step01"
  pp user
  if user.authority == 1
    pp "cancancan_debug_step02"
    can :manage, :all
  else                         
    pp "cancancan_debug_step03"                                                                                                  
    can :read, :all
  end
end

 補足情報(FW/ツールのバージョンなど)

・Phusion Passenger
Phusion Passenger 5.2.3

・Apache
Server version: Apache/2.4.6 (CentOS)

・Rails
Rails 4.2.10

・OSバージョン
CentOS Linux release 7.4.1708 (Core)

・Mysql
mysql  Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using  EditLine wrapper

・Git
git version 1.8.3.1

・Ruby
ruby 2.3.7p456 (2018-03-28 revision 63024) [x86_64-linux]

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

公式のドキュメントをしっかり読みましょう。そのまんまの答えが書いてありますよ?
https://github.com/CanCanCommunity/cancancan#3-controller-helpers

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/25 10:46

    ご回答ありがとうございます。ロードの方法が間違っており、それがドキュメントに記載されているということでしょうか。

    キャンセル

  • 2018/05/25 10:57

    公式ドキュメントにはライブラリの使い方が丁寧に書いてあるので、まずは全体をしっかり読んでみるのをオススメします。英語の意味がわからなければGoogle翻訳などもあります。
    「ドキュメントのこの部分の内容が理解できない」なら分かるのですが、文章を読まずに必要な部分を教えてもらおうとするのはダメです。

    今回の件の問題は権限の設定は書いたのに、コントローラーで権限のチェックをしていないことです。 3. Controller helpers をしっかりと読んでライブラリの使用方法確認してください。

    キャンセル

  • 2018/05/25 11:58 編集

    ご回答ありがとうございます。
    ドキュメント等を確認したところ、current_userメソッドがコントローラ内に記載されていないことが原因かと思っています。そのため、application_controller.rb内にメソッドを利用できるようにする helper_method :current_user, :logged_in?
    を記載しましたが以下のエラーが表示されました。
    ----
    NameError in UsersController#logout
    uninitialized constant User
    Extracted source (around line #261):
    259
    260
    261
    262
    263
    264

    names.inject(Object) do |constant, name|
    if constant == Object
    constant.const_get(name)
    else
    candidate = constant.const_get(name)
    next candidate if constant.const_defined?(name, false)

    Rails.root: /Myapp
    ---

    おそらく記載が誤っていると思うのですが、参考URL等をご存じであれば、教えて頂けると幸いです。

    もしくは公式ドキュメントに記載されているDevise または Authlogicのインストールが必須ということでしょうか。
    ご回答を頂けると幸いです。

    キャンセル

  • 2018/05/25 13:04

    CanCanCan expects a current_user method to exist in the controller. First, set up some authentication (such as Devise or Authlogic).
    とあるように、current_userはDeviseなどのライブラリで自動的に付与されることを前提にしています。

    キャンセル

  • 2018/05/25 13:51

    ご回答ありがとうございます。cancancanを利用するにはDeviseまたはauthlogicというgemが必須ということでしょうか。ユーザ認証をgemを利用しないで実装しているので、cancancanの利用は難しそうです。何度も回答して頂きありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby on Rails 4

    2380questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。