active_data 0.3.0 → 1.0.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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rspec +0 -1
  4. data/.rvmrc +1 -1
  5. data/.travis.yml +13 -6
  6. data/Appraisals +7 -0
  7. data/Gemfile +1 -5
  8. data/Guardfile +68 -15
  9. data/README.md +144 -2
  10. data/active_data.gemspec +19 -11
  11. data/gemfiles/rails.4.0.gemfile +14 -0
  12. data/gemfiles/rails.4.1.gemfile +14 -0
  13. data/gemfiles/rails.4.2.gemfile +14 -0
  14. data/gemfiles/rails.5.0.gemfile +14 -0
  15. data/lib/active_data.rb +120 -3
  16. data/lib/active_data/active_record/associations.rb +50 -0
  17. data/lib/active_data/active_record/nested_attributes.rb +24 -0
  18. data/lib/active_data/config.rb +40 -0
  19. data/lib/active_data/errors.rb +93 -0
  20. data/lib/active_data/extensions.rb +33 -0
  21. data/lib/active_data/model.rb +16 -74
  22. data/lib/active_data/model/associations.rb +84 -15
  23. data/lib/active_data/model/associations/base.rb +79 -0
  24. data/lib/active_data/model/associations/collection/embedded.rb +12 -0
  25. data/lib/active_data/model/associations/collection/proxy.rb +32 -0
  26. data/lib/active_data/model/associations/collection/referenced.rb +26 -0
  27. data/lib/active_data/model/associations/embeds_many.rb +124 -18
  28. data/lib/active_data/model/associations/embeds_one.rb +90 -15
  29. data/lib/active_data/model/associations/nested_attributes.rb +180 -0
  30. data/lib/active_data/model/associations/references_many.rb +96 -0
  31. data/lib/active_data/model/associations/references_one.rb +83 -0
  32. data/lib/active_data/model/associations/reflections/base.rb +100 -0
  33. data/lib/active_data/model/associations/reflections/embeds_many.rb +25 -0
  34. data/lib/active_data/model/associations/reflections/embeds_one.rb +49 -0
  35. data/lib/active_data/model/associations/reflections/reference_reflection.rb +45 -0
  36. data/lib/active_data/model/associations/reflections/references_many.rb +28 -0
  37. data/lib/active_data/model/associations/reflections/references_one.rb +28 -0
  38. data/lib/active_data/model/associations/validations.rb +63 -0
  39. data/lib/active_data/model/attributes.rb +247 -0
  40. data/lib/active_data/model/attributes/attribute.rb +73 -0
  41. data/lib/active_data/model/attributes/base.rb +116 -0
  42. data/lib/active_data/model/attributes/collection.rb +17 -0
  43. data/lib/active_data/model/attributes/dictionary.rb +26 -0
  44. data/lib/active_data/model/attributes/localized.rb +42 -0
  45. data/lib/active_data/model/attributes/reference_many.rb +21 -0
  46. data/lib/active_data/model/attributes/reference_one.rb +42 -0
  47. data/lib/active_data/model/attributes/reflections/attribute.rb +55 -0
  48. data/lib/active_data/model/attributes/reflections/base.rb +62 -0
  49. data/lib/active_data/model/attributes/reflections/collection.rb +10 -0
  50. data/lib/active_data/model/attributes/reflections/dictionary.rb +13 -0
  51. data/lib/active_data/model/attributes/reflections/localized.rb +43 -0
  52. data/lib/active_data/model/attributes/reflections/reference_many.rb +10 -0
  53. data/lib/active_data/model/attributes/reflections/reference_one.rb +58 -0
  54. data/lib/active_data/model/attributes/reflections/represents.rb +55 -0
  55. data/lib/active_data/model/attributes/represents.rb +64 -0
  56. data/lib/active_data/model/callbacks.rb +71 -0
  57. data/lib/active_data/model/conventions.rb +35 -0
  58. data/lib/active_data/model/dirty.rb +77 -0
  59. data/lib/active_data/model/lifecycle.rb +307 -0
  60. data/lib/active_data/model/localization.rb +21 -0
  61. data/lib/active_data/model/persistence.rb +57 -0
  62. data/lib/active_data/model/primary.rb +51 -0
  63. data/lib/active_data/model/scopes.rb +77 -0
  64. data/lib/active_data/model/validations.rb +27 -0
  65. data/lib/active_data/model/validations/associated.rb +19 -0
  66. data/lib/active_data/model/validations/nested.rb +39 -0
  67. data/lib/active_data/railtie.rb +7 -0
  68. data/lib/active_data/version.rb +1 -1
  69. data/spec/lib/active_data/active_record/associations_spec.rb +149 -0
  70. data/spec/lib/active_data/active_record/nested_attributes_spec.rb +16 -0
  71. data/spec/lib/active_data/config_spec.rb +44 -0
  72. data/spec/lib/active_data/model/associations/embeds_many_spec.rb +362 -52
  73. data/spec/lib/active_data/model/associations/embeds_one_spec.rb +250 -31
  74. data/spec/lib/active_data/model/associations/nested_attributes_spec.rb +23 -0
  75. data/spec/lib/active_data/model/associations/references_many_spec.rb +196 -0
  76. data/spec/lib/active_data/model/associations/references_one_spec.rb +134 -0
  77. data/spec/lib/active_data/model/associations/reflections/embeds_many_spec.rb +144 -0
  78. data/spec/lib/active_data/model/associations/reflections/embeds_one_spec.rb +116 -0
  79. data/spec/lib/active_data/model/associations/reflections/references_many_spec.rb +255 -0
  80. data/spec/lib/active_data/model/associations/reflections/references_one_spec.rb +208 -0
  81. data/spec/lib/active_data/model/associations/validations_spec.rb +153 -0
  82. data/spec/lib/active_data/model/associations_spec.rb +189 -0
  83. data/spec/lib/active_data/model/attributes/attribute_spec.rb +144 -0
  84. data/spec/lib/active_data/model/attributes/base_spec.rb +82 -0
  85. data/spec/lib/active_data/model/attributes/collection_spec.rb +73 -0
  86. data/spec/lib/active_data/model/attributes/dictionary_spec.rb +93 -0
  87. data/spec/lib/active_data/model/attributes/localized_spec.rb +88 -33
  88. data/spec/lib/active_data/model/attributes/reflections/attribute_spec.rb +72 -0
  89. data/spec/lib/active_data/model/attributes/reflections/base_spec.rb +56 -0
  90. data/spec/lib/active_data/model/attributes/reflections/collection_spec.rb +37 -0
  91. data/spec/lib/active_data/model/attributes/reflections/dictionary_spec.rb +43 -0
  92. data/spec/lib/active_data/model/attributes/reflections/localized_spec.rb +37 -0
  93. data/spec/lib/active_data/model/attributes/reflections/represents_spec.rb +70 -0
  94. data/spec/lib/active_data/model/attributes/represents_spec.rb +153 -0
  95. data/spec/lib/active_data/model/attributes_spec.rb +243 -0
  96. data/spec/lib/active_data/model/callbacks_spec.rb +338 -0
  97. data/spec/lib/active_data/model/conventions_spec.rb +12 -0
  98. data/spec/lib/active_data/model/dirty_spec.rb +75 -0
  99. data/spec/lib/active_data/model/lifecycle_spec.rb +330 -0
  100. data/spec/lib/active_data/model/nested_attributes.rb +202 -0
  101. data/spec/lib/active_data/model/persistence_spec.rb +47 -0
  102. data/spec/lib/active_data/model/primary_spec.rb +84 -0
  103. data/spec/lib/active_data/model/scopes_spec.rb +88 -0
  104. data/spec/lib/active_data/model/typecasting_spec.rb +192 -0
  105. data/spec/lib/active_data/model/validations/associated_spec.rb +94 -0
  106. data/spec/lib/active_data/model/validations/nested_spec.rb +93 -0
  107. data/spec/lib/active_data/model/validations_spec.rb +31 -0
  108. data/spec/lib/active_data/model_spec.rb +1 -32
  109. data/spec/lib/active_data_spec.rb +12 -0
  110. data/spec/spec_helper.rb +39 -0
  111. data/spec/support/model_helpers.rb +10 -0
  112. metadata +246 -54
  113. data/gemfiles/Gemfile.rails-3 +0 -14
  114. data/lib/active_data/attributes/base.rb +0 -69
  115. data/lib/active_data/attributes/localized.rb +0 -42
  116. data/lib/active_data/model/associations/association.rb +0 -30
  117. data/lib/active_data/model/attributable.rb +0 -122
  118. data/lib/active_data/model/collectionizable.rb +0 -55
  119. data/lib/active_data/model/collectionizable/proxy.rb +0 -42
  120. data/lib/active_data/model/extensions.rb +0 -9
  121. data/lib/active_data/model/extensions/array.rb +0 -24
  122. data/lib/active_data/model/extensions/big_decimal.rb +0 -17
  123. data/lib/active_data/model/extensions/boolean.rb +0 -38
  124. data/lib/active_data/model/extensions/date.rb +0 -17
  125. data/lib/active_data/model/extensions/date_time.rb +0 -17
  126. data/lib/active_data/model/extensions/float.rb +0 -17
  127. data/lib/active_data/model/extensions/hash.rb +0 -22
  128. data/lib/active_data/model/extensions/integer.rb +0 -17
  129. data/lib/active_data/model/extensions/localized.rb +0 -22
  130. data/lib/active_data/model/extensions/object.rb +0 -17
  131. data/lib/active_data/model/extensions/string.rb +0 -17
  132. data/lib/active_data/model/extensions/time.rb +0 -17
  133. data/lib/active_data/model/localizable.rb +0 -31
  134. data/lib/active_data/model/nested_attributes.rb +0 -58
  135. data/lib/active_data/model/parameterizable.rb +0 -29
  136. data/lib/active_data/validations.rb +0 -7
  137. data/lib/active_data/validations/associated.rb +0 -17
  138. data/spec/lib/active_data/model/attributable_spec.rb +0 -191
  139. data/spec/lib/active_data/model/collectionizable_spec.rb +0 -60
  140. data/spec/lib/active_data/model/nested_attributes_spec.rb +0 -67
  141. data/spec/lib/active_data/model/type_cast_spec.rb +0 -116
  142. data/spec/lib/active_data/validations/associated_spec.rb +0 -88
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f1d47fec4ebf9836edc6f7fe5ac6d6a35ed1d69
4
- data.tar.gz: 5d0be004664a569a8219e3f2437145f361fd935c
3
+ metadata.gz: 78fecd490979a5391a3de607a19c5e4605198af0
4
+ data.tar.gz: ebd1d4111fafc03aeb982bdb2965768920f728fd
5
5
  SHA512:
