constantize 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in constantize.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,55 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ constantize (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activemodel (3.0.1)
10
+ activesupport (= 3.0.1)
11
+ builder (~> 2.1.2)
12
+ i18n (~> 0.4.1)
13
+ activerecord (3.0.1)
14
+ activemodel (= 3.0.1)
15
+ activesupport (= 3.0.1)
16
+ arel (~> 1.0.0)
17
+ tzinfo (~> 0.3.23)
18
+ activesupport (3.0.1)
19
+ arel (1.0.1)
20
+ activesupport (~> 3.0.0)
21
+ awesome_print (0.2.1)
22
+ builder (2.1.2)
23
+ diff-lcs (1.1.2)
24
+ ffi (0.6.3)
25
+ rake (>= 0.8.7)
26
+ i18n (0.4.2)
27
+ mocha (0.9.9)
28
+ rake
29
+ rake (0.8.7)
30
+ rspec (2.0.1)
31
+ rspec-core (~> 2.0.1)
32
+ rspec-expectations (~> 2.0.1)
33
+ rspec-mocks (~> 2.0.1)
34
+ rspec-core (2.0.1)
35
+ rspec-expectations (2.0.1)
36
+ diff-lcs (>= 1.1.2)
37
+ rspec-mocks (2.0.1)
38
+ rspec-core (~> 2.0.1)
39
+ rspec-expectations (~> 2.0.1)
40
+ sqlite3 (0.1.1)
41
+ ffi (>= 0.6.3)
42
+ tzinfo (0.3.23)
43
+ wirble (0.1.3)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ activerecord
50
+ awesome_print
51
+ constantize!
52
+ mocha
53
+ rspec
54
+ sqlite3
55
+ wirble
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # constantize
2
+
3
+ ## Description
4
+
5
+ Simple, dynamic and efficient activerecord model constants.
6
+
7
+ Ever wanted to be able to be able to do something like:
8
+
9
+ <pre>
10
+ case buoy.buoy_type
11
+ when BuoyType::NOAA
12
+ ..
13
+ when BuoyType::SCRIPPS
14
+ ..
15
+ end
16
+ </pre>
17
+
18
+ or
19
+
20
+ <pre>
21
+ User.create(:login => :foo, :user_status => UserStatus::ACTIVE)
22
+ </pre>
23
+
24
+ but weren't sure the best / most efficient way to implement?
25
+
26
+ One way would be to do something like:
27
+
28
+ class BuoyType < ActiveRecord::Base
29
+ NOAA = find_by_name('noaa')
30
+ ..
31
+ end
32
+
33
+ which would work but in a production environment could result in a non-trivial amount
34
+ of unecessary db queries.
35
+
36
+ Another way would be to dynamically create the constants for all the rows in the given
37
+ table at rails start. However, for models w/hundreds of rows, e.g., Country, City,
38
+ this wouldn't be very efficient either.
39
+
40
+ This gem minimizes the db calls by memoizing the finder that is used to look up the constant
41
+ values. So, it depends on your app server but only the first refernece to a given constant
42
+ should require a db query (see the code and specs for more details).
43
+
44
+ ## Install
45
+
46
+ ### Manual Install
47
+
48
+ Standard gem install:
49
+
50
+ <pre>
51
+ gem install constantize
52
+ </pre>
53
+
54
+ After installing the gem you would need to require it:
55
+
56
+ <pre>
57
+ require 'constantize'
58
+ </pre>
59
+
60
+ ### Rails 2.x / No Bundler
61
+
62
+ In a Rails 2.x project you can add this to your environment.rb:
63
+
64
+ <pre>
65
+ config.gem 'constantize'
66
+ </pre>
67
+
68
+ followed by:
69
+
70
+ <pre>
71
+ rake gems:install
72
+ </pre>
73
+
74
+ ### Rails 3.x / Bundler
75
+
76
+ In Rails 3.x add this to your Gemfile:
77
+
78
+ <pre>
79
+ gem 'constantize'
80
+ </pre>
81
+
82
+ followed by:
83
+
84
+ <pre>
85
+ bundle install
86
+ </pre>
87
+
88
+ ## Usage
89
+
90
+ In the model that you will be "constantizing" simply add the following to the top:
91
+
92
+ constantize :key
93
+
94
+ where :key is the name of the field that will be used to build the finder.
95
+
96
+ E.g.,
97
+
98
+ class AccountStatus < ActiveRecord::Base
99
+ constantize :name
100
+ ..
101
+ end
102
+
103
+ this would assume that your account_statuses table looked something like:
104
+
105
+ +----+---------+
106
+ | id | name |
107
+ +----+---------+
108
+ | 1 | active |
109
+ | .. |
110
+ +----+---------+
111
+
112
+ if your table used a different field, say :title, rather than :name:
113
+
114
+ +----+---------+
115
+ | id | title |
116
+ +----+---------+
117
+ | 1 | active |
118
+ | .. |
119
+ +----+---------+
120
+
121
+ then your model definition would look like:
122
+
123
+ class AccountStatus < ActiveRecord::Base
124
+ constantize :title
125
+ ..
126
+ end
127
+
128
+ Finally, if you wanted only the :id to be returned from the constant call (rather than
129
+ the entire model) you could do:
130
+
131
+
132
+ class AccountStatus < ActiveRecord::Base
133
+ constantize :name, :id
134
+ ..
135
+ end
136
+
137
+ and your call to AccountStatus::ACTIVE would return only the interger :id value (1 in this
138
+ case).
139
+
140
+ ## Note on Patches/Pull Requests
141
+
142
+ * Fork the project.
143
+ * Make your feature addition or bug fix.
144
+ * Add tests for it. This is important so I don't break it in a
145
+ future version unintentionally.
146
+ * Commit, do not mess with rakefile, version, or history.
147
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
148
+ * Send me a pull request. Bonus points for topic branches.
149
+
150
+ ## Copyright
151
+
152
+ Copyright (c) 2010 Adam Weller. See LICENSE for details.
153
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "constantize/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "constantize"
7
+ s.version = Constantize::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Adam Weller"]
10
+ s.email = ["mincheastwood@gmail.com"]
11
+ s.homepage = "http://rubygems.org/gems/constantize"
12
+ s.summary = %q{Simple, dynamic and efficient activerecord model constants.}
13
+ s.description = %q{This gem provides dynamically created constants for activerecord models}
14
+
15
+ s.rubyforge_project = "constantize"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency "rspec"
23
+ s.add_development_dependency "activerecord"
24
+ s.add_development_dependency "sqlite3"
25
+ s.add_development_dependency "mocha"
26
+ s.add_development_dependency "wirble"
27
+ s.add_development_dependency "awesome_print"
28
+ end
@@ -0,0 +1,40 @@
1
+ module Constantize
2
+ def self.included(base)
3
+ base.extend ClassMethods
4
+ end
5
+
6
+ module ClassMethods
7
+ extend ActiveSupport::Memoizable
8
+
9
+ # :key => the field name that we are going to use to build the finder
10
+ # :field => only return this field of data (optional, default is the entire object)
11
+ def constantize(key, field = nil)
12
+ # Yes, those are instance variables at the class level
13
+ @key = key
14
+ @field = field
15
+ end
16
+
17
+ def const_missing(*args)
18
+ if args.size == 1
19
+ value = args[0].to_s.downcase
20
+ value = constant_for(@key, value, @field)
21
+ return value if value
22
+ end
23
+
24
+ super(*args)
25
+ end
26
+
27
+ def constant_for(key, value, field = nil)
28
+ method = "find_by_#{key}"
29
+ value = self.send(method, value) rescue nil
30
+ return unless value
31
+
32
+ field ? value.send(field) : value
33
+ end
34
+ memoize :constant_for
35
+ end
36
+ end
37
+
38
+ class ActiveRecord::Base
39
+ include Constantize
40
+ end
@@ -0,0 +1,3 @@
1
+ module Constantize
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ require 'constantize'
4
+
5
+ describe Constantize do
6
+
7
+ context "returning model" do
8
+ it "should set key to constantize" do
9
+ BuoyType.instance_variable_get(:@key).should == :name
10
+ end
11
+
12
+ it "should memoize constants" do
13
+ buoy_type = BuoyType.create(:name => 'noaa')
14
+ BuoyType.expects(:find_by_name).with('noaa').returns(buoy_type)
15
+ BuoyType::NOAA.id.should == 1
16
+
17
+ # The following should fail unless memoization is working
18
+ # because :find_by_name has already met the expectation above
19
+ BuoyType::NOAA.id.should == 1
20
+ end
21
+
22
+ it "should not break const_missing for missing constants" do
23
+ lambda { BuoyType::FOO }.should raise_error(NameError)
24
+ end
25
+ end
26
+
27
+ context "returning :id" do
28
+ it "should set key to constantize" do
29
+ UserStatus.instance_variable_get(:@key).should == :name
30
+ end
31
+
32
+ it "should set field to constantize" do
33
+ UserStatus.instance_variable_get(:@field).should == :id
34
+ end
35
+
36
+ it "should memoize constants" do
37
+ buoy_type = UserStatus.create(:name => 'active')
38
+ UserStatus.expects(:find_by_name).with('active').returns(buoy_type)
39
+ UserStatus::ACTIVE.should == 1
40
+
41
+ # The following should fail unless memoization is working
42
+ # because :find_by_name has already met the expectation above
43
+ UserStatus::ACTIVE.should == 1
44
+ end
45
+
46
+ it "should not break const_missing for missing constants" do
47
+ lambda { UserStatus::FOO }.should raise_error(NameError)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ class BuoyType < ActiveRecord::Base
2
+ validates_presence_of :name
3
+
4
+ require 'constantize'
5
+
6
+ constantize :name
7
+ end
@@ -0,0 +1,7 @@
1
+ class UserStatus < ActiveRecord::Base
2
+ validates_presence_of :name
3
+
4
+ require 'constantize'
5
+
6
+ constantize :name, :id
7
+ end
@@ -0,0 +1,32 @@
1
+ require "active_record"
2
+ require "mocha"
3
+
4
+ #ActiveRecord::Schema.verbose = false
5
+
6
+ begin
7
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
8
+ rescue ArgumentError
9
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
10
+ end
11
+
12
+ ActiveRecord::Base.configurations = true
13
+ ActiveRecord::Schema.define(:version => 1) do
14
+ create_table :buoy_types do |t|
15
+ t.string :name
16
+ t.datetime :created_at
17
+ t.datetime :updated_at
18
+ end
19
+
20
+ create_table :user_statuses do |t|
21
+ t.string :name
22
+ t.datetime :created_at
23
+ t.datetime :updated_at
24
+ end
25
+ end
26
+
27
+ require File.dirname(__FILE__) + '/libs/buoy_type'
28
+ require File.dirname(__FILE__) + '/libs/user_status'
29
+
30
+ RSpec.configure do |config|
31
+ config.mock_with :mocha
32
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: constantize
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Adam Weller
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-30 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: activerecord
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: sqlite3
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: mocha
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :development
71
+ version_requirements: *id004
72
+ - !ruby/object:Gem::Dependency
73
+ name: wirble
74
+ prerelease: false
75
+ requirement: &id005 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ type: :development
84
+ version_requirements: *id005
85
+ - !ruby/object:Gem::Dependency
86
+ name: awesome_print
87
+ prerelease: false
88
+ requirement: &id006 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :development
97
+ version_requirements: *id006
98
+ description: This gem provides dynamically created constants for activerecord models
99
+ email:
100
+ - mincheastwood@gmail.com
101
+ executables: []
102
+
103
+ extensions: []
104
+
105
+ extra_rdoc_files: []
106
+
107
+ files:
108
+ - .gitignore
109
+ - Gemfile
110
+ - Gemfile.lock
111
+ - README.md
112
+ - Rakefile
113
+ - constantize.gemspec
114
+ - lib/constantize.rb
115
+ - lib/constantize/version.rb
116
+ - spec/constantize_spec.rb
117
+ - spec/libs/buoy_type.rb
118
+ - spec/libs/user_status.rb
119
+ - spec/spec_helper.rb
120
+ has_rdoc: true
121
+ homepage: http://rubygems.org/gems/constantize
122
+ licenses: []
123
+
124
+ post_install_message:
125
+ rdoc_options: []
126
+
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ segments:
135
+ - 0
136
+ version: "0"
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ segments:
143
+ - 0
144
+ version: "0"
145
+ requirements: []
146
+
147
+ rubyforge_project: constantize
148
+ rubygems_version: 1.3.7
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: Simple, dynamic and efficient activerecord model constants.
152
+ test_files:
153
+ - spec/constantize_spec.rb
154
+ - spec/libs/buoy_type.rb
155
+ - spec/libs/user_status.rb
156
+ - spec/spec_helper.rb