rails_lookup 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -5,6 +5,8 @@ By: Nimrod Priell
5
5
 
6
6
  This gem adds an ActiveRecord macro to define memory-cached, dynamically growing, normalized lookup tables for entity 'type'-like objects. Or in plain English - if you want to have a table containing, say, ProductTypes which can grow with new types simply when you refer to them, and not keep the Product table containing a thousand repeating 'type="book"' entries - sit down and try to follow through.
7
7
 
8
+ Installation is described down the page.
9
+
8
10
  Motivation
9
11
  ----------
10
12
 
@@ -81,6 +83,7 @@ I've looked thoroughly for a nice rails solution to this, but after failing to f
81
83
 
82
84
  Installation
83
85
  ------------
86
+ First, run `gem install rails_lookup` to install the latest version of the gem.
84
87
 
85
88
  The result of this hook is that you get the exact syntax described above, with only two lines of code (no extra classes or anything):
86
89
  In your ActiveRecord object simply add
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('rails_lookup', '0.0.1') do |s|
5
+ Echoe.new('rails_lookup', '0.0.2') do |s|
6
6
  s.description = File.read(File.join(File.dirname(__FILE__), 'README'))
7
7
  s.summary = "Lookup table macro for ActiveRecords"
8
8
  s.url = "http://github.com/Nimster/RailsLookup/"
@@ -5,130 +5,149 @@
5
5
  # include ActiveRecord::Lookup
6
6
  # in your class that extends ActiveRecord::Base
7
7
  module ActiveRecord
8
- module Lookup
9
- #These will be defined as class methods.
10
- module ClassMethods
11
- #We define only this "macro". In your ActiveRecord entity (say, Car), use
12
- # lookup :car_type
13
- # which will create Car#car_type, Car#car_type=, Car#car_type_id,
14
- # Car#car_type_id= and CarType, an ActiveRecord with a name (String)
15
- # attribute, that has_many :cars.
16
- #
17
- # You can also use
18
- # lookup :car_type, :as => :type
19
- # which will do the same thing but create Car#type, Car#type=, Car#type_id
20
- # and Car#type_id= instead.
21
- def lookup(lookup_name, opts = {})
22
- as_name = opts[:as] || lookup_name
23
- mycls = self #Class I'm defined in
24
-
25
- #Create the new ActiveRecord for the lookup
26
- cls = Class.new(ActiveRecord::Base) do
27
- #It has_many of the containing class
28
- has_many mycls.to_s.split(/[A-Z]/).map(&:downcase).join('_').to_sym
29
-
30
- validates_uniqueness_of :name
31
- validates :name, :presence => true
32
-
33
- #Query the cache for the DB ID of a certain value
34
- def self.id_for(name, id = nil)
35
- class_variable_get(:@@rcaches)[name] ||= id
36
- end
8
+ module Lookup
9
+ #These will be defined as class methods so they can be called as "macros"
10
+ #like belongs_to
11
+ module ClassMethods
12
+ #We define only this "macro". In your ActiveRecord entity (say, Car), use
13
+ # lookup :car_type
14
+ # which will create Car#car_type, Car#car_type=, Car#car_type_id,
15
+ # Car#car_type_id= and CarType, an ActiveRecord with a name (String)
16
+ # attribute, that has_many :cars.
17
+ #
18
+ # You can also use
19
+ # lookup :car_type, :as => :type
20
+ # which will do the same thing but create Car#type, Car#type=, Car#type_id
21
+ # and Car#type_id= instead.
22
+ def lookup(lookup_name, opts = {})
23
+ as_name = opts[:as] || lookup_name
24
+
25
+ #Define the setter for the attribute by textual value
26
+ mycls = self #Class I'm defined in
27
+ #Ignore anonymous classes:
28
+ mycls_sym = mycls.name.tableize.to_sym unless mycls.to_s =~ /#<.*>/
29
+ lookup_cls_name = lookup_name.to_s.camelize
30
+ begin
31
+ #If it exists, just tack on the extra has_many
32
+ cls = Object.const_get lookup_cls_name
33
+ cls.has_many mycls_sym unless mycls_sym.blank? #for annon classes
34
+ rescue NameError
35
+ #Otherwise, actually define it
36
+ cls = Class.new(ActiveRecord::Base) do
37
+ has_many mycls_sym unless mycls_sym.blank? #For anon classes
38
+ validates_uniqueness_of :name
39
+ validates :name, :presence => true
40
+
41
+ def self.id_for(name, id = nil)
42
+ class_variable_get(:@@rcaches)[name] ||= id
43
+ end
37
44
 
