redtape 0.0.1
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.
- data/lib/redtape.rb +63 -0
- data/spec/form_spec.rb +87 -0
- metadata +121 -0
data/lib/redtape.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require "redtape/version"
|
2
|
+
|
3
|
+
require 'active_model'
|
4
|
+
|
5
|
+
module Redtape
|
6
|
+
class Form
|
7
|
+
extend ActiveModel::Naming
|
8
|
+
include ActiveModel::Conversion
|
9
|
+
include ActiveModel::Validations
|
10
|
+
|
11
|
+
attr_accessor :model_accessors
|
12
|
+
|
13
|
+
validate :models_correct
|
14
|
+
|
15
|
+
def self.validates_and_saves(*args)
|
16
|
+
attr_accessor *args
|
17
|
+
@@model_accessors = args
|
18
|
+
end
|
19
|
+
|
20
|
+
def models_correct
|
21
|
+
@@model_accessors.each do |accessor|
|
22
|
+
begin
|
23
|
+
model = send(accessor)
|
24
|
+
unless model.valid?
|
25
|
+
errors.add(
|
26
|
+
model.class.to_s.underscore,
|
27
|
+
model.errors.full_messages
|
28
|
+
)
|
29
|
+
end
|
30
|
+
rescue
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Forms are never themselves persisted
|
36
|
+
def persisted?
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def save
|
41
|
+
populate
|
42
|
+
if valid?
|
43
|
+
persist!
|
44
|
+
else
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def persist!
|
50
|
+
@@model_accessors.each do |accessor|
|
51
|
+
model = send(accessor)
|
52
|
+
unless model.save
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def populate
|
60
|
+
fail NotImplementedError, "Implement populate in your subclass"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/spec/form_spec.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
|
3
|
+
require 'redtape'
|
4
|
+
require 'active_model'
|
5
|
+
|
6
|
+
class TestUser
|
7
|
+
include Virtus
|
8
|
+
|
9
|
+
extend ActiveModel::Naming
|
10
|
+
include ActiveModel::Validations
|
11
|
+
include ActiveModel::Conversion
|
12
|
+
|
13
|
+
attribute :name, String
|
14
|
+
|
15
|
+
validates_presence_of :name
|
16
|
+
validate :name_contains_at_least_two_parts
|
17
|
+
|
18
|
+
def name_contains_at_least_two_parts
|
19
|
+
unless name =~ /.+ .+/
|
20
|
+
errors.add(:name, "should contain at least two parts")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def persisted?
|
25
|
+
valid?
|
26
|
+
end
|
27
|
+
|
28
|
+
def save
|
29
|
+
valid?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class TestRegistrationForm < Redtape::Form
|
34
|
+
validates_and_saves :test_user
|
35
|
+
|
36
|
+
attr_accessor :test_user
|
37
|
+
|
38
|
+
attr_accessor :first_name, :last_name
|
39
|
+
|
40
|
+
validates_presence_of :first_name, :last_name
|
41
|
+
|
42
|
+
def populate
|
43
|
+
self.test_user = TestUser.new(:name => "#{first_name} #{last_name}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe Redtape::Form do
|
48
|
+
context "given a Form accepting a first and last name that creates a User" do
|
49
|
+
context "with valid data" do
|
50
|
+
subject {
|
51
|
+
TestRegistrationForm.new.tap do |f|
|
52
|
+
f.first_name = "Evan"
|
53
|
+
f.last_name = "Light"
|
54
|
+
end
|
55
|
+
}
|
56
|
+
|
57
|
+
context "after saving the form" do
|
58
|
+
before do
|
59
|
+
subject.save
|
60
|
+
end
|
61
|
+
|
62
|
+
specify { subject.should be_valid }
|
63
|
+
specify { subject.test_user.should be_valid }
|
64
|
+
specify { subject.test_user.should be_persisted }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with invalid data" do
|
69
|
+
subject {
|
70
|
+
TestRegistrationForm.new.tap do |f|
|
71
|
+
f.first_name = "Evan"
|
72
|
+
end
|
73
|
+
}
|
74
|
+
|
75
|
+
context "after saving the form" do
|
76
|
+
before do
|
77
|
+
subject.save
|
78
|
+
end
|
79
|
+
|
80
|
+
specify { subject.should_not be_valid }
|
81
|
+
specify { subject.should_not be_persisted }
|
82
|
+
specify { subject.errors.should have_key(:last_name) }
|
83
|
+
specify { subject.test_user.should_not be_valid }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redtape
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Evan Light
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: virtus
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rails
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: activemodel
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: ! 'A handy dandy way to avoid using #accepts_nested_attributes_for'
|
79
|
+
email:
|
80
|
+
- evan.light@tripledogdare.net
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- lib/redtape.rb
|
86
|
+
- spec/form_spec.rb
|
87
|
+
homepage: http://github.com/ClearFit/redtape
|
88
|
+
licenses: []
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
hash: 1171762928256566195
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
hash: 1171762928256566195
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 1.8.24
|
114
|
+
signing_key:
|
115
|
+
specification_version: 3
|
116
|
+
summary: Redtape provides an alternative to [ActiveRecord::NestedAttributes#accepts\_nested\_attributes\_for](http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for)
|
117
|
+
in the form of, well, a Form! The initial implementation was heavily inspired by
|
118
|
+
["7 Ways to Decompose Fat Activerecord Models"](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/)
|
119
|
+
by [Bryan Helmkamp](https://github.com/brynary).
|
120
|
+
test_files:
|
121
|
+
- spec/form_spec.rb
|