active_hash 0.7.5 → 0.7.6

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,11 @@
1
+ 2009-12-19
2
+ - Added ActiveHash::Enum (John Pignata)
3
+
4
+ 2009-12-10
5
+ - Fixed a bug where belongs_to associations would raise an error instead of returning
6
+ nil when the parent object didn't exist.
7
+ - Added #[] and #[]= accessors for more ActiveRecord-esque-ness. (Pat Nakajima & Dave Yeu)
8
+
1
9
  2009-12-01
2
10
  - Add marked_for_destruction? to be compatible with nested attributes (Brandon Keene)
3
11
  - Added second parameter to respond_to? and cleaned up specs (Brian Takita)
data/README.md CHANGED
@@ -282,10 +282,48 @@ In Rails, in development mode, it reloads the entire class, which reloads the fi
282
282
 
283
283
  NOTE: By default, .full_path refers to the current working directory. In a rails app, this will be RAILS_ROOT.
284
284
 
285
- ## Authors
285
+ ## Enum
286
+
287
+ ActiveHash can expose its data in an Enumeration by setting constants for each record. This allows records to be accessed in code through a constant set in the ActiveHash class.
286
288
 
287
- Written by Jeff Dean, Mike Dalessio and Ben Woosley
289
+ The field to be used as the constant is set using _enum_accessor_ which takes the name of a field as an argument.
290
+
291
+ class Country < ActiveHash::Base
292
+ extend ActiveHash::Enum
293
+ self.data = [
294
+ {:id => 1, :name => "US", :capital => "Washington, DC"},
295
+ {:id => 2, :name => "Canada", :capital => "Ottawa"},
296
+ {:id => 3, :name => "Mexico", :capital => "Mexico City"}
297
+ ]
298
+ enum_accessor :name
299
+ end
300
+
301
+ Records can be accessed by looking up the field constant:
302
+
303
+ >> Country::US.capital
304
+ => "Washington DC"
305
+ >> Country::MEXICO.id
306
+ => 3
307
+ >> Country::CANADA
308
+ => #<Country:0x10229fb28 @attributes={:name=>"Canada", :id=>2}
309
+
310
+ Constants are formed by first stripping all non-word characters and then upcasing the result. This means strings like "Blazing Saddles", "ReBar", "Mike & Ike" and "Ho! Ho! Ho!" become BLAZINGSADDLES, REBAR, MIKEIKE and HOHOHO.
311
+
312
+ The field specified as the _enum_accessor_ must contain unique data values.
313
+
314
+ ## Authors
288
315
 
289
- == Copyright
316
+ * Jeff Dean
317
+ * Mike Dalessio
318
+ * Ben Woosley
319
+ * John Pignata
320
+ * Pat Nakajima
321
+ * Brandon Keene
322
+ * Dave Yeu
323
+ * Brian Takita
324
+ * Corey Innis
325
+ * Peter Jaros
326
+
327
+ ## Copyright
290
328
 
291
329
  Copyright (c) 2009 Jeff Dean. See LICENSE for details.
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ begin
8
8
  gem.summary = %Q{An ActiveRecord-like model that uses a hash or file 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", "Corey Innis", "Peter Jaros", "Brandon Keene", "Brian Takita", "Pat Nakajima"]
11
+ gem.authors = ["Jeff Dean", "Mike Dalessio", "Corey Innis", "Peter Jaros", "Brandon Keene", "Brian Takita", "Pat Nakajima", "John Pignata"]
12
12
  gem.add_dependency('activesupport', [">= 2.2.2"])
13
13
  end
14
14
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.5
1
+ 0.7.6
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{active_hash}
8
- s.version = "0.7.5"
8
+ s.version = "0.7.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Jeff Dean", "Mike Dalessio", "Corey Innis", "Peter Jaros", "Brandon Keene", "Brian Takita", "Pat Nakajima"]
12
- s.date = %q{2009-12-01}
11
+ s.authors = ["Jeff Dean", "Mike Dalessio", "Corey Innis", "Peter Jaros", "Brandon Keene", "Brian Takita", "Pat Nakajima", "John Pignata"]
12
+ s.date = %q{2009-12-19}
13
13
  s.email = %q{jeff@zilkey.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
@@ -30,11 +30,14 @@ Gem::Specification.new do |s|
30
30
  "lib/active_hash/base.rb",
31
31
  "lib/active_yaml/base.rb",
32
32
  "lib/associations/associations.rb",
33
+ "lib/enum/enum.rb",
33
34
  "spec/active_file/base_spec.rb",
34
35
  "spec/active_hash/base_spec.rb",
35
36
  "spec/active_yaml/base_spec.rb",
36
37
  "spec/associations/associations_spec.rb",
38
+ "spec/enum/enum_spec.rb",
37
39
  "spec/fixtures/array_rows.yml",
40
+ "spec/fixtures/boroughs.yml",
38
41
  "spec/fixtures/cities.yml",
39
42
  "spec/fixtures/countries.yml",
40
43
  "spec/fixtures/states.yml",
@@ -50,6 +53,7 @@ Gem::Specification.new do |s|
50
53
  "spec/active_hash/base_spec.rb",
51
54
  "spec/active_yaml/base_spec.rb",
52
55
  "spec/associations/associations_spec.rb",
56
+ "spec/enum/enum_spec.rb",
53
57
  "spec/spec_helper.rb"
54
58
  ]
