zilkey-active_hash 0.5.0 → 0.6.0

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/CHANGELOG CHANGED
@@ -1,3 +1,6 @@
1
+ 2009-08-19
2
+ - Added custom finders for multiple fields, such as .find_all_by_name_and_age
3
+
1
4
  2009-07-23
2
5
  - Added support for auto-defining methods based on hash keys in ActiveHash::Base
3
6
  - Changed the :field and :fields API so that they don't overwrite existing methods (useful when ActiveHash auto-defines methods)
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ begin
8
8
  gem.summary = %Q{An ActiveRecord-like model that uses a hash as a datasource}
9
9
  gem.email = "jeff@zilkey.com"
10
10
  gem.homepage = "http://github.com/zilkey/active_hash"
11
- gem.authors = ["Jeff Dean", "Mike Dalessio"]
11
+ gem.authors = ["Jeff Dean", "Mike Dalessio", "Corey Innis", "Peter Jaros"]
12
12
  gem.add_dependency('activesupport')
13
13
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
14
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
data/active_hash.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{active_hash}
5
- s.version = "0.5.0"
5
+ s.version = "0.6.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Jeff Dean", "Mike Dalessio"]
9
- s.date = %q{2009-07-24}
8
+ s.authors = ["Jeff Dean", "Mike Dalessio", "Corey Innis", "Peter Jaros"]
9
+ s.date = %q{2009-08-19}
10
10
  s.email = %q{jeff@zilkey.com}
11
11
  s.extra_rdoc_files = [
12
12
  "LICENSE",
@@ -31,10 +31,11 @@ Gem::Specification.new do |s|
31
31
  "spec/active_yaml/sample.yml",
32
32
  "spec/spec_helper.rb"
33
33
  ]
