active_hash 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
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