55
59
 
@@ -1,5 +1,6 @@
1
- require 'activesupport'
1
+ require 'active_support'
2
2
  require 'active_hash/base'
3
3
  require 'active_file/base'
4
4
  require 'active_yaml/base'
5
5
  require 'associations/associations'
6
+ require 'enum/enum'
@@ -211,7 +211,13 @@ module ActiveHash
211
211
  def base_class
212
212
  ActiveHash::Base
213
213
  end
214
-
214
+
215
+ def reload
216
+ self.data = read_inheritable_attribute(:data)
217
+ end
218
+
219
+ private :reload
220
+
215
221
  end
216
222
 
217
223
  attr_reader :attributes
@@ -224,6 +230,14 @@ module ActiveHash
224
230
  end
225
231
  end
226
232
 
233
+ def [](key)
234
+ attributes[key]
235
+ end
236
+
237
+ def []=(key, val)
238
+ attributes[key] = val
239
+ end
240
+
227
241
  def id
228
242
  attributes[:id] ? attributes[:id] : nil
229
243
  end
@@ -27,7 +27,7 @@ module ActiveHash
27
27
  }.merge(options)
28
28
 
29
29
  define_method(association_id) do
30
- options[:class_name].constantize.find(send(options[:foreign_key]))
30
+ options[:class_name].constantize.find_by_id(send(options[:foreign_key]))
31
31
  end
32
32
 
33
33
  define_method("#{association_id}=") do |new_value|
@@ -0,0 +1,44 @@
1
+ module ActiveHash
2
+ module Enum
3
+
4
+ DuplicateConstant = Class.new(RuntimeError)
5
+
6
+ def enum_accessor(field_name)
7
+ @enum_accessor = field_name
8
+ reload
9
+ end
10
+
11
+ def insert(record)
12
+ super
13
+ set_constant(record) if enum_accessor?
14
+ end
15
+
16
+ private :insert
17
+
18
+ def set_constant(record)
19
+ if constant = constant_for(record.attributes[@enum_accessor])
20
+ self.const_set(constant, record)
21
+ end
22
+ end
23
+
24
+ private :set_constant
25
+
26
+ def enum_accessor?
27
+ !@enum_accessor.nil?
28
+ end
29
+
30
+ private :enum_accessor?
31
+
32
+ def constant_for(field_value)
33
+ if constant = field_value.dup
34
+ constant.gsub!(/[^A-Za-z]*/, "")
35
+ constant.upcase!
36
+ raise DuplicateConstant, "#{constant} is already defined on #{self.class.name}" if const_defined?(constant)
37
+ constant
38
+ end
39
+ end
40
+
41
+ private :constant_for
42
+ end
43
+
44
+ end
@@ -346,6 +346,19 @@ describe ActiveHash, "Base" do
346
346
  country = Country.new("foo" => :bar)
347
347
  country.attributes.should == {:foo => :bar}
348
348
  end
349
+
350
+ it "is works with #[]" do
351
+ Country.field :foo
352
+ country = Country.new(:foo => :bar)
353
+ country[:foo].should == :bar
354
+ end
355
+
356
+ it "is works with #[]=" do
357
+ Country.field :foo
358
+ country = Country.new
359
+ country[:foo] = :bar
360
+ country.foo.should == :bar
361
+ end
349
362
  end
350
363
 
351
364
  describe "reader methods" do
@@ -74,6 +74,12 @@ describe ActiveHash::Base, "associations" do
74
74
  city = City.create :country_id => country.id
75
75
  city.country.should == country
76
76
  end
77
+
78
+ it "returns nil when the record does not exist" do
79
+ City.belongs_to :country
80
+ city = City.create :country_id => 123
81
+ city.country.should be_nil
82
+ end
77
83
  end
78
84
 
79
85
  context "with an ActiveHash parent" do
@@ -83,6 +89,12 @@ describe ActiveHash::Base, "associations" do
83
89
  author = Author.create :city_id => city.id
84
90
  author.city.should == city
85
91
  end
92
+
93
+ it "returns nil when the record does not exist" do
94
+ Author.belongs_to :city
95
+ author = Author.create :city_id => 123
96
+ author.city.should be_nil
97
+ end
86
98
  end
87
99
 
88
100
  describe "#parent=" do
@@ -0,0 +1,55 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ActiveHash::Base, "enum" do
4
+
5
+ before do
6
+ ActiveYaml::Base.set_root_path File.expand_path(File.dirname(__FILE__) + "/../fixtures")
7
+
8
+ class Borough < ActiveYaml::Base
9
+ extend ActiveHash::Enum
10
+ fields :name, :county, :population
11
+ end
12
+ end
13
+
14
+ after do
15
+ Object.send(:remove_const, :Borough)
16
+ end
17
+
18
+ describe "#enum_accessor" do
19
+ it "sets the field used for accessing records by constants" do
20
+ Borough.enum_accessor :name
21
+ Borough::BROOKLYN.should == Borough.find_by_name("Brooklyn")
22
+ end
23
+
24
+ it "ensures that values stored in the field specified are unique" do
25
+ lambda do
26
+ Class.new(ActiveHash::Base) do
27
+ extend ActiveHash::Enum
28
+ self.data = [
29
+ { :name => 'Woodford Reserve' },
30
+ { :name => 'Bulliet Bourbon' },
31
+ { :name => 'Woodford Reserve' }
32
+ ]
33
+ enum_accessor :name
34
+ end
35
+ end.should raise_error(ActiveHash::Enum::DuplicateConstant)
36
+ end
37
+
38
+ it "removes non-word characters from values before setting constants" do
39
+ Movie = Class.new(ActiveHash::Base) do
40
+ extend ActiveHash::Enum
41
+ self.data = [
42
+ {:name => 'Die Hard 2', :rating => '4.3'},
43
+ {:name => 'The Informant!', :rating => '4.3'},
44
+ {:name => 'In & Out', :rating => '4.3'}
45
+ ]
46
+ enum_accessor :name
47
+ end
48
+
49
+ Movie::DIEHARD.name.should == 'Die Hard 2'
50
+ Movie::THEINFORMANT.name.should == 'The Informant!'
51
+ Movie::INOUT.name.should == 'In & Out'
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,20 @@
1
+ - id: 1
2
+ name: Manhattan
3
+ county: New York
4
+ population: 1634795
5
+ - id: 2
6
+ name: Brooklyn
7
+ county: Kings
8
+ population: 2556598
9
+ - id: 3
10
+ name: Queens
11
+ county: Queens
12
+ population: 2293007
13
+ - id: 4
14
+ name: Bronx
15
+ county: Bronx
16
+ population: 1391903
17
+ - id: 5
18
+ name: Staten Island
19
+ county: Richmond
20
+ population: 487407
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.7.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dean
@@ -11,11 +11,12 @@ authors:
11
11
  - Brandon Keene
12
12
  - Brian Takita
13
13
  - Pat Nakajima
14
+ - John Pignata
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2009-12-01 00:00:00 -05:00
19
+ date: 2009-12-19 00:00:00 -05:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -52,11 +53,14 @@ files:
52
53
  - lib/active_hash/base.rb
53
54
  - lib/active_yaml/base.rb
54
55
  - lib/associations/associations.rb
56
+ - lib/enum/enum.rb
55
57
  - spec/active_file/base_spec.rb
56
58
  - spec/active_hash/base_spec.rb
57
59
  - spec/active_yaml/base_spec.rb
58
60
  - spec/associations/associations_spec.rb
61
+ - spec/enum/enum_spec.rb
59
62
  - spec/fixtures/array_rows.yml
63
+ - spec/fixtures/boroughs.yml
60
64
  - spec/fixtures/cities.yml
61
65
  - spec/fixtures/countries.yml
62
66
  - spec/fixtures/states.yml
@@ -94,4 +98,5 @@ test_files:
94
98
  - spec/active_hash/base_spec.rb
95
99
  - spec/active_yaml/base_spec.rb
96
100
  - spec/associations/associations_spec.rb
101
+ - spec/enum/enum_spec.rb
97
102
  - spec/spec_helper.rb