active_hash 1.2.3 → 1.3.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjFhNmFkYzdjYTBlYjE0MDM1NWU2YTUwZjY1MWJkN2Q2YmNmNGRiOQ==
4
+ ODAxNDcxMTI0NjIwNDQ3ZjJjZmVkYmY1Yjc2NGQ5MDZjMTBjNDAzZg==
5
5
  data.tar.gz: !binary |-
6
- M2RiMDQ0ODQxYTBhMDY2YzQ0YmI5OTgxZjVjNDA0OTMwNTA2OThjMA==
6
+ YzA5OWQ3YjMzNGQ5MzM0NzhkZjk3ZDJmODFiMDdkMzA0YTRiODc5OA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NzI2ODRiYTMxYTI3YWNjMjEyM2JjMjU3ZmRiYmRlMjllYTIzYzJmNzMyOGE2
10
- MjZjNzM4MGRhYjhhNTcwMDIxZmI4MTdkNTEzYTg2NDZlOWNmOGQ1MjQ0YTgw
11
- MTZiZDE2MmM3ZDk5NmM4MDJmODk1YzNiMDQ0OTJiMjhlOWNjNzg=
9
+ YjNkMzdjMmY5MjYwYTg4ZGJmMzJkM2I1Y2QxYjRlYTQzODc2ZWFlNjY5ODA3
10
+ MTk3NWE4MGIyYTc1ZDhjYzYxYTc0MDkyYWU5MTE4NTg2ODhiZGE5NjhlYWM1
11
+ YWQ4OTJmYWJlOWUyZGE4NzMwZTkwNTdhMGJlYmFjOTljYzI2Njk=
12
12
  data.tar.gz: !binary |-
13
- ZDI3ZjMzM2UwNmM1N2QyY2ExZGRiZDM4MjFmZTBmMzJiNTU5ZmExOTQ3OGU4
14
- ZDc5YjYyZDNmMGE3MjlmMjZkODgzZjNhNzkxM2E5YjEzZjJhNGMxZmQxOTVk
15
- MzhkN2ZiYjdiODQ2MjliMGEzNjJkNGZmOWQ2ZThjMzkyZjhhODM=
13
+ YzAzMzJlMTYzNmVlYzA2NDBjYmMxZTViOWNjNmMzNDNlNGFjMTUwZGUzYTk4
14
+ NDViYjk2MTUzYzZmZTNjOGNlNTUwZDM4NDA5ZjE5MzM0NTkxN2ZhNTljMjc1
15
+ ZGFjYWRkODJiMjNiMGJiN2Q1Njc2MGExNmE0MWJhMDUxOTdhOWI=
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 2014-02-18 (v1.3.0)
2
+ - fix bug where including ActiveHash associations would make `belongs_to :imageable, polymorphic: true` blow up
3
+ - fixed several bugs that prevented active hash from being used without active record / active model
4
+ - add support for splitting up data sources into multiple files (rheaton)
5
+ - add support for storing data in json files (rheaton)
6
+
1
7
  2013-11-29 (v1.2.3)
2
8
  - fix bug where active hash would call `.all` on models when setting has_many (grosser)
3
9
 
data/README.md CHANGED
@@ -62,10 +62,6 @@ You can also use _add_:
62
62
  add :id => 2, :name => "Canada"
63
63
  end
64
64
 
65
- ## WARNING
66
-
67
- If you add data to an ActiveHash file during an initializer, it will not be reloaded in development in Rails.
68
-
69
65
  ## Auto-Defined fields
70
66
 
71
67
  ActiveHash will auto-define all fields for you when you load the hash. For example, if you have the following class:
@@ -105,10 +101,12 @@ You can define data inside your class or outside. For example, you might have a
105
101
  end
106
102
 
107
103
  # config/initializers/data.rb
108
- Country.data = [
109
- {:id => 1, :name => "US"},
110
- {:id => 2, :name => "Canada"}
111
- ]
104
+ Rails.application.config.to_prepare do
105
+ Country.data = [
106
+ {:id => 1, :name => "US"},
107
+ {:id => 2, :name => "Canada"}
108
+ ]
109
+ end
112
110
 
113
111
  If you prefer to store your data in YAML, see below.
114
112
 
@@ -250,10 +248,12 @@ Since ActiveHashes usually are static, we can use shortcuts to assign via an eas
250
248
  end
251
249
 
252
250
  # config/initializers/data.rb
253
- Country.data = [
254
- {:id => 1, :name => "US"},
255
- {:id => 2, :name => "Canada"}
256
- ]
251
+ Rails.application.config.to_prepare do
252
+ Country.data = [
253
+ {:id => 1, :name => "US"},
254
+ {:id => 2, :name => "Canada"}
255
+ ]
256
+ end
257
257
 
258
258
  # Using `rails console`
259
259
  john = Person.new
@@ -334,6 +334,15 @@ Since ActiveYaml just creates a hash from the YAML file, you will have all field
334
334
  id: 3
335
335
  name: Mexico
336
336
 
337
+ ### Multiple files per model
338
+
339
+ You can use multiple files to store your data. You will have to choose between hash or array style as you cannot use both for one model.
340
+
341
+ class Country < ActiveYaml::Base
342
+ use_mutliple_files
343
+ set_filenames "europe", "america", "asia", "africa"
344
+ end
345
+
337
346
  ### Using aliases in YAML
338
347
 
339
348
  Aliases can be used in ActiveYaml using either array or hash style by including `ActiveYaml::Aliases`.
@@ -373,6 +382,59 @@ With that module included, keys beginning with a '/' character can be safely add
373
382
  Soda.first.flavor # => sweet
374
383
  Soda.first.price # => 1.0
375
384
 
385
+ ## ActiveJSON
386
+
387
+ If you want to store your data in JSON files, just inherit from ActiveJSON and specify your path information:
388
+
389
+ class Country < ActiveJSON::Base
390
+ end
391
+
392
+ By default, this class will look for a json file named "countries.json" in the same directory as the file. You can either change the directory it looks in, the filename it looks for, or both:
393
+
394
+ class Country < ActiveJSON::Base
395
+ set_root_path "/u/data"
396
+ set_filename "sample"
397
+ end
398
+
399
+ The above example will look for the file "/u/data/sample.json".
400
+
401
+ Since ActiveJSON just creates a hash from the JSON file, you will have all fields specified in JSON auto-defined for you. You can format your JSON as an array, or as a hash:
402
+
403
+ # array style
404
+ [
405
+ {
406
+ "id": 1,
407
+ "name": "US",
408
+ "custom_field_1": "value1"
409
+ },
410
+ {
411
+ "id": 2,
412
+ "name": "Canada",
413
+ "custom_field_2": "value2"
414
+ }
415
+ ]
416
+
417
+ # hash style
418
+ {
419
+ { "us":
420
+ {
421
+ "id": 1,
422
+ "name": "US",
423
+ "custom_field_1": "value1"
424
+ }
425
+ },
426
+ { "canada":
427
+ {
428
+ "id": 2,
429
+ "name": "Canada",
430
+ "custom_field_2": "value2"
431
+ }
432
+ }
433
+ }
434
+
435
+ ### Multiple files per model
436
+
437
+ This works as it does for `ActiveYaml`
376
438
 
377
439
  ## ActiveFile
378
440
 
@@ -469,8 +531,7 @@ To make users' lives easier, please maintain support for:
469
531
 
470
532
  To that end, run specs against all rubies before committing:
471
533
 
472
- rake appraisal:install
473
- rake appraisal spec
534
+ wwtd
474
535
 
475
536
  Once appraisal passes in all supported rubies, follow these steps to release a new version of active_hash:
476
537
 
@@ -2,14 +2,10 @@
2
2
 
3
3
  $:.push File.expand_path("../lib", __FILE__)
4
4
  require "active_hash/version"
5
- require "util/ruby_engine"
6
- require "util/ruby_version"
7
5
 
8
6
  Gem::Specification.new do |s|
9
7
  s.name = %q{active_hash}
10
8
  s.version = ActiveHash::Gem::VERSION
11
-
12
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
13
9
  s.authors = [
14
10
  "Jeff Dean",
15
11
  "Mike Dalessio",
@@ -30,14 +26,15 @@ Gem::Specification.new do |s|
30
26
  "Keenan Brock",
31
27
  "Desmond Bowe",
32
28
  "Matthew O'Riordan",
33
- "Brett Richardson"
29
+ "Brett Richardson",
30
+ "Rachel Heaton",
34
31
  ]
35
- s.date = %q{2012-01-18}
36
32
  s.email = %q{jeff@zilkey.com}
37
- s.extra_rdoc_files = [
38
- "LICENSE",
39
- "README.md"
40
- ]
33
+ s.summary = %q{An ActiveRecord-like model that uses a hash or file as a datasource}
34
+ s.description = %q{Includes the ability to specify data using hashes, yml files or JSON files}
35
+ s.homepage = %q{http://github.com/zilkey/active_hash}
36
+ s.license = "MIT"
37
+
41
38
  s.files = [
42
39
  "CHANGELOG",
43
40
  "LICENSE",
@@ -45,60 +42,8 @@ Gem::Specification.new do |s|
45
42
  "active_hash.gemspec",
46
43
  Dir.glob("lib/**/*")
47
44
  ].flatten
48
- s.homepage = %q{http://github.com/zilkey/active_hash}
45
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
49
46
  s.require_paths = ["lib"]
50
- s.rubygems_version = %q{1.3.7}
51
- s.summary = %q{An ActiveRecord-like model that uses a hash or file as a datasource}
52
- s.test_files = [
53
- "Gemfile",
54
- "spec/active_file/base_spec.rb",
55
- "spec/active_hash/base_spec.rb",
56
- "spec/active_yaml/base_spec.rb",
57
- "spec/associations/associations_spec.rb",
58
- "spec/enum/enum_spec.rb",
59
- "spec/lint_spec.rb",
60
- "spec/spec_helper.rb"
61
- ]
62
-
63
- supported_rails_versions = [">= 2.2.2"]
64
-
65
- sqlite_gem = if RubyEngine.jruby?
66
- if RubyVersion >= '1.9.3'
67
- # Until 1.3.0 is released, we need to depend on a Beta version for JRuby and Rails 4
68
- # https://github.com/jruby/activerecord-jdbc-adapter/issues/419#issuecomment-20567142
69
- ['activerecord-jdbcsqlite3-adapter', ['>= 1.3.0.beta2']]
70
- else
71
- ['activerecord-jdbcsqlite3-adapter']
72
- end
73
- else
74
- ['sqlite3']
75
- end
76
-
77
- if s.respond_to? :specification_version then
78
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
79
- s.specification_version = 3
80
47
 
81
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0')
82
- s.add_runtime_dependency(%q<activesupport>, supported_rails_versions)
83
- s.add_development_dependency(%q<rspec>, ["~> 2.2.0"])
84
- s.add_development_dependency(*sqlite_gem)
85
- s.add_development_dependency(%q<activerecord>, supported_rails_versions)
86
- s.add_development_dependency(%q<wwtd>)
87
- s.add_development_dependency(%q<rake>)
88
- else
89
- s.add_dependency(%q<activesupport>, supported_rails_versions)
90
- s.add_dependency(%q<rspec>, ["~> 2.2.0"])
91
- s.add_dependency(*sqlite_gem)
92
- s.add_dependency(%q<activerecord>, supported_rails_versions)
93
- s.add_dependency(%q<wwtd>)
94
- s.add_dependency(%q<rake>)
95
- end
96
- else
97
- s.add_dependency(%q<activesupport>, supported_rails_versions)
98
- s.add_dependency(%q<rspec>, ["~> 2.2.0"])
99
- s.add_dependency(*sqlite_gem)
100
- s.add_dependency(%q<activerecord>, supported_rails_versions)
101
- s.add_dependency(%q<wwtd>)
102
- s.add_dependency(%q<rake>)
103
- end
48
+ s.add_runtime_dependency('activesupport', '>= 2.2.2')
104
49
  end
@@ -1,6 +1,7 @@
1
1
  module ActiveFile
2
2
 
3
3
  class Base < ActiveHash::Base
4
+ extend ActiveFile::MultipleFiles
4
5
 
5
6
  if respond_to?(:class_attribute)
6
7
  class_attribute :filename, :root_path, :data_loaded
@@ -35,7 +36,6 @@ module ActiveFile
35
36
  end
36
37
 
37
38
  def full_path
38
- actual_root_path = root_path || Dir.pwd
39
39
  actual_filename = filename || name.tableize
40
40
  File.join(actual_root_path, "#{actual_filename}.#{extension}")
41
41
  end
@@ -45,6 +45,11 @@ module ActiveFile
45
45
  end
46
46
  protected :extension
47
47
 
48
+ def actual_root_path
49
+ root_path || Dir.pwd
50
+ end
51
+ protected :actual_root_path
52
+
48
53
  [:find, :find_by_id, :all, :where, :method_missing].each do |method|
49
54
  define_method(method) do |*args|
50
55
  reload unless data_loaded
@@ -0,0 +1,24 @@
1
+ module ActiveFile
2
+ module HashAndArrayFiles
3
+ def raw_data
4
+ if multiple_files?
5
+ data_from_multiple_files
6
+ else
7
+ load_path(full_path)
8
+ end
9
+ end
10
+
11
+ private
12
+ def data_from_multiple_files
13
+ loaded_files = full_paths.collect { |path| load_path(path) }
14
+
15
+ if loaded_files.all?{ |file_data| file_data.is_a?(Array) }
16
+ loaded_files.sum
17
+ elsif loaded_files.all?{ |file_data| file_data.is_a?(Hash) }
18
+ loaded_files.inject({}) { |hash, file_data| hash.merge(file_data) }
19
+ else
20
+ raise ActiveHash::FileTypeMismatchError.new("Choose between hash or array syntax")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ module ActiveFile
2
+ module MultipleFiles
3
+ def multiple_files?
4
+ false
5
+ end
6
+
7
+ def use_multiple_files
8
+ if respond_to?(:class_attribute)
9
+ class_attribute :filenames
10
+ else
11
+ class_inheritable_accessor :filenames
12
+ end
13
+
14
+ def self.set_filenames(*filenames)
15
+ self.filenames = filenames
16
+ end
17
+
18
+ def self.multiple_files?
19
+ true
20
+ end
21
+
22
+ def self.full_paths
23
+ if filenames.present?
24
+ filenames.collect do |filename|
25
+ File.join(actual_root_path, "#{filename}.#{extension}")
26
+ end
27
+ else
28
+ [full_path]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -12,8 +12,11 @@ rescue LoadError
12
12
  end
13
13
 
14
14
  require 'active_hash/base'
15
+ require 'active_file/multiple_files'
16
+ require 'active_file/hash_and_array_files'
15
17
  require 'active_file/base'
16
18
  require 'active_yaml/base'
17
19
  require 'active_yaml/aliases'
20
+ require 'active_json/base'
18
21
  require 'associations/associations'
19
22
  require 'enum/enum'
@@ -9,6 +9,9 @@ module ActiveHash
9
9
  class IdError < StandardError
10
10
  end
11
11
 
12
+ class FileTypeMismatchError < StandardError
13
+ end
14
+
12
15
  class Base
13
16
 
14
17
  if respond_to?(:class_attribute)
@@ -28,6 +31,14 @@ module ActiveHash
28
31
 
29
32
  class << self
30
33
 
34
+ def cache_key
35
+ if Object.const_defined?(:ActiveModel)
36
+ model_name.cache_key
37
+ else
38
+ ActiveSupport::Inflector.tableize(self)
39
+ end
40
+ end
41
+
31
42
  def primary_key
32
43
  "id"
33
44
  end
@@ -111,7 +122,7 @@ module ActiveHash
111
122
  private :add_to_record_index
112
123
 
113
124
  def validate_unique_id(record)
114
- raise IdError.new("Duplicate Id found for record #{record.attributes}") if record_index.has_key?(record.id.to_s)
125
+ raise IdError.new("Duplicate ID found for record #{record.attributes.inspect}") if record_index.has_key?(record.id.to_s)
115
126
  end
116
127
 
117
128
  private :validate_unique_id
@@ -154,7 +165,10 @@ module ActiveHash
154
165
  yield
155
166
  rescue LocalJumpError => err
156
167
  raise err
157
- rescue ActiveRecord::Rollback
168
+ rescue StandardError => e
169
+ unless Object.const_defined?(:ActiveRecord) && e.is_a?(ActiveRecord::Rollback)
170
+ raise e
171
+ end
158
172
  end
159
173
 
160
174
  def delete_all
@@ -428,11 +442,11 @@ module ActiveHash
428
442
  def cache_key
429
443
  case
430
444
  when new_record?
431
- "#{self.class.model_name.cache_key}/new"
445
+ "#{self.class.cache_key}/new"
432
446
  when timestamp = self[:updated_at]
433
- "#{self.class.model_name.cache_key}/#{id}-#{timestamp.to_s(:number)}"
447
+ "#{self.class.cache_key}/#{id}-#{timestamp.to_s(:number)}"
434
448
  else
435
- "#{self.class.model_name.cache_key}/#{id}"
449
+ "#{self.class.cache_key}/#{id}"
436
450
  end
437
451
  end
438
452
 
@@ -1,5 +1,5 @@
1
1
  module ActiveHash
2
2
  module Gem
3
- VERSION = "1.2.3"
3
+ VERSION = "1.3.0"
4
4
  end
5
5
  end
@@ -0,0 +1,25 @@
1
+ module ActiveJSON
2
+ class Base < ActiveFile::Base
3
+ extend ActiveFile::HashAndArrayFiles
4
+ class << self
5
+ def load_file
6
+ if (data = raw_data).is_a?(Array)
7
+ data
8
+ else
9
+ data.values
10
+ end
11
+ end
12
+
13
+ def extension
14
+ "json"
15
+ end
16
+
17
+ private
18
+ def load_path(path)
19
+ JSON.load(File.open(path, 'r:bom|utf-8'))
20
+ end
21
+
22
+ end
23
+ end
24
+
25
+ end