38
- #This helper method is the "find_or_create" of the class that also
39
- #updates the DB. I didn't want to overwrite the original
40
- #find_or_create_by_name since it is linked with a lot of the rails
41
- #behaviour and I want to avoid altering that.
42
- def self.gen_id_for(val)
43
- id = id_for val
44
- if id.nil?
45
- #Define this new possible value
46
- new_db_obj = find_or_create_by_name val #You could just override this...
47
- id_for val, new_db_obj.id
48
- name_for new_db_obj.id, val
49
- id = new_db_obj.id
45
+ def self.gen_id_for(val)
46
+ id = id_for val
47
+ if id.nil?
48
+ #Define this new possible value
49
+ new_db_obj = find_or_create_by_name val #You could just override this...
50
+ id_for val, new_db_obj.id
51
+ name_for new_db_obj.id, val
52
+ id = new_db_obj.id
53
+ end
54
+ id
55
+ end
56
+
57
+ def self.name_for(id, name = nil)
58
+ class_variable_get(:@@caches)[id] ||= name
59
+ end
60
+
61
+ #This is especially useful for tests - you want deletion to also clear
62
+ #the caches otherwise odd stuff might happen
63
+ def self.delete_all(*args)
64
+ class_variable_set :@@caches, []
65
+ class_variable_set :@@rcaches, {}
66
+ super *args
67
+ end
50
68
  end
51
- id
69
+
70
+ Object.const_set lookup_cls_name, cls #Define it as a global class
52
71
  end
53
72
 
54
- #Query the cache for the value that goes with a certain DB ID
55
- def self.name_for(id, name = nil)
56
- class_variable_get(:@@caches)[id] ||= name
73
+
74
+ define_method("#{as_name.to_s}_id=") do |id|
75
+ write_attribute "#{as_name.to_s}".to_sym, id
57
76
  end
58
- end
59
77
 
60
- #Bind the created class to a name
61
- lookup_cls_name = lookup_name.to_s.split("_").map(&:capitalize).join("")
62
- Object.const_set lookup_cls_name, cls #Define it as a global class
78
+ define_method("#{as_name.to_s}=") do |val|
79
+ id = cls.gen_id_for val #TODO: Just call #{as_name.to_s}_id=
80
+ write_attribute "#{as_name.to_s}".to_sym, id
81
+ end
63
82
 
64
- #Define the setter by string value
65
- define_method("#{as_name.to_s}=") do |val|
66
- id = cls.gen_id_for val
67
- write_attribute "#{as_name.to_s}_id".to_sym, id
68
- end
83
+ define_method("#{as_name.to_s}_id") do
84
+ read_attribute "#{as_name.to_s}".to_sym
85
+ end
69
86
 
70
- #Define the getter
71
- define_method("#{as_name.to_s}") do
72
- id = read_attribute "@#{as_name.to_s}_id".to_sym
73
- if not id.nil?
74
- value = cls.name_for id
75
- if value.nil?
76
- lookup_obj = cls.find_by_id id
77
- if not lookup_obj.nil?
78
- cls.name_for id, lookup_obj.name
79
- cls.id_for lookup_obj.name, id
87
+ #Define the getter
88
+ define_method("#{as_name.to_s}") do
89
+ id = read_attribute "#{as_name.to_s}".to_sym
90
+ if not id.nil?
91
+ value = cls.name_for id
92
+ if value.nil?
93
+ lookup_obj = cls.find_by_id id
94
+ if not lookup_obj.nil?
95
+ #TODO: Extract to a method
96
+ cls.name_for id, lookup_obj.name
97
+ cls.id_for lookup_obj.name, id
98
+ end
80
99
  end
81
100
  end
101
+ value
82
102
  end
83
- value
84
- end
85
103
 
