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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 4

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

Q&A

解決済

1回答

3407閲覧

CanCanCanで権限設定ができない

koichi8888

総合スコア24

Ruby on Rails 4

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

0グッド

0クリップ

投稿2018/05/24 09:05

編集2018/05/24 10:13

前提・実現したいこと

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

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

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

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

該当のソースコード

ability.rb

Ruby

1class Ability 2 include CanCan::Ability 3 4 # def initialize(user) 5 # Define abilities for the passed in user here. For example: 6 # 7 # user ||= User.new # guest user (not logged in) 8 # if user.admin? 9 # can :manage, :all 10 # else 11 # can :read, :all 12 # end 13 # 14 # The first argument to `can` is the action you are giving the user 15 # permission to do. 16 # If you pass :manage it will apply to every action. Other common actions 17 # here are :read, :create, :update and :destroy. 18 # 19 # The second argument is the resource the user can perform the action on. 20 # If you pass :all it will apply to every resource. Otherwise pass a Ruby 21 # class of the resource. 22 # 23 # The third argument is an optional hash of conditions to further filter the 24 # objects. 25 # For example, here the user can only update published articles. 26 # 27 # can :update, Article, :published => true 28 # 29 # See the wiki for details: 30 # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities 31 32 # end 33 34 def initialize(user) 35 user ||= UserDatum.new 36 if user.authority == 1 37 can :manage, :all 38 39 else 40 can :read, :all 41 end 42 end 43 44 45end

users_controller.rb

Ruby

1class UsersController < ApplicationController 2 3# before_action :authenticate_user, {only: [:index, :show, :new, :create, :edit, :update, :destroy, :archive]} 4# before_action :forbid_login_user, {only: [:login_form]} 5 6 load_and_authorize_resource 7 8 def index 9 # データを降順で表示する 10 @users = UserDatum.all.order(created_at: 'desc') 11 end 12 13 def show 14 end 15 16 def new 17 @users = UserDatum.new 18 end 19 20 def create 21 @user = UserDatum.new(user_params) 22 23 if @user.save 24 # redirect 25 redirect_to users_path 26 else 27 # render plain: @user.errors.inspect 28 render 'new' 29 end 30 end 31 32 33 def edit 34 @user = UserDatum.find(params[:id]) 35 end 36 37 def update 38 @user = UserDatum.find(params[:id]) 39# pp @item 40# pp item_params 41 42 if @user.update(user_params) 43 redirect_to users_path 44 else 45 render 'edit' 46 end 47 end 48 49 def destroy 50 @user = UserDatum.find(params[:id]) 51 @user.destroy 52 redirect_to users_path 53 end 54 55# login_formアクションを追加してください 56 def login_form 57 end 58 59# loginアクションを追加してください 60 def login 61 62 # フォームに入力されたメールアドレスとパスワードに一致するユーザーを取得 63 @user = UserDatum.find_by(user_name: params[:user_name], password: params[:password]) 64 65 # 一致するユーザーが存在する場合と存在しない場合の処理を追加 66 if @user 67 session[:user_id] = @user.user_id 68 flash[:notice] = "ログインしました" 69 redirect_to("/") 70 else 71 @error_message = "ユーザまたはパスワードが間違っています" 72 @user_name = params[:user_name] 73 @password = params[:password] 74 redirect_to("/login") 75 # render("/login") 76 end 77 78 end 79 80 def logout 81 session[:user_id] = nil 82 flash[:notice] = "ログアウトしました" 83 redirect_to("/login") 84 end 85 86 # 操作履歴一覧 87 def archive 88 @users = UserDatum.new 89 end 90 91 92 # プライベートメソッド定義 93 94 private 95 def user_params 96 permits = [ 97 :user_name, 98 :authority, 99 :password, 100 :comment 101 ] 102 params.require(:user_datum).permit(permits) 103 end 104 105 106 107end

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]

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

投稿2018/05/24 10:32

mather

総合スコア6753

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

koichi8888

2018/05/25 01:46

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

2018/05/25 01:57

公式ドキュメントにはライブラリの使い方が丁寧に書いてあるので、まずは全体をしっかり読んでみるのをオススメします。英語の意味がわからなければGoogle翻訳などもあります。 「ドキュメントのこの部分の内容が理解できない」なら分かるのですが、文章を読まずに必要な部分を教えてもらおうとするのはダメです。 今回の件の問題は権限の設定は書いたのに、コントローラーで権限のチェックをしていないことです。 3. Controller helpers をしっかりと読んでライブラリの使用方法確認してください。
koichi8888

2018/05/25 03:01 編集

ご回答ありがとうございます。 ドキュメント等を確認したところ、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のインストールが必須ということでしょうか。 ご回答を頂けると幸いです。
mather

2018/05/25 04: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などのライブラリで自動的に付与されることを前提にしています。
koichi8888

2018/05/25 04:51

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問