activerecord-enumerations 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/enumerations.rb +133 -0
  2. metadata +61 -0
@@ -0,0 +1,133 @@
1
+ # i want to be able to write
2
+ # DogType < Enumeration
3
+ # enumerate_values :pekinezer, :bulldog, :jack_russell
4
+ #
5
+ # enumerate_values :pekinezer => 'Jako lijepi pekinezer'
6
+ # end
7
+ #
8
+ # DogType.all => [DogType, DogType, DogType]
9
+ # DogType.find(id) => DogType
10
+ #
11
+ # if something == DogType.pekinezer # => <#DogType>
12
+ # if something == DogType::Pekinezer # => <#DogType> # => TODO
13
+ # if something == DogType[:pekinezer] # => <#DogType> # => TODO
14
+ #
15
+ # So we have
16
+ # * id (numeric). used in database
17
+ # * lookup method (for comparison), symbol basically, used in source code
18
+ # * name. used in user interface
19
+ #
20
+ # Status.draft?
21
+ # Status.review_pending?
22
+ #
23
+ # TODO
24
+ # - http://github.com/binarylogic/enumlogic/blob/master/lib/enumlogic.rb
25
+ # - http://github.com/eeng/ar-enums
26
+ # - think about storing strings, not integers
27
+ module Enumeration
28
+ def self.included(receiver)
29
+ receiver.extend ClassMethods
30
+ end
31
+
32
+ module ClassMethods
33
+ # create an enumeration for the symbol <tt>name</tt>. Options include <tt>foreign key</tt> attribute and Class name
34
+ def enumeration(name, options = {})
35
+ options[:foreign_key] ||= "#{name}_id".to_sym
36
+ options[:class_name] ||= name.to_s.camelize
37
+
38
+ # getter for belongs_to
39
+ define_method name do
40
+ options[:class_name].constantize.find(send(options[:foreign_key]))
41
+ end
42
+
43
+ # setter for belongs_to
44
+ define_method "#{name}=" do |other|
45
+ send("#{options[:foreign_key]}=", other.id)
46
+ end
47
+ end
48
+ end
49
+
50
+ class Base < Struct.new(:id, :name, :symbol)
51
+ class_attribute :all, :id_index, :symbol_index
52
+
53
+ def singleton_class
54
+ class << self
55
+ self
56
+ end
57
+ end
58
+
59
+ def self.values(values)
60
+ # all values
61
+ self.all = []
62
+ # for id based lookup
63
+ self.id_index = {}
64
+ # for symbol based lookup
65
+ self.symbol_index = {}
66
+
67
+ values.each_pair do |symbol, attributes|
68
+ attributes[:name] ||= symbol.to_s.humanize
69
+ object = self.new(attributes[:id], attributes[:name], symbol)
70
+
71
+ self.singleton_class.send(:define_method, symbol) do
72
+ object
73
+ end
74
+
75
+ raise "Duplicate id #{attributes[:id]}" if self.id_index[attributes[:id]]
76
+ raise "Duplicate symbol #{symbol}" if self.symbol_index[symbol]
77
+
78
+ self.id_index[attributes[:id]] = object
79
+ self.symbol_index[symbol] = object
80
+ self.all << object
81
+ end
82
+ end
83
+
84
+ # lookup a specific enum
85
+ def self.find(id)
86
+ if id.is_a?(Fixnum)
87
+ self.id_index[id]
88
+ elsif id.is_a?(Symbol) || id.is_a?(String)
89
+ self.symbol_index[id.to_sym]
90
+ end
91
+ end
92
+
93
+ # FIXME for some reason this doesn't work for case..when expressions
94
+ def ==(object)
95
+ if object.is_a?(Fixnum)
96
+ object == self.id
97
+ elsif object.is_a?(Symbol)
98
+ object == self.symbol
99
+ elsif object.is_a?(self.class)
100
+ object.id == self.id
101
+ end
102
+ end
103
+
104
+ # TODO alias method??
105
+ def to_s
106
+ name
107
+ end
108
+
109
+ def to_i
110
+ id
111
+ end
112
+
113
+ def to_sym
114
+ symbol
115
+ end
116
+
117
+ def to_param
118
+ id
119
+ end
120
+
121
+ def method_missing(method_name, *args)
122
+ symbol = method_name.to_s.gsub(/[?]$/, '')
123
+ if self.class.find(symbol) && method_name.to_s.last=="?"
124
+ self.symbol == symbol.to_sym
125
+ else
126
+ super(method_name, args)
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # Extend ActiveRecord with Enumeration capabilites
133
+ ActiveRecord::Base.send(:include, Enumeration)
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-enumerations
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tomislav Car
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2010-04-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Extends ActiveRecord with enumeration capabilites.
31
+ email: carr@infinum.hr
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - lib/enumerations.rb
37
+ homepage: http://rubygems.org/gems/activerecord-enumerations
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.23
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Enumerations for activerecord!
61
+ test_files: []