86
- #This sucks but it's the only way I could figure out to create the exact
87
- #method_missing method signature and still pass it the values I need to
88
- #use it. Maybe these should be class variables, but the best thing is if
89
- #they could only be defined in this scope and carried along with the
90
- #closure to the actual method.
91
- @as_name = as_name
92
- @cls = cls
93
- #We need to wrap around rails' default finders so that
94
- #find_by_car_type and similar methods will behave correctly. We translate
95
- #them on the fly to find_by_car_type_id and give the id instead of the
96
- #requested name.
97
- def method_missing(method_id, *arguments, &block)
98
- if match = ActiveRecord::DynamicFinderMatch.match(method_id)
99
- #reroute car_type to _car_type_id
100
- idx = match.attribute_names.find_index { |n| n == @as_name.to_s }
101
- if not idx.nil?
102
- self.new.send "#{@as_name}=", arguments[idx] #Make sure there's a cached value
103
- arguments[idx] = @cls.id_for arguments[idx] #Change the argument
104
- method_id = method_id.to_s.sub /(by|and)_#{@as_name}$/, "\\1_#{@as_name}_id"
105
- method_id = method_id.to_s.sub /(by|and)_#{@as_name}_and/, "\\1_#{@as_name}_id_and"
106
- method_id = method_id.to_sym
104
+
105
+ #Rails ActiveRecord support:
106
+ @cls_for_name = {} if @cls_for_name.nil?
107
+ @cls_for_name[as_name.to_s.to_sym] = cls
108
+ #We need to override this for the dynamic finders.
109
+ def method_missing(method_id, *arguments, &block)
110
+ if match = ActiveRecord::DynamicFinderMatch.match(method_id)
111
+ #reroute kind to _kind_id
112
+ idxs = match.attribute_names.collect.with_index { |n,i| [i,n.to_sym] if @cls_for_name.has_key? n.to_sym }.compact
113
+ idxs.each do |elm|
114
+ if method_id =~ /^find_by_/
115
+ arguments[elm[0]] = @cls_for_name[elm[1]].gen_id_for arguments[elm[0]] #Change the argument
116
+ end
117
+ end
107
118
  end
108
- end
109
- super
119
+ super
120
+ end
121
+
122
+ def where(opts, *rest)
123
+ #Change the values of the keys in the lookup to their ids
124
+ mapped = opts.map { |k,v| @cls_for_name.has_key?(k) ? [k, @cls_for_name[k].id_for(v)] : [k, v] }
125
+ opts = Hash[mapped]
126
+ super(opts, *rest)
127
+ end
128
+
129
+ #Might need to be in class_eval
130
+ belongs_to lookup_name.to_s.to_sym, :foreign_key => "#{as_name}_id"
131
+ validates as_name.to_s.to_sym, :presence => true
132
+
133
+ #Prefill the hashes from the DB:
134
+ all_vals = cls.all
135
+ #No need for the class_exec
136
+ cls.class_variable_set(:@@rcaches, all_vals.inject({}) do |r, obj|
137
+ r[obj.name] = obj.id
138
+ r
139
+ end)
140
+ cls.class_variable_set(:@@caches, all_vals.inject([]) do |r, obj|
141
+ r[obj.id] = obj.name
142
+ r
143
+ end)
110
144
  end
111
145
 
112
- #Define the link between the host class and the newly created ActiveRecord
113
- belongs_to lookup_name.to_s.to_sym, :foreign_key => "#{as_name}_id".to_sym
114
- validates "#{as_name.to_s}_id".to_sym, :presence => true
115
-
116
- #Prefill the hashes from the DB
117
- all_vals = cls.all
118
- cls.class_variable_set(:@@rcaches, all_vals.inject({}) do |r, obj|
119
- r[obj.name] = obj.id
120
- r
121
- end)
122
- cls.class_variable_set(:@@caches, all_vals.inject([]) do |r, obj|
123
- r[obj.id] = obj.name
124
- r
125
- end)
126
146
  end
127
- end
128
147
 
129
- # extend host class with class methods when we're included
130
- def self.included(host_class)
131
- host_class.extend(ClassMethods)
148
+ # extend host class with class methods when we're included
149
+ def self.included(host_class)
150
+ host_class.extend(ClassMethods)
151
+ end
132
152
  end
133
153
  end