34
+ s.has_rdoc = true
34
35
  s.homepage = %q{http://github.com/zilkey/active_hash}
35
36
  s.rdoc_options = ["--charset=UTF-8"]
36
37
  s.require_paths = ["lib"]
37
- s.rubygems_version = %q{1.3.4}
38
+ s.rubygems_version = %q{1.3.1}
38
39
  s.summary = %q{An ActiveRecord-like model that uses a hash as a datasource}
39
40
  s.test_files = [
40
41
  "spec/active_file/base_spec.rb",
@@ -45,7 +46,7 @@ Gem::Specification.new do |s|
45
46
 
46
47
  if s.respond_to? :specification_version then
47
48
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
- s.specification_version = 3
49
+ s.specification_version = 2
49
50
 
50
51
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
52
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
@@ -2,6 +2,7 @@ module ActiveHash
2
2
  class Base
3
3
  class_inheritable_accessor :data
4
4
  class << self
5
+ attr_reader :field_names
5
6
 
6
7
  def data=(array_of_hashes)
7
8
  @records = nil
@@ -46,12 +47,42 @@ module ActiveHash
46
47
  end
47
48
 
48
49
  def field(field_name, options = {})
50
+ @field_names ||= []
51
+ @field_names << field_name
52
+
49
53
  define_getter_method(field_name, options[:default])
50
54
  define_interrogator_method(field_name)
51
55
  define_custom_find_method(field_name)
52
56
  define_custom_find_all_method(field_name)
53
57
  end
54
58
 
59
+ def respond_to?(method_name)
60
+ super ||
61
+ begin
62
+ config = configuration_for_custom_finder(method_name)
63
+ config && config[:fields].all? { |field| field_names.include?(field.to_sym) }
64
+ end
65
+ end
66
+
67
+ def method_missing(method_name, *args)
68
+ config = configuration_for_custom_finder(method_name)
69
+
70
+ return super unless config
71
+
72
+ attribute_pairs = config[:fields].zip(args)
73
+ matches = all.select { |base| attribute_pairs.all? { |field, value| base.send(field) == value } }
74
+ config[:all?] ? matches : matches.first
75
+ end
76
+
77
+ def configuration_for_custom_finder(finder_name)
78
+ if finder_name.to_s.match(/^find_(all_)?by_(.*)/)
79
+ {
80
+ :all? => !!$1,
81
+ :fields => $2.split('_and_')
82
+ }
83
+ end
84
+ end
85
+
55
86
  def define_getter_method(field, default_value)
56
87
  unless instance_methods.include?(field.to_s)
57
88
  define_method(field) do
@@ -35,6 +35,16 @@ describe ActiveHash, "Base" do
35
35
  Country.should respond_to(:find_all_by_name)
36
36
  Country.should respond_to(:find_all_by_iso_name)
37
37
  end
38
+
39
+ it "defines single finder methods for all combinations of fields" do
40
+ Country.should respond_to(:find_by_name_and_iso_name)
41
+ Country.should respond_to(:find_by_iso_name_and_name)
42
+ end
43
+
44
+ it "defines array finder methods for all combinations of fields" do
45
+ Country.should respond_to(:find_all_by_name_and_iso_name)
46
+ Country.should respond_to(:find_all_by_iso_name_and_name)
47
+ end
38
48
  end
39
49
 
40
50
  describe ".data=" do
@@ -209,47 +219,96 @@ describe ActiveHash, "Base" do
209
219
 
210
220
  describe "custom finders" do
211
221
  before do
212
- Country.field :name
222
+ Country.fields :name, :monarch
223
+
224
+ # Start ids above 4 lest we get nil and think it's an AH::Base model with id=4.
213
225
  Country.data = [
214
- {:id => 1, :name => "US"},
215
- {:id => 2, :name => "US"},
216
- {:id => 3, :name => "Canada"}
226
+ {:id => 11, :name => nil, :monarch => nil, :language => "Latin"},
227
+ {:id => 12, :name => "US", :monarch => nil, :language => "English"},
228
+ {:id => 13, :name => "Canada", :monarch => "The Crown of England", :language => "English"},
229
+ {:id => 14, :name => "UK", :monarch => "The Crown of England", :language => "English"}
217
230
  ]
218
231
  end
219
232
 
220
233
  describe "find_by_<field_name>" do
221
- context "with a name" do
222
- it "returns the first record matching that name" do
223
- Country.find_by_name("US").id.should == 1
234
+ describe "with a match" do
235
+ context "for a non-nil argument" do
236
+ it "returns the first matching record" do
237
+ Country.find_by_name("US").id.should == 12
238
+ end
239
+ end
240
+
241
+ context "for a nil argument" do
242
+ it "returns the first matching record" do
243
+ Country.find_by_name(nil).id.should == 11
244
+ end
224
245
  end
225
246
  end
226
247
 
227
- context "with nil" do
228
- it "returns nil" do
229
- Country.find_by_name(nil).should be_nil
248
+ describe "without a match" do
249
+ before do
250
+ Country.data = []
251
+ end
252
+
253
+ context "for a non-nil argument" do
254
+ it "returns nil" do
255
+ Country.find_by_name("Mexico").should be_nil
256
+ end
257
+ end
258
+
259
+ context "for a nil argument" do
260
+ it "returns nil" do
261
+ Country.find_by_name(nil).should be_nil
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+ describe "find_all_by_<field_name>" do
268
+ describe "with matches" do
269
+ it "returns all matching records" do
270
+ countries = Country.find_all_by_monarch("The Crown of England")
271
+ countries.length.should == 2
272
+ countries.first.name.should == "Canada"
273
+ countries.last.name.should == "UK"
274
+ end
275
+ end
276
+
277
+ describe "without matches" do
278
+ it "returns an empty array" do
279
+ Country.find_all_by_name("Mexico").should be_empty
280
+ end
281
+ end
282
+ end
283
+
284
+ describe "find_by_<field_one>_and_<field_two>" do
285
+ describe "with a match" do
286
+ it "returns the first matching record" do
287
+ Country.find_by_name_and_monarch("Canada", "The Crown of England").id.should == 13
288
+ Country.find_by_monarch_and_name("The Crown of England", "Canada").id.should == 13
230
289
  end
231
290
  end
232
291
 
233
- context "with a name not present" do
292
+ describe "without a match" do
234
293
  it "returns nil" do
235
- Country.find_by_name("foo").should be_nil
294
+ Country.find_by_name_and_monarch("US", "The Crown of England").should be_nil
236
295
  end
237
296
  end
238
297
  end
239
298
 
240
- describe "find_all_by_<field_name>" do
241
- context "with a name" do
242
- it "returns the records matching that name" do
243
- countries = Country.find_all_by_name("US")
299
+ describe "find_all_by_<field_one>_and_<field_two>" do
300
+ describe "with matches" do
301
+ it "returns all matching records" do
302
+ countries = Country.find_all_by_monarch_and_language("The Crown of England", "English")
244
303
  countries.length.should == 2
245
- countries.first.name.should == "US"
246
- countries.last.name.should == "US"
304
+ countries.first.name.should == "Canada"
305
+ countries.last.name.should == "UK"
247
306
  end
248
307
  end
249
308
 
250
- context "with a name not present" do
309
+ describe "without matches" do
251
310
  it "returns an empty array" do
252
- Country.find_all_by_name("foo").should be_empty
311
+ Country.find_all_by_monarch_and_language("Shaka Zulu", "Zulu").should be_empty
253
312
  end
254
313
  end
255
314
  end
metadata CHANGED
@@ -1,16 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zilkey-active_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dean
8
8
  - Mike Dalessio
9
+ - Corey Innis
10
+ - Peter Jaros
9
11
  autorequire:
10
12
  bindir: bin
11
13
  cert_chain: []
12
14
 
13
- date: 2009-07-24 00:00:00 -07:00
15
+ date: 2009-08-19 00:00:00 -07:00
14
16
  default_executable:
15
17
  dependencies:
16
18
  - !ruby/object:Gem::Dependency
@@ -50,8 +52,9 @@ files:
50
52
  - spec/active_yaml/base_spec.rb
51
53
  - spec/active_yaml/sample.yml
52
54
  - spec/spec_helper.rb
53
- has_rdoc: false
55
+ has_rdoc: true
54
56
  homepage: http://github.com/zilkey/active_hash
57
+ licenses:
55
58
  post_install_message:
56
59
  rdoc_options:
57
60
  - --charset=UTF-8
@@ -72,9 +75,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
75
  requirements: []
73
76
 
74
77
  rubyforge_project:
75
- rubygems_version: 1.2.0
78
+ rubygems_version: 1.3.5
76
79
  signing_key:
77
- specification_version: 3
80
+ specification_version: 2
78
81
  summary: An ActiveRecord-like model that uses a hash as a datasource
79
82
  test_files:
80
83
  - spec/active_file/base_spec.rb