acts_as_lookup 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +27 -2
- data/TODO +1 -0
- data/acts_as_lookup.gemspec +13 -24
- data/lib/acts_as_lookup.rb +43 -11
- metadata +28 -47
- data/spec/acts_as_lookup_spec.rb +0 -436
- data/spec/spec_helper.rb +0 -1
data/README.rdoc
CHANGED
@@ -42,9 +42,34 @@ TODO: probably won't work yet...at least need to add an _id attribute to the ass
|
|
42
42
|
|
43
43
|
Some work is yet to be done to support general classes using acts_as_lookup
|
44
44
|
|
45
|
-
== Configuration
|
45
|
+
== Configuration
|
46
46
|
|
47
|
-
|
47
|
+
+acts_as_lookup+ accepts an options hash with one required key: +:values+, which is
|
48
|
+
an array of hashes that contain lookup data (see above).
|
49
|
+
|
50
|
+
Other options available:
|
51
|
+
|
52
|
+
==== +:sync_with_db+
|
53
|
+
|
54
|
+
Fetches existing records from the db and merges them into the cached values (default true).
|
55
|
+
|
56
|
+
==== +:write_to_db+
|
57
|
+
|
58
|
+
Writes any missing values to the db (default true).
|
59
|
+
|
60
|
+
==== +:add_query_methods+
|
61
|
+
|
62
|
+
Defines query methods on instances of the lookup model for checking the identity of a value (default false). For example:
|
63
|
+
|
64
|
+
def Status < ActiveRecord::Base
|
65
|
+
VALS = [ { :id => 1, :name => "active", },
|
66
|
+
{ :id => 2, :name => "disabled", }
|
67
|
+
]
|
68
|
+
acts_as_lookup :values => VALS, :add_query_methods => true
|
69
|
+
end
|
70
|
+
|
71
|
+
Status.active.active? # => true
|
72
|
+
Status.active.disabled? # => false
|
48
73
|
|
49
74
|
== Development
|
50
75
|
|
data/TODO
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
Things to work on:
|
2
2
|
|
3
|
+
* TESTING: commented out rspec gem in Rakefile...need to resurrect to reenable testing! May just need to specify rspec version, but would probably be good to bring up to date. :(
|
3
4
|
|
4
5
|
* for now, it's required to include :id in the values hashes; enhance to allow leaving :id off (by specifying :uniqueness_column) and fetch them from db (option will only be available for :sync_with_db == true)
|
5
6
|
* allow gem to be used outside Rails by specifying alternative implementations for db-hitting methods....e.g. add configuration values that specify method names to call to load/write/remove from db. see +acts_as_lookup_fetch_values+ method comment.
|
data/acts_as_lookup.gemspec
CHANGED
@@ -1,44 +1,33 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.
|
7
|
+
s.name = "acts_as_lookup"
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Percival"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
|
15
|
-
push these to the associated db tables (or not). Also dynamically adds helpful
|
16
|
-
class-level methods to access singleton instances of each value in your lookup
|
17
|
-
table.
|
18
|
-
}
|
19
|
-
s.email = %q{percivalatdiscovereadsdotcom}
|
12
|
+
s.date = "2012-07-31"
|
13
|
+
s.description = "Provides an easy means for creating models that act like enumerations or lookup\ntables. You can specify the lookup values in your Rails models and can lazily\npush these to the associated db tables (or not). Also dynamically adds helpful\nclass-level methods to access singleton instances of each value in your lookup\ntable.\n"
|
14
|
+
s.email = "percivalatdiscovereadsdotcom"
|
20
15
|
s.extra_rdoc_files = [
|
21
16
|
"LICENSE",
|
22
|
-
|
23
|
-
|
17
|
+
"README.rdoc",
|
18
|
+
"TODO"
|
24
19
|
]
|
25
20
|
s.files = [
|
26
21
|
"README.rdoc",
|
27
|
-
|
28
|
-
|
22
|
+
"acts_as_lookup.gemspec",
|
23
|
+
"lib/acts_as_lookup.rb"
|
29
24
|
]
|
30
|
-
s.homepage =
|
31
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
25
|
+
s.homepage = "http://github.com/bmpercy/acts_as_lookup"
|
32
26
|
s.require_paths = ["lib"]
|
33
|
-
s.rubygems_version =
|
34
|
-
s.summary =
|
35
|
-
s.test_files = [
|
36
|
-
"spec/acts_as_lookup_spec.rb",
|
37
|
-
"spec/spec_helper.rb"
|
38
|
-
]
|
27
|
+
s.rubygems_version = "1.8.15"
|
28
|
+
s.summary = "Helpful for creating lookup-table-like models"
|
39
29
|
|
40
30
|
if s.respond_to? :specification_version then
|
41
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
31
|
s.specification_version = 3
|
43
32
|
|
44
33
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
data/lib/acts_as_lookup.rb
CHANGED
@@ -60,6 +60,9 @@ module ActsAsLookupClassMethods
|
|
60
60
|
# FUTURE: allow for a different column to be used for generating class
|
61
61
|
# accessor methods
|
62
62
|
@acts_as_lookup_by_name.each_pair do |name,val|
|
63
|
+
if acts_as_lookup_options[:add_query_methods]
|
64
|
+
self.acts_as_lookup_add_query_method name
|
65
|
+
end
|
63
66
|
self.acts_as_lookup_add_shortcut name
|
64
67
|
end
|
65
68
|
|
@@ -123,30 +126,51 @@ module ActsAsLookupClassMethods
|
|
123
126
|
# adds a class method to access a particular lookup value via a shortcut
|
124
127
|
# method
|
125
128
|
#
|
129
|
+
# FUTURE: will allow for any column to be used here; for now, hardcoded
|
130
|
+
# to lookup by name
|
131
|
+
#-----------------------------------------------------------------------------
|
132
|
+
def acts_as_lookup_add_shortcut(name)
|
133
|
+
method_name = get_method_name(name)
|
134
|
+
if respond_to?(method_name.to_sym)
|
135
|
+
raise "Cannot create method '#{method_name}' to #{self.inspect} " +
|
136
|
+
"as it conflicts with existing method with same name"
|
137
|
+
end
|
138
|
+
|
139
|
+
instance_eval "def #{method_name}; self.lookup_by_name '#{name}'; end"
|
140
|
+
end
|
141
|
+
|
142
|
+
# adds an instance method of the form [lookup_value_name]? to check the
|
143
|
+
# identity of a lookup object
|
144
|
+
#-----------------------------------------------------------------------------
|
145
|
+
def acts_as_lookup_add_query_method(lookup_name)
|
146
|
+
method_name = "#{get_method_name(lookup_name)}?"
|
147
|
+
if respond_to?(method_name.to_sym)
|
148
|
+
raise "Cannot create method '#{method_name}?' to #{self.inspect} " +
|
149
|
+
"as it conflicts with existing method with same name"
|
150
|
+
end
|
151
|
+
|
152
|
+
define_method(method_name) { self.name == lookup_name }
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
126
157
|
# does the following transformations:
|
127
158
|
# - converts spaces to underscores
|
128
159
|
# - downcases entire method name unless the constant is already all caps,
|
129
160
|
# in which case, leaves method name in all caps
|
130
161
|
# - checks for name conflicts and raises exception if the shortcut method
|
131
162
|
# name collides with existing method
|
132
|
-
#
|
133
|
-
# FUTURE: will allow for any column to be used here; for now, hardcoded
|
134
|
-
# to lookup by name
|
135
163
|
#-----------------------------------------------------------------------------
|
136
|
-
def
|
164
|
+
def get_method_name(name)
|
137
165
|
method_name = name.gsub(/ /, '_')
|
138
166
|
unless method_name.upcase == method_name
|
139
167
|
method_name.downcase!
|
140
168
|
end
|
141
|
-
|
142
|
-
raise "Cannot create method '#{method_name}' to #{self.inspect} " +
|
143
|
-
"as it conflicts with existing method with same name"
|
144
|
-
end
|
145
|
-
|
146
|
-
instance_eval "def #{method_name}; self.lookup_by_name '#{name}'; end"
|
169
|
+
method_name
|
147
170
|
end
|
148
171
|
end
|
149
172
|
|
173
|
+
|
150
174
|
# modify object to allow any class to act like a lookup class
|
151
175
|
#------------------------------------------------------------------------------
|
152
176
|
class Object
|
@@ -161,6 +185,7 @@ class Object
|
|
161
185
|
|
162
186
|
options.merge!(:sync_with_db => true) unless options.include?(:sync_with_db)
|
163
187
|
options.merge!(:write_to_db => true) unless options.include?(:write_to_db)
|
188
|
+
options.merge!(:add_query_methods => false) unless options.include?(:add_query_methods)
|
164
189
|
# FUTURE:
|
165
190
|
# :remove_from_db => false,
|
166
191
|
# :shortcut_method_column => :name
|
@@ -219,8 +244,15 @@ if defined?(ActiveRecord)
|
|
219
244
|
# double-class loading problems that arise in rails: see for example
|
220
245
|
# https://rails.lighthouseapp.com/projects/8994/tickets/1339
|
221
246
|
# it may create other problems though, so be careful....
|
247
|
+
rails_root = nil
|
248
|
+
begin
|
249
|
+
rails_root = Rails.root
|
250
|
+
rescue
|
251
|
+
end
|
252
|
+
# fallback for Rails 2
|
253
|
+
rails_root ||= RAILS_ROOT if defined?(RAILS_ROOT)
|
222
254
|
if !Object.const_defined?(cname)
|
223
|
-
require File.join(
|
255
|
+
require File.join(rails_root, 'app', 'models', cname.underscore)
|
224
256
|
end
|
225
257
|
end
|
226
258
|
end
|
metadata
CHANGED
@@ -1,82 +1,63 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_lookup
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 0.1.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Brian Percival
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2011-02-23 00:00:00 -08:00
|
19
|
-
default_executable:
|
12
|
+
date: 2012-07-31 00:00:00.000000000 Z
|
20
13
|
dependencies: []
|
14
|
+
description: ! 'Provides an easy means for creating models that act like enumerations
|
15
|
+
or lookup
|
21
16
|
|
22
|
-
description: |
|
23
|
-
Provides an easy means for creating models that act like enumerations or lookup
|
24
17
|
tables. You can specify the lookup values in your Rails models and can lazily
|
18
|
+
|
25
19
|
push these to the associated db tables (or not). Also dynamically adds helpful
|
20
|
+
|
26
21
|
class-level methods to access singleton instances of each value in your lookup
|
22
|
+
|
27
23
|
table.
|
28
24
|
|
25
|
+
'
|
29
26
|
email: percivalatdiscovereadsdotcom
|
30
27
|
executables: []
|
31
|
-
|
32
28
|
extensions: []
|
33
|
-
|
34
|
-
extra_rdoc_files:
|
29
|
+
extra_rdoc_files:
|
35
30
|
- LICENSE
|
36
31
|
- README.rdoc
|
37
32
|
- TODO
|
38
|
-
files:
|
33
|
+
files:
|
39
34
|
- README.rdoc
|
40
35
|
- acts_as_lookup.gemspec
|
41
36
|
- lib/acts_as_lookup.rb
|
42
37
|
- LICENSE
|
43
38
|
- TODO
|
44
|
-
- spec/acts_as_lookup_spec.rb
|
45
|
-
- spec/spec_helper.rb
|
46
|
-
has_rdoc: true
|
47
39
|
homepage: http://github.com/bmpercy/acts_as_lookup
|
48
40
|
licenses: []
|
49
|
-
|
50
41
|
post_install_message:
|
51
|
-
rdoc_options:
|
52
|
-
|
53
|
-
require_paths:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
54
44
|
- lib
|
55
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
46
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
- 0
|
63
|
-
version: "0"
|
64
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
52
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
70
|
-
segments:
|
71
|
-
- 0
|
72
|
-
version: "0"
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
73
57
|
requirements: []
|
74
|
-
|
75
58
|
rubyforge_project:
|
76
|
-
rubygems_version: 1.
|
59
|
+
rubygems_version: 1.8.15
|
77
60
|
signing_key:
|
78
61
|
specification_version: 3
|
79
62
|
summary: Helpful for creating lookup-table-like models
|
80
|
-
test_files:
|
81
|
-
- spec/acts_as_lookup_spec.rb
|
82
|
-
- spec/spec_helper.rb
|
63
|
+
test_files: []
|
data/spec/acts_as_lookup_spec.rb
DELETED
@@ -1,436 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
class Base
|
5
|
-
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
# add a helper method that's defined in rails...the gem only uses it if
|
10
|
-
# ActiveRecord is defined
|
11
|
-
class String
|
12
|
-
def camelize
|
13
|
-
splits = self.split("_")
|
14
|
-
splits.map! do |s|
|
15
|
-
s.downcase!
|
16
|
-
s[0] = s[0].upcase
|
17
|
-
s
|
18
|
-
end
|
19
|
-
splits.join
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# a dummy lookup class (see has_lookup tests)
|
24
|
-
class DummyLookup < Struct.new(:id, :name)
|
25
|
-
def self.one_instance
|
26
|
-
self.new(1,"dummy one")
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.another_instance
|
30
|
-
self.new(2,"dummy two")
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.yet_another_instance
|
34
|
-
self.new(3,"dummy three")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "ActsAsLookup" do
|
39
|
-
# this is kinda hacky, but what we're doing here is trying to clear out all
|
40
|
-
# entries in namespace for acts as lookup between each run so that we don't
|
41
|
-
# see any bugs that are tied to double-loading the acts as lookup
|
42
|
-
# infrastructure
|
43
|
-
# so we:
|
44
|
-
# - unload all classes that are either part of gem or are test classes
|
45
|
-
# - reload the acts as lookup lib file
|
46
|
-
# - re-declare each of the test classes we're using
|
47
|
-
#
|
48
|
-
# (alternative would be to generate new classes for each test but that's
|
49
|
-
# likely equally messy with dynamically defined class names etc.)
|
50
|
-
#-----------------------------------------------------------------------------
|
51
|
-
before :each do
|
52
|
-
Object.constants.each do |klass|
|
53
|
-
if (klass.to_s =~ /LookupClass/) && (Object.const_defined?(klass.to_s))
|
54
|
-
Object.send(:remove_const,klass.to_s)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
load File.join(File.dirname(__FILE__), '../lib/acts_as_lookup.rb')
|
58
|
-
|
59
|
-
class ClassOnlyLookupClass < Struct.new(:id, :name); end
|
60
|
-
|
61
|
-
# another one to detect shared var conflict
|
62
|
-
class SecondClassOnlyLookupClass < Struct.new(:id, :name); end
|
63
|
-
|
64
|
-
# all values are in db and in class specification
|
65
|
-
class ActiveRecordLookupClassWithAllValuesInDbAndClass < Struct.new(:id, :name)
|
66
|
-
ALL_VALUES = [self.new(1, "one"), self.new(2, "two")]
|
67
|
-
|
68
|
-
def self.all_values
|
69
|
-
ALL_VALUES
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.class_vals
|
73
|
-
all_values
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.all
|
77
|
-
all_values
|
78
|
-
end
|
79
|
-
end
|
80
|
-
# some values are in db; the rest are in class specification
|
81
|
-
class ActiveRecordLookupClassWithSomeValuesInDb < Struct.new(:id, :name)
|
82
|
-
ALL_VALUES = [self.new(1, "one"), self.new(2, "two"), self.new(3, "three")]
|
83
|
-
|
84
|
-
def self.all_values
|
85
|
-
ALL_VALUES
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.db_missing_val
|
89
|
-
all_values[1]
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.class_vals
|
93
|
-
all_values
|
94
|
-
end
|
95
|
-
|
96
|
-
# don't return all vals in query
|
97
|
-
def self.all
|
98
|
-
all_values.reject { |v| v.id == db_missing_val.id }
|
99
|
-
end
|
100
|
-
|
101
|
-
# a method for checking what's saved when save! is called
|
102
|
-
def self.created_val(val)
|
103
|
-
# doesn't need to do anything
|
104
|
-
end
|
105
|
-
|
106
|
-
# "active record" method for creating new lookup values
|
107
|
-
def save!
|
108
|
-
self.class.created_val(self)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
# all values in db; some are in class specification
|
112
|
-
class ActiveRecordLookupClassWithSomeValuesInClass < Struct.new(:id, :name)
|
113
|
-
ALL_VALUES = [self.new(1, "one"), self.new(2, "two"), self.new(3, "three")]
|
114
|
-
|
115
|
-
def self.all_values
|
116
|
-
ALL_VALUES
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.class_missing_val
|
120
|
-
all_values[1]
|
121
|
-
end
|
122
|
-
|
123
|
-
def self.class_vals
|
124
|
-
all_values.reject { |v| v.id == class_missing_val.id }
|
125
|
-
end
|
126
|
-
|
127
|
-
# return all vals in query
|
128
|
-
def self.all
|
129
|
-
all_values
|
130
|
-
end
|
131
|
-
end
|
132
|
-
class ClassWithLookupClass < ActiveRecord::Base
|
133
|
-
attr_accessor :dummy_lookup_id
|
134
|
-
attr_accessor :other_lookup_id
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
#-----------------------------------------------------------------------------
|
140
|
-
describe "class-only (non ActiveRecord) lookup classes" do
|
141
|
-
it "should not insert any new values if :write_to_db is false" do
|
142
|
-
klass = ClassOnlyLookupClass
|
143
|
-
klass.should_not_receive :acts_as_lookup_write_missing_values
|
144
|
-
instances = [klass.new(1, "one"), klass.new(2, "two")]
|
145
|
-
|
146
|
-
klass.acts_as_lookup(
|
147
|
-
:sync_with_db => false,
|
148
|
-
:values => instances
|
149
|
-
)
|
150
|
-
end
|
151
|
-
|
152
|
-
it "should not query values if :sync_with_db is false" do
|
153
|
-
klass = ClassOnlyLookupClass
|
154
|
-
klass.should_not_receive :all
|
155
|
-
instances = [klass.new(1, "one"), klass.new(2, "two")]
|
156
|
-
|
157
|
-
klass.acts_as_lookup(
|
158
|
-
:sync_with_db => false,
|
159
|
-
:values => instances
|
160
|
-
)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
# "active record" tests
|
165
|
-
# note: these test classes aren't really active record classes (to enable
|
166
|
-
# testing in absence of active record), but mimic enough of the
|
167
|
-
# interface for the tests
|
168
|
-
|
169
|
-
#-----------------------------------------------------------------------------
|
170
|
-
describe "when active record lookup class specifies all values and db has all values" do
|
171
|
-
it "should run select query if :sync_with_db is true" do
|
172
|
-
klass = ActiveRecordLookupClassWithAllValuesInDbAndClass
|
173
|
-
|
174
|
-
klass.should_receive(:all).and_return klass.all_values
|
175
|
-
|
176
|
-
klass.acts_as_lookup(
|
177
|
-
:values => klass.class_vals
|
178
|
-
)
|
179
|
-
end
|
180
|
-
|
181
|
-
it "should not insert any new values even if :write_to_db is true" do
|
182
|
-
klass = ActiveRecordLookupClassWithAllValuesInDbAndClass
|
183
|
-
|
184
|
-
klass.should_not_receive(:new)
|
185
|
-
|
186
|
-
klass.acts_as_lookup(
|
187
|
-
:write_to_db => true,
|
188
|
-
:values => klass.class_vals
|
189
|
-
)
|
190
|
-
end
|
191
|
-
|
192
|
-
it "should return correct value accessed by lookup_by_id" do
|
193
|
-
klass = ActiveRecordLookupClassWithAllValuesInDbAndClass
|
194
|
-
klass.acts_as_lookup(
|
195
|
-
:write_to_db => true,
|
196
|
-
:values => klass.class_vals
|
197
|
-
)
|
198
|
-
|
199
|
-
klass.lookup_by_id(klass.all_values.first.id).should == klass.all_values.first
|
200
|
-
end
|
201
|
-
|
202
|
-
it "should return correct value accessed by lookup_by_name" do
|
203
|
-
klass = ActiveRecordLookupClassWithAllValuesInDbAndClass
|
204
|
-
klass.acts_as_lookup(
|
205
|
-
:write_to_db => true,
|
206
|
-
:values => klass.class_vals
|
207
|
-
)
|
208
|
-
|
209
|
-
klass.lookup_by_name(klass.all_values.last.name).should == klass.all_values.last
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
#-----------------------------------------------------------------------------
|
214
|
-
describe "when lookup class specifies all lookup values but db only specifies some" do
|
215
|
-
before :each do
|
216
|
-
@klass = ActiveRecordLookupClassWithSomeValuesInDb
|
217
|
-
end
|
218
|
-
|
219
|
-
it "should run select query if :sync_with_db is true" do
|
220
|
-
all_result = @klass.all
|
221
|
-
|
222
|
-
@klass.should_receive(:all).and_return all_result
|
223
|
-
|
224
|
-
@klass.acts_as_lookup(
|
225
|
-
:values => @klass.class_vals
|
226
|
-
)
|
227
|
-
end
|
228
|
-
|
229
|
-
it "should insert any new values when :write_to_db is true" do
|
230
|
-
# this is a dummy class method that gets called when instance method
|
231
|
-
# save! is called, so we can check what was created
|
232
|
-
@klass.should_receive(:created_val) { |val|
|
233
|
-
val.id.should == @klass.db_missing_val.id
|
234
|
-
val.name.should == @klass.db_missing_val.name
|
235
|
-
}
|
236
|
-
|
237
|
-
@klass.acts_as_lookup(
|
238
|
-
:write_to_db => true,
|
239
|
-
:values => @klass.class_vals
|
240
|
-
)
|
241
|
-
end
|
242
|
-
|
243
|
-
it "should return correct value accessed by lookup_by_id" do
|
244
|
-
@klass.acts_as_lookup(
|
245
|
-
:write_to_db => true,
|
246
|
-
:values => @klass.class_vals
|
247
|
-
)
|
248
|
-
|
249
|
-
@klass.lookup_by_id(@klass.db_missing_val.id).should == @klass.db_missing_val
|
250
|
-
end
|
251
|
-
|
252
|
-
it "should return correct value accessed by lookup_by_name" do
|
253
|
-
@klass.acts_as_lookup(
|
254
|
-
:write_to_db => true,
|
255
|
-
:values => @klass.class_vals
|
256
|
-
)
|
257
|
-
|
258
|
-
@klass.lookup_by_name(@klass.db_missing_val.name).should == @klass.db_missing_val
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
#-----------------------------------------------------------------------------
|
263
|
-
describe "when lookup class doesn't specify all lookup values but db does" do
|
264
|
-
before :each do
|
265
|
-
@klass = ActiveRecordLookupClassWithSomeValuesInClass
|
266
|
-
end
|
267
|
-
|
268
|
-
it "should run select query if :sync_with_db is true" do
|
269
|
-
all_result = @klass.all
|
270
|
-
|
271
|
-
@klass.should_receive(:all).and_return all_result
|
272
|
-
|
273
|
-
@klass.acts_as_lookup(
|
274
|
-
:values => @klass.class_vals
|
275
|
-
)
|
276
|
-
end
|
277
|
-
|
278
|
-
it "shouldn't insert any new values even if :write_to_db is true" do
|
279
|
-
@klass.should_not_receive(:new)
|
280
|
-
|
281
|
-
@klass.acts_as_lookup(
|
282
|
-
:write_to_db => true,
|
283
|
-
:values => @klass.class_vals
|
284
|
-
)
|
285
|
-
end
|
286
|
-
|
287
|
-
it "should return correct value accessed by lookup_by_id" do
|
288
|
-
@klass.acts_as_lookup(
|
289
|
-
:write_to_db => true,
|
290
|
-
:values => @klass.class_vals
|
291
|
-
)
|
292
|
-
|
293
|
-
@klass.lookup_by_id(@klass.class_missing_val.id).should == @klass.class_missing_val
|
294
|
-
end
|
295
|
-
|
296
|
-
it "should return correct value accessed by lookup_by_name" do
|
297
|
-
@klass.acts_as_lookup(
|
298
|
-
:write_to_db => true,
|
299
|
-
:values => @klass.class_vals
|
300
|
-
)
|
301
|
-
|
302
|
-
@klass.lookup_by_name(@klass.class_missing_val.name).should == @klass.class_missing_val
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
#-----------------------------------------------------------------------------
|
307
|
-
describe "single-lookup-class scenarios" do
|
308
|
-
before :each do
|
309
|
-
@klass = ActiveRecordLookupClassWithSomeValuesInClass
|
310
|
-
@klass.acts_as_lookup(:values => @klass.class_vals)
|
311
|
-
end
|
312
|
-
|
313
|
-
it "should not query values on calls to lookup_by_id" do
|
314
|
-
@klass.should_not_receive(:find)
|
315
|
-
@klass.should_not_receive(:find_by_id)
|
316
|
-
|
317
|
-
@klass.lookup_by_id(1)
|
318
|
-
end
|
319
|
-
|
320
|
-
it "should not query values calls to lookup_by_name" do
|
321
|
-
@klass.should_not_receive(:find)
|
322
|
-
@klass.should_not_receive(:find_by_name)
|
323
|
-
|
324
|
-
@klass.lookup_by_name('one')
|
325
|
-
end
|
326
|
-
|
327
|
-
it "should dynamically add specific methods to access lookup value by name" do
|
328
|
-
@klass.all_values.each do |val|
|
329
|
-
@klass.send(val.name.to_sym).should == val
|
330
|
-
end
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
describe "two-lookup-class scenarios" do
|
335
|
-
it "should return the correct object (type) even if ids overlap between two lookup classes" do
|
336
|
-
klass1 = ClassOnlyLookupClass
|
337
|
-
klass2 = SecondClassOnlyLookupClass
|
338
|
-
instances1 = [klass1.new(1, "one"), klass1.new(2, "two")]
|
339
|
-
instances2 = [klass2.new(1, "class two one"), klass2.new(2, "class two two")]
|
340
|
-
klass1.acts_as_lookup(
|
341
|
-
:sync_with_db => false,
|
342
|
-
:values => instances1
|
343
|
-
)
|
344
|
-
klass2.acts_as_lookup(
|
345
|
-
:sync_with_db => false,
|
346
|
-
:values => instances2
|
347
|
-
)
|
348
|
-
|
349
|
-
klass1.lookup_by_id(1).should == instances1.first
|
350
|
-
klass2.lookup_by_id(1).should == instances2.first
|
351
|
-
end
|
352
|
-
|
353
|
-
it "should return the correct object (type) even if names overlap between two lookup classes" do
|
354
|
-
klass1 = ClassOnlyLookupClass
|
355
|
-
klass2 = SecondClassOnlyLookupClass
|
356
|
-
instances1 = [klass1.new(3, "three"), klass1.new(4, "four")]
|
357
|
-
instances2 = [klass2.new(33, "three"), klass2.new(44, "four")]
|
358
|
-
klass1.acts_as_lookup(
|
359
|
-
:sync_with_db => false,
|
360
|
-
:values => instances1
|
361
|
-
)
|
362
|
-
klass2.acts_as_lookup(
|
363
|
-
:sync_with_db => false,
|
364
|
-
:values => instances2
|
365
|
-
)
|
366
|
-
|
367
|
-
klass1.lookup_by_name('four').should == instances1.last
|
368
|
-
klass2.lookup_by_name('four').should == instances2.last
|
369
|
-
end
|
370
|
-
|
371
|
-
it "should keep acts as lookup options separate for different lookup classes" do
|
372
|
-
klass1 = ClassOnlyLookupClass
|
373
|
-
klass2 = SecondClassOnlyLookupClass
|
374
|
-
instances1 = [klass1.new(1, "one"), klass1.new(2, "two")]
|
375
|
-
instances2 = [klass2.new(3, "three"), klass2.new(4, "four")]
|
376
|
-
klass1.acts_as_lookup(
|
377
|
-
:sync_with_db => false,
|
378
|
-
:values => instances1
|
379
|
-
)
|
380
|
-
klass2.acts_as_lookup(
|
381
|
-
:sync_with_db => false,
|
382
|
-
:values => instances2
|
383
|
-
)
|
384
|
-
|
385
|
-
klass1.acts_as_lookup_options[:values].should == instances1
|
386
|
-
klass2.acts_as_lookup_options[:values].should == instances2
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
describe "when using has_lookup to associate classes" do
|
391
|
-
it "should not make a db hit to look up a single record when accessing a has_lookup accessor" do
|
392
|
-
DummyLookup.acts_as_lookup(
|
393
|
-
:values => [DummyLookup.one_instance],
|
394
|
-
:sync_with_db => false
|
395
|
-
)
|
396
|
-
klass = ClassWithLookupClass
|
397
|
-
klass.has_lookup :dummy_lookup
|
398
|
-
lookup_instance = DummyLookup.one_instance
|
399
|
-
|
400
|
-
instance = klass.new
|
401
|
-
instance.dummy_lookup_id = lookup_instance.id
|
402
|
-
|
403
|
-
instance.dummy_lookup.should == lookup_instance
|
404
|
-
end
|
405
|
-
|
406
|
-
it "should set the id attribute of an object that has_lookup when the whole-object setter is used" do
|
407
|
-
DummyLookup.acts_as_lookup(
|
408
|
-
:values => [DummyLookup.another_instance],
|
409
|
-
:sync_with_db => false
|
410
|
-
)
|
411
|
-
klass = ClassWithLookupClass
|
412
|
-
klass.has_lookup :dummy_lookup
|
413
|
-
lookup_instance = DummyLookup.one_instance
|
414
|
-
|
415
|
-
instance = klass.new
|
416
|
-
instance.dummy_lookup = lookup_instance
|
417
|
-
|
418
|
-
instance.dummy_lookup_id.should == lookup_instance.id
|
419
|
-
end
|
420
|
-
|
421
|
-
it "should allow overriding the class name on a has_lookup association" do
|
422
|
-
DummyLookup.acts_as_lookup(
|
423
|
-
:values => [DummyLookup.yet_another_instance],
|
424
|
-
:sync_with_db => false
|
425
|
-
)
|
426
|
-
klass = ClassWithLookupClass
|
427
|
-
klass.has_lookup :other_lookup, :class_name => 'DummyLookup'
|
428
|
-
lookup_instance = DummyLookup.one_instance
|
429
|
-
|
430
|
-
instance = klass.new
|
431
|
-
instance.other_lookup = lookup_instance
|
432
|
-
|
433
|
-
instance.other_lookup_id.should == lookup_instance.id
|
434
|
-
end
|
435
|
-
end
|
436
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '../lib/acts_as_lookup')
|