134
- end
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{rails_lookup}
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = [%q{Nimrod Priell}]
9
- s.date = %q{2011-08-06}
9
+ s.date = %q{2011-08-08}
10
10
  s.description = %q{Lookup tables with ruby-on-rails
11
11
  --------------------------------
12
12
 
@@ -14,6 +14,8 @@ By: Nimrod Priell
14
14
 
15
15
  This gem adds an ActiveRecord macro to define memory-cached, dynamically growing, normalized lookup tables for entity 'type'-like objects. Or in plain English - if you want to have a table containing, say, ProductTypes which can grow with new types simply when you refer to them, and not keep the Product table containing a thousand repeating 'type="book"' entries - sit down and try to follow through.
16
16
 
17
+ Installation is described down the page.
18
+
17
19
  Motivation
18
20
  ----------
19
21
 
@@ -90,6 +92,7 @@ I've looked thoroughly for a nice rails solution to this, but after failing to f
90
92
 
91
93
  Installation
92
94
  ------------
95
+ First, run `gem install rails_lookup` to install the latest version of the gem.
93
96
 
94
97
  The result of this hook is that you get the exact syntax described above, with only two lines of code (no extra classes or anything):
95
98
  In your ActiveRecord object simply add
@@ -149,13 +152,14 @@ I hope this helped you and saved a lot of time and frustration. Follow me on twi
149
152
  }
150
153
  s.email = %q{@nimrodpriell}
151
154
  s.extra_rdoc_files = [%q{README}, %q{lib/active_record/lookup.rb}]
152
- s.files = [%q{README}, %q{Rakefile}, %q{lib/active_record/lookup.rb}, %q{Manifest}, %q{rails_lookup.gemspec}]
155
+ s.files = [%q{README}, %q{Rakefile}, %q{lib/active_record/lookup.rb}, %q{rails_lookup.gemspec}, %q{test/20110808002412_create_test_lookup_db.rb}, %q{test/test_lookup.rb} ]
153
156
  s.homepage = %q{http://github.com/Nimster/RailsLookup/}
154
157
  s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Rails_lookup}, %q{--main}, %q{README}]
155
158
  s.require_paths = [%q{lib}]
156
159
  s.rubyforge_project = %q{rails_lookup}
157
160
  s.rubygems_version = %q{1.8.7}
158
161
  s.summary = %q{Lookup table macro for ActiveRecords}
162
+ s.test_files = [%q{test/test_lookup.rb}]
159
163
 
160
164
  if s.respond_to? :specification_version then
161
165
  s.specification_version = 3
