Class: ConstantEnum::Base
- Inherits:
-
Struct
- Object
- Struct
- ConstantEnum::Base
- Extended by:
- Enumerable
- Defined in:
- lib/constant_enum/base.rb
Overview
This supports the creation of a constant class that is designed to work well with ActiveRecord enums. The benefit is you get additional functionality, like finders and slugs. Performance is excellent as these are in-memory structures and not DB calls.
In the simplest structure, you specify a name and an integer ID:
class Genre < ConstantEnum::Base
enum_of skate: 1,
surf: 2,
snow: 3,
bike: 4,
end
Then, in an ActiveRecord class that wants to use this enum:
class Video < ActiveRecord::Base
enum genre: Genre.enum
...
end
From there, you can now do things like:
@genre = Genre.find_by_name!(:skate)
@videos = Video.where(genre: genre)
Interesting routes can be created like:
# /videos/bike, /videos/surf, etc
get 'videos/:genre' => 'videos#index', as: 'videos_genre',
constraints: { genre: Genre.all.map(&:slug) }
If you have extra data for your enum, you can specify a hash:
class AssetType < ConstantEnum::Base
enum_of \
photo: {id: 1, type: 'jpg', bucket: 'photos'},
video: {id: 2, type: 'mp4', bucket: 'videos'}
Instance Attribute Summary collapse
-
#attributes ⇒ Object
Returns the value of attribute attributes.
-
#id ⇒ Object
Returns the value of attribute id.
-
#name ⇒ Object
Returns the value of attribute name.
Class Method Summary collapse
- .[](what) ⇒ Object
- .all ⇒ Object
- .count ⇒ Object
-
.dropdown ⇒ Object
Dropdown is actually [Title, name] for Rails 4.1 enums.
-
.each(&block) ⇒ Object
Enumerable support.
-
.enum ⇒ Object
Just return the hash.
- .enum_of(hash) ⇒ Object
- .find(id) ⇒ Object
- .find_by(hash) ⇒ Object
- .find_by!(hash) ⇒ Object
- .find_by_id(id) ⇒ Object
- .find_by_name(name) ⇒ Object
- .find_by_name!(name) ⇒ Object
- .find_by_slug(slug) ⇒ Object
- .find_by_slug!(slug) ⇒ Object
- .ids ⇒ Object
- .names ⇒ Object
-
.where(hash = {}) ⇒ Object
Allow simple detection, similar to ActiveRecord.
Instance Method Summary collapse
-
#method_missing(meth, *args, &block) ⇒ Object
Handle extra attribute methods like .label or .delivery_type.
-
#slug ⇒ Object
Instance methods: @role = Role.new ; @role.slug.
- #title ⇒ Object
- #to_param ⇒ Object
- #to_s ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object
Handle extra attribute methods like .label or .delivery_type
182 183 184 185 186 187 188 |
# File 'lib/constant_enum/base.rb', line 182 def method_missing(meth, *args, &block) if attributes.has_key?(meth) attributes[meth] else super end end |
Instance Attribute Details
#attributes ⇒ Object
Returns the value of attribute attributes
43 44 45 |
# File 'lib/constant_enum/base.rb', line 43 def attributes @attributes end |
#id ⇒ Object
Returns the value of attribute id
43 44 45 |
# File 'lib/constant_enum/base.rb', line 43 def id @id end |
#name ⇒ Object
Returns the value of attribute name
43 44 45 |
# File 'lib/constant_enum/base.rb', line 43 def name @name end |
Class Method Details
.[](what) ⇒ Object
72 73 74 75 76 77 78 |
# File 'lib/constant_enum/base.rb', line 72 def self.[](what) if what.is_a?(Integer) find(what).id else find_by_name!(what).id end end |
.all ⇒ Object
114 115 116 |
# File 'lib/constant_enum/base.rb', line 114 def self.all where() end |
.count ⇒ Object
153 154 155 |
# File 'lib/constant_enum/base.rb', line 153 def self.count enum.keys.length end |
.dropdown ⇒ Object
Dropdown is actually [Title, name] for Rails 4.1 enums
158 159 160 |
# File 'lib/constant_enum/base.rb', line 158 def self.dropdown enum.collect{|name,id| [name.to_s.titleize, name] } end |
.each(&block) ⇒ Object
Enumerable support
140 141 142 |
# File 'lib/constant_enum/base.rb', line 140 def self.each(&block) all.each(&block) end |
.enum ⇒ Object
Just return the hash. For use in ActiveRecord models, eg “enum role: Role.enum”
67 68 69 |
# File 'lib/constant_enum/base.rb', line 67 def self.enum @enum end |
.enum_of(hash) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/constant_enum/base.rb', line 46 def self.enum_of(hash) raise ArgumentError, "#{self}.enum_of name1: id2, name2: id2" unless hash.is_a?(Hash) @data = {} @enum = {} hash.each do |name,value| if value.is_a?(Hash) @enum[name] = value[:id] # for Rails @data[name] = new(name, value[:id], value) else @enum[name] = value # for Rails @data[name] = new(name, value) end # Create constants such as ADMIN=1 etc const_name = name.to_s.upcase.strip.gsub(/[-\s]+/,'_').sub(/^[0-9_]+/,'').gsub(/\W+/,'') const_set const_name, @enum[name] unless const_defined?(const_name) end end |
.find(id) ⇒ Object
96 97 98 |
# File 'lib/constant_enum/base.rb', line 96 def self.find(id) find_by!(id: id) end |
.find_by(hash) ⇒ Object
104 105 106 |
# File 'lib/constant_enum/base.rb', line 104 def self.find_by(hash) where(hash).first end |
.find_by!(hash) ⇒ Object
108 109 110 111 112 |
# File 'lib/constant_enum/base.rb', line 108 def self.find_by!(hash) find_by(hash) or raise RecordNotFound, %Q(Couldn't find #{self} with #{hash.collect{|k,v| "#{k}=#{v.inspect}"} * ' '}) end |
.find_by_id(id) ⇒ Object
100 101 102 |
# File 'lib/constant_enum/base.rb', line 100 def self.find_by_id(id) find(id) rescue nil end |
.find_by_name(name) ⇒ Object
84 85 86 |
# File 'lib/constant_enum/base.rb', line 84 def self.find_by_name(name) find_by_name!(name) rescue nil end |
.find_by_name!(name) ⇒ Object
80 81 82 |
# File 'lib/constant_enum/base.rb', line 80 def self.find_by_name!(name) find_by!(name: name) end |
.find_by_slug(slug) ⇒ Object
92 93 94 |
# File 'lib/constant_enum/base.rb', line 92 def self.find_by_slug(slug) find_by!(slug: slug) rescue nil end |
.find_by_slug!(slug) ⇒ Object
88 89 90 |
# File 'lib/constant_enum/base.rb', line 88 def self.find_by_slug!(slug) find_by!(slug: slug) end |
.ids ⇒ Object
145 146 147 |
# File 'lib/constant_enum/base.rb', line 145 def self.ids enum.map{|r| r.last} end |
.names ⇒ Object
149 150 151 |
# File 'lib/constant_enum/base.rb', line 149 def self.names enum.map{|r| r.first} end |
.where(hash = {}) ⇒ Object
Allow simple detection, similar to ActiveRecord. This method is a little verbose because we need to mimic where({}) which returns everything. It also supports where(type: ‘video’, active: true) for multiple restrictions.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/constant_enum/base.rb', line 121 def self.where(hash={}) raise RecordNotFound, "No records defined for #{self}" if @data.nil? results = [] @data.each do |name,struct| found = true # where({}) hash.each do |k,v| if k.to_s == 'name' found = false if name.to_s != v.to_s else found = false if struct.send(k) != v end end # for where({}) results << struct if found end results end |
Instance Method Details
#slug ⇒ Object
Instance methods: @role = Role.new ; @role.slug
165 166 167 |
# File 'lib/constant_enum/base.rb', line 165 def slug name.to_s.downcase.gsub(/\W+/,'') end |
#title ⇒ Object
169 170 171 |
# File 'lib/constant_enum/base.rb', line 169 def title name.to_s.titleize end |
#to_param ⇒ Object
177 178 179 |
# File 'lib/constant_enum/base.rb', line 177 def to_param id.to_s end |
#to_s ⇒ Object
173 174 175 |
# File 'lib/constant_enum/base.rb', line 173 def to_s name.to_s end |