galetahub-enum_field 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96da53c393009eaee6d98a66b4107c243577a44c
4
- data.tar.gz: 7c17bffc0d29bfdb5b8399341031bb296f287835
3
+ metadata.gz: d8fe01fd9a421a42a8bc5a49fc1f1f57d78b3ef8
4
+ data.tar.gz: 3b86f719ab1b2dc329af61fca85ffff9e797bf42
5
5
  SHA512:
6
- metadata.gz: 4ae37aca910cbef3b82a0a67ea4003368c5b832654fcd404b9e45d4e986bbe5f371c2b10f2381c9448d92c064e2111ca487b09cb2937c39d94da306b7ba8a764
7
- data.tar.gz: fca89c19f39e43eadca5395b860d3d3fc9d6b8a669dd0ad37820d5511a25e1a6bce8f86f442aa95e716ac6c69edb641e5667b70129ef8bb5786dbafae71e1e70
6
+ metadata.gz: c51540d123b2444fbc79dcde8457590960911e5147d19aac45931eda9ce5aa842efe64bd95e5fa3e258e5699e51d9fe3b47c33348290be6dfd9040d003f634e8
7
+ data.tar.gz: 744b7af8a17cf2c2ee51f5a1d154a42ad03926a2a5e8f72943d63f5053110f658a7ce2bfe97c50f7ed2ad3040fd9e7cffc6df90b415ebd40f5d01e782beb7446
data/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # enum_field
2
+
3
+ [![Build Status](https://semaphoreci.com/api/v1/igor-galeta/enum_field/branches/master/shields_badge.svg)](https://semaphoreci.com/igor-galeta/enum_field)
4
+ [![Code Climate](https://codeclimate.com/github/galetahub/enum_field/badges/gpa.svg)](https://codeclimate.com/github/galetahub/enum_field)
5
+
6
+ Enables Active Record attributes to point to enum like objects, by saving in your database
7
+ only an integer ID.
8
+
9
+ ## INSTALL:
10
+
11
+ gem 'galetahub-enum_field', require: 'enum_field'
12
+
13
+ ## FEATURES:
14
+
15
+ * Allows creation of Classes with enum like behaviour.
16
+ * Allows any number of members and methods in the enum classes.
17
+ * Allows an integer id to be used in your database columns to link to the enum members (user.role_id)
18
+ * Enables higher abstraction interaction with +AR+ attributes:
19
+ * <code>user.role = Role.admin</code>
20
+ * <code>if user.role.can_edit?</code>
21
+ * Saves in your +AR+ tables, only an integer id pointing to the enumeration member.
22
+
23
+ ## SYNOPSIS:
24
+
25
+ When in an Active Record class, you have an attribute like role, state or country you have
26
+ several options.
27
+
28
+ * You can create a roles, states or countries table, and dump there all possible values.
29
+ * You can use a string to identify, for instance, the role.
30
+ * You can use an id to identify the role.
31
+
32
+ If you are not comfortable with any of this options, maybe +enum_field+ is an answer for you.
33
+
34
+ ## BASIC USAGE:
35
+
36
+ Define rules:
37
+
38
+ ``` ruby
39
+ class Role
40
+ include EnumField::DefineEnum
41
+
42
+ define_enum do
43
+ member :admin
44
+ member :manager
45
+ member :employee
46
+ end
47
+ end
48
+
49
+ class User < ActiveRecord::Base
50
+ extend EnumField::EnumeratedAttribute
51
+
52
+ # in the database table there is a role_id integer column
53
+ enumerated_attribute :role
54
+ end
55
+ ```
56
+
57
+ Usage:
58
+
59
+ ``` ruby
60
+ user.role = Role.manager
61
+ user.role_id == Role.manager.id # will be true
62
+
63
+ Role.manager.name # :manager
64
+ user.role.name # :manager
65
+
66
+ User.first.role.id == User.first.role_id # will be true
67
+
68
+ Role[:manager] == Role.manager # will be true
69
+ Role['manager'] == Role.manager # will be true
70
+
71
+ instance = Role[:employee]
72
+ instance.admin? # false
73
+ instance.employee? # true
74
+ ```
75
+
76
+ Your enum classes can have all the methods you need:
77
+
78
+ ``` ruby
79
+ class PhoneType
80
+ include EnumField::DefineEnum
81
+
82
+ def initialize(name)
83
+ @name = name
84
+ end
85
+
86
+ define_enum do
87
+ member :home, object: new('home')
88
+ member :commercial, object: new('commercial')
89
+ member :mobile, object: new('mobile')
90
+ end
91
+ end
92
+
93
+ user.phone.type.name
94
+ ```
95
+
96
+ You have some +AR+ like methods in enum classes
97
+
98
+ ``` ruby
99
+ PhoneType.all == [PhoneType.home, PhoneType.commercial, PhoneType.mobile] # ordered all
100
+ PhoneType.first == PhoneType.home
101
+ PhoneType.last == PhoneType.mobile
102
+
103
+ PhoneType.find_by_id(PhoneType.home.id) == PhoneType.home
104
+ PhoneType.find_by_id(123456) == nil
105
+ PhoneType.find(2) == PhoneType.commercial
106
+ PhoneType.find(123456) # will raise
107
+
108
+ PhoneType.find([1, 2]) == [PhoneType.home, PhoneType.commercial]
109
+ ```
110
+
111
+ ### Start id from specific number
112
+
113
+ ``` ruby
114
+ class CommentType
115
+ include EnumField::DefineEnum
116
+
117
+ define_enum id_start_from: 100 do
118
+ member :video
119
+ member :audio
120
+ member :text
121
+ end
122
+ end
123
+
124
+ CommentType.video.id # 101
125
+ CommentType.audio.id # 102
126
+ CommentType.text.id # 103
127
+ ```
128
+
129
+ ## Tests
130
+
131
+ bundle install
132
+ bundle exec rspec ./spec/
133
+
134
+ ## LICENSE
135
+
136
+ (The MIT License)
137
+
138
+ Copyright (c) 2017 Fodojo LLC
data/lib/enum_field.rb CHANGED
@@ -1,20 +1,24 @@
1
1
  # encoding: utf-8
2
+
3
+ # Basic usage:
4
+ #
5
+ # class Role
6
+ # include EnumField::DefineEnum
7
+ #
8
+ # define_enum do
9
+ # member :admin
10
+ # member :manager
11
+ # member :employee
12
+ # end
13
+ # end
14
+ #
2
15
  module EnumField
3
16
  autoload :DefineEnum, 'enum_field/define_enum'
4
17
  autoload :Builder, 'enum_field/builder'
5
18
  autoload :EnumeratedAttribute, 'enum_field/enumerated_attribute'
6
19
  autoload :Version, 'enum_field/version'
7
-
8
- class BadId < StandardError
9
- attr_reader :repeated_id
10
-
11
- def initialize(repeated_id)
12
- @repeated_id = repeated_id
13
- end
14
- end
15
20
 
16
21
  class RepeatedId < StandardError; end
17
22
  class InvalidId < StandardError; end
18
- class InvalidOptions < StandardError; end
19
23
  class ObjectNotFound < StandardError; end
20
24
  end
@@ -1,96 +1,91 @@
1
1
  # encoding: utf-8
2
+
2
3
  module EnumField
3
4
  class Builder
5
+ METHODS = %w[all names find_by_id find first last ids].freeze
4
6
 
5
- METHODS = [:all, :names, :find_by_id, :find, :first, :last]
7
+ attr_reader :members
6
8
 
7
- def initialize(target)
9
+ def initialize(target, options = {})
8
10
  @target = target
9
- @next_id = 0
10
- @id2obj = {}
11
- @name2obj = {}
12
- @sorted = []
11
+ @options = options
12
+ @members = {}
13
13
  end
14
14
 
15
15
  def member(name, options = {})
16
- obj, candidate_id = process_options(options)
17
- assign_id(obj, candidate_id)
18
- assign_name(obj, name)
19
- define_in_meta(name) { obj }
20
- save(name, obj)
21
- obj.freeze
16
+ unique_name = normalize_name(name)
17
+ @members[unique_name] = create_new_object(unique_name, options)
22
18
  end
23
19
 
24
20
  def all
25
- @sorted.dup
21
+ @members.values
22
+ end
23
+
24
+ def [](value)
25
+ unique_name = normalize_name(value)
26
+ @members[unique_name]
26
27
  end
27
28
 
28
29
  def names
29
- @name2obj.keys
30
+ @members.keys
31
+ end
32
+
33
+ def first
34
+ key = names.first
35
+ @members[key]
36
+ end
37
+
38
+ def last
39
+ key = names.last
40
+ @members[key]
41
+ end
42
+
43
+ def ids
44
+ all.map(&:id)
30
45
  end
31
46
 
32
47
  def find(id)
33
- find_by_id(id) or raise EnumField::ObjectNotFound
48
+ find_by_id(id) || raise(EnumField::ObjectNotFound)
34
49
  end
35
50
 
36
51
  def find_by_id(id)
37
52
  case id
38
- when Integer, String, Float, Fixnum then
39
- @id2obj[id.to_i]
40
53
  when Array then
41
- id.inject([]) do |items, value|
42
- if value && value.respond_to?(:to_i)
43
- items << @id2obj[value.to_i]
44
- end
45
-
46
- items
47
- end
54
+ all.select { |object| id.include?(object.id) }
55
+ else
56
+ all.detect { |object| object.id == id }
48
57
  end
49
58
  end
50
59
 
51
- def first; @sorted.first; end
52
- def last; @sorted.last; end
53
-
54
60
  private
55
61
 
56
- def define_in_meta(name, &block)
57
- metaclass = class << @target; self; end
58
- metaclass.send(:define_method, name, &block)
59
- end
62
+ def create_new_object(name, options)
63
+ object = (options[:object] || @target.new)
60
64
 
61
- def assign_id(obj, candidate_id)
62
- id = new_id(candidate_id)
63
- obj.instance_variable_set(:@id, id)
64
- end
65
-
66
- def assign_name(obj, name)
67
- obj.instance_variable_set(:@name, name)
68
- end
65
+ object.instance_variable_set(:@name, name)
66
+ object.instance_variable_set(:@id, find_next_object_id(options))
67
+ object.freeze
69
68
 
70
- def new_id(candidate)
71
- validate_candidate_id(candidate)
72
- candidate || find_next_id
69
+ object
73
70
  end
74
71
 
75
- def validate_candidate_id(id)
76
- raise EnumField::InvalidId.new(id) unless id.nil? || id.is_a?(Integer) && id > 0
77
- raise EnumField::RepeatedId.new(id) if @id2obj.has_key?(id)
72
+ def find_next_object_id(options)
73
+ new_id = (options[:id] || generate_next_object_id)
74
+ validate_candidate_id!(new_id)
75
+ new_id
78
76
  end
79
77
 
80
- def find_next_id
81
- @next_id += 1 while @id2obj.has_key?(@next_id) || @next_id <= 0
82
- @next_id
78
+ def generate_next_object_id
79
+ @options.fetch(:id_start_from, 0) + @members.size + 1
83
80
  end
84
81
 
85
- def process_options(options)
86
- raise EnumField::InvalidOptions unless options.reject {|k,v| k == :object || k == :id}.empty?
87
- [options[:object] || @target.new, options[:id]]
82
+ def validate_candidate_id!(id)
83
+ raise EnumField::InvalidId.new(message: id) if id.nil?
84
+ raise EnumField::RepeatedId.new(message: id) if ids.include?(id)
88
85
  end
89
86
 
90
- def save(name, obj)
91
- @id2obj[obj.id] = obj
92
- @sorted << obj
93
- @name2obj[name] = obj
87
+ def normalize_name(value)
88
+ value.to_s.to_sym
94
89
  end
95
90
  end
96
91
  end
@@ -1,26 +1,55 @@
1
1
  # encoding: utf-8
2
+
2
3
  module EnumField
4
+ # Add enum methods to class
5
+ # Usage:
6
+ # class Role
7
+ # include EnumField::DefineEnum
8
+ # ...
9
+ # end
10
+ #
3
11
  module DefineEnum
4
12
  def self.included(base)
5
13
  base.send :extend, ClassMethods
14
+ base.send :include, InstanceMethods
6
15
  end
7
16
 
8
17
  module ClassMethods
9
- def self.extended(base)
10
- base.class_eval do
11
- attr_reader :id, :name
18
+ def define_enum(options = {}, &block)
19
+ @enum_builder ||= EnumField::Builder.new(self, options)
20
+ @enum_builder.instance_exec(&block)
21
+
22
+ EnumField::Builder::METHODS.each do |method|
23
+ define_singleton_method method do |*args, &method_block|
24
+ @enum_builder.send(method, *args, &method_block)
25
+ end
12
26
  end
13
- end
14
27
 
15
- def define_enum(&block)
16
- @enum_builder ||= EnumField::Builder.new(self)
17
- yield @enum_builder
28
+ @enum_builder.members.keys.each do |method|
29
+ define_singleton_method method do
30
+ @enum_builder.members[method]
31
+ end
18
32
 
19
- EnumField::Builder::METHODS.each do |method|
20
- define_singleton_method method do |*args, &block|
21
- @enum_builder.send(method, *args, &block)
33
+ define_method "#{method}?" do
34
+ @name == method
22
35
  end
23
36
  end
37
+
38
+ define_singleton_method '[]' do |value|
39
+ @enum_builder[value]
40
+ end
41
+
42
+ @enum_builder.members.freeze
43
+ end
44
+ end
45
+
46
+ module InstanceMethods
47
+ def id
48
+ @id
49
+ end
50
+
51
+ def name
52
+ @name
24
53
  end
25
54
  end
26
55
  end
@@ -1,4 +1,7 @@
1
1
  # encoding: utf-8
2
+
3
+ require 'active_support/inflector'
4
+
2
5
  module EnumField
3
6
  # Easies the inclusion of enumerations as ActiveRecord columns.
4
7
  # If you have a User AR, with a role_id column, you could do:
@@ -19,7 +22,7 @@ module EnumField
19
22
  # class User
20
23
  # extend EnumField::EnumeratedAttribute
21
24
  #
22
- # has_many_enumerated_attributes :roles, :through => UserRole
25
+ # enumerated_attribute :role
23
26
  # end
24
27
  #
25
28
  # class UserRole < ActiveRecord::Base
@@ -41,53 +44,18 @@ module EnumField
41
44
  # * +class+: the class that will be instantiated when +name_attribute+ method is called. Defaults to
42
45
  # +name_attribute+ in camelcase form.
43
46
  #
44
- def enumerated_attribute(name_attribute, options = {})
47
+ def enumerated_attribute(name_attribute, options = {})
45
48
  id_attribute = (options[:id_attribute] || "#{name_attribute}_id").to_sym
46
49
  klass = options[:class] || (options[:class_name] || name_attribute).to_s.camelcase.constantize
47
50
 
48
51
  define_method(name_attribute) do
49
- (raw = read_attribute(id_attribute)) && klass.find_by_id(raw)
52
+ raw = send(id_attribute)
53
+ klass.find_by_id(raw)
50
54
  end
51
55
 
52
56
  define_method("#{name_attribute}=") do |value|
53
- write_attribute(id_attribute, value ? value.id : nil)
54
- end
55
- end
56
-
57
- # alias of enumerated_attribute
58
- alias belongs_to_enumerated_attribute enumerated_attribute
59
-
60
- # Defines a one-to-many association between an AR class and the enumerated
61
- # * +association+: the name of the one-to-many association, for instance +roles+
62
- # * +options+: Valid options are:
63
- # * +through+ : the name of the AR class needed to persist the one-to-many association.
64
- # Defaults to AR class in camelcase form concatenated with the enumerated class in camelcase form.
65
- # * +class+: the enumerated class, it will be instantiated +n+ times when +association+ method is called.
66
- # Defaults to +association+ in singular camelcase form.
67
- def has_many_enumerated_attributes(association, options = {})
68
- enum_attr = association.to_s.singularize
69
- klass = options[:class] || enum_attr.camelcase.constantize
70
- through = options[:through] || (self.name + klass.name)
71
- self_attribute = self.name.demodulize.underscore
72
- association_ids = association.to_s.singularize + '_ids'
73
- has_many_aux = through.demodulize.underscore.pluralize
74
-
75
- has_many has_many_aux, {:class_name => through, :dependent => :destroy}
76
-
77
- define_method(association) do
78
- self.send(has_many_aux).map(&enum_attr.to_sym)
79
- end
80
-
81
- define_method(association.to_s + '=') do |values|
82
- self.send(has_many_aux + '=', values.map{|g| through.constantize.new(self_attribute => self, enum_attr => g)})
83
- end
84
-
85
- define_method(association_ids) do
86
- self.send(association).map(&:id)
87
- end
88
-
89
- define_method(association_ids + '=') do |values|
90
- self.send(has_many_aux + '=', values.map{|g| g.to_i unless g.blank?}.compact.map{|g_id| through.constantize.new(self_attribute => self, enum_attr + '_id' => g_id) })
57
+ raw = value ? value.id : nil
58
+ send("#{id_attribute}=", raw)
91
59
  end
92
60
  end
93
61
  end
@@ -1,3 +1,3 @@
1
1
  module EnumField
2
- VERSION = "0.4.0".freeze
2
+ VERSION = '0.5.0'.freeze
3
3
  end
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+
3
+ describe EnumField::DefineEnum do
4
+ # Sample ruby class
5
+ class Role
6
+ include EnumField::DefineEnum
7
+
8
+ define_enum do
9
+ member :admin
10
+ member :manager
11
+ member :employee
12
+ end
13
+ end
14
+
15
+ it 'must setup class methods for fast instance get' do
16
+ expect(Role.admin).not_to eq nil
17
+ expect(Role.admin.id).to eq 1
18
+ expect(Role.admin.name).to eq :admin
19
+
20
+ expect(Role[:admin]).to eq(Role.admin)
21
+ expect(Role['admin']).to eq(Role.admin)
22
+ end
23
+
24
+ context 'static' do
25
+ it 'must get all instances' do
26
+ expect(Role.all.size).to eq 3
27
+ expect(Role.all).to eq [Role.admin, Role.manager, Role.employee]
28
+ end
29
+
30
+ it 'must get all names' do
31
+ expect(Role.names.size).to eq 3
32
+ expect(Role.names).to eq [:admin, :manager, :employee]
33
+ end
34
+
35
+ it 'must find_by_id one instance' do
36
+ expect(Role.find_by_id(1)).to eq Role.admin
37
+ expect(Role.find_by_id(2)).to eq Role.manager
38
+ expect(Role.find_by_id(3)).to eq Role.employee
39
+ end
40
+
41
+ it 'must find_by_id array of instances' do
42
+ expect(Role.find_by_id([2, 3])).to eq [Role.manager, Role.employee]
43
+ expect(Role.find_by_id([nil, 1])).to eq [Role.admin]
44
+ end
45
+
46
+ it 'must not find instance via wrong id' do
47
+ expect(Role.find_by_id(4)).to eq nil
48
+ expect(Role.find_by_id('1')).to eq nil
49
+ expect(Role.find_by_id(nil)).to eq nil
50
+ expect(Role.find_by_id('wrong')).to eq nil
51
+ expect(Role.find_by_id(0)).to eq nil
52
+ expect(Role.find_by_id(-1)).to eq nil
53
+ end
54
+
55
+ it 'must find one instance' do
56
+ expect(Role.find(1)).to eq Role.admin
57
+ expect(Role.find(2)).to eq Role.manager
58
+ expect(Role.find(3)).to eq Role[:employee]
59
+ end
60
+
61
+ it 'must not find one instance with invalid id' do
62
+ expect { Role.find(100) }.to raise_error(EnumField::ObjectNotFound)
63
+ expect { Role.find(-1) }.to raise_error(EnumField::ObjectNotFound)
64
+ expect { Role.find('1') }.to raise_error(EnumField::ObjectNotFound)
65
+ expect { Role.find(nil) }.to raise_error(EnumField::ObjectNotFound)
66
+ end
67
+
68
+ it 'must get first instance' do
69
+ expect(Role.first).to eq(Role.admin)
70
+ end
71
+
72
+ it 'must get last instance' do
73
+ expect(Role.last).to eq(Role.employee)
74
+ end
75
+
76
+ it 'must get all ids' do
77
+ expect(Role.ids).to eq([1, 2, 3])
78
+ end
79
+ end
80
+
81
+ context 'wrong id' do
82
+ it 'must raise error on dublicated id' do
83
+ expect do
84
+ # Wrong class
85
+ class PostType
86
+ include EnumField::DefineEnum
87
+
88
+ define_enum do
89
+ member :default, id: 1
90
+ member :video, id: 1
91
+ member :audio, id: 2
92
+ end
93
+ end
94
+ end.to raise_error(EnumField::RepeatedId)
95
+ end
96
+ end
97
+
98
+ context 'check' do
99
+ let(:instance) { Role[:admin] }
100
+
101
+ it 'must check methods' do
102
+ expect(instance.admin?).to eq true
103
+ expect(instance.manager?).to eq false
104
+ expect(instance.employee?).to eq false
105
+ end
106
+ end
107
+
108
+ context 'id start number' do
109
+ let(:start_number) { 100 }
110
+ let(:comment_type) do
111
+ Class.new(Object) do
112
+ include EnumField::DefineEnum
113
+
114
+ define_enum id_start_from: 100 do
115
+ member :video
116
+ member :audio
117
+ member :text
118
+ end
119
+ end
120
+ end
121
+
122
+ it 'must set id + start_number' do
123
+ expect(comment_type.video.id).to eq start_number + 1
124
+ expect(comment_type.audio.id).to eq start_number + 2
125
+ expect(comment_type.text.id).to eq start_number + 3
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe EnumField::EnumeratedAttribute do
4
+ # Sample ruby class
5
+ class RoleType
6
+ include EnumField::DefineEnum
7
+
8
+ define_enum do
9
+ member :admin
10
+ member :manager
11
+ member :employee
12
+ end
13
+ end
14
+
15
+ # Sample ruby class
16
+ class User
17
+ extend EnumField::EnumeratedAttribute
18
+
19
+ attr_accessor :role_type_id
20
+
21
+ enumerated_attribute :role_type
22
+
23
+ def initialize(role_type_id)
24
+ @role_type_id = role_type_id
25
+ end
26
+ end
27
+
28
+ let(:admin_user) { User.new(RoleType.admin.id) }
29
+ let(:new_role) { RoleType.employee }
30
+
31
+ it 'must set role value' do
32
+ expect(admin_user.role_type).to eq RoleType.admin
33
+ expect(admin_user.role_type_id).to eq RoleType.admin.id
34
+ expect(admin_user.role_type.admin?).to eq true
35
+ end
36
+
37
+ it 'must set role_type_id' do
38
+ expect {
39
+ admin_user.role_type = new_role
40
+ }.to change { admin_user.role_type_id }.from(RoleType.admin.id).to(new_role.id)
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe EnumField do
4
+ it 'has a version number' do
5
+ expect(EnumField::VERSION).not_to be nil
6
+ end
7
+
8
+ it 'must be a module' do
9
+ expect(EnumField.is_a?(Module)).to eq true
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'enum_field'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: galetahub-enum_field
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Galeta
@@ -9,24 +9,84 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-12-11 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2017-04-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.12'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.12'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.0'
14
70
  description: Enables Active Record attributes to point to enum like objects, by saving
15
71
  in your database only an integer ID
16
72
  email: galeta.igor@gmail.com
17
73
  executables: []
18
74
  extensions: []
19
75
  extra_rdoc_files:
20
- - README.rdoc
76
+ - README.md
21
77
  files:
78
+ - MIT-LICENSE
79
+ - README.md
80
+ - Rakefile
81
+ - lib/enum_field.rb
22
82
  - lib/enum_field/builder.rb
23
83
  - lib/enum_field/define_enum.rb
24
84
  - lib/enum_field/enumerated_attribute.rb
25
85
  - lib/enum_field/version.rb
26
- - lib/enum_field.rb
27
- - MIT-LICENSE
28
- - Rakefile
29
- - README.rdoc
86
+ - spec/enum_field/define_enum_spec.rb
87
+ - spec/enum_field/enumerated_attribute_spec.rb
88
+ - spec/enum_field_spec.rb
89
+ - spec/spec_helper.rb
30
90
  homepage: https://github.com/galetahub/enum_field
31
91
  licenses: []
32
92
  metadata: {}
@@ -45,9 +105,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
105
  - !ruby/object:Gem::Version
46
106
  version: '0'
47
107
  requirements: []
48
- rubyforge_project: enum_field
49
- rubygems_version: 2.1.11
108
+ rubyforge_project:
109
+ rubygems_version: 2.5.1
50
110
  signing_key:
51
111
  specification_version: 4
52
- summary: Enumerated attributes for Active Record
53
- test_files: []
112
+ summary: Enumerated attributes for any ruby class aka Active Record
113
+ test_files:
114
+ - spec/enum_field/define_enum_spec.rb
115
+ - spec/enum_field/enumerated_attribute_spec.rb
116
+ - spec/enum_field_spec.rb
117
+ - spec/spec_helper.rb
data/README.rdoc DELETED
@@ -1,143 +0,0 @@
1
- = enum_field
2
-
3
- * http://github.com/paraseba/enum_field
4
-
5
- == DESCRIPTION:
6
-
7
- Enables Active Record attributes to point to enum like objects, by saving in your database
8
- only an integer ID.
9
-
10
- == INSTALL:
11
-
12
- gem 'galetahub-enum_field', require: 'enum_field'
13
-
14
-
15
- == FEATURES:
16
-
17
- * Allows creation of Classes with enum like behaviour.
18
- * Allows any number of members and methods in the enum classes.
19
- * Allows an integer id to be used in your database columns to link to the enum members (user.role_id)
20
- * Enables higher abstraction interaction with +AR+ attributes:
21
- * <code>user.role = Role.admin</code>
22
- * <code>if user.role.can_edit?</code>
23
- * Saves in your +AR+ tables, only an integer id pointing to the enumeration member.
24
-
25
- == SYNOPSIS:
26
-
27
- When in an Active Record class, you have an attribute like role, state or country you have
28
- several options.
29
-
30
- * You can create a roles, states or countries table, and dump there all possible values.
31
- * You can use a string to identify, for instance, the role.
32
- * You can use an id to identify the role.
33
-
34
- If you are not comfortable with any of this options, maybe +enum_field+ is an answer for you.
35
-
36
- == BASIC USAGE:
37
-
38
- class Role
39
- include EnumField::DefineEnum
40
-
41
- define_enum do |builder|
42
- builder.member :admin
43
- builder.member :manager
44
- builder.member :employee
45
- end
46
- end
47
-
48
- class User < ActiveRecord::Base
49
- extend EnumField::EnumeratedAttribute
50
-
51
- # in the database table there is a role_id integer column
52
- enumerated_attribute :role
53
- end
54
-
55
-
56
- link_to_if(current_user.role == Role.admin, edit_foo_path(@foo))
57
-
58
- user.role = Role.manager
59
- user.role_id == Role.manager.id #will be true
60
-
61
- Role.manager.name # :manager
62
- user.role.name # :manager
63
-
64
- User.first.role.id == User.first.role_id #will be true
65
-
66
- Your enum classes can have all the methods you need:
67
-
68
- class PhoneType
69
- include EnumField::DefineEnum
70
-
71
- def initialize(name)
72
- @name = name
73
- end
74
- attr_reader :name
75
-
76
- define_enum do |b|
77
- b.member :home, :object => new('home')
78
- b.member :commercial, :object => new('commercial')
79
- b.member :mobile, :object => new('mobile')
80
- end
81
- end
82
-
83
- user.phone.type.name
84
-
85
- You have some +AR+ like methods in enum classes
86
-
87
- PhoneType.all == [PhoneType.home, PhoneType.commercial, PhoneType.mobile] # ordered all
88
- PhoneType.first == PhoneType.home
89
- PhoneType.last == PhoneType.mobile
90
-
91
- PhoneType.find_by_id(PhoneType.home.id) == PhoneType.home
92
- PhoneType.find_by_id(123456) == nil
93
- PhoneType.find(2) == PhoneType.commercial
94
- PhoneType.find(123456) # will raise
95
-
96
- PhoneType.find([1, 2]) == [PhoneType.home, PhoneType.commercial]
97
-
98
- The library also mimics has_many :through behavior, for cases such as:
99
-
100
- class Role
101
- include EnumField::DefineEnum
102
-
103
- define_enum do |builder|
104
- builder.member :admin
105
- builder.member :manager
106
- builder.member :employee
107
- end
108
- end
109
-
110
- class User
111
- extend EnumField::EnumeratedAttribute
112
-
113
- has_many_enumerated_attributes :roles, :through => UserRole
114
- end
115
-
116
- class UserRole < ActiveRecord::Base
117
- extend EnumField::EnumeratedAttribute
118
-
119
- belongs_to :user
120
- enumerated_attribute :role
121
- end
122
-
123
- user = User.create
124
- user.role = [Role.manager, Role.admin]
125
- user.roles.include?(Role.admin) #will be true
126
- user.roles.include?(Role.manager) #will be true
127
- user.roles.include?(Role.employee) #will be false
128
- user.role_ids.include?(Role.manager.id) #will be true
129
- user.role_ids = [Role.employee.id]
130
- user.roles.include?(Role.employee) #will be true
131
- user.roles.include?(Role.admin) #will be false
132
-
133
-
134
-
135
- == REQUIREMENTS:
136
-
137
- * activerecord
138
-
139
- == LICENSE:
140
-
141
- (The MIT License)
142
-
143
- Copyright (c) 2009 Sebastián Bernardo Galkin