@@ -0,0 +1,35 @@
1
+ class CreateTestLookupDb < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :cars do |t|
4
+ t.integer :kind
5
+ t.integer :color
6
+ t.string :name
7
+
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :car_kinds do |t|
12
+ t.string :name
13
+ end
14
+ create_table :planes do |t|
15
+ t.integer :kind
16
+ t.string :name
17
+
18
+ t.timestamps
19
+ end
20
+ create_table :plane_kinds do |t|
21
+ t.string :name
22
+ end
23
+ create_table :car_colors do |t|
24
+ t.string :name
25
+ end
26
+ end
27
+
28
+ def self.down
29
+ drop_table :cars
30
+ drop_table :car_kinds
31
+ drop_table :car_colors
32
+ drop_table :planes
33
+ drop_table :plane_kinds
34
+ end
35
+ end
@@ -0,0 +1,223 @@
1
+ require 'lookup'
2
+ require 'minitest/autorun'
3
+
4
+ class Car < ActiveRecord::Base
5
+ include Lookup
6
+ lookup :car_kind, :as => :kind
7
+ lookup :car_color, :as => :color
8
+ end
9
+
10
+ class Plane < ActiveRecord::Base
11
+ include Lookup
12
+ lookup :plane_kind, :as => :kind
13
+ end
14
+
15
+ class TestLookup < MiniTest::Unit::TestCase
16
+
17
+ def setup
18
+ clear_tables
19
+ end
20
+
21
+ def teardown
22
+ clear_tables
23
+ end
24
+
25
+ def clear_tables
26
+ Car.delete_all
27
+ CarKind.delete_all
28
+ CarColor.delete_all
29
+ Plane.delete_all
30
+ PlaneKind.delete_all
31
+ end
32
+
33
+ def test_initializers
34
+ assert_equal 0, CarKind.count
35
+ assert_equal 0, CarColor.count
36
+ bimba = Car.new(:name => "Bimba", :kind => "Compact", :color => "Yellow")
37
+ assert_equal "Yellow", bimba.color
38
+ assert_equal "Compact", bimba.kind
39
+ assert_equal "Bimba", bimba.name
40
+ assert_equal 1, CarKind.count
41
+ assert_equal 1, CarColor.count
42
+ ferrari = Car.new(:kind => "Sports", :color => "Yellow")
43
+ assert_equal "Yellow", ferrari.color
44
+ assert_equal "Sports", ferrari.kind
45
+ refute(ferrari == bimba)
46
+ assert_equal bimba.color_id, ferrari.color_id
47
+ refute_equal bimba.kind_id, ferrari.kind_id
48
+ assert_equal 2, CarKind.count
49
+ assert_equal 1, CarColor.count
50
+ f16 = Plane.new(:name => "F-16", :kind => "Fighter Jet")
51
+ assert_equal "Fighter Jet", f16.kind
52
+ assert_equal 1, PlaneKind.count
53
+ end
54
+
55
+ def test_saving_and_creating
56
+ bimba = Car.new(:name => "Bimba", :kind => "Compact", :color => "Yellow")
57
+ assert_equal "Yellow", bimba.color
58
+ assert_equal "Compact", bimba.kind
59
+ assert_equal "Bimba", bimba.name
60
+ bimba.save!
61
+ bimba_reloaded = Car.all.first
62
+ assert_equal "Yellow", bimba_reloaded.color
63
+ assert_equal "Compact", bimba_reloaded.kind
64
+ assert_equal "Bimba", bimba_reloaded.name
65
+ ferrari = Car.create!(:kind => "Sports", :color => "Yellow")
66
+ assert_equal "Yellow", ferrari.color
67
+ assert_equal "Sports", ferrari.kind
68
+ ferrari_reloaded = Car.all.last
69
+ assert_equal "Yellow", ferrari_reloaded.color
70
+ assert_equal "Sports", ferrari_reloaded.kind
71
+ end
72
+
73
+ def test_string_setting_and_getting
74
+ bimba = Car.new
75
+ ferrari = Car.new
76
+ assert_equal 0, CarKind.count
77
+ assert_equal 0, CarColor.count
78
+ bimba.color = "Yellow"
79
+ bimba.name = "Bimba"
80
+ bimba.kind = "Compact"
81
+ assert_equal "Yellow", bimba.color
82
+ assert_equal "Compact", bimba.kind
83
+ assert_equal "Bimba", bimba.name
84
+ assert_equal 1, CarKind.count
85
+ assert_equal 1, CarColor.count
86
+ ferrari.color = "Yellow"
87
+ ferrari.kind = "Sports"
88
+ assert_equal "Yellow", ferrari.color
89
+ assert_equal "Sports", ferrari.kind
90
+ assert_equal bimba.color_id, ferrari.color_id
91
+ refute_equal bimba.kind_id, ferrari.kind_id
92
+ assert_equal 2, CarKind.count
93
+ assert_equal 1, CarColor.count
94
+ bimba.color = "Red"
95
+ assert_equal 2, CarColor.count
96
+ assert_equal "Red", bimba.color
97
+ refute(bimba.color == ferrari.color)
98
+ bimba.color_id = ferrari.color_id #Set via the property_id
99
+ assert_equal "Yellow", bimba.color
100
+ end
101
+
102
+ def test_id_for_name_for
103
+ bimba = Car.new
104
+ assert_nil CarKind.id_for("Compact")
105
+ assert_nil CarKind.name_for(1)
106
+ bimba.kind = "Compact"
107
+ assert_equal bimba.kind_id, CarKind.id_for("Compact")
108
+ assert_equal "Compact", CarKind.name_for(bimba.kind_id)
109
+ end
110
+
111
+ def test_find_by
112
+ bimba = Car.create! :name => "Bimba", :kind => "Compact", :color => "Yellow"
113
+ ferrari = Car.create! :kind => "Sports", :color => "Yellow"
114
+ bimba2 = Car.find_by_kind_and_name "Compact", "Bimba"
115
+ assert_equal bimba, bimba2
116
+ assert_equal "Yellow", bimba2.color
117
+ bimba2 = Car.find_by_name_and_kind "Bimba", "Compact"
118
+ assert_equal bimba, bimba2
119
+ assert_equal "Yellow", bimba2.color
120
+ bimba2 = Car.find_by_kind "Compact"
121
+ assert_equal bimba, bimba2
122
+ assert_equal "Yellow", bimba2.color
123
+ bimba2 = Car.find_by_kind_and_color_and_name "Compact", "Yellow", "Bimba"
124
+ assert_equal bimba, bimba2
125
+ assert_equal "Yellow", bimba2.color
126
+ assert_equal "Compact", bimba2.kind
127
+ susita = Car.find_or_create_by_name_and_kind_and_color "Susita", "Compact", "Gray"
128
+ assert_equal "Gray", susita.color
129
+ assert_equal "Compact", susita.kind
130
+ bimba2 = Car.find_or_create_by_name_and_kind_and_color "Bimba", "Compact", "Yellow"
131
+ assert_equal "Yellow", bimba2.color
132
+ assert_equal "Compact", bimba2.kind
133
+ assert_equal "Bimba", bimba2.name
134
+ f16 = Plane.find_or_create_by_kind_and_name "Fighter Jet", "F-16"
135
+ assert_equal "Fighter Jet", f16.kind
136
+ assert_equal "F-16", f16.name
137
+ ferrari = Car.find_or_create_by_kind_and_color "Sports", "Yellow"
138
+ assert_equal "Yellow", ferrari.color
139
+ assert_equal "Sports", ferrari.kind
140
+ batmobile = Car.find_or_create_by_kind_and_color "Fantasy", "Black"
141
+ assert_equal "Black", batmobile.color
142
+ assert_equal "Fantasy", batmobile.kind
143
+ assert_equal 3, CarKind.count
144
+ assert_equal 3, CarColor.count
145
+ assert_equal 1, PlaneKind.count
146
+ end
147
+
148
+ #This test will issue warnings as we re-set existing constants
149
+ def test_preload_caches
150
+ #We have to define a new ActiveRecord class for this
151
+ CarKind.create! name: "Compact"
152
+ CarKind.create! name: "Sports"
153
+ assert_nil CarKind.id_for("Compact")
154
+ assert_nil CarKind.id_for("Sports")
155
+ #We get a new CarKind class - but this one will be preloaded
156
+ tmp = CarKind
157
+ Class.new(ActiveRecord::Base) do
158
+ include Lookup
159
+ lookup :car_kind
160
+ end
161
+ refute_nil CarKind.id_for("Compact")
162
+ refute_nil CarKind.id_for("Sports")
163
+ refute_equal CarKind.id_for("Compact"), CarKind.id_for("Sports")
164
+ assert_equal "Compact", CarKind.name_for(CarKind.id_for("Compact"))
165
+ assert_equal "Sports", CarKind.name_for(CarKind.id_for("Sports"))
166
+ #Revert to the old class
167
+ #Object.const_set "CarKind", tmp
168
+ end
169
+
170
+ def test_where
171
+ bimba = Car.create! :name => "Bimba", :kind => "Compact", :color => "Yellow"
172
+ ferrari = Car.create! :kind => "Sports", :color => "Yellow"
173
+ assert_equal 1, Car.where(kind: "Compact").count
174
+ assert_equal 2, Car.where(color: "Yellow").count
175
+ assert_equal 0, Car.where(color: "Red").count
176
+ assert_equal 1, Car.where(color: "Yellow", kind: "Compact").count
177
+ assert_equal 1, Car.where(name: "Bimba", kind: "Compact").count
178
+ end
179
+
180
+ #TODO: This currently fails
181
+ def test_belongs_to
182
+ bimba = Car.create! :name => "Bimba", :kind => "Compact", :color => "Yellow"
183
+ ferrari = Car.create! :kind => "Sports", :color => "Yellow"
184
+ # yellow = CarColor.find_by_name "Yellow"
185
+ # assert_equal 2, yellow.cars.size
186
+ end
187
+ end
188
+
189
+ =begin
190
+ a = TestLookup.new
191
+ puts "Cache hits: "
192
+ puts(TestLookupKind.id_for "simian")
193
+ puts "Setting test_lookup_kind: "
194
+ a.test_lookup_kind="simian"
195
+ puts "Reading test_lookup_kind: "
196
+ puts a.test_lookup_kind
197
+ puts a.test_lookup_kind_id
198
+
199
+ puts "Hacking the ID: "
200
+ a.test_lookup_kind_id = 1
201
+ puts a.test_lookup_kind
202
+
203
+ puts "Setting another_lookup_kind: "
204
+ a.another_lookup_kind="simian"
205
+ puts "Reading another_lookup_kind: "
206
+ puts a.another_lookup_kind
207
+ puts a.another_lookup_kind_id
208
+
209
+ b = TestLookupKind.new
210
+ puts "HERE"
211
+ p TestLookupKind.all
212
+
213
+ puts "Testing different class"
214
+ b = OneMore.new
215
+ b.taverna_kind = "williwok"
216
+ puts b.taverna_kind
217
+ puts b.taverna_kind_id
218
+
219
+ puts "Testing original class: "
220
+ puts a.test_lookup_kind
221
+ puts a.another_lookup_kind
222
+
223
+ =end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rails_lookup
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nimrod Priell
@@ -10,13 +10,14 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-08-06 00:00:00 Z
13
+ date: 2011-08-08 00:00:00 Z
14
14
  dependencies: []
15
15
 
16
16
  description: "Lookup tables with ruby-on-rails\n\
17
17
  --------------------------------\n\n\
18
18
  By: Nimrod Priell\n\n\
19
19
  This gem adds an ActiveRecord macro to define memory-cached, dynamically growing, normalized lookup tables for entity 'type'-like objects. Or in plain English - if you want to have a table containing, say, ProductTypes which can grow with new types simply when you refer to them, and not keep the Product table containing a thousand repeating 'type=\"book\"' entries - sit down and try to follow through.\n\n\
20
+ Installation is described down the page.\n\n\
20
21
  Motivation\n\
21
22
  ----------\n\n\
22
23
  A [normalized DB][1] means that you want to keep types as separate tables, with foreign keys pointing from your main entity to its type. For instance, instead of \n\
@@ -51,7 +52,8 @@ description: "Lookup tables with ruby-on-rails\n\
51
52
  But you wanna minimize generating these numerous type classes. If you're like me, you don't even want to see them lying around in app/model. Who cares about them?\n\n\
52
53
  I've looked thoroughly for a nice rails solution to this, but after failing to find one, I created my own rails metaprogramming hook.\n\n\
53
54
  Installation\n\
54
- ------------\n\n\
55
+ ------------\n\
56
+ First, run `gem install rails_lookup` to install the latest version of the gem.\n\n\
55
57
  The result of this hook is that you get the exact syntax described above, with only two lines of code (no extra classes or anything):\n\
