active_finite 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -15,32 +15,30 @@ Let's start by defining a simple migration:
15
15
 
16
16
  class Hellos < ActiveRecord::Migration
17
17
  self.up
18
- create_table :hellos do |t|
19
- t.string default_column_name, :null => false
20
- end
21
- create_finite in_table: :hellos, values: ['oy', 'que tal', 'hi']
18
+ add_finites in_table: :hellos, values: ['oy', 'que tal', 'hi']
22
19
  end
23
20
 
24
21
  self.down
25
- drop_finite in_table: :hellos, values: ['oy', 'que tal', 'hi']
26
- drop_table :hellos
22
+ delete_finites in_table: :hellos, values: ['oy', 'que tal', 'hi']
27
23
  end
28
24
  end
29
25
 
30
- Note that if it doesn't matter what the column's name is, the method
31
- default_column_name can be used.
32
-
33
26
  Now that we some hellos in our Hello model, we can access them using:
34
- hellos = active_finite :hellos
27
+ hellos = get_finite_table :hellos
35
28
 
36
29
  The variable hellos now holds a class derived from ActiveRecord named
37
30
  Hello, so all of the normal ActiveRecord methods can be used.
38
- By using the method active_finite, there is no need to define the model classes
39
- explicitly.
31
+
32
+ We can also a collection of all of the active record classes defined by
33
+ active_finite by using:
34
+ all_finite_tables
35
+
36
+ Using get_finite_table and all_finite_tables implicitly bring the associated
37
+ classes into scope, so a single call to all_finite_tables is sufficent to
38
+ define all of the models.
40
39
 
41
40
  == Other options
42
- If the column name must be different than the default (i.e. when working with
43
- an existing database), the column_name option can be used. Also, a json
41
+ If the column name must be different than the default, the column_name option can be used. Also, a json
44
42
  file can be used instead of explicitly listing the possible values in
45
43
  the migration. For example:
46
44
 
@@ -49,22 +47,21 @@ the migration. For example:
49
47
  require 'active_support/core_ext'
50
48
  class HellosWithCustomColumn < ActiveRecord::Migration
51
49
  self.up
52
- create_table :hellos do |t|
53
- t.string :custom, :null => false
54
- end
55
- create_finite in_table: :hellos,
56
- values: ['oy', 'que tal', 'hi']
57
- column_name: :custom
58
- from_file: 'hellos.json'
50
+ add_finites in_table: :hellos,
51
+ values: ['oy', 'que tal', 'hi']
52
+ column_name: :custom
53
+ from_file: 'hellos.json'
59
54
  end
60
55
 
61
56
  self.down
62
- drop_finite in_table: :hellos, values: ['oy', 'que tal', 'hi']
63
- drop_table :hellos
57
+ delete_finites in_table: :hellos, values: all
64
58
  end
65
59
  end
66
60
 
67
61
  If both values and from_file are defined, active_finite will pull entries from both.
62
+ Another option to be aware of is that values do not have to be explicitly listed
63
+ upon deletion, using the all option is sufficent.
64
+
68
65
 
69
66
  == Other ideas
