active_finite 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,24 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ gem "activesupport", "~> 3.0.3"
9
+ gem "activerecord", "~> 3.0.3"
10
+ gem "json", "~> 1.5.1"
11
+
12
+ group :development do
13
+ gem "rspec", "~> 2.3.0"
14
+ gem "bundler", "~> 1.0.0"
15
+ gem "jeweler", "~> 1.5.2"
16
+ end
17
+
18
+ group :test do
19
+ gem "rspec", "~> 2.3.0"
20
+ gem 'sqlite3-ruby', '1.3.3', :require => 'sqlite3'
21
+ gem "activesupport", "~> 3.0.3"
22
+ gem "activerecord", "~> 3.0.3"
23
+ end
24
+
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 me
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,88 @@
1
+ = active_finite
2
+
3
+ == What is active_finite?
4
+
5
+ The goal of active_finite is to provide a simple way to define
6
+ database enumerations with ActiveRecord. There are many[https://github.com/ikspres/enum_fu] existing[https://github.com/adzap/active_enum] projects[https://github.com/jeffp/enumerated_attribute] that bring some enum support to ActiveRecord. However, these projects tend to define the enums in code, instead of in the migration itself.
7
+
8
+ == Hello, active_finite!
9
+
10
+ Let's start by defining a simple migration:
11
+
12
+ require 'active_finite'
13
+ require 'active_record'
14
+ require 'active_support/core_ext'
15
+
16
+ class Hellos < ActiveRecord::Migration
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']
22
+ end
23
+
24
+ self.down
25
+ drop_finite in_table: :hellos, values: ['oy', 'que tal', 'hi']
26
+ drop_table :hellos
27
+ end
28
+ end
29
+
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
+ Now that we some hellos in our Hello model, we can access them using:
34
+ hellos = active_finite :hellos
35
+
36
+ The variable hellos now holds a class derived from ActiveRecord named
37
+ 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.
40
+
41
+ == 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
44
+ file can be used instead of explicitly listing the possible values in
45
+ the migration. For example:
46
+
47
+ require 'active_finite'
48
+ require 'active_record'
49
+ require 'active_support/core_ext'
50
+ class HellosWithCustomColumn < ActiveRecord::Migration
51
+ 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'
59
+ end
60
+
61
+ self.down
62
+ drop_finite in_table: :hellos, values: ['oy', 'que tal', 'hi']
63
+ drop_table :hellos
64
+ end
65
+ end
66
+
67
+ If both values and from_file are defined, active_finite will pull entries from both.
68
+
69
+ == Other ideas
70
+ Combine active_finite with foreigner[https://github.com/matthuhiggins/foreigner] to put foreign key constraints on users of defined enums.
71
+
72
+ == Contributing to active_finite
73
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
74
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
75
+ * Fork the project
76
+ * Start a feature/bugfix branch
77
+ * Commit and push until you are happy with your contribution
78
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
79
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
80
+
81
+ == Contact
82
+ me@stuffivemade.com
83
+
84
+ == Copyright
85
+
86
+ Copyright (c) 2011 me. See LICENSE.txt for
87
+ further details.
88
+
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "active_finite"
16
+ gem.homepage = "http://github.com/r4pdevteam/active_finite"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{one-line summary of your gem}
19
+ gem.description = %Q{longer description of your gem}
20
+ gem.email = "me@stuffihavemade.com"
21
+ gem.authors = ["me"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rspec/core'
30
+ require 'rspec/core/rake_task'
31
+ RSpec::Core::RakeTask.new(:spec) do |spec|
32
+ spec.pattern = FileList['spec/**/*_spec.rb']
33
+ end
34
+
35
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :default => :spec
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
45
+
46
+ rdoc.rdoc_dir = 'rdoc'
47
+ rdoc.title = "active_finite #{version}"
48
+ rdoc.rdoc_files.include('README*')
49
+ rdoc.rdoc_files.include('lib/**/*.rb')
50
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{active_finite}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["me"]
12
+ s.date = %q{2011-04-12}
13
+ s.description = %q{longer description of your gem}
14
+ s.email = %q{me@stuffihavemade.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "LICENSE.txt",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "active_finite.gemspec",
27
+ "lib/active_finite.rb",
28
+ "spec/active_finite_spec.rb",
29
+ "spec/spec_helper.rb",
30
+ "spec/villans.json"
31
+ ]
32
+ s.homepage = %q{http://github.com/r4pdevteam/active_finite}
33
+ s.licenses = ["MIT"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.5.0}
36
+ s.summary = %q{one-line summary of your gem}
37
+ s.test_files = [
38
+ "spec/active_finite_spec.rb",
39
+ "spec/spec_helper.rb"
40
+ ]
41
+
42
+ if s.respond_to? :specification_version then
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.3"])
47
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.3"])
48
+ s.add_runtime_dependency(%q<json>, ["~> 1.5.1"])
49
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
50
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
51
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
52
+ else
53
+ s.add_dependency(%q<activesupport>, ["~> 3.0.3"])
54
+ s.add_dependency(%q<activerecord>, ["~> 3.0.3"])
55
+ s.add_dependency(%q<json>, ["~> 1.5.1"])
56
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
57
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
58
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<activesupport>, ["~> 3.0.3"])
62
+ s.add_dependency(%q<activerecord>, ["~> 3.0.3"])
63
+ s.add_dependency(%q<json>, ["~> 1.5.1"])
64
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
65
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
66
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
67
+ end
68
+ end
69
+
@@ -0,0 +1,61 @@
1
+ require 'pathname'
2
+ require 'find'
3
+ require 'active_support/inflector'
4
+ require 'active_record'
5
+ require 'json'
6
+
7
+ def active_finite sym
8
+ anon = Class.new ActiveRecord::Base
9
+ klass = Object.const_set(sym.to_s.singularize.capitalize, anon)
10
+ klass
11
+ end
12
+
13
+ def create_finite args
14
+ modify_finite args do |vs, klass, column_name|
15
+ vs.each do |v|
16
+ obj = klass.new
17
+ obj.send column_name.to_s + '=', v
18
+ obj.save
19
+ end
20
+ end
21
+ end
22
+
23
+ def drop_finite args
24
+ modify_finite args do |vs, klass, column_name|
25
+ vs.each do |v|
26
+ objs = klass.where column_name => v
27
+ objs.each do |o|
28
+ klass.destroy o
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def modify_finite args
35
+ table_name = args[:in_table]
36
+ if table_name.nil?
37
+ raise 'A table name must be specified for :in_table .'
38
+ end
39
+ file_name = args[:from_file]
40
+ values = args[:values]
41
+ column_name = args[:column_name] || :value
42
+ if values.nil? and file_name.nil?
43
+ raise 'Either :from_file or :values must be specified.'
44
+ end
45
+
46
+ to_be_modified = Array.new
47
+ if not values.nil?
48
+ to_be_modified = to_be_modified.concat values
49
+ end
50
+
51
+ if not file_name.nil?
52
+ to_be_modified = to_be_modified.concat JSON.load open file_name
53
+ end
54
+
55
+ klass = active_finite table_name
56
+ yield to_be_modified, klass, column_name
57
+ end
58
+
59
+ def default_column_name
60
+ :value
61
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
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
18
+ end
19
+
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
29
+
30
+ finites.each do |f|
31
+ Color. where(default_column_name => f).should_not nil
32
+ end
33
+ end
34
+
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']
42
+
43
+ create_finite in_table: :characters,
44
+ values: finites,
45
+ column_name: :column_name
46
+
47
+ finites.each do |f|
48
+ Color.where(:column_name => f).should_not nil
49
+ end
50
+ end
51
+
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
61
+
62
+ ['scaramanga', 'no', 'janus'].each do |v|
63
+ Villan.where(default_column_name => v).should_not nil
64
+ end
65
+ end
66
+ end
67
+
68
+ describe 'drop_finite' do
69
+ it 'can delete previously added finites' do
70
+ ActiveRecord::Schema.define do
71
+ create_table :adjs do |t|
72
+ t.string default_column_name, :null => false
73
+ end
74
+
75
+ create_finite in_table: :adj, values: ['delete', 'drop']
76
+ drop_finite in_table: :adj, values: ['delete']
77
+ Adj.where(default_column_name => 'delete').should nil
78
+ Adj.where(default_column_name => 'drop').should_not nil
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'active_finite'
5
+ require 'active_support/core_ext'
6
+
7
+ # Requires supporting files with custom matchers and macros, etc,
8
+ # in ./support/ and its subdirectories.
9
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
10
+
11
+ RSpec.configure do |config|
12
+
13
+ end
data/spec/villans.json ADDED
@@ -0,0 +1,2 @@
1
+ ["scaramanga", "no", "janus"]
2
+
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_finite
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - me
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-12 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: activesupport
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.3
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 3.0.3
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: json
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.5.1
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 2.3.0
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: bundler
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 1.0.0
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: jeweler
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 1.5.2
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *id006
82
+ description: longer description of your gem
83
+ email: me@stuffihavemade.com
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files:
89
+ - LICENSE.txt
90
+ - README.rdoc
91
+ files:
92
+ - .document
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.rdoc
96
+ - Rakefile
97
+ - VERSION
98
+ - active_finite.gemspec
99
+ - lib/active_finite.rb
100
+ - spec/active_finite_spec.rb
101
+ - spec/spec_helper.rb
102
+ - spec/villans.json
103
+ has_rdoc: true
104
+ homepage: http://github.com/r4pdevteam/active_finite
105
+ licenses:
106
+ - MIT
107
+ post_install_message:
108
+ rdoc_options: []
109
+
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 192715187
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: "0"
127
+ requirements: []
128
+
129
+ rubyforge_project:
130
+ rubygems_version: 1.5.0
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: one-line summary of your gem
134
+ test_files:
135
+ - spec/active_finite_spec.rb
136
+ - spec/spec_helper.rb