56
58
  In your ActiveRecord object simply add\n\n require 'active_record/lookup'\n class Car < ActiveRecord::Base\n #...\n include ActiveRecord::Lookup\n lookup :car_type\n #...\n end\n\n\
57
59
  That's it. the generated CarType class (which you won't see as a car_type.rb file, obviously, as it is generated in real-time), contains some nice methods to look into the cache as well: So you can call\n\n CarType.id_for \"Sports\" #Returns 2\n CarType.name_for 1 #Returns \"Compact\"\n\n\
@@ -74,8 +76,9 @@ files:
74
76
  - README
75
77
  - Rakefile
76
78
  - lib/active_record/lookup.rb
77
- - Manifest
78
79
  - rails_lookup.gemspec
80
+ - test/20110808002412_create_test_lookup_db.rb
81
+ - test/test_lookup.rb
79
82
  homepage: http://github.com/Nimster/RailsLookup/
80
83
  licenses: []
81
84
 
@@ -108,5 +111,5 @@ rubygems_version: 1.8.7
108
111
  signing_key:
109
112
  specification_version: 3
110
113
  summary: Lookup table macro for ActiveRecords
111
- test_files: []
112
-
114
+ test_files:
115
+ - test/test_lookup.rb
data/Manifest DELETED
@@ -1,4 +0,0 @@
1
- README
2
- Rakefile
3
- lib/active_record/lookup.rb
4
- Manifest