Skip to content

Instantly share code, notes, and snippets.

@apavlyut
Created May 29, 2014 07:46
Show Gist options
  • Save apavlyut/a694c61e51805aba843b to your computer and use it in GitHub Desktop.
Save apavlyut/a694c61e51805aba843b to your computer and use it in GitHub Desktop.
module Accessible
extend ActiveSupport::Concern
included do
has_many :accessibilities, as: :accessible, dependent: :destroy
has_many :roles, -> { uniq }, through: :accessibilities
scope :visible_to, ->(role_names) {
role_names = [role_names] if [String, Symbol].include?(role_names.class)
if role_names.include?(Role::ROOT_ROLE)
all
else
joins(:roles).where(roles: {title: role_names})
end
}
# validates :roles, presence: true
after_save :update_visibility
end
VISIBILITIES = {
public: %w(guest rookie patriot),
team: %w(rookie patriot)#,
# patriot: %w(patriot)
}
attr_accessor :visibility
def visible_to
roles.pluck(:title)
end
def visible_to?(role_titles)
role_titles = [role_titles] if [String, Symbol].include?(role_titles.class)
role_titles.map!{|role_name| role_name.to_s}
if role_titles.include?(Role::ROOT_ROLE)
true
else
(role_titles & roles.pluck(:title)).any?
end
end
def allow_for(role_titles = [])
role_titles = [role_titles] if [String, Symbol].include?(role_titles.class)
if role_titles && role_titles.any?
role_titles.map!{|role_name| role_name.to_s}
else
Role.pluck(:title)
return
end
role_titles.uniq.compact.each do |role_title|
role = Role.where(title: role_title).first_or_create
roles << role unless visible_to?(role.title)
end
roles
end
def update_roles(role_titles = [])
role_titles = [role_titles] if [String, Symbol].include?(role_titles.class)
if role_titles && role_titles.any?
role_titles.map!{|role_name| role_name.to_s}
else
Role.pluck(:title)
return
end
roles.destroy_all
role_titles.uniq.compact.each do |role_title|
role = Role.where(title: role_title).first_or_create
roles << role unless visible_to?(role.title)
end
roles
end
def disallow_for(role_titles = [])
role_titles = [role_titles] if [String, Symbol].include?(role_titles.class)
role_titles.map!{|role_name| role_name.to_s}
return Role.pluck(:title) if role_titles.empty?
role_titles.uniq.compact.each do |role_title|
role_titles.map!{|role_name| role_name.to_s}
role = Role.where(title: role_title).first_or_create
roles.delete role if visible_to?(role.title)
end
roles
end
private
def update_visibility
puts "AAA"
update_roles(VISIBILITIES[visibility.to_sym]) if visibility
end
end
class PostPolicy < ApplicationPolicy
class Scope < Struct.new(:user, :scope)
def resolve
if user
scope.visible_to(user.roles.pluck(:title))
else
scope.visible_to(:guest).not_notices.order(:created_at)
end
end
end
def show?
if user
record.visible_to? user.role_names
else
record.visible_to?(:guest)
end
end
def create?
deppkind? || (user && user.has_role?(:patriot))
end
def update?
deppkind? #|| (user && record.author == user)
end
def destroy?
deppkind? || (user && record.user == user)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment