active_hash 1.2.3 → 1.3.0

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