trans_forms 0.1.0 → 0.2.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 +5 -13
- data/README.md +3 -2
- data/lib/trans_forms/form_base.rb +44 -5
- data/lib/trans_forms/main_model/proxy.rb +92 -1
- data/lib/trans_forms/main_model.rb +64 -7
- data/lib/trans_forms/version.rb +1 -1
- data/lib/trans_forms.rb +0 -1
- data/spec/spec_helper.rb +5 -2
- data/spec/support/schema.rb +12 -12
- data/spec/support/trans_forms/main_model_forms.rb +11 -2
- data/spec/trans_forms/form_base_spec.rb +19 -7
- data/spec/trans_forms/main_model/proxy_spec.rb +14 -1
- data/spec/trans_forms/main_model_spec.rb +46 -14
- metadata +23 -103
- data/.gitignore +0 -3
- data/.rspec +0 -2
- data/.travis.yml +0 -5
- data/Gemfile +0 -4
- data/LICENSE +0 -22
- data/Rakefile +0 -27
- data/lib/trans_forms/form_errors.rb +0 -38
- data/spec/trans_forms/form_errors_spec.rb +0 -14
- data/trans_forms.gemspec +0 -29
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MDQxZWY0NTJkNWQ5NWIyNTkyOTBjYjhlNmViMjUwZDI5NzkwOTcwZA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 816031429c4c367af9bfee0e344f49bd11432fef
|
4
|
+
data.tar.gz: 326b77fa9d791c60808b71a57c2386b60b0a6041
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZWE3MjgwNTA3Y2Q3OTM5OGExMmU3Y2Q1Yzk2NzNiODI0MTg1YTY3ODUzOTVj
|
11
|
-
NTBhYjQ2YmRkNWFkNWFjNWVmMGFlMWZjYTMxYWRmMjkzMTk4YWQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NDE0NzQ4YTY2MmVkZmZjZWUwNGU2NzE3ZGJiY2M0ZTdmMmRhZWM5NDFhMWI4
|
14
|
-
NDM1ODUxZTFmY2VjNGU0YWJlODQ0MjQ5ZThiOGNlZmZhODA0MGMwNmM5ZjVl
|
15
|
-
Mzc5MTBmNWQzNWNmNjQ4ODY3MTk4YmU2YTFjYzlkMDAyNTNlYzY=
|
6
|
+
metadata.gz: e94173975503abd86f039254b66bbcc4c5e1868b8a67226fd72db4b053184115862d7656679cce2e9f9732445e69a516ddd88f5686fa0937226fb82b03703e4f
|
7
|
+
data.tar.gz: 7b2aee4f0f4f06bbb0f1e064592164135fed78d46b5f91447175718e6733e59908ad02350b31b03aaec843f1e1edb54012f9dfa2a121b223768477eb251e9518
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
# TransForms
|
2
|
+
[](http://badge.fury.io/rb/trans_forms)
|
1
3
|
[](https://travis-ci.org/dannemanne/trans_forms)
|
2
4
|
[](https://codeclimate.com/github/dannemanne/trans_forms)
|
3
|
-
|
4
|
-
# TransForms
|
5
|
+
[](https://codeclimate.com/github/dannemanne/trans_forms)
|
5
6
|
|
6
7
|
TransForms is short for Transactional Forms. I created it mainly because I felt that
|
7
8
|
the ActiveRecord Models all to often get cluttered with a lot of conditional validations
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'virtus'
|
2
|
-
|
3
|
-
|
4
|
-
require 'rails/all'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_model'
|
5
4
|
|
6
5
|
module TransForms
|
7
6
|
class FormBase
|
@@ -14,16 +13,22 @@ module TransForms
|
|
14
13
|
|
15
14
|
include TransForms::Callbacks
|
16
15
|
|
16
|
+
attr_accessor :_last_error
|
17
|
+
|
17
18
|
def save
|
18
19
|
valid? && run_transaction
|
19
20
|
end
|
20
21
|
|
21
22
|
def save!
|
22
|
-
|
23
|
+
valid? || raise(ActiveRecord::RecordInvalid.new(self))
|
24
|
+
save || (_last_error && raise(_last_error) || raise(ActiveRecord::RecordNotSaved))
|
23
25
|
end
|
24
26
|
|
25
|
-
# ActiveModel support
|
27
|
+
# ActiveModel support.
|
28
|
+
# Note that these methods will be overwritten if the +proxy+ option
|
29
|
+
# is enabled in the call to +set_main_model+
|
26
30
|
def persisted?; false end
|
31
|
+
def new_record?; !persisted? end
|
27
32
|
def to_key; nil end
|
28
33
|
|
29
34
|
protected
|
@@ -40,8 +45,42 @@ module TransForms
|
|
40
45
|
rescue ActiveRecord::ActiveRecordError => e
|
41
46
|
# Triggers callback
|
42
47
|
after_save_on_error_callback e
|
48
|
+
self._last_error = e
|
49
|
+
if e.respond_to?(:record)
|
50
|
+
e.record.errors.each do |attribute, message|
|
51
|
+
errors.add(attribute, message)
|
52
|
+
end
|
53
|
+
end
|
43
54
|
false
|
44
55
|
end
|
45
56
|
|
57
|
+
# A method to to use when you want to redirect any errors raised to a
|
58
|
+
# specific attribute. It requires a block and any ActiveRecordErrors
|
59
|
+
# that are raised within this block will be assigned to the Form Models
|
60
|
+
# Errors instance for the key specified by +attr+.
|
61
|
+
#
|
62
|
+
# class ArticleCreator < ApplicationTransForm
|
63
|
+
# attribute :author_name
|
64
|
+
# ...
|
65
|
+
#
|
66
|
+
# transaction do
|
67
|
+
# all_errors_to(:author_name) do
|
68
|
+
# # If this following statement raises an ActiveRecordError, then
|
69
|
+
# # that error message will be stored on the attribute :author_name
|
70
|
+
# Author.create!(name: author_name)
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# ...
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
def all_errors_to(attr)
|
78
|
+
raise 'No block given' unless block_given?
|
79
|
+
yield
|
80
|
+
rescue ActiveRecord::ActiveRecordError => e
|
81
|
+
errors[attr] = e.message
|
82
|
+
raise e
|
83
|
+
end
|
84
|
+
|
46
85
|
end
|
47
86
|
end
|
@@ -7,7 +7,98 @@ module TransForms
|
|
7
7
|
# and controllers handle the form model as if it were
|
8
8
|
# the main model itself
|
9
9
|
|
10
|
+
# Dependency for the Proxy Module. Usually this is already
|
11
|
+
# included before Proxy is included, but we make sure it
|
12
|
+
# is present by including it from here as well.
|
13
|
+
include ::TransForms::MainModel::Active
|
14
|
+
|
15
|
+
def persisted?
|
16
|
+
respond_to?(:main_instance) && main_instance && main_instance.persisted?
|
17
|
+
end
|
18
|
+
|
19
|
+
# In case the Main Model has implemented custom +to_param+ method, we need
|
20
|
+
# to make sure we use it here as well
|
21
|
+
def to_param
|
22
|
+
respond_to?(:main_instance) && main_instance && main_instance.to_param || super
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns an Enumerable of all key attributes of the main instanceif any is
|
26
|
+
# set, regardless if the object is persisted or not. Returns +nil+ if there
|
27
|
+
# is no main_instance or if main_instance have no key attributes.
|
28
|
+
#
|
29
|
+
# class UserForm < TransForms::BaseForm
|
30
|
+
# set_main_model :user, proxy: true
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# form = UserForm.new
|
34
|
+
# form.to_key # => nil
|
35
|
+
#
|
36
|
+
# form.user = User.new
|
37
|
+
# form.to_key # => nil
|
38
|
+
#
|
39
|
+
# form.user.save # => true
|
40
|
+
# form.to_key # => [1]
|
41
|
+
def to_key
|
42
|
+
respond_to?(:main_instance) && main_instance && main_instance.to_key
|
43
|
+
end
|
44
|
+
|
10
45
|
module ClassMethods
|
46
|
+
RESERVED_COLUMN_NAMES = %w(id created_at updated_at)
|
47
|
+
REJECT_COLUMN_PROC = Proc.new { |c| RESERVED_COLUMN_NAMES.include?(c.name) }
|
48
|
+
|
49
|
+
# Configures the proxy setup. Called from +set_main_model+ when
|
50
|
+
# the option :proxy was supplied. +proxy_options+ will be the value
|
51
|
+
# for that :proxy key.
|
52
|
+
#
|
53
|
+
# If +proxy
|
54
|
+
def configure_proxy(proxy_options)
|
55
|
+
if proxy_options.is_a?(Hash)
|
56
|
+
set_proxy_attributes proxy_options[:attributes] if proxy_options[:attributes]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# If +attributes+ is the Boolean value TRUE then we will proxy all
|
61
|
+
# of the attributes from the main_model class except for a few
|
62
|
+
# reserved attributes.
|
63
|
+
#
|
64
|
+
# But if +attributes+ is an array then we only proxy those attributes
|
65
|
+
# listed in the array. If any of the attributes listed in the array is
|
66
|
+
# not an actual attribute of the main model then an Error will be
|
67
|
+
# raised.
|
68
|
+
def set_proxy_attributes(attributes)
|
69
|
+
if attributes == :all
|
70
|
+
proxy_columns main_class.columns.reject(&REJECT_COLUMN_PROC)
|
71
|
+
elsif attributes.is_a?(Array)
|
72
|
+
attr_names = attributes.map(&:to_s)
|
73
|
+
proxy_columns main_class.columns.reject(&REJECT_COLUMN_PROC).select { |c| attr_names.include?(c.name) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Given a set of ActiveRecord Columns, will setup attributes according
|
78
|
+
# to the Virtus standard that will have the default value of the main
|
79
|
+
# instance record.
|
80
|
+
def proxy_columns(columns)
|
81
|
+
columns.each do |column|
|
82
|
+
if (type = column_type(column.type)).present?
|
83
|
+
# When setting the default value, note that +main_instance+ might be nil, so we have to use +try+
|
84
|
+
attribute column.name, type, default: proc { |f| f.main_instance.try(column.name) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns a Class for the specific column type.
|
90
|
+
def column_type(type)
|
91
|
+
case type
|
92
|
+
when :integer then Integer
|
93
|
+
when :float, :decimal then Float
|
94
|
+
when :string, :text, :uuid then String
|
95
|
+
when :datetime, :timestamp, :time then DateTime
|
96
|
+
when :date then Date
|
97
|
+
when :boolean then Virtus::Attribute::Boolean # Boolean is not a standard Ruby class
|
98
|
+
else
|
99
|
+
raise "Could not match column type '#{type}' for #{model_name}"
|
100
|
+
end
|
101
|
+
end
|
11
102
|
|
12
103
|
# Returns an ActiveModel::Name object for module. It can be
|
13
104
|
# used to retrieve all kinds of naming-related information
|
@@ -23,7 +114,7 @@ module TransForms
|
|
23
114
|
# PostForm.model_name.plural # => "posts"
|
24
115
|
def model_name
|
25
116
|
@_model_name ||= begin
|
26
|
-
klass = respond_to?(:
|
117
|
+
klass = respond_to?(:main_class) ? main_class : self
|
27
118
|
|
28
119
|
namespace = klass.parents.detect do |n|
|
29
120
|
n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
|
@@ -6,20 +6,55 @@ module TransForms
|
|
6
6
|
|
7
7
|
# This method will extend the BaseForm functionality with the
|
8
8
|
# TransForms::MainModel::Active module.
|
9
|
+
#
|
10
|
+
# The +model+ argument is a symbol in the underscore format
|
11
|
+
# of a Class name, i.e. +:post+ or +:product_group+
|
12
|
+
#
|
13
|
+
# The +options+ argument is a Hash that can have the following
|
14
|
+
# options set:
|
15
|
+
#
|
16
|
+
# +:proxy+
|
17
|
+
# With proxy defined, the method +model_name+, +to_key+ and
|
18
|
+
# +persisted?+ will refer to the main_model and main_instance
|
19
|
+
# instead of the Form Model.
|
20
|
+
#
|
21
|
+
# class PostForm < TransForms::FormBase
|
22
|
+
# set_main_model :post, proxy: true
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# You can also configure the proxy further by defining the
|
26
|
+
# +attributes+ option inside the proxy. If the value is +:all+
|
27
|
+
# then it will define all the columns of the main model. But
|
28
|
+
# you can also set the value to an array with the names of the
|
29
|
+
# columns you wish to proxy:
|
30
|
+
#
|
31
|
+
# class PostForm < TransForms::FormBase
|
32
|
+
# set_main_model :post, proxy: { attributes: :all }
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# class PostForm < TransForms::FormBase
|
36
|
+
# set_main_model :post, proxy: { attributes: %w(title body status) }
|
37
|
+
# end
|
9
38
|
def set_main_model(model, options = {})
|
10
39
|
include TransForms::MainModel::Active
|
11
40
|
|
12
41
|
# Stores the main_model record in a class_attribute
|
13
|
-
class_attribute :main_model
|
14
42
|
self.main_model = model
|
15
43
|
|
44
|
+
# If model is in namespace then it might be needed to specify manually
|
45
|
+
self._class_name = options[:class_name] if options.has_key?(:class_name)
|
46
|
+
|
16
47
|
# Defines an instance accessor for the main_model
|
17
48
|
attr_accessor model
|
18
49
|
|
19
50
|
# Implements proxy module that overwrites model_name method
|
20
51
|
# to instead return an ActiveModel::Mame class for the
|
21
52
|
# main_model class
|
22
|
-
|
53
|
+
if options[:proxy]
|
54
|
+
include TransForms::MainModel::Proxy
|
55
|
+
|
56
|
+
configure_proxy options[:proxy]
|
57
|
+
end
|
23
58
|
end
|
24
59
|
|
25
60
|
end
|
@@ -34,17 +69,24 @@ module TransForms
|
|
34
69
|
# anyway. If this module is included manually (like in one of the specs) then
|
35
70
|
# it prevents any error to occur.
|
36
71
|
after_save_on_error :assert_record_on_error if respond_to?(:after_save_on_error)
|
72
|
+
|
73
|
+
# Adding class attributes to store model and options for each usage.
|
74
|
+
class_attribute :main_model, :_class_name
|
37
75
|
end
|
38
76
|
|
39
|
-
#
|
40
|
-
# models involved in the form transation.
|
77
|
+
# Instance method to retrieve the current main model instance
|
41
78
|
def main_instance
|
42
79
|
send main_model
|
43
80
|
end
|
44
81
|
|
45
82
|
# Combines the errors from the FormModel as well as the main model instances
|
46
83
|
def errors
|
47
|
-
@errors ||=
|
84
|
+
@errors ||= ActiveModel::Errors.new(self)
|
85
|
+
if respond_to?(:main_instance) && main_instance && main_instance.errors.any?
|
86
|
+
main_instance.errors
|
87
|
+
else
|
88
|
+
@errors
|
89
|
+
end
|
48
90
|
end
|
49
91
|
|
50
92
|
# In it's default implementation, this method will look at the class name
|
@@ -80,7 +122,7 @@ module TransForms
|
|
80
122
|
end
|
81
123
|
end
|
82
124
|
|
83
|
-
|
125
|
+
protected
|
84
126
|
|
85
127
|
# This method is assigned to the after_save_on_error callback
|
86
128
|
#
|
@@ -104,10 +146,25 @@ module TransForms
|
|
104
146
|
if record.class.model_name.is_a?(ActiveModel::Name)
|
105
147
|
record.class.model_name.element
|
106
148
|
else
|
107
|
-
record.class.model_name.
|
149
|
+
record.class.model_name.param_key
|
108
150
|
end
|
109
151
|
end
|
110
152
|
|
153
|
+
|
154
|
+
module ClassMethods
|
155
|
+
|
156
|
+
# Returns the class of the main_model
|
157
|
+
def main_class
|
158
|
+
@main_class ||=
|
159
|
+
if _class_name.present?
|
160
|
+
_class_name.constantize
|
161
|
+
else
|
162
|
+
main_model.to_s.classify.constantize
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
111
168
|
end
|
112
169
|
end
|
113
170
|
end
|
data/lib/trans_forms/version.rb
CHANGED
data/lib/trans_forms.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter '/spec/'
|
4
|
+
end
|
5
|
+
|
1
6
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
7
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
8
|
# Require this file using `require "spec_helper"` to ensure that it is only
|
@@ -7,7 +12,6 @@
|
|
7
12
|
|
8
13
|
require 'bundler/setup'
|
9
14
|
require 'trans_forms'
|
10
|
-
require 'rails/version'
|
11
15
|
require 'support/schema'
|
12
16
|
require 'support/models'
|
13
17
|
require 'database_cleaner'
|
@@ -17,7 +21,6 @@ Dir[File.expand_path('../support/trans_forms/*.rb', __FILE__)].each { |f| requir
|
|
17
21
|
I18n.enforce_available_locales = false
|
18
22
|
|
19
23
|
RSpec.configure do |config|
|
20
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
21
24
|
config.run_all_when_everything_filtered = true
|
22
25
|
config.filter_run :focus
|
23
26
|
|
data/spec/support/schema.rb
CHANGED
@@ -6,18 +6,18 @@ ActiveRecord::Base.establish_connection({
|
|
6
6
|
})
|
7
7
|
|
8
8
|
# prepare test data
|
9
|
-
|
10
|
-
|
11
|
-
create_table "users", :force => true do |t|
|
12
|
-
t.string "name"
|
13
|
-
t.integer "age"
|
14
|
-
end
|
9
|
+
ActiveRecord::Schema.define do
|
10
|
+
self.verbose = false
|
15
11
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
create_table "users", :force => true do |t|
|
13
|
+
t.string "name"
|
14
|
+
t.integer "age"
|
15
|
+
t.datetime "created_at", :null => false
|
16
|
+
t.datetime "updated_at", :null => false
|
20
17
|
end
|
21
|
-
end
|
22
18
|
|
23
|
-
|
19
|
+
create_table "phone_numbers", :force => true do |t|
|
20
|
+
t.integer "user_id"
|
21
|
+
t.string "number"
|
22
|
+
end
|
23
|
+
end
|
@@ -3,9 +3,8 @@ class MainModelModel
|
|
3
3
|
end
|
4
4
|
|
5
5
|
class ProxyModel
|
6
|
-
class_attribute :main_model
|
7
|
-
self.main_model = :user
|
8
6
|
include TransForms::MainModel::Proxy
|
7
|
+
self.main_model = :user
|
9
8
|
end
|
10
9
|
|
11
10
|
class UserUpdater < TransForms::FormBase
|
@@ -25,3 +24,13 @@ end
|
|
25
24
|
class UserProxyModel < TransForms::FormBase
|
26
25
|
set_main_model :user, proxy: true
|
27
26
|
end
|
27
|
+
|
28
|
+
class UserProxyAllModel < TransForms::FormBase
|
29
|
+
ATTR_ARG = :all
|
30
|
+
set_main_model :user, proxy: { attributes: ATTR_ARG }
|
31
|
+
end
|
32
|
+
|
33
|
+
class UserProxySelectModel < TransForms::FormBase
|
34
|
+
ATTR_ARG = %w(name)
|
35
|
+
set_main_model :user, proxy: { attributes: ATTR_ARG }
|
36
|
+
end
|
@@ -10,7 +10,7 @@ module TransForms
|
|
10
10
|
|
11
11
|
expect(form.name).to eq(attr[:name])
|
12
12
|
expect(form.age).to eq(attr[:age])
|
13
|
-
expect { form.foo }.to raise_error
|
13
|
+
expect { form.foo }.to raise_error(NoMethodError)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -26,14 +26,26 @@ module TransForms
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe '#save' do
|
29
|
-
|
30
|
-
form
|
31
|
-
expect(form.save).to be true
|
29
|
+
context 'when no errors occur inside +transaction+ block' do
|
30
|
+
let(:form) { NoErrorInTransactionForm.new }
|
31
|
+
it { expect( form.save ).to be true }
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
form
|
36
|
-
expect(form.save).to be false
|
34
|
+
context 'when errors do occur inside the +transaction+ block' do
|
35
|
+
let(:form) { ErrorInTransactionForm.new }
|
36
|
+
it { expect( form.save ).to be false }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#save!' do
|
41
|
+
context 'when no errors occur inside +transaction+ block' do
|
42
|
+
let(:form) { NoErrorInTransactionForm.new }
|
43
|
+
it { expect( form.save! ).to be true }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when active errors do occur inside the +transaction+ block' do
|
47
|
+
let(:form) { ErrorInTransactionForm.new }
|
48
|
+
it { expect { form.save! }.to raise_error(ActiveRecord::ActiveRecordError) }
|
37
49
|
end
|
38
50
|
end
|
39
51
|
|
@@ -7,7 +7,20 @@ module TransForms
|
|
7
7
|
it 'returns an ActiveModel::Name instance for the main_model instead of form model' do
|
8
8
|
expect(ProxyModel.main_model).to eq :user
|
9
9
|
expect(ProxyModel.name).to eq 'ProxyModel'
|
10
|
-
expect(ProxyModel.model_name
|
10
|
+
expect(ProxyModel.model_name).to eq 'User'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'column_type' do
|
15
|
+
it 'returns a Class representing the type of an ActiveRecord Column' do
|
16
|
+
expect(ProxyModel.column_type(:integer)).to eq Integer
|
17
|
+
expect(ProxyModel.column_type(:string)).to eq String
|
18
|
+
expect(ProxyModel.column_type(:text)).to eq String
|
19
|
+
expect(ProxyModel.column_type(:datetime)).to eq DateTime
|
20
|
+
expect(ProxyModel.column_type(:date)).to eq Date
|
21
|
+
expect(ProxyModel.column_type(:float)).to eq Float
|
22
|
+
expect(ProxyModel.column_type(:decimal)).to eq Float
|
23
|
+
expect(ProxyModel.column_type(:boolean)).to eq Virtus::Attribute::Boolean
|
11
24
|
end
|
12
25
|
end
|
13
26
|
end
|
@@ -8,8 +8,8 @@ module TransForms
|
|
8
8
|
describe 'set_main_model' do
|
9
9
|
it 'defines accessor attributes for main model and stores them in a class attribute' do
|
10
10
|
form = MainModelModel.new
|
11
|
-
expect{ form.user }.to raise_error
|
12
|
-
expect{ form.user = User.new }.to raise_error
|
11
|
+
expect{ form.user }.to raise_error(NoMethodError)
|
12
|
+
expect{ form.user = User.new }.to raise_error(NoMethodError)
|
13
13
|
|
14
14
|
MainModelModel.set_main_model :user
|
15
15
|
form = MainModelModel.new
|
@@ -18,10 +18,49 @@ module TransForms
|
|
18
18
|
|
19
19
|
expect(MainModelModel.main_model).to eq :user
|
20
20
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
|
22
|
+
describe 'option[:proxy]' do
|
23
|
+
it 'proxies +model_name+ method to the main_model' do
|
24
|
+
expect(UserProxyModel.main_model).to eq :user
|
25
|
+
expect(UserProxyModel.name).to eq 'UserProxyModel'
|
26
|
+
expect(UserProxyModel.model_name).to eq 'User'
|
27
|
+
end
|
28
|
+
it 'proxies +persisted?+ method to the main_instance' do
|
29
|
+
form = UserProxyModel.new(user: User.new)
|
30
|
+
expect(form.user.persisted?).to be false
|
31
|
+
expect(form.persisted?).to be false
|
32
|
+
|
33
|
+
form.user = User.create!(name: 'John Doe')
|
34
|
+
expect(form.user.persisted?).to be true
|
35
|
+
expect(form.persisted?).to be true
|
36
|
+
end
|
37
|
+
it 'proxies +to_key+ method to the main_instance' do
|
38
|
+
form = UserProxyModel.new(user: User.new)
|
39
|
+
expect(form.user.to_key).to be nil
|
40
|
+
expect(form.to_key).to be nil
|
41
|
+
|
42
|
+
form.user = User.create!(name: 'John Doe')
|
43
|
+
expect(form.user.to_key).not_to be nil
|
44
|
+
expect(form.to_key).to eq form.user.to_key
|
45
|
+
end
|
46
|
+
it 'defines attributes for all non-reserved column names of the main model' do
|
47
|
+
# ATTR_ARG is defined in test model, just to make
|
48
|
+
# sure we test with a correct model.
|
49
|
+
expect(UserProxyAllModel::ATTR_ARG).to eq :all
|
50
|
+
expect(UserProxyAllModel.main_class).to eq User
|
51
|
+
expect(UserProxyAllModel.attribute_set.each.map(&:name).map(&:to_s)).to eq User.columns.reject { |c| %w(id created_at updated_at).include?(c.name) }.map(&:name)
|
52
|
+
end
|
53
|
+
it 'defines attributes for the specified columns' do
|
54
|
+
# ATTR_ARG is defined in test model, just to make
|
55
|
+
# sure we test with a correct model.
|
56
|
+
expect(UserProxySelectModel::ATTR_ARG).to eq %w(name)
|
57
|
+
expect(UserProxySelectModel.main_class).to eq User
|
58
|
+
expect(UserProxySelectModel.attribute_set.each.map(&:name).map(&:to_s)).to eq %w(name)
|
59
|
+
end
|
60
|
+
it 'sets the default value of an attribute to the corresponding attribute of the main instance' do
|
61
|
+
form = UserProxyAllModel.new(model: user)
|
62
|
+
expect(form.name).to eq user.name
|
63
|
+
end
|
25
64
|
end
|
26
65
|
end
|
27
66
|
|
@@ -34,14 +73,7 @@ module TransForms
|
|
34
73
|
|
35
74
|
it 'raises an error if the model supplied is not the type of main model' do
|
36
75
|
expect(UserUpdater.main_model).to eq :user
|
37
|
-
expect { UserUpdater.new(model: phone_number) }.to raise_error
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe 'model_name' do
|
42
|
-
it 'does not raise an error when raised' do
|
43
|
-
#TODO: Improve this spec
|
44
|
-
expect { UserUpdater.model_name }.not_to raise_error
|
76
|
+
expect { UserUpdater.new(model: phone_number) }.to raise_error(TransForms::NotImplementedError)
|
45
77
|
end
|
46
78
|
end
|
47
79
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trans_forms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Viklund
|
@@ -10,118 +10,48 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2014-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rake
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ! '>='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ! '>='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rspec
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ! '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ! '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '2'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec-rails
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ! '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '2'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '2'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: sqlite3
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ! '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: database_cleaner
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ! '>='
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ! '>='
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
13
|
- !ruby/object:Gem::Dependency
|
84
14
|
name: virtus
|
85
15
|
requirement: !ruby/object:Gem::Requirement
|
86
16
|
requirements:
|
87
|
-
- -
|
17
|
+
- - ">="
|
88
18
|
- !ruby/object:Gem::Version
|
89
19
|
version: '0'
|
90
20
|
type: :runtime
|
91
21
|
prerelease: false
|
92
22
|
version_requirements: !ruby/object:Gem::Requirement
|
93
23
|
requirements:
|
94
|
-
- -
|
24
|
+
- - ">="
|
95
25
|
- !ruby/object:Gem::Version
|
96
26
|
version: '0'
|
97
27
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
28
|
+
name: activemodel
|
99
29
|
requirement: !ruby/object:Gem::Requirement
|
100
30
|
requirements:
|
101
|
-
- -
|
31
|
+
- - ">="
|
102
32
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
33
|
+
version: 3.1.0
|
104
34
|
type: :runtime
|
105
35
|
prerelease: false
|
106
36
|
version_requirements: !ruby/object:Gem::Requirement
|
107
37
|
requirements:
|
108
|
-
- -
|
38
|
+
- - ">="
|
109
39
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
40
|
+
version: 3.1.0
|
111
41
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
42
|
+
name: activesupport
|
113
43
|
requirement: !ruby/object:Gem::Requirement
|
114
44
|
requirements:
|
115
|
-
- -
|
45
|
+
- - ">="
|
116
46
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
47
|
+
version: 3.1.0
|
118
48
|
type: :runtime
|
119
49
|
prerelease: false
|
120
50
|
version_requirements: !ruby/object:Gem::Requirement
|
121
51
|
requirements:
|
122
|
-
- -
|
52
|
+
- - ">="
|
123
53
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
54
|
+
version: 3.1.0
|
125
55
|
description: Gem to create Form records that handles multiple changes wrapped in a
|
126
56
|
transaction
|
127
57
|
email:
|
@@ -130,13 +60,7 @@ executables: []
|
|
130
60
|
extensions: []
|
131
61
|
extra_rdoc_files: []
|
132
62
|
files:
|
133
|
-
- .gitignore
|
134
|
-
- .rspec
|
135
|
-
- .travis.yml
|
136
|
-
- Gemfile
|
137
|
-
- LICENSE
|
138
63
|
- README.md
|
139
|
-
- Rakefile
|
140
64
|
- lib/generators/rails/setup_generator.rb
|
141
65
|
- lib/generators/rails/templates/application_trans_form.rb
|
142
66
|
- lib/generators/rails/templates/trans_form.rb
|
@@ -149,7 +73,6 @@ files:
|
|
149
73
|
- lib/trans_forms/callbacks.rb
|
150
74
|
- lib/trans_forms/errors.rb
|
151
75
|
- lib/trans_forms/form_base.rb
|
152
|
-
- lib/trans_forms/form_errors.rb
|
153
76
|
- lib/trans_forms/main_model.rb
|
154
77
|
- lib/trans_forms/main_model/proxy.rb
|
155
78
|
- lib/trans_forms/nested_forms.rb
|
@@ -166,11 +89,9 @@ files:
|
|
166
89
|
- spec/support/trans_forms/user_creator_1.rb
|
167
90
|
- spec/trans_forms/callbacks_spec.rb
|
168
91
|
- spec/trans_forms/form_base_spec.rb
|
169
|
-
- spec/trans_forms/form_errors_spec.rb
|
170
92
|
- spec/trans_forms/main_model/proxy_spec.rb
|
171
93
|
- spec/trans_forms/main_model_spec.rb
|
172
94
|
- spec/trans_forms/nested_forms_spec.rb
|
173
|
-
- trans_forms.gemspec
|
174
95
|
homepage: https://github.com/dannemanne/trans_forms
|
175
96
|
licenses:
|
176
97
|
- MIT
|
@@ -181,34 +102,33 @@ require_paths:
|
|
181
102
|
- lib
|
182
103
|
required_ruby_version: !ruby/object:Gem::Requirement
|
183
104
|
requirements:
|
184
|
-
- -
|
105
|
+
- - ">="
|
185
106
|
- !ruby/object:Gem::Version
|
186
|
-
version:
|
107
|
+
version: 1.9.3
|
187
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
109
|
requirements:
|
189
|
-
- -
|
110
|
+
- - ">="
|
190
111
|
- !ruby/object:Gem::Version
|
191
112
|
version: '0'
|
192
113
|
requirements: []
|
193
114
|
rubyforge_project:
|
194
|
-
rubygems_version: 2.2.2
|
115
|
+
rubygems_version: 2.5.2.2
|
195
116
|
signing_key:
|
196
117
|
specification_version: 4
|
197
118
|
summary: Gem to create Form records that handles multiple changes wrapped in a transaction
|
198
119
|
test_files:
|
199
|
-
- spec/generators/trans_form/trans_form_generator_spec.rb
|
200
120
|
- spec/spec_helper.rb
|
201
|
-
- spec/support/models.rb
|
202
121
|
- spec/support/schema.rb
|
203
|
-
- spec/support/trans_forms/callback_forms.rb
|
204
122
|
- spec/support/trans_forms/main_model_forms.rb
|
205
123
|
- spec/support/trans_forms/multiple_records_forms.rb
|
206
124
|
- spec/support/trans_forms/nested_forms.rb
|
125
|
+
- spec/support/trans_forms/callback_forms.rb
|
207
126
|
- spec/support/trans_forms/simple_forms.rb
|
208
127
|
- spec/support/trans_forms/user_creator_1.rb
|
209
|
-
- spec/
|
210
|
-
- spec/
|
211
|
-
- spec/trans_forms/form_errors_spec.rb
|
212
|
-
- spec/trans_forms/main_model/proxy_spec.rb
|
128
|
+
- spec/support/models.rb
|
129
|
+
- spec/generators/trans_form/trans_form_generator_spec.rb
|
213
130
|
- spec/trans_forms/main_model_spec.rb
|
131
|
+
- spec/trans_forms/main_model/proxy_spec.rb
|
132
|
+
- spec/trans_forms/callbacks_spec.rb
|
214
133
|
- spec/trans_forms/nested_forms_spec.rb
|
134
|
+
- spec/trans_forms/form_base_spec.rb
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/LICENSE
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2014 Daniel Viklund
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'bundler/gem_tasks'
|
3
|
-
require 'rspec/core/rake_task'
|
4
|
-
|
5
|
-
task 'default' => 'ci'
|
6
|
-
|
7
|
-
desc 'Run all tests for CI'
|
8
|
-
task 'ci' => 'spec'
|
9
|
-
|
10
|
-
desc 'Run all specs'
|
11
|
-
task 'spec' => 'spec:all'
|
12
|
-
|
13
|
-
namespace 'spec' do
|
14
|
-
task 'all' => ['trans_forms', 'generators']
|
15
|
-
|
16
|
-
def spec_task(name)
|
17
|
-
desc "Run #{name} specs"
|
18
|
-
RSpec::Core::RakeTask.new(name) do |t|
|
19
|
-
t.pattern = "spec/#{name}/**/*_spec.rb"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
spec_task 'trans_forms'
|
24
|
-
spec_task 'generators'
|
25
|
-
|
26
|
-
end
|
27
|
-
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module TransForms
|
2
|
-
class FormErrors
|
3
|
-
attr_accessor :form_model, :original
|
4
|
-
|
5
|
-
def initialize(form_model, original)
|
6
|
-
self.form_model, self.original = form_model, original
|
7
|
-
end
|
8
|
-
|
9
|
-
def error_models
|
10
|
-
[original, form_model.main_instance.try(:errors)].compact
|
11
|
-
end
|
12
|
-
|
13
|
-
def full_messages
|
14
|
-
original.full_messages
|
15
|
-
end
|
16
|
-
|
17
|
-
def clear
|
18
|
-
error_models.each do |em|
|
19
|
-
em.clear
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def [](key)
|
24
|
-
error_models.inject([]) { |acc, error_model|
|
25
|
-
acc += (error_model[key])
|
26
|
-
}
|
27
|
-
end
|
28
|
-
|
29
|
-
def empty?
|
30
|
-
error_models.all?(&:empty?)
|
31
|
-
end
|
32
|
-
|
33
|
-
def method_missing(m, *args, &block)
|
34
|
-
original.send(m, *args, &block)
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module TransForms
|
4
|
-
describe FormErrors do
|
5
|
-
describe '#error_models' do
|
6
|
-
it 'does not raise an error when called on a form model without a main_instance' do
|
7
|
-
form = UserUpdater.new
|
8
|
-
expect(form.main_model).to eq(:user)
|
9
|
-
expect(form.main_instance).to be nil
|
10
|
-
expect { form.errors.error_models }.not_to raise_error
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/trans_forms.gemspec
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require File.expand_path('../lib/trans_forms/version', __FILE__)
|
2
|
-
|
3
|
-
Gem::Specification.new do |s|
|
4
|
-
s.authors = ['Daniel Viklund']
|
5
|
-
s.email = ['dannemanne@gmail.com']
|
6
|
-
s.summary = 'Gem to create Form records that handles multiple changes wrapped in a transaction'
|
7
|
-
s.description = 'Gem to create Form records that handles multiple changes wrapped in a transaction'
|
8
|
-
s.homepage = 'https://github.com/dannemanne/trans_forms'
|
9
|
-
s.license = 'MIT'
|
10
|
-
|
11
|
-
s.name = 'trans_forms'
|
12
|
-
s.version = TransForms::VERSION
|
13
|
-
s.date = '2014-07-08'
|
14
|
-
|
15
|
-
s.files = `git ls-files`.split("\n")
|
16
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
-
s.require_paths = ['lib']
|
19
|
-
|
20
|
-
s.add_development_dependency 'rake'
|
21
|
-
s.add_development_dependency 'rspec', '>= 2'
|
22
|
-
s.add_development_dependency 'rspec-rails', '>= 2'
|
23
|
-
s.add_development_dependency 'sqlite3'
|
24
|
-
s.add_development_dependency 'database_cleaner'
|
25
|
-
|
26
|
-
s.add_dependency 'virtus'
|
27
|
-
s.add_dependency 'rails', '>= 3'
|
28
|
-
s.add_dependency 'activemodel', '>= 3'
|
29
|
-
end
|