Я пытаюсь создать область :readable
в моей модели Page
, чтобы вернуть все Pages
, которые current_person
имеют достаточный «ранг» для чтения:
scope :readable, lambda { |current_person| joins(:role_readable)
.where(:role_readable[:rank].gte(current_person.roles.first.rank) ) }
Я пробовал много перестановок области, в том числе эту, безуспешно (приведенная выше дает ошибку «не удается преобразовать символ в целое число»).
Проблема усложняется тем, что Users
(обрабатывающие аутентификацию и т. д. / синонимичные учетным записям) имеют_множество People
, которые представляют присутствие User
в организации, т.е. User
может быть членом нескольких организаций, но ему нужен только один способ входа в систему...
Roles
, из которых User's
People
имеет_много, дают ранг, который область использует для возврата :readable
страниц. (т. е. Users
обрабатывает аутентификацию, тогда как People
обрабатывает авторизацию (среди прочего), поскольку User
может быть членом нескольких организаций, для которых пользователь имеет разные Roles
и, следовательно, иерархию и привилегии.)
class User < ActiveRecord::Base
has_many :people
has_many :roles, through: :people
class Person < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :roles
class Role < ActiveRecord::Base
# name :string(255)
# rank :integer
has_and_belongs_to_many :people
class Page < ActiveRecord::Base
belongs_to :role_readable, class_name: "Role", foreign_key: :role_read_id
belongs_to :role_editable, class_name: "Role", foreign_key: :role_write_id
Роли имеют иерархию (например, Босс, Менеджер, Рабочий...), записанную как rank
(целое число) — чем ниже целое число, тем выше иерархия (и, следовательно, привилегия). Если какой-либо из Roles
Человека имеет ранг меньше или равен :role_readable
из Page
, то пользователь имеет право просматривать страницу.
Например. Person
с ролью Manager
может просматривать все страницы с :role_readable
из Manager
или Worker
, но не Boss
. Мне нужна область, в которой перечислены все такие читаемые страницы.
Roles
имеют default_scope, который гарантирует, что они возвращаются в порядке возрастания ранга, поэтому role.first
для Person
будет возвращать роль с наибольшей иерархией (т. е. с самым низким значением ранга).
Я использую Rails 3.2 и Postgres 9.2.2.0, поэтому меня также смущает множество доступных опций query/Arel.
Заранее спасибо!
ОБНОВЛЕНИЕ:
Если я попробую эту область:
scope :readable, lambda { |current_person| where("role_readable.rank
=> ?",current_person.roles.first.rank) }
Я получаю эту ошибку:
PGError: ERROR: missing FROM-clause entry for table "role_readable"
LINE 1: ...*) FROM "pages" WHERE "pages"."team_id" = 2 AND (role_reada...
^
: SELECT COUNT(*) FROM "pages" WHERE "pages"."team_id" = 2 AND (role_readable.rank => 1)
Я не уверен, что делать с «отсутствующим предложением FROM»