В моем Rails 4 приложения, есть 5 моделей:Rails 4: "Пандит :: NotAuthorizedError"
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many :posts
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
я реализовал проверку подлинности с Devise (поэтому у нас есть доступ к current_user
).
Теперь я пытаюсь реализовать авторизацию с помощью Pundit (первый таймер).
Следуя documentation, я установил драгоценный камень и запустил генератор rails g pundit:install
.
Затем я создал CalendarPolicy
следующим образом:
class CalendarPolicy < ApplicationPolicy
attr_reader :user, :calendar
def initialize(user, calendar)
@user = user
@calendar = calendar
end
def index?
user.owner? || user.editor? || user.viewer?
end
def show?
user.owner? || user.editor? || user.viewer?
end
def update?
user.owner? || user.editor?
end
def edit?
user.owner? || user.editor?
end
def destroy?
user.owner?
end
end
Я также обновил свой User
модель со следующими методами:
def owner?
Administration.find_by(user_id: params[:user_id], calendar_id: params[:calendar_id]).role == "Owner"
end
def editor?
Administration.find_by(user_id: params[:user_id], calendar_id: params[:calendar_id]).role == "Editor"
end
def viewer?
Administration.find_by(user_id: params[:user_id], calendar_id: params[:calendar_id]).role == "Viewer"
end
Я обновил свои CalendarsController
действия с authorize @calendar
, следующим образом:
def index
@user = current_user
@calendars = @user.calendars.all
end
# GET /calendars/1
# GET /calendars/1.json
def show
@user = current_user
@calendar = @user.calendars.find(params[:id])
authorize @calendar
end
# GET /calendars/new
def new
@user = current_user
@calendar = @user.calendars.new
authorize @calendar
end
# GET /calendars/1/edit
def edit
@user = current_user
authorize @calendar
end
# POST /calendars
# POST /calendars.json
def create
@user = current_user
@calendar = @user.calendars.create(calendar_params)
authorize @calendar
respond_to do |format|
if @calendar.save
current_user.set_default_role(@calendar.id, 'Owner')
format.html { redirect_to calendar_path(@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /calendars/1
# PATCH/PUT /calendars/1.json
def update
@user = current_user
@calendar = Calendar.find(params[:id])
authorize @calendar
respond_to do |format|
if @calendar.update(calendar_params)
format.html { redirect_to calendar_path(@calendar), notice: 'Calendar was successfully updated.' }
format.json { render :show, status: :ok, location: @calendar }
else
format.html { render :edit }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# DELETE /calendars/1
# DELETE /calendars/1.json
def destroy
@user = current_user
@calendar.destroy
authorize @calendar
respond_to do |format|
format.html { redirect_to calendars_url, notice: 'Calendar was successfully destroyed.' }
format.json { head :no_content }
end
end
И я включил after_action :verify_authorized, :except => :index
в мой ApplicationController
.
Теперь, когда я войти, я могу получить доступ к http://localhost:3000/calendars/
, но когда я пытаюсь посетить http://localhost:3000/calendars/new
, я получаю следующее сообщение об ошибке:
Pundit::NotAuthorizedError in CalendarsController#new
not allowed to new? this #<Calendar id: nil, name: nil, created_at: nil, updated_at: nil>
@user = current_user
@calendar = @user.calendars.new
authorize @calendar
end
Очевидно, что я должен сделать что-то неправильно.
Проблема: я не могу понять, что.
Любая идея?
Итак, я обновил все 3 метода в модели 'User', а также' CalendarPolicy' в соответствии с вашим ответом. Но я все равно получаю такое же сообщение об ошибке. Любая другая идея? –
Вы используете pry или отладчик? Я бы поставил один в контроллер, один в методе авторизации и один в модели. Затем убедитесь, что все переменные заданы так, как ожидалось на этом пути. – penner
Я не использую Pry и Debugger. У меня есть Byebug, установленный в разработке и тестировании. Что вы подразумеваете под «Я бы поставил один в контроллер, один в методе авторизации и один в модели».? –