Last active
December 21, 2015 04:48
-
-
Save forest/6251831 to your computer and use it in GitHub Desktop.
Use OO instead of basic ruby types to represent Rights
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ALL_RIGHTS = [ | |
CAN_ACCESS_RESOURCES, | |
CAN_ACCESS_ORGANIZATIONS, | |
CAN_CREATE_ORGANIZATIONS, | |
CAN_ACCESS_SCHOOL_EDITION | |
] | |
# --------------------------- | |
class Rights | |
extend Forwardable | |
def_delegators :@rights, :each | |
def initialize(*rights) | |
@rights = rights | |
end | |
def cache_key | |
Digest::MD5.hexdigest(@rights.map(&:cache_key).join) | |
end | |
end | |
class Right | |
attr_accessor :name, :version | |
def initialize(name, version) | |
@name = name | |
@version = version | |
end | |
def to_s | |
name | |
end | |
def to_sym | |
name.to_sym | |
end | |
def cache_key | |
Digest::MD5.hexdigest([name, version].join) | |
end | |
end | |
ALL_RIGHTS = Rights.new( | |
Right.new('CAN_ACCESS_RESOURCES', 1), | |
Right.new('CAN_ACCESS_ORGANIZATIONS', 1), | |
Right.new('CAN_CREATE_ORGANIZATIONS', 1), | |
Right.new('CAN_ACCESS_SCHOOL_EDITION', 1) | |
) | |
# -------- OR ---------------- | |
class Right | |
def name | |
self.class.name.split('::').last.underscorize | |
end | |
def to_s | |
name | |
end | |
def to_sym | |
name.to_sym | |
end | |
def cache_key | |
Digest::MD5.hexdigest([name, version].join) | |
end | |
end | |
class CanAccessResources < Right | |
def version; 1; end | |
end | |
ALL_RIGHTS = Rights.new( | |
CanAccessResources.new | |
) | |
# ------------------------------ | |
# The key to working productively in an object-oriented language is to make the type system and polymorphic method dispatch do your work for you. When | |
# dealing with string (or Symbol) values coming from the "borders" of our code, it can be tempting to simply ensure that they are in the expected set | |
# of valid values, and leave it at that. However, when we look deeper we may discover a distinct concept struggling to emerge. Representing this concept | |
# as a class or set of classes can not only make the code less error-prone; it can clarify our understanding of the problem, and improve the design of | |
# all the classes which deal with that concept. This, in turn, means methods which spend less time reiterating input checks, and more time telling a | |
# clear story. | |
# - Avdi (Confident Ruby) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment