active_hash 0.8.3 → 0.8.4

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,8 @@
1
+ 2010-10-07
2
+ - Add conditions to ActiveHash#all (Ryan Garver)
3
+ - Add #cache_key to ActiveHash::Base (Tom Stuart)
4
+ - Add banged dynamic finder support to ActiveHash::Base (Tom Stuart)
5
+
1
6
  2010-09-16
2
7
  - Enum format now uses underscores instead of removing all characters
3
8
  - Removed test dependency on acts_as_fu
data/Gemfile CHANGED
@@ -5,4 +5,5 @@ gem "activesupport", "2.3.8"
5
5
  gem "rspec", ">= 1.3.0"
6
6
  gem "fixjour", "0.4.1"
7
7
  gem "jeweler", "1.4.0"
8
- gem "sqlite3-ruby", ">= 1.2.5"
8
+ gem "sqlite3-ruby", ">= 1.2.5"
9
+ gem 'rake'
@@ -13,6 +13,7 @@ GEM
13
13
  git (>= 1.2.5)
14
14
  rubyforge (>= 2.0.0)
15
15
  json_pure (1.4.6)
16
+ rake (0.8.7)
16
17
  rspec (1.3.0)
17
18
  rubyforge (2.0.4)
18
19
  json_pure (>= 1.1.7)
@@ -26,5 +27,6 @@ DEPENDENCIES
26
27
  activesupport (= 2.3.8)
27
28
  fixjour (= 0.4.1)
28
29
  jeweler (= 1.4.0)
30
+ rake
29
31
  rspec (>= 1.3.0)
30
32
  sqlite3-ruby (>= 1.2.5)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.3
1
+ 0.8.4
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{active_hash}
8
- s.version = "0.8.3"
8
+ s.version = "0.8.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeff Dean", "Mike Dalessio", "Corey Innis", "Peter Jaros", "Brandon Keene", "Brian Takita", "Pat Nakajima", "John Pignata", "Michael Schubert", "Jeremy Weiskotten"]
12
- s.date = %q{2010-09-17}
12
+ s.date = %q{2010-10-07}
13
13
  s.email = %q{jeff@zilkey.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -5,7 +5,7 @@ module ActiveFile
5
5
 
6
6
  class << self
7
7
 
8
- def all
8
+ def all(options={})
9
9
  reload unless data_loaded
10
10
  super
11
11
  end
@@ -57,8 +57,14 @@ module ActiveHash
57
57
  record
58
58
  end
59
59
 
60
- def all
61
- @records || []
60
+ def all(options={})
61
+ if options.has_key?(:conditions)
62
+ (@records || []).select do |record|
63
+ options[:conditions].all? {|col, match| record[col] == match}
64
+ end
65
+ else
66
+ @records || []
67
+ end
62
68
  end
63
69
 
64
70
  def count
@@ -131,13 +137,24 @@ module ActiveHash
131
137
  config = configuration_for_custom_finder(method_name)
132
138
  attribute_pairs = config[:fields].zip(args)
133
139
  matches = all.select { |base| attribute_pairs.all? { |field, value| base.send(field).to_s == value.to_s } }
134
- config[:all?] ? matches : matches.first
140
+
141
+ if config[:all?]
142
+ matches
143
+ else
144
+ result = matches.first
145
+ if config[:bang?]
146
+ result || raise(RecordNotFound, "Couldn\'t find #{name} with #{attribute_pairs.collect {|pair| "#{pair.first} = #{pair.second}"}.join(', ')}")
147
+ else
148
+ result
149
+ end
150
+ end
135
151
  end
136
152
 
137
153
  def configuration_for_custom_finder(finder_name)
138
- if finder_name.to_s.match(/^find_(all_)?by_(.*)/)
154
+ if finder_name.to_s.match(/^find_(all_)?by_(.*?)(!)?$/) && !($1 && $3)
139
155
  {
140
156
  :all? => !!$1,
157
+ :bang? => !!$3,
141
158
  :fields => $2.split('_and_')
142
159
  }
143
160
  end
@@ -301,6 +318,17 @@ module ActiveHash
301
318
  id.hash
302
319
  end
303
320
 
321
+ def cache_key
322
+ case
323
+ when new_record?
324
+ "#{self.class.model_name.cache_key}/new"
325
+ when timestamp = self[:updated_at]
326
+ "#{self.class.model_name.cache_key}/#{id}-#{timestamp.to_s(:number)}"
327
+ else
328
+ "#{self.class.model_name.cache_key}/#{id}"
329
+ end
330
+ end
331
+
304
332
  def save
305
333
  self.class.insert(self)
306
334
  true
@@ -31,20 +31,40 @@ describe ActiveHash, "Base" do
31
31
  Country.should respond_to(:find_by_iso_name)
32
32
  end
33
33
 
34
+ it "defines banged single finder methods for each field" do
35
+ Country.should respond_to(:find_by_name!)
36
+ Country.should respond_to(:find_by_iso_name!)
37
+ end
38
+
34
39
  it "defines array finder methods for each field" do
35
40
  Country.should respond_to(:find_all_by_name)
36
41
  Country.should respond_to(:find_all_by_iso_name)
37
42
  end
38
43
 
44
+ it "does not define banged array finder methods for each field" do
45
+ Country.should_not respond_to(:find_all_by_name!)
46
+ Country.should_not respond_to(:find_all_by_iso_name!)
47
+ end
48
+
39
49
  it "defines single finder methods for all combinations of fields" do
40
50
  Country.should respond_to(:find_by_name_and_iso_name)
41
51
  Country.should respond_to(:find_by_iso_name_and_name)
42
52
  end
43
53
 
54
+ it "defines banged single finder methods for all combinations of fields" do
55
+ Country.should respond_to(:find_by_name_and_iso_name!)
56
+ Country.should respond_to(:find_by_iso_name_and_name!)
57
+ end
58
+
44
59
  it "defines array finder methods for all combinations of fields" do
45
60
  Country.should respond_to(:find_all_by_name_and_iso_name)
46
61
  Country.should respond_to(:find_all_by_iso_name_and_name)
47
62
  end
63
+
64
+ it "does not define banged array finder methods for all combinations of fields" do
65
+ Country.should_not respond_to(:find_all_by_name_and_iso_name!)
66
+ Country.should_not respond_to(:find_all_by_iso_name_and_name!)
67
+ end
48
68
  end
49
69
 
50
70
  describe ".data=" do
@@ -137,6 +157,13 @@ describe ActiveHash, "Base" do
137
157
  records.first.name.should == "Canada"
138
158
  records.length.should == 1
139
159
  end
160
+
161
+ it "filters the records from a AR-like conditions hash" do
162
+ record = Country.all(:conditions => {:name => 'US'})
163
+ record.count.should == 1
164
+ record.first.id.should == 1
165
+ record.first.name.should == 'US'
166
+ end
140
167
  end
141
168
 
142
169
  describe ".count" do
@@ -304,6 +331,40 @@ describe ActiveHash, "Base" do
304
331
  end
305
332
  end
306
333
 
334
+ describe "find_by_<field_name>!" do
335
+ describe "with a match" do
336
+ context "for a non-nil argument" do
337
+ it "returns the first matching record" do
338
+ Country.find_by_name!("US").id.should == 12
339
+ end
340
+ end
341
+
342
+ context "for a nil argument" do
343
+ it "returns the first matching record" do
344
+ Country.find_by_name!(nil).id.should == 11
345
+ end
346
+ end
347
+ end
348
+
349
+ describe "without a match" do
350
+ before do
351
+ Country.data = []
352
+ end
353
+
354
+ context "for a non-nil argument" do
355
+ it "raises ActiveHash::RecordNotFound" do
356
+ lambda { Country.find_by_name!("Mexico") }.should raise_error(ActiveHash::RecordNotFound, /Couldn't find Country with name = Mexico/)
357
+ end
358
+ end
359
+
360
+ context "for a nil argument" do
361
+ it "raises ActiveHash::RecordNotFound" do
362
+ lambda { Country.find_by_name!(nil) }.should raise_error(ActiveHash::RecordNotFound, /Couldn't find Country with name = /)
363
+ end
364
+ end
365
+ end
366
+ end
367
+
307
368
  describe "find_all_by_<field_name>" do
308
369
  describe "with matches" do
309
370
  it "returns all matching records" do
@@ -350,6 +411,35 @@ describe ActiveHash, "Base" do
350
411
  end
351
412
  end
352
413
 
414
+ describe "find_by_<field_one>_and_<field_two>!" do
415
+ describe "with a match" do
416
+ it "returns the first matching record" do
417
+ Country.find_by_name_and_monarch!("Canada", "The Crown of England").id.should == 13
418
+ Country.find_by_monarch_and_name!("The Crown of England", "Canada").id.should == 13
419
+ end
420
+ end
421
+
422
+ describe "with a match based on to_s" do
423
+ it "returns the first matching record" do
424
+ Country.find_by_name_and_id!("Canada", "13").id.should == 13
425
+ end
426
+ end
427
+
428
+ describe "without a match" do
429
+ it "raises ActiveHash::RecordNotFound" do
430
+ lambda { Country.find_by_name_and_monarch!("US", "The Crown of England") }.should raise_error(ActiveHash::RecordNotFound, /Couldn't find Country with name = US, monarch = The Crown of England/)
431
+ end
432
+ end
433
+
434
+ describe "for fields the class doesn't have" do
435
+ it "raises a NoMethodError" do
436
+ lambda {
437
+ Country.find_by_name_and_shoe_size!("US", 10)
438
+ }.should raise_error(NoMethodError, "undefined method `find_by_name_and_shoe_size!' for Country:Class")
439
+ end
440
+ end
441
+ end
442
+
353
443
  describe "find_all_by_<field_one>_and_<field_two>" do
354
444
  describe "with matches" do
355
445
  it "returns all matching records" do
@@ -619,6 +709,30 @@ describe ActiveHash, "Base" do
619
709
 
620
710
  end
621
711
 
712
+ describe "#cache_key" do
713
+ it 'should use the class\'s cache_key and id' do
714
+ Country.data = [
715
+ {:id => 1, :name => "foo"}
716
+ ]
717
+
718
+ Country.first.cache_key.should == 'countries/1'
719
+ end
720
+
721
+ it 'should use the record\'s updated_at if present' do
722
+ timestamp = Time.now
723
+
724
+ Country.data = [
725
+ {:id => 1, :name => "foo", :updated_at => timestamp}
726
+ ]
727
+
728
+ Country.first.cache_key.should == "countries/1-#{timestamp.to_s(:number)}"
729
+ end
730
+
731
+ it 'should use "new" instead of the id for a new record' do
732
+ Country.new(:id => 1).cache_key.should == 'countries/new'
733
+ end
734
+ end
735
+
622
736
  describe "#save" do
623
737
 
624
738
  before do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_hash
3
3
  version: !ruby/object:Gem::Version
4
- hash: 57
4
+ hash: 55
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 8
9
- - 3
10
- version: 0.8.3
9
+ - 4
10
+ version: 0.8.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeff Dean
@@ -24,7 +24,7 @@ autorequire:
24
24
  bindir: bin
25
25
  cert_chain: []
26
26
 
27
- date: 2010-09-17 00:00:00 -04:00
27
+ date: 2010-10-07 00:00:00 -06:00
28
28
  default_executable:
29
29
  dependencies:
30
30
  - !ruby/object:Gem::Dependency