active_data 0.3.0 → 1.0.0

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