6
- metadata.gz: fe96cad358ac8a1bf476ffba428f5bd321688c8741e2769673962081b1608789e4bae0b3bb1fd12c00b94b93f1531031710818a4e2d746aeaa7c2bc4205bcd3a
7
- data.tar.gz: d8f29ecf02190df7fac8d108fcb1a1e5e54877c31c0775ab6c2045dffe4b21a0759eac793526ed95b9684308ac3b1f7345a85e067e02e77c9a51a0dbcb6be7d9
6
+ metadata.gz: 4d1583b8f09bf37a44343301be1bb802a62f414a8888f323dd13a1b56537986bf140cf5b238c91441ef298b6c0999883930539a3366303e8e4386863e97e357a
7
+ data.tar.gz: 3b0d862750cb159de0ab0911a515e80d8a8b30160918d0ab413095932da6f37a44d43c6133bf37943003f44a49977a24c99e09f5561334d07174fbfab9f8491e
data/.gitignore CHANGED
@@ -3,7 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
- Gemfile.lock
6
+ *.lock
7
7
  InstalledFiles
8
8
  _yardoc
9
9
  coverage
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
1
  --colour
2
2
  --backtrace
3
- --order random
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use --create 2.0.0@active_data
1
+ rvm use --create 2.3@active_data
data/.travis.yml CHANGED
@@ -1,9 +1,16 @@
1
+ sudo: false
2
+
1
3
  rvm:
