Skip to content

Instantly share code, notes, and snippets.

@thermistor
Forked from pcreux/policy.rb
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thermistor/d74dcaa732218ae2eb77 to your computer and use it in GitHub Desktop.
Save thermistor/d74dcaa732218ae2eb77 to your computer and use it in GitHub Desktop.
require 'virtus'
class User
include Virtus.model
attribute :confirmed_at, Time
attribute :subscribed, Boolean, default: false
end
class Screencast
include Virtus.model
attribute :published_at, Time
attribute :public, Boolean, default: false
def private?
!public
end
end
class Policy
def self.call(*args)
new(*args).call
end
end
class IsConfirmed < Policy
include Virtus.model
attribute :user
def call
!user.confirmed_at.nil?
end
end
class IsSubscribed < Policy
include Virtus.model
attribute :user
def call
user.subscribed?
end
end
class IsPublished < Policy
include Virtus.model
attribute :screencast
def call
!!screencast.published_at
end
end
class IsPublic < Policy
include Virtus.model
attribute :screencast
def call
screencast.public?
end
end
class IsPrivate < Policy
include Virtus.model
attribute :screencast
def call
screencast.private?
end
end
def check(*args)
params = args.pop
policies = args
results = {}
policies.each do |policy|
results[policy] = policy.call(params)
end
results
end
CheckFailed = Class.new(StandardError)
def check!(*args)
results = check(*args)
failures = results.select { |k, v| v != true }
if failures.any?
raise CheckFailed, "unmet conditions: #{failures.keys}"
else
true
end
end
chuck = User.new(confirmed_at: Time.now, subscribed: true)
public_screencast = Screencast.new(published_at: Time.now, public: true)
private_screencast = Screencast.new(published_at: Time.now)
draft_screencast = Screencast.new(published_at: nil)
p check(IsConfirmed, user: chuck)
# => {IsConfirmed=>true}
p check(IsConfirmed, IsSubscribed, user: chuck)
# => {IsConfirmed=>true, IsSubscribed=>true}
p check(IsPublished, IsPublic, user: nil, screencast: public_screencast)
# => {IsPublished=>true, IsPublic=>true}
p check(IsPublished, IsPublic, user: nil, screencast: private_screencast)
# => {IsPublished=>true, IsPublic=>false}
p check(IsConfirmed, IsPublished, IsSubscribed, IsPrivate, user: chuck, screencast: private_screencast)
# => {IsConfirmed=>true, IsPublished=>true, IsSubscribed=>true, IsPrivate=>true}
p check!(IsConfirmed, IsSubscribed, IsPublished, user: chuck, screencast: draft_screencast)
# => policy.rb:98:in `check!': unmet conditions: [IsPublished] (CheckFailed)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment