galetahub-enum_field 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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