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 CHANGED
@@ -1,2 +1,3 @@
1
+ rvm_gemset_create_on_use_flag=1
1
2
  rvm use 1.8.7
2
3
  rvm gemset use has_constant
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
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.5.1"
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
- self.class.send(name)[read_attribute(singular).to_i]
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
- eval("#{self.class}.#{name.to_s}[self.attributes[singular].to_i] if self.attributes[singular]")
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
@@ -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
@@ -35,6 +35,9 @@ def connect_active_record
35
35
  create_table :users, :force => true do |t|
36
36
  t.integer :salutation
37
37
  end
38
+ create_table :things, :force => true do |t|
39
+ t.string :salutation
40
+ end
38
41
  end
39
42
  end
40
43
 
@@ -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 MongoUserWithProc
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 MongoUserWithout
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
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs']
29
- assert MongoUserWithout.fields.map(&:first).include?('salutation')
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
- MongoUserWithout.send(:field, :salutation, :type => Integer, :default => 0)
34
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs']
35
- assert_equal 'Mr', MongoUserWithout.new.salutation
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
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs'], :accessor => :sal
40
- assert MongoUserWithout.fields.map(&:first).include?('sal')
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
- MongoUserWithout.has_constant :titles
46
- assert_equal ['a', 'b'], MongoUserWithout.titles
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
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs'], :index => true
51
- MongoUserWithout.create_indexes
52
- assert MongoUserWithout.index_information.keys.any? { |key| key.match(/salutation/) }
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
- MongoUser.create_indexes
57
- assert !MongoUser.index_information.keys.any? { |key| key.match(/salutation/) }
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
- m = MongoUserWithProc.new(:salutation => 'asefe')
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
- m = MongoUserWithProc.new(:salutation => '')
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: 9
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
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)