70
67
  Combine active_finite with foreigner[https://github.com/matthuhiggins/foreigner] to put foreign key constraints on users of defined enums.
data/Rakefile CHANGED
@@ -13,11 +13,10 @@ require 'jeweler'
13
13
  Jeweler::Tasks.new do |gem|
14
14
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
15
  gem.name = "active_finite"
16
- gem.homepage = "http://github.com/stuffihavemade/active_finite"
16
+ gem.homepage = "http://github.com/r4pdevteam/active_finite"
17
17
  gem.license = "MIT"
18
- gem.summary = %Q{An ActiveRecord addon for enums, based on DRY and that enums
19
- should be database columns}
20
- gem.description = %Q{see README.rdoc}
18
+ gem.summary = %Q{one-line summary of your gem}
19
+ gem.description = %Q{longer description of your gem}
21
20
  gem.email = "me@stuffihavemade.com"
22
21
  gem.authors = ["me"]
23
22
  # Include your dependencies below. Runtime dependencies are required when using your gem,
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
data/lib/active_finite.rb CHANGED
@@ -4,13 +4,68 @@ require 'active_support/inflector'
4
4
  require 'active_record'
5
5
  require 'json'
6
6
 
7
- def active_finite sym
8
- anon = Class.new ActiveRecord::Base
9
- Object.const_set(sym.to_s.singularize.capitalize, anon)
7
+ def get_finite_table sym, *args
8
+ class_name = as_class_name sym
9
+ class_not_defined = not(Object.const_defined? class_name)
10
+ should_force = args.any? {|x| x == :force}
11
+ if class_not_defined or should_force
12
+ anon = Class.new ActiveRecord::Base
13
+ Object.const_set class_name, anon
14
+ else
15
+ Object.const_get class_name
16
+ end
17
+ end
18
+
19
+ def as_class_name table_name
20
+ table_name.to_s.singularize.capitalize.to_sym
21
+ end
22
+
23
+ def all_finite_tables
24
+ master = get_finite_table(master_table_name)
25
+ if master.table_exists?
26
+ master
27
+ .where("#{default_column_name} != ?", master_table_name)
28
+ .collect {|x| x.send default_column_name.to_s}
29
+ .collect {|x| get_finite_table x}
30
+ else
31
+ []
32
+ end
33
+ end
34
+
35
+ def master_table_name
36
+ :active_finites
37
+ end
38
+
39
+ def add_to_master table_name
40
+ add_finites in_table: master_table_name, values: [table_name]
41
+ end
42
+
43
+ def delete_from_master table_name
44
+ delete_finites in_table: master_table_name, values: [table_name]
10
45
  end
11
46
 
12
- def create_finite args
47
+ def is_in_master_table? table_name
48
+ if table_name.eql? master_table_name
49
+ true
50
+ else
51
+ get_finite_table(master_table_name)
52
+ .where("#{default_column_name} != ?", master_table_name)
53
+ .where("#{default_column_name} == ?", table_name)
54
+ .any?
55
+ end
56
+ end
57
+
58
+
59
+ def add_finites args
13
60
  modify_finite args do |vs, klass, column_name|
61
+ if not klass.table_exists?
62
+ ActiveRecord::Schema.define do
63
+ create_table klass.table_name do |t|
64
+ t.string column_name, :null => false
65
+ end
66
+ end
67
+ add_to_master klass.table_name
68
+ end
14
69
  vs.each do |v|
15
70
  obj = klass.new
16
71
  obj.send column_name.to_s + '=', v
@@ -19,13 +74,30 @@ def create_finite args
19
74
  end
20
75
  end
21
76
 
22
- def drop_finite args
77
+ def delete_finites args,
78
+ delete_all = args[:values] == :all
79
+ if delete_all
80
+ args[:values] = []
81
+ end
23
82
  modify_finite args do |vs, klass, column_name|
24
- vs.each do |v|
25
- objs = klass.where column_name => v
26
- objs.each do |o|
83
+ if delete_all
84
+ klass.all.each do |o|
27
85
  klass.destroy o
28
86
  end
87
+ else
88
+ vs.each do |v|
89
+ objs = klass.where column_name => v
90
+ objs.each do |o|
91
+ klass.destroy o
92
+ end
93
+ end
94
+ end
95
+ if klass.count.eql? 0
96
+ ActiveRecord::Schema.define do
97
+ drop_table klass.table_name
98
+ end
99
+ delete_from_master klass.table_name
100
+ Object.send 'remove_const', klass.to_s.to_sym
29
101
  end
30
102
  end
31
103
  end
@@ -51,7 +123,7 @@ def modify_finite args
51
123
  to_be_modified = to_be_modified.concat JSON.load open file_name
52
124
  end
53
125
 
54
- klass = active_finite table_name
126
+ klass = get_finite_table table_name
55
127
  ActiveRecord::Base.transaction do
56
128
  yield to_be_modified, klass, column_name
57
129
  end
@@ -1,97 +1,138 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- ActiveRecord::Base.establish_connection(
4
- :adapter => 'sqlite3',
5
- :database => ':memory:',
6
- :pool => 5,
7
- :timeout => 5000)
8
-
9
- describe 'active_finite' do
10
- it 'returns a class that is a child of active record base' do
11
- active_finite(:test).superclass.should eql ActiveRecord::Base
12
- end
13
- it 'properly singularizes its classes' do
14
- active_finite(:users).should eql User
15
- active_finite(:foxes).should eql Fox
16
- active_finite(:sheep).should eql Sheep
17
- end
3
+ def reconnect
4
+ ActiveRecord::Base.establish_connection(
5
+ :adapter => 'sqlite3',
6
+ :database => ':memory:',
7
+ :pool => 5,
8
+ :timeout => 5000)
9
+ end
10
+
11
+ describe 'get_finite_table' do
12
+ before :each do
13
+ reconnect
14
+ end
15
+ it 'returns a class that is a child of active record base' do
16
+ get_finite_table(:test).superclass.should eql ActiveRecord::Base
17
+ end
18
+ it 'brings a class into scope' do
19
+ get_finite_table :spaces
20
+ Object.const_defined?(:Space).should be true
18
21
  end
22
+ it 'will not redefine a previously defined constant' do
23
+ Define = true
24
+ get_finite_table :defines
25
+ Define.should == true
26
+ end
27
+ it 'will redefine a previously defined constant with the force option' do
28
+ Anyway = true
29
+ get_finite_table :anyways, :force
30
+ Anyway.should_not == true
31
+ end
32
+ end
19
33
 
20
- describe 'create_finite' do
21
- it 'adds finites as rows to the database' do
22
- ActiveRecord::Schema.define do
23
- create_table :colors do |t|
24
- t.string default_column_name, :null => false
25
- end
26
- end
27
- finites = ['red', 'blue', 'green']
28
- create_finite in_table: :colors, values: finites
34
+ describe 'all_finite_tables' do
35
+ before :each do
36
+ reconnect
37
+ end
38
+ it 'returns all active record classes created by active_finite' do
39
+ add_finites in_table: :things, values: ['1']
40
+ add_finites in_table: :stuffs, values: ['s']
41
+ all_finite_tables.should == [Thing, Stuff]
42
+ end
43
+ it 'will no longer return a removed finite table' do
44
+ add_finites in_table: :things, values: ['1']
45
+ delete_finites in_table: :things, values: ['1']
46
+ all_finite_tables.should == []
47
+ end
48
+ end
29
49
 
30
- finites.each do |f|
31
- Color.where(default_column_name => f).should_not nil
32
- end
50
+ describe 'as_class_name' do
51
+ before :each do
52
+ reconnect
53
+ end
54
+ it 'capitalizes its input' do
55
+ as_class_name(:as).should eql :A
56
+ end
57
+ it 'properly singularizes its input' do
58
+ as_class_name(:users).should eql :User
59
+ as_class_name(:foxes).should eql :Fox
60
+ as_class_name(:sheep).should eql :Sheep
61
+ end
62
+ end
63
+
64
+ describe 'add_finites' do
65
+ before :each do
66
+ reconnect
67
+ end
68
+ it 'adds finites as rows to the database' do
69
+ finites = ['red', 'blue', 'green']
70
+ add_finites in_table: :colors, values: finites
71
+
72
+ finites.each do |f|
73
+ Color.where(default_column_name => f).should_not nil
33
74
  end
75
+ end
34
76
 
35
- it 'can change the column name' do
36
- ActiveRecord::Schema.define do
37
- create_table :characters do |t|
38
- t.string :column_name, :null => false
39
- end
40
- end
41
- finites = ['mickey', 'donald', 'scrooge']
77
+ it 'creates the coresponding table if it doesn\`t exist' do
78
+ add_finites in_table: :tests, values: [1]
79
+ Object.const_defined?(:Test).should be true
80
+ end
42
81
 
43
- create_finite in_table: :characters,
44
- values: finites,
45
- column_name: :column_name
82
+ it 'can use a different column name' do
83
+ finites = ['mickey', 'donald', 'scrooge']
84
+ add_finites in_table: :characters,
85
+ values: finites,
86
+ column_name: :column_name
46
87
 
47
- finites.each do |f|
48
- Color.where(:column_name => f).should_not nil
49
- end
88
+ finites.each do |f|
89
+ Color.where(:column_name => f).should_not nil
50
90
  end
91
+ end
51
92
 
52
- it 'can load from a json file' do
53
- ActiveRecord::Schema.define do
54
- create_table :villans do |t|
55
- t.string default_column_name, :null => false
56
- end
57
- end
58
- file_path = File.expand_path(File.dirname(__FILE__) + '/villans.json')
59
- create_finite in_table: :villans,
60
- from_file: file_path
93
+ it 'can load from a json file' do
94
+ file_path = File.expand_path(File.dirname(__FILE__) + '/villans.json')
95
+ add_finites in_table: :villans,
96
+ from_file: file_path
61
97
 
62
- ['scaramanga', 'no', 'janus'].each do |v|
63
- Villan.where(default_column_name => v).should_not nil
64
- end
98
+ ['scaramanga', 'no', 'janus'].each do |v|
99
+ Villan.where(default_column_name => v).should_not nil
65
100
  end
101
+ end
66
102
 
67
- it 'will fail atomically' do
68
- ActiveRecord::Schema.define do
69
- create_table :wu_members do |t|
70
- t.string default_column_name, :null => false
71
- end
72
- end
73
- begin
74
- create_finite in_table: :wu_members, values: ['rza', 'gza', nil]
75
- rescue
76
- ['rza', 'gza'].each do |w|
77
- active_finite(:wu_members).where(default_column_name => w).should nil
78
- end
103
+ it 'will fail atomically' do
104
+ begin
105
+ add_finites in_table: :wu_members, values: ['rza', 'gza', nil]
106
+ rescue
107
+ ['rza', 'gza'].each do |w|
108
+ get_finite_table(:wu_members).where(default_column_name => w).should nil
79
109
  end
80
110
  end
81
111
  end
112
+ end
82
113
 
83
- describe 'drop_finite' do
84
- it 'can delete previously added finites' do
85
- ActiveRecord::Schema.define do
86
- create_table :adjs do |t|
87
- t.string default_column_name, :null => false
88
- end
114
+ describe 'delete_finies' do
115
+ before :each do
116
+ reconnect
117
+ end
89
118
 
90
- create_finite in_table: :adj, values: ['delete', 'drop']
91
- drop_finite in_table: :adj, values: ['delete']
92
- Adj.where(default_column_name => 'delete').should nil
93
- Adj.where(default_column_name => 'drop').should_not nil
94
- end
95
- end
119
+ it 'can delete previously added finites' do
120
+ add_finites in_table: :adjs, values: ['delete', 'drop']
121
+ delete_finites in_table: :adjs, values: ['delete']
122
+ Adj.where(default_column_name => 'delete').should nil
123
+ Adj.where(default_column_name => 'drop').should_not nil
124
+ end
125
+
126
+ it 'will remove the table if there are no finites left' do
127
+ add_finites in_table: :deletes, values: ['delete']
128
+ delete_finites in_table: :deletes, values: ['delete']
129
+ Object.const_defined?(:Delete).should_not be true
130
+ end
131
+
132
+ it 'can delete all values with the all option' do
133
+ add_finites in_table: :adjs, values: ['delete', 'drop']
134
+ delete_finites in_table: :adjs, values: :all
135
+ Object.const_defined?(:Adj).should_not be true
96
136
  end
137
+ end
97
138
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: active_finite
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.3
5
+ version: 0.1.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - me
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-12 00:00:00 -04:00
13
+ date: 2011-04-21 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -79,7 +79,7 @@ dependencies:
79
79
  type: :development
80
80
  prerelease: false
81
81
  version_requirements: *id006
82
- description: see README.rdoc
82
+ description: longer description of your gem
83
83
  email: me@stuffihavemade.com
84
84
  executables: []
85
85
 
@@ -100,7 +100,7 @@ files:
100
100
  - spec/spec_helper.rb
101
101
  - spec/villans.json
102
102
  has_rdoc: true
103
- homepage: http://github.com/stuffihavemade/active_finite
103
+ homepage: http://github.com/r4pdevteam/active_finite
104
104
  licenses:
105
105
  - MIT
106
106
  post_install_message:
@@ -113,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
- hash: -927353165
116
+ hash: 138921425
117
117
  segments:
118
118
  - 0
119
119
  version: "0"
@@ -129,7 +129,7 @@ rubyforge_project:
129
129
  rubygems_version: 1.5.0
130
130
  signing_key:
131
131
  specification_version: 3
132
- summary: An ActiveRecord addon for enums, based on DRY and that enums should be database columns
132
+ summary: one-line summary of your gem
133
133
  test_files:
134
134
  - spec/active_finite_spec.rb
135
135
  - spec/spec_helper.rb