Rails cancancan извлекает записи для конкретного пользователя - PullRequest
0 голосов
/ 05 июня 2019

Мне нужно получать только определенные записи из базы данных при определенных условиях, используя CanCanCan. Это моя модель данных.

class User < ApplicationRecord
  has_many :regions_users
end

class RegionsUser < ApplicationRecord
  belongs_to :region
end

class Region < ApplicationRecord
  has_many :regions_users
  has_many :sites
end

class Site < ApplicationRecord
  belongs_to :region
  has_many :offers
end

class Offer < ApplicationRecord
  belongs_to :site
end

Например, пользователю назначены два региона, что означает, что пользователь user.regions_users возвращает и массив из двух RegionsUser [RegionsUser1, RegionsUser2]. RegionsUser1 принадлежит к области A, а RegionsUser2 принадлежит к области B, поэтому, если я вошел в систему как пользователь, я являюсь пользователем региона, который может контролировать данные, принадлежащие этим регионам. Теперь мне нужно отобразить предложения, которые принадлежат этим регионам (регион A и регион B). Это означает, что пользователь не может получить доступ к предложению, относящемуся к региону, отличному от региона A и региона B, поэтому при доступе к /offers/3 должно появиться сообщение Access Denied error.

Я могу вытащить регионы из RegionsUser:

region_ids = user.regions_users.pluck(:regions_id)

, а затем предложения:

Offer.joins(:site).where(sites: { region_id: region_ids })

Я читал об определении способностей, используя описанный блок здесь

can :update, Project, ["priority < ?", 3] do |project|
  project.priority < 3
end

но я не могу придумать никакого решения для моего случая. Буду признателен за любые идеи.

UPDATE

Это вроде работает, но вместо отображения страницы «Отказано в доступе» возникает ошибка 404 Page Not Found.

offers_controller.rb

def offer
  @offer ||= Offer.accessible_by(current_ability).find(params[:id])
end

ability.rb

if user.region_user?
  region_ids = user.regions_users.pluck(:region_id)
  can :read, Offer, site: { region_id: region_ids }
end

ОБНОВЛЕНИЕ 2

Я мог бы поймать ActiveRecord::RecordNotFound и raise CanCanCan::AccessDenied, но это обходной путь. Я ожидаю, что CanCanCan обработает часть авторизации. Я мог бы просто вытащить записи в контроллере и вызвать исключение, но это не имеет отношения к CanCanCan, не так ли?

1 Ответ

1 голос
/ 06 июня 2019

Я думаю, вам нужно load_and_authorize_resource в ваших контроллерах.Я не думаю, что это поднимет

raise CanCan::AccessDenied.new("Not authorized!", :read, Article), если вы не сделаете этого.accessible_by(currrent_ability) просто ограничил набор результатов тем, что определены в вашем файле способностей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...