2
- - 1.9.3
3
- - 2.0.0
4
- - rbx-19mode
5
- - rbx-20mode
4
+ - 2.2.5
5
+ - 2.3.1
6
+ - rbx
6
7
 
7
8
  gemfile:
8
- - Gemfile
9
- - gemfiles/Gemfile.rails-3
9
+ - gemfiles/rails.4.0.gemfile
10
+ - gemfiles/rails.4.1.gemfile
11
+ - gemfiles/rails.4.2.gemfile
12
+ - gemfiles/rails.5.0.gemfile
13
+
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: rbx
data/Appraisals ADDED
@@ -0,0 +1,7 @@
1
+ %w(4.0 4.1 4.2 5.0).each do |version|
2
+ appraise "rails.#{version}" do
3
+ gem 'activesupport', "~> #{version}.0"
4
+ gem 'activemodel', "~> #{version}.0"
5
+ gem 'activerecord', "~> #{version}.0"
6
+ end
7
+ end
data/Gemfile CHANGED
@@ -1,12 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in active_data.gemspec
4
3
  gemspec
5
4
 
6
5
  group :test do
7
6
  gem 'guard'
8
7
  gem 'guard-rspec'
9
- gem 'rb-inotify', require: false
10
- gem 'rb-fsevent', require: false
11
- gem 'rb-fchange', require: false
12
- end
8
+ end
data/Guardfile CHANGED
@@ -1,24 +1,77 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard :rspec do
5
- watch(%r{^spec/.+_spec\.rb$})
6
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
- watch('spec/spec_helper.rb') { "spec" }
8
-
9
- # Rails example
10
- watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
- watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
- watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
- watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
- watch('config/routes.rb') { "spec/routing" }
15
- watch('app/controllers/application_controller.rb') { "spec/controllers" }
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features)
6
+
7
+ ## Uncomment to clear the screen before every task
8
+ # clearing :on
9
+
10
+ ## Guard internally checks for changes in the Guardfile and exits.
11
+ ## If you want Guard to automatically start up again, run guard in a
12
+ ## shell loop, e.g.:
13
+ ##
14
+ ## $ while bundle exec guard; do echo "Restarting Guard..."; done
15
+ ##
16
+ ## Note: if you are using the `directories` clause above and you are not
17
+ ## watching the project directory ('.'), then you will want to move
18
+ ## the Guardfile to a watched dir and symlink it back, e.g.
19
+ #
20
+ # $ mkdir config
21
+ # $ mv Guardfile config/
22
+ # $ ln -s config/Guardfile .
23
+ #
24
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
25
+
26
+ # Note: The cmd option is now required due to the increasing number of ways
27
+ # rspec may be run, below are examples of the most common uses.
28
+ # * bundler: 'bundle exec rspec'
29
+ # * bundler binstubs: 'bin/rspec'
30
+ # * spring: 'bin/rspec' (This will use spring if running and you have
31
+ # installed the spring binstubs per the docs)
32
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
33
+ # * 'just' rspec: 'rspec'
34
+
35
+ guard :rspec, cmd: "bundle exec rspec" do
36
+ require "guard/rspec/dsl"
37
+ dsl = Guard::RSpec::Dsl.new(self)
38
+
39
+ # Feel free to open issues for suggestions and improvements
40
+
41
+ # RSpec files
42
+ rspec = dsl.rspec
43
+ watch(rspec.spec_helper) { rspec.spec_dir }
44
+ watch(rspec.spec_support) { rspec.spec_dir }
45
+ watch(rspec.spec_files)
46
+
47
+ # Ruby files
48
+ ruby = dsl.ruby
49
+ dsl.watch_spec_files_for(ruby.lib_files)
50
+
51
+ # Rails files
52
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
53
+ dsl.watch_spec_files_for(rails.app_files)
54
+ dsl.watch_spec_files_for(rails.views)
55
+
56
+ watch(rails.controllers) do |m|
57
+ [
58
+ rspec.spec.("routing/#{m[1]}_routing"),
59
+ rspec.spec.("controllers/#{m[1]}_controller"),
60
+ rspec.spec.("acceptance/#{m[1]}")
61
+ ]
62
+ end
63
+
64
+ # Rails config changes
65
+ watch(rails.spec_helper) { rspec.spec_dir }
66
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
67
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
16
68
 
17
69
  # Capybara features specs
18
- watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
70
+ watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
19
71
 
20
72
  # Turnip features and steps
21
73
  watch(%r{^spec/acceptance/(.+)\.feature$})
22
- watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
74
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
75
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
76
+ end
23
77
  end
24
-
data/README.md CHANGED
@@ -1,8 +1,118 @@
1
1
  [![Build Status](https://travis-ci.org/pyromaniac/active_data.png?branch=master)](https://travis-ci.org/pyromaniac/active_data)
2
+ [![Code Climate](https://codeclimate.com/github/pyromaniac/active_data.png)](https://codeclimate.com/github/pyromaniac/active_data)
2
3
 
3
4
  # ActiveData
4
5
 
5
- TODO: Write a gem description
6
+ ActiveData is a ActiveModel-based front-end for your data. You might need to use it in the following cases:
7
+
8
+ * When you need a form objects pattern.
9
+
10
+ ```ruby
11
+ class ProfileForm
12
+ include ActiveData::Model
13
+
14
+ attribute 'first_name', String
15
+ attribute 'last_name', String
16
+ attribute 'birth_date', Date
17
+
18
+ def full_name
19
+ [first_name, last_name].reject(&:blank).join(' ')
20
+ end
21
+
22
+ def full_name= value
23
+ self.first_name, self.last_name = value.split(' ', 2).map(&:strip)
24
+ end
25
+ end
26
+
27
+ class ProfileController < ApplicationController
28
+ def edit
29
+ @form = ProfileForm.new current_user.attributes
30
+ end
31
+
32
+ def update
33
+ result = ProfileForm.new(params[:profile_form]).save do |form|
34
+ current_user.update_attributes(form.attributes)
35
+ end
36
+
37
+ if result
38
+ redirect_to ...
39
+ else
40
+ render 'edit'
41
+ end
42
+ end
43
+ end
44
+ ```
45
+
46
+ * When you need to work with data-storage in ActiveRecord style with
47
+
48
+ ```ruby
49
+ class Flight
50
+ include ActiveData::Model
51
+
52
+ attribute :airline, String
53
+ attribute :number, String
54
+ attribute :departure, Time
55
+ attribute :arrival, Time
56
+
57
+ validates :airline, :number, presence: true
58
+
59
+ def id
60
+ [airline, number].join('-')
61
+ end
62
+
63
+ def self.find id
64
+ source = REDIS.get(id)
65
+ instantiate(JSON.parse(source)) if source.present?
66
+ end
67
+
68
+ define_save do
69
+ REDIS.set(id, attributes.to_json)
70
+ end
71
+
72
+ define_destroy do
73
+ REDIS.del(id)
74
+ end
75
+ end
76
+ ```
77
+
78
+ * When you need to implement embedded objects for ActiveRecord models
79
+
80
+ ```ruby
81
+ class Answer
82
+ include ActiveData::Model
83
+
84
+ attribute :question_id, Integer
85
+ attribute :content, String
86
+
87
+ validates :question_id, :content, presence: true
88
+ end
89
+
90
+ class Quiz < ActiveRecord::Base
91
+ embeds_many :answers
92
+
93
+ validates :user_id, presence: true
94
+ validates :answers, associated: true
95
+ end
96
+
97
+ q = Quiz.new
98
+ q.answers.build(question_id: 42, content: 'blabla')
99
+ q.save
100
+ ```
101
+
102
+ ## Why?
103
+
104
+ ActiveData is an ActiveModel-based library that provides the following abilities:
105
+
106
+ * Standard form objects building toolkit: attributes with typecasting, validations, etc.
107
+ * High-level universal ORM/ODM library using any data source (DB, http, redis, text files).
108
+ * Embedding objects into your ActiveRecord entities. Quite useful with PG JSON capabilities.
109
+
110
+ Key features:
111
+
112
+ * Complete objects lifecycle support: saving, updating, destroying.
113
+ * Embedded and referenced associations.
114
+ * Backend-agnostic named scopes functionality.
115
+ * Callbacks, validations and dirty attributes inside.
6
116
 
7
117
  ## Installation
8
118
 
@@ -20,7 +130,39 @@ Or install it yourself as:
20
130
 
21
131
  ## Usage
22
132
 
23
- TODO: Write usage instructions here
133
+ ActiveData has modular architecture, so it is required to include modules to obtain additional features. By default ActiveData supports attributes definition and validations.
134
+
135
+ ### Attributes
136
+
137
+
138
+
139
+ #### Attribute
140
+ #### Collection
141
+ #### Dictionary
142
+ #### Localized
143
+ #### Represents
144
+
145
+ ### Associations
146
+
147
+ #### EmbedsOne
148
+ #### EmbedsMany
149
+ #### ReferencesOne
150
+ #### ReferencesMany
151
+ #### Interacting with ActiveRecord
152
+
153
+ ### Primary
154
+
155
+ ### Persistence
156
+
157
+ ### Lifecycle
158
+
159
+ ### Callbacks
160
+
161
+ ### Dirty
162
+
163
+ ### Validations
164
+
165
+ ### Scopes
24
166
 
25
167
  ## Contributing
26
168
 
data/active_data.gemspec CHANGED
@@ -2,21 +2,29 @@
2
2
  require File.expand_path('../lib/active_data/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["pyromaniac"]
6
- gem.email = ["kinwizard@gmail.com"]
7
- gem.description = %q{Making object from any hash or hash array}
8
- gem.summary = %q{Working with hashes in AR style}
9
- gem.homepage = ""
5
+ gem.authors = ['pyromaniac']
6
+ gem.email = ['kinwizard@gmail.com']
7
+ gem.description = 'Making object from any hash or hash array'
8
+ gem.summary = 'Working with hashes in AR style'
9
+ gem.homepage = ''
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
12
12
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
- gem.name = "active_data"
15
- gem.require_paths = ["lib"]
14
+ gem.name = 'active_data'
15
+ gem.require_paths = ['lib']
16
16
  gem.version = ActiveData::VERSION
17
17
 
18
- gem.add_development_dependency "rake"
19
- gem.add_development_dependency "rspec"
20
- gem.add_runtime_dependency "activesupport"
21
- gem.add_runtime_dependency "activemodel"
18
+ gem.add_development_dependency 'rake'
19
+ gem.add_development_dependency 'appraisal'
20
+ gem.add_development_dependency 'rspec'
21
+ gem.add_development_dependency 'rspec-its'
22
+ gem.add_development_dependency 'rubysl', '~> 2.0' if RUBY_ENGINE == 'rbx'
23
+ gem.add_development_dependency 'sqlite3'
24
+ gem.add_development_dependency 'database_cleaner'
25
+ gem.add_development_dependency 'activerecord', '>= 4.0'
26
+ gem.add_development_dependency 'uuidtools'
27
+ gem.add_runtime_dependency 'activesupport', '>= 4.0'
28
+ gem.add_runtime_dependency 'activemodel', '>= 4.0'
29
+ gem.add_runtime_dependency 'tzinfo'
22
30
  end
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.0.0"
6
+ gem "activemodel", "~> 4.0.0"
7
+ gem "activerecord", "~> 4.0.0"
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.1.0"
6
+ gem "activemodel", "~> 4.1.0"
7
+ gem "activerecord", "~> 4.1.0"
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.2.0"
6
+ gem "activemodel", "~> 4.2.0"
7
+ gem "activerecord", "~> 4.2.0"
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 5.0.0"
6
+ gem "activemodel", "~> 5.0.0"
7
+ gem "activerecord", "~> 5.0.0"
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
data/lib/active_data.rb CHANGED
@@ -1,9 +1,126 @@
1
- require 'active_support/concern'
1
+ require 'tzinfo'
2
+ require 'active_support'
3
+ require 'active_support/deprecation'
2
4
  require 'active_support/core_ext'
5
+ require 'active_support/concern'
6
+ require 'singleton'
7
+
3
8
  require 'active_model'
9
+
4
10
  require 'active_data/version'
5
- require 'active_data/model'
6
- require 'active_data/validations'
11
+ require 'active_data/errors'
12
+ require 'active_data/extensions'
13
+ require 'active_data/config'
14
+ require 'active_data/railtie' if defined? Rails
7
15
 
8
16
  module ActiveData
17
+ BOOLEAN_MAPPING = {
18
+ 1 => true,
19
+ 0 => false,
20
+ '1' => true,
21
+ '0' => false,
22
+ 't' => true,
23
+ 'f' => false,
24
+ 'T' => true,
25
+ 'F' => false,
26
+ true => true,
27
+ false => false,
28
+ 'true' => true,
29
+ 'false' => false,
30
+ 'TRUE' => true,
31
+ 'FALSE' => false,
32
+ 'y' => true,
33
+ 'n' => false,
34
+ 'yes' => true,
35
+ 'no' => false,
36
+ }
37
+
38
+ def self.config
39
+ ActiveData::Config.instance
40
+ end
41
+
42
+ singleton_class.delegate *ActiveData::Config.delegated, to: :config
43
+
44
+ typecaster('Object') { |value, attribute| value if value.class < attribute.type }
45
+ typecaster('String') { |value| value.to_s }
46
+ typecaster('Array') do |value|
47
+ case value
48
+ when ::Array then
49
+ value
50
+ when ::String then
51
+ value.split(',').map(&:strip)
52
+ else
53
+ nil
54
+ end
55
+ end
56
+ typecaster('Hash') do |value|
57
+ case value
58
+ when ::Hash then
59
+ value
60
+ else
61
+ nil
62
+ end
63
+ end
64
+ typecaster('Date') do |value|
65
+ begin
66
+ value.to_date
67
+ rescue ArgumentError, NoMethodError
68
+ nil
69
+ end
70
+ end
71
+ typecaster('DateTime') do |value|
72
+ begin
73
+ value.to_datetime
74
+ rescue ArgumentError
75
+ nil
76
+ end
77
+ end
78
+ typecaster('Time') do |value|
79
+ begin
80
+ value.is_a?(String) && ::Time.zone ? ::Time.zone.parse(value) : value.to_time
81
+ rescue ArgumentError
82
+ nil
83
+ end
84
+ end
85
+ typecaster('ActiveSupport::TimeZone') do |value|
86
+ case value
87
+ when ActiveSupport::TimeZone
88
+ value
89
+ when ::TZInfo::Timezone
90
+ ActiveSupport::TimeZone[value.name]
91
+ when String, Numeric, ActiveSupport::Duration
92
+ value = Float(value) rescue value
93
+ ActiveSupport::TimeZone[value]
94
+ else
95
+ nil
96
+ end
97
+ end
98
+ typecaster('BigDecimal') { |value| ::BigDecimal.new Float(value).to_s rescue nil if value }
99
+ typecaster('Float') { |value| Float(value) rescue nil }
100
+ typecaster('Integer') { |value| Float(value).to_i rescue nil }
101
+ typecaster('Boolean') { |value| BOOLEAN_MAPPING[value] }
102
+ typecaster('ActiveData::UUID') do |value|
103
+ case value
104
+ when UUIDTools::UUID
105
+ ActiveData::UUID.parse_raw value.raw
106
+ when ActiveData::UUID
107
+ value
108
+ when String
109
+ ActiveData::UUID.parse_string value
110
+ when Integer
111
+ ActiveData::UUID.parse_int value
112
+ else
113
+ nil
114
+ end
115
+ end
116
+ end
117
+
118
+ require 'active_data/model'
119
+
120
+ ActiveSupport.on_load :active_record do
121
+ require 'active_data/active_record/associations'
122
+ require 'active_data/active_record/nested_attributes'
123
+
124
+ include ActiveData::ActiveRecord::Associations
125
+ include ActiveData::ActiveRecord::NestedAttributes
9
126
  end