has_constant 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rvmrc +1 -0
- data/VERSION +1 -1
- data/has_constant.gemspec +1 -4
- data/lib/has_constant/orm/active_model.rb +8 -2
- data/lib/has_constant/orm/mongoid.rb +9 -3
- data/lib/has_constant.rb +4 -1
- data/test/has_constant_test.rb +7 -0
- data/test/helper.rb +3 -0
- data/test/unit/orm/active_model_test.rb +19 -0
- data/test/unit/orm/mongoid_test.rb +40 -23
- metadata +4 -7
- data/lib/has_constant/orm/active_record.rb +0 -65
- data/test/unit/orm/active_record_test.rb +0 -40
data/.rvmrc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/has_constant.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{has_constant}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["mattbeedle"]
|
@@ -28,12 +28,10 @@ Gem::Specification.new do |s|
|
|
28
28
|
"has_constant.gemspec",
|
29
29
|
"lib/has_constant.rb",
|
30
30
|
"lib/has_constant/orm/active_model.rb",
|
31
|
-
"lib/has_constant/orm/active_record.rb",
|
32
31
|
"lib/has_constant/orm/mongoid.rb",
|
33
32
|
"test/has_constant_test.rb",
|
34
33
|
"test/helper.rb",
|
35
34
|
"test/unit/orm/active_model_test.rb",
|
36
|
-
"test/unit/orm/active_record_test.rb",
|
37
35
|
"test/unit/orm/mongoid_test.rb"
|
38
36
|
]
|
39
37
|
s.homepage = %q{http://github.com/mattbeedle/has_constant}
|
@@ -44,7 +42,6 @@ Gem::Specification.new do |s|
|
|
44
42
|
"test/has_constant_test.rb",
|
45
43
|
"test/helper.rb",
|
46
44
|
"test/unit/orm/active_model_test.rb",
|
47
|
-
"test/unit/orm/active_record_test.rb",
|
48
45
|
"test/unit/orm/mongoid_test.rb"
|
49
46
|
]
|
50
47
|
|
@@ -13,13 +13,19 @@ module HasConstant
|
|
13
13
|
# the stored value
|
14
14
|
define_method(singular) do
|
15
15
|
if read_attribute(singular)
|
16
|
-
|
16
|
+
if values.is_a?(Array)
|
17
|
+
self.class.send(name)[read_attribute(singular).to_i]
|
18
|
+
elsif values.is_a?(Hash)
|
19
|
+
self.class.send(name)[read_attribute(singular)]
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
24
|
define_method("#{singular}=") do |val|
|
21
|
-
if val.instance_of?(String)
|
25
|
+
if values.is_a?(Array) && val.instance_of?(String)
|
22
26
|
write_attribute singular.to_sym, self.class.send(name.to_s).index(val)
|
27
|
+
elsif values.is_a?(Hash) && values.has_value?(val)
|
28
|
+
write_attribute singular.to_sym, values.invert[val].to_s
|
23
29
|
else
|
24
30
|
write_attribute singular.to_sym, val
|
25
31
|
end
|
@@ -23,7 +23,7 @@ module HasConstant
|
|
23
23
|
|
24
24
|
class_eval do
|
25
25
|
unless fields.map(&:first).include?(singular.to_s)
|
26
|
-
field singular.to_sym, { :type => Integer }.merge(options)
|
26
|
+
field singular.to_sym, { :type => values.is_a?(Array) ? Integer : String }.merge(options)
|
27
27
|
end
|
28
28
|
|
29
29
|
index singular.to_sym, :background => true if options[:index]
|
@@ -34,8 +34,10 @@ module HasConstant
|
|
34
34
|
|
35
35
|
define_method("#{singular}=") do |val|
|
36
36
|
if val.instance_of?(String)
|
37
|
-
if index = self.class.send(name.to_s).index(val)
|
37
|
+
if values.is_a?(Array) && index = self.class.send(name.to_s).index(val)
|
38
38
|
write_attribute singular.to_sym, index
|
39
|
+
elsif values.is_a?(Hash) && values.has_value?(val)
|
40
|
+
write_attribute singular.to_sym, values.invert[val]
|
39
41
|
elsif !val.blank?
|
40
42
|
values = values.call if values.respond_to?(:call)
|
41
43
|
@has_constant_errors ||= {}
|
@@ -48,7 +50,11 @@ module HasConstant
|
|
48
50
|
|
49
51
|
# Add the getter method. This returns the string representation of the stored value
|
50
52
|
define_method(singular) do
|
51
|
-
|
53
|
+
if values.is_a?(Array)
|
54
|
+
self.class.send(name.to_s)[attributes[singular].to_i] if attributes[singular]
|
55
|
+
else
|
56
|
+
self.class.send(name.to_s)[attributes[singular]] if attributes[singular]
|
57
|
+
end
|
52
58
|
end
|
53
59
|
|
54
60
|
(class << self; self; end).instance_eval do
|
data/lib/has_constant.rb
CHANGED
@@ -42,6 +42,7 @@ module HasConstant
|
|
42
42
|
singular = (options[:accessor] || name.to_s.singularize).to_s
|
43
43
|
|
44
44
|
(class << self; self; end).instance_eval do
|
45
|
+
values = HashWithIndifferentAccess.new(values) if values.is_a?(Hash)
|
45
46
|
define_method(name.to_s, values) if values.respond_to?(:call)
|
46
47
|
define_method(name.to_s, lambda { values }) unless values.respond_to?(:call)
|
47
48
|
end
|
@@ -53,8 +54,10 @@ module HasConstant
|
|
53
54
|
# Add the setter method. This takes the string representation and converts it to an integer to store in the DB
|
54
55
|
define_method("#{singular}=") do |val|
|
55
56
|
if val.instance_of?(String)
|
56
|
-
if values.index(val)
|
57
|
+
if values.is_a?(Array) && values.index(val)
|
57
58
|
instance_variable_set("@#{singular}", values.index(val))
|
59
|
+
elsif values.is_a?(Hash) && values.has_value?(val)
|
60
|
+
instance_variable_set("@#{singular}", values.invert[val].to_s)
|
58
61
|
else
|
59
62
|
raise ArgumentError, "value for #{singular} must be in #{self.class.send(name.to_s).join(', ')}"
|
60
63
|
end
|
data/test/has_constant_test.rb
CHANGED
@@ -7,6 +7,13 @@ end
|
|
7
7
|
|
8
8
|
class TestHasConstant < Test::Unit::TestCase
|
9
9
|
|
10
|
+
should 'be able to store values in a hash' do
|
11
|
+
Model.has_constant :salutations, { :first => 'Mr', :second => 'Mrs' }
|
12
|
+
m = Model.new
|
13
|
+
m.salutation = 'Mr'
|
14
|
+
assert m.instance_variable_get("@salutation") == 'first'
|
15
|
+
end
|
16
|
+
|
10
17
|
should 'default values to translated values list' do
|
11
18
|
I18n.stubs(:t).returns(['a', 'b'])
|
12
19
|
Model.has_constant :titles
|
data/test/helper.rb
CHANGED
@@ -7,8 +7,27 @@ class User < ActiveRecord::Base
|
|
7
7
|
include HasConstant
|
8
8
|
end
|
9
9
|
|
10
|
+
class Thing < ActiveRecord::Base
|
11
|
+
include HasConstant
|
12
|
+
end
|
13
|
+
|
10
14
|
class ActiveModelTest < Test::Unit::TestCase
|
11
15
|
context 'Instance' do
|
16
|
+
context 'using a hash' do
|
17
|
+
setup do
|
18
|
+
Thing.has_constant :salutations, { :first => 'Mr', :second => 'Mrs' }
|
19
|
+
@u = Thing.new :salutation => 'Mrs'
|
20
|
+
end
|
21
|
+
|
22
|
+
should 'store the hash key' do
|
23
|
+
assert_equal 'second', @u.attributes['salutation']
|
24
|
+
end
|
25
|
+
|
26
|
+
should 'return the correct value' do
|
27
|
+
assert_equal 'Mrs', @u.salutation
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
12
31
|
should 'save values as integers' do
|
13
32
|
User.has_constant :salutations, %w(Mr Mrs)
|
14
33
|
u = User.new(:salutation => 'Mr')
|
@@ -6,58 +6,71 @@ setup_mongoid
|
|
6
6
|
class MongoUser
|
7
7
|
include Mongoid::Document
|
8
8
|
include HasConstant
|
9
|
-
|
10
|
-
has_constant :salutations, ['Mr', 'Mrs']
|
11
9
|
end if defined?(Mongoid)
|
12
10
|
|
13
|
-
class
|
11
|
+
class MongoUser2
|
14
12
|
include Mongoid::Document
|
15
13
|
include HasConstant
|
16
|
-
|
17
|
-
has_constant :salutations, lambda { ['Mr', 'Mrs'] }
|
18
14
|
end if defined?(Mongoid)
|
19
15
|
|
20
|
-
class
|
16
|
+
class MongoUserWithHash
|
21
17
|
include Mongoid::Document
|
22
18
|
include HasConstant
|
23
|
-
end
|
19
|
+
end if defined?(Mongoid)
|
24
20
|
|
25
21
|
class MongoidTest < Test::Unit::TestCase
|
26
22
|
context 'Instance' do
|
23
|
+
|
24
|
+
context 'using a hash' do
|
25
|
+
setup do
|
26
|
+
MongoUserWithHash.has_constant :salutations, { :first => 'Mr', :second => 'Mrs' }
|
27
|
+
@m = MongoUserWithHash.new(:salutation => 'Mr')
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'store the hash key' do
|
31
|
+
assert_equal 'first', @m.attributes['salutation']
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'return the correct value' do
|
35
|
+
assert_equal 'Mr', @m.salutation
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
27
39
|
should 'add the field automatically' do
|
28
|
-
|
29
|
-
assert
|
40
|
+
MongoUser.has_constant :salutations, ['Mr', 'Mrs']
|
41
|
+
assert MongoUser.fields.map(&:first).include?('salutation')
|
30
42
|
end
|
31
43
|
|
32
44
|
should 'not add the field if it is already there' do
|
33
|
-
|
34
|
-
|
35
|
-
assert_equal 'Mr',
|
45
|
+
MongoUser.send(:field, :salutation, :type => Integer, :default => 0)
|
46
|
+
MongoUser.has_constant :salutations, ['Mr', 'Mrs']
|
47
|
+
assert_equal 'Mr', MongoUser.new.salutation
|
36
48
|
end
|
37
49
|
|
38
50
|
should 'take the accessor into account when adding the field' do
|
39
|
-
|
40
|
-
assert
|
51
|
+
MongoUser.has_constant :salutations, ['Mr', 'Mrs'], :accessor => :sal
|
52
|
+
assert MongoUser.fields.map(&:first).include?('sal')
|
41
53
|
end
|
42
54
|
|
43
55
|
should 'default values to translated values list' do
|
44
56
|
I18n.stubs(:t).returns(['a', 'b'])
|
45
|
-
|
46
|
-
assert_equal ['a', 'b'],
|
57
|
+
MongoUser.has_constant :titles
|
58
|
+
assert_equal ['a', 'b'], MongoUser.titles
|
47
59
|
end
|
48
60
|
|
49
61
|
should 'add index when index option is supplied' do
|
50
|
-
|
51
|
-
|
52
|
-
assert
|
62
|
+
MongoUser.has_constant :salutations, ['Mr', 'Mrs'], :index => true
|
63
|
+
MongoUser.create_indexes
|
64
|
+
assert MongoUser.index_information.keys.any? { |key| key.match(/salutation/) }
|
53
65
|
end
|
54
66
|
|
55
67
|
should 'not index when index option is not supplied' do
|
56
|
-
|
57
|
-
assert !
|
68
|
+
MongoUser2.create_indexes
|
69
|
+
assert !MongoUser2.index_information.keys.any? { |key| key.match(/salutation/) }
|
58
70
|
end
|
59
71
|
|
60
72
|
should 'save values as integers' do
|
73
|
+
MongoUser.has_constant :salutations, %w(Mr Mrs)
|
61
74
|
m = MongoUser.new(:salutation => 'Mr')
|
62
75
|
m.save!
|
63
76
|
assert_equal 'Mr', m.salutation
|
@@ -65,25 +78,29 @@ class MongoidTest < Test::Unit::TestCase
|
|
65
78
|
end
|
66
79
|
|
67
80
|
should 'not be valid when an incorrect value is supplied' do
|
81
|
+
MongoUser.has_constant :salutations, %w(Mr Mrs)
|
68
82
|
m = MongoUser.new(:salutation => 'asefe')
|
69
83
|
assert !m.valid?
|
70
84
|
assert_equal ['must be one of Mr, Mrs'], m.errors[:salutation]
|
71
85
|
end
|
72
86
|
|
73
87
|
should 'not be valid with an incorrect value is supplied and a proc/lambda has been used' do
|
74
|
-
|
88
|
+
MongoUser.has_constant :salutations, Proc.new { %w(Mr Mrs) }
|
89
|
+
m = MongoUser.new(:salutation => 'asefe')
|
75
90
|
assert !m.valid?
|
76
91
|
assert_equal ['must be one of Mr, Mrs'], m.errors[:salutation]
|
77
92
|
end
|
78
93
|
|
79
94
|
should 'be valid when a blank value is supplied' do
|
80
|
-
|
95
|
+
MongoUser.has_constant :salutations, Proc.new { %w(Mr Mrs) }
|
96
|
+
m = MongoUser.new(:salutation => '')
|
81
97
|
assert m.valid?
|
82
98
|
end
|
83
99
|
end
|
84
100
|
|
85
101
|
context 'Named Scopes' do
|
86
102
|
setup do
|
103
|
+
MongoUser.has_constant :salutations, %w(Mr Mrs)
|
87
104
|
@man = MongoUser.create!(:salutation => 'Mr')
|
88
105
|
@woman = MongoUser.create!(:salutation => 'Mrs')
|
89
106
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_constant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 6
|
9
|
+
- 0
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- mattbeedle
|
@@ -81,12 +81,10 @@ files:
|
|
81
81
|
- has_constant.gemspec
|
82
82
|
- lib/has_constant.rb
|
83
83
|
- lib/has_constant/orm/active_model.rb
|
84
|
-
- lib/has_constant/orm/active_record.rb
|
85
84
|
- lib/has_constant/orm/mongoid.rb
|
86
85
|
- test/has_constant_test.rb
|
87
86
|
- test/helper.rb
|
88
87
|
- test/unit/orm/active_model_test.rb
|
89
|
-
- test/unit/orm/active_record_test.rb
|
90
88
|
- test/unit/orm/mongoid_test.rb
|
91
89
|
has_rdoc: true
|
92
90
|
homepage: http://github.com/mattbeedle/has_constant
|
@@ -126,5 +124,4 @@ test_files:
|
|
126
124
|
- test/has_constant_test.rb
|
127
125
|
- test/helper.rb
|
128
126
|
- test/unit/orm/active_model_test.rb
|
129
|
-
- test/unit/orm/active_record_test.rb
|
130
127
|
- test/unit/orm/mongoid_test.rb
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module HasConstant
|
2
|
-
module Orm
|
3
|
-
module ActiveRecord
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def has_constant( name, values, options = {} )
|
8
|
-
super(name, values, options)
|
9
|
-
|
10
|
-
singular = (options[:accessor] || name.to_s.singularize).to_s
|
11
|
-
|
12
|
-
# Add the getter method. This returns the string representation of
|
13
|
-
# the stored value
|
14
|
-
define_method(singular) do
|
15
|
-
if read_attribute(singular)
|
16
|
-
self.class.send(name)[read_attribute(singular).to_i]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
define_method("#{singular}=") do |val|
|
21
|
-
if val.instance_of?(String)
|
22
|
-
write_attribute singular.to_sym, self.class.send(name.to_s).index(val)
|
23
|
-
else
|
24
|
-
write_attribute singular.to_sym, val
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class_eval do
|
29
|
-
if respond_to?(:scope)
|
30
|
-
scope :by_constant, lambda { |constant,value| { :conditions =>
|
31
|
-
{ constant.to_sym =>
|
32
|
-
eval("#{self.to_s}.#{constant.pluralize}.index(value)") } } }
|
33
|
-
|
34
|
-
scope "#{singular}_is".to_sym, lambda { |*values| { :conditions =>
|
35
|
-
{ singular.to_sym => indexes_for(name, values) }
|
36
|
-
} }
|
37
|
-
|
38
|
-
scope "#{singular}_is_not".to_sym, lambda { |*values| {
|
39
|
-
:conditions => ["#{singular} NOT IN (?)",
|
40
|
-
indexes_for(name, values)] } }
|
41
|
-
else
|
42
|
-
named_scope :by_constant, lambda { |constant,value| {
|
43
|
-
:conditions =>
|
44
|
-
{ constant.to_sym =>
|
45
|
-
eval("#{self.to_s}.#{constant.pluralize}.index(value)") } } }
|
46
|
-
|
47
|
-
named_scope "#{singular}_is".to_sym, lambda { |*values| {
|
48
|
-
:conditions => { singular.to_sym => indexes_for(name, values) }
|
49
|
-
} }
|
50
|
-
|
51
|
-
named_scope "#{singular}_is_not".to_sym, lambda { |*values| {
|
52
|
-
:conditions => ["#{singular} NOT IN (?)",
|
53
|
-
indexes_for(name, values)] } }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
def indexes_for( name, values )
|
60
|
-
values.map { |v| self.send(name.to_sym).index(v) }
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
setup_active_record
|
4
|
-
|
5
|
-
class User < ActiveRecord::Base
|
6
|
-
include HasConstant
|
7
|
-
|
8
|
-
has_constant :salutations, ['Mr', 'Mrs']
|
9
|
-
end
|
10
|
-
|
11
|
-
class ActiveRecordTest < Test::Unit::TestCase
|
12
|
-
should 'save values as integers' do
|
13
|
-
u = User.new(:salutation => 'Mr')
|
14
|
-
u.save!
|
15
|
-
assert_equal 'Mr', u.salutation
|
16
|
-
assert_equal 0, u.attributes['salutation']
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'scopes' do
|
20
|
-
setup do
|
21
|
-
@man = User.create!(:salutation => 'Mr')
|
22
|
-
@woman = User.create!(:salutation => 'Mrs')
|
23
|
-
end
|
24
|
-
|
25
|
-
should 'provide by_constant scope' do
|
26
|
-
assert_equal 1, User.by_constant('salutation', 'Mr').count
|
27
|
-
assert_equal @man, User.by_constant('salutation', 'Mr').first
|
28
|
-
end
|
29
|
-
|
30
|
-
should 'provide singular_is scope' do
|
31
|
-
assert_equal 1, User.salutation_is('Mr').count
|
32
|
-
assert_equal @man, User.salutation_is('Mr').first
|
33
|
-
end
|
34
|
-
|
35
|
-
should 'provide singular_is_not scope' do
|
36
|
-
assert_equal 1, User.salutation_is_not('Mr').count
|
37
|
-
assert_equal @woman, User.salutation_is_not('Mr').first
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end if defined?(ActiveRecord)
|