prepro 0.0.3 → 0.0.4
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/doc/gem_workflow.textile +8 -0
- data/lib/prepro/authorization_error.rb +6 -0
- data/lib/prepro/presenter.rb +28 -16
- data/lib/prepro/processor.rb +27 -12
- data/lib/prepro/version.rb +1 -1
- data/prepro-0.0.3.gem +0 -0
- data/readme.textile +39 -0
- metadata +7 -4
data/lib/prepro/presenter.rb
CHANGED
@@ -10,10 +10,14 @@ module Prepro
|
|
10
10
|
# @param[User, AnonymousUser] actor the actor who will view the model
|
11
11
|
# @param[ActionView::Base] view_context An instance of a view class. The default view class is
|
12
12
|
# ActionView::Base
|
13
|
-
# @param[Hash, optional] options
|
13
|
+
# @param[Hash, optional] options:
|
14
|
+
# * :enforce_permissions - default true
|
14
15
|
# @return[DecoratedModel, Array<DecoratedModel>] a model or collection thereof, decorated for
|
15
16
|
# presentation
|
16
17
|
def self.new(id_model_hash_collection, actor, view_context, options = {})
|
18
|
+
options = {
|
19
|
+
:enforce_permissions => true
|
20
|
+
}.merge(options)
|
17
21
|
case id_model_hash_collection
|
18
22
|
when Array, ActiveRecord::Relation
|
19
23
|
present_collection(id_model_hash_collection, actor, view_context, options)
|
@@ -21,7 +25,7 @@ module Prepro
|
|
21
25
|
present_single(id_model_hash_collection, actor, view_context, options)
|
22
26
|
end
|
23
27
|
end
|
24
|
-
|
28
|
+
|
25
29
|
# Alias the basic access methods, so that they can be called for classes further down the
|
26
30
|
# inheritance chain, after another class overrode the method
|
27
31
|
# Aliasing class methods can only be done in the singleton method
|
@@ -38,12 +42,16 @@ module Prepro
|
|
38
42
|
# @param[Hash, optional] options
|
39
43
|
# @return[Array<DecoratedModel>] An array of models, each decorated for presentation
|
40
44
|
def self.present_collection(model_instances, actor, view_context, options = {})
|
41
|
-
presenter_attrs = OpenStruct.new(
|
42
|
-
|
45
|
+
presenter_attrs = OpenStruct.new(
|
46
|
+
:actor => actor, :view_context => view_context, :options => options
|
47
|
+
)
|
48
|
+
if options[:enforce_permissions]
|
49
|
+
enforce_permissions(model_class.listable_by?(actor))
|
50
|
+
end
|
43
51
|
model_instances.each { |e| make_presentable!(e, presenter_attrs) }
|
44
52
|
model_instances
|
45
53
|
end
|
46
|
-
|
54
|
+
|
47
55
|
# Prepares a model instance for presentation
|
48
56
|
# @param[Integer, String(number), Model] id_hash_model id of model, attributes for model, or model
|
49
57
|
# to present
|
@@ -55,11 +63,13 @@ module Prepro
|
|
55
63
|
def self.present_single(id_hash_model, actor, view_context, options = {})
|
56
64
|
presenter_attrs = OpenStruct.new(:actor => actor, :view_context => view_context, :options => options)
|
57
65
|
model_instance = load_model_instance(id_hash_model)
|
58
|
-
enforce_permissions
|
66
|
+
if options[:enforce_permissions]
|
67
|
+
enforce_permissions(model_instance.viewable_by?(actor))
|
68
|
+
end
|
59
69
|
make_presentable!(model_instance, presenter_attrs)
|
60
70
|
model_instance
|
61
71
|
end
|
62
|
-
|
72
|
+
|
63
73
|
# Returns a model_instance, based on given id_hash_model
|
64
74
|
def self.load_model_instance(id_hash_model)
|
65
75
|
case id_hash_model
|
@@ -76,22 +86,24 @@ module Prepro
|
|
76
86
|
def self.model_class
|
77
87
|
raise "Implement me in concrete presenter"
|
78
88
|
end
|
79
|
-
|
80
|
-
#
|
89
|
+
|
90
|
+
# Raises an AuthorizationError if actor doesn't have permission
|
91
|
+
# @param[Boolean] has_permission indicates whether actor has permission
|
92
|
+
# @return[Nil] nil, or raises AuthorizationError
|
81
93
|
def self.enforce_permissions(has_permission)
|
82
|
-
raise
|
94
|
+
raise Prepro::AuthorizationError unless has_permission
|
83
95
|
end
|
84
|
-
|
96
|
+
|
85
97
|
module DecoratorMixin
|
86
|
-
|
98
|
+
|
87
99
|
def presenter_attrs=(the_presenter_attrs)
|
88
100
|
@presenter_attrs = the_presenter_attrs
|
89
101
|
end
|
90
|
-
|
102
|
+
|
91
103
|
def presenter_attrs
|
92
104
|
@presenter_attrs
|
93
105
|
end
|
94
|
-
|
106
|
+
|
95
107
|
# Formats a_datetime
|
96
108
|
# @param[DateTime, Nil] a_datetime the datetime to format
|
97
109
|
# @param[Symbol] output_format the format to be applied: :distance_in_words,
|
@@ -167,8 +179,8 @@ module Prepro
|
|
167
179
|
def indicate_blank
|
168
180
|
presenter_attrs.view_context.content_tag :span, "None Given", :class => 'label'
|
169
181
|
end
|
170
|
-
|
182
|
+
|
171
183
|
end
|
172
|
-
|
184
|
+
|
173
185
|
end
|
174
186
|
end
|
data/lib/prepro/processor.rb
CHANGED
@@ -3,24 +3,33 @@
|
|
3
3
|
# Use it for the create, update, and destroy actions in a rails app.
|
4
4
|
module Prepro
|
5
5
|
class Processor
|
6
|
-
|
6
|
+
|
7
7
|
# Creates a new model_instance based on model_attrs.
|
8
8
|
# @param[Hash] model_attrs The attributes for the new model_instance. Includes DB columns,
|
9
9
|
# associated objects, nested attributes, etc.
|
10
10
|
# @param[User, AnonymousUser, Nil] actor The actor who creates the model_instance
|
11
|
+
# @param[Hash, optional] options:
|
12
|
+
# * :enforce_permissions - default true
|
11
13
|
# @return[Array<ModelInstance, Boolean>] A tuple with the newly created model_instance and a
|
12
14
|
# success flag.
|
13
15
|
def self.create(model_attrs, actor, options = {})
|
14
|
-
|
16
|
+
options = {
|
17
|
+
:enforce_permissions => true
|
18
|
+
}.merge(options)
|
19
|
+
processor_attrs = OpenStruct.new(
|
20
|
+
:attributes => model_attrs, :actor => actor, :options => options
|
21
|
+
)
|
15
22
|
model_instance = model_class.new
|
16
|
-
enforce_permissions
|
23
|
+
if options[:enforce_permissions]
|
24
|
+
enforce_permissions(model_instance.creatable_by?(actor))
|
25
|
+
end
|
17
26
|
before_assign_attributes_on_create(model_instance, processor_attrs)
|
18
27
|
model_instance.assign_attributes(model_attrs, :as => options[:as])
|
19
28
|
before_save_on_create(model_instance, processor_attrs)
|
20
29
|
success = model_instance.save
|
21
30
|
[model_instance, success]
|
22
31
|
end
|
23
|
-
|
32
|
+
|
24
33
|
# Updates an existing model_instance based on model_attrs.
|
25
34
|
# @param[Hash] model_attrs The attributes for the updated model_instance. Includes DB columns,
|
26
35
|
# the model's id, associated objects, nested attributes, etc.
|
@@ -29,21 +38,25 @@ module Prepro
|
|
29
38
|
def self.update(model_attrs, actor, options = {})
|
30
39
|
processor_attrs = OpenStruct.new(:attributes => model_attrs, :actor => actor, :options => options)
|
31
40
|
model_instance = model_class.find(model_attrs[:id])
|
32
|
-
enforce_permissions
|
41
|
+
if options[:enforce_permissions]
|
42
|
+
enforce_permissions(model_instance.updatable_by?(actor))
|
43
|
+
end
|
33
44
|
before_assign_attributes_on_update(model_instance, processor_attrs)
|
34
45
|
model_instance.assign_attributes(model_attrs, :as => options[:as])
|
35
46
|
before_save_on_update(model_instance, processor_attrs)
|
36
47
|
success = model_instance.save
|
37
48
|
[model_instance, success]
|
38
49
|
end
|
39
|
-
|
50
|
+
|
40
51
|
# Destroys an existing model_instance based on model_id
|
41
52
|
# @param[Integer, String<Number>] model_id The id of the model_instance to be destroyed
|
42
53
|
# @param[User, AnonymousUser, Nil] actor The actor who updates the model_instance
|
43
54
|
# @return[Array<ModelInstance, Boolean>] A tuple with the destroyed model_instance and a success flag.
|
44
55
|
def self.destroy(model_id, actor, options = {})
|
45
56
|
model_instance = model_class.find(model_id)
|
46
|
-
enforce_permissions
|
57
|
+
if options[:enforce_permissions]
|
58
|
+
enforce_permissions(model_instance.destroyable_by?(actor))
|
59
|
+
end
|
47
60
|
model_instance.destroy
|
48
61
|
[model_instance, true]
|
49
62
|
end
|
@@ -74,15 +87,17 @@ module Prepro
|
|
74
87
|
def self.model_class
|
75
88
|
raise "Implement me in concrete processor"
|
76
89
|
end
|
77
|
-
|
78
|
-
#
|
90
|
+
|
91
|
+
# Raises an AuthorizationError if actor doesn't have permission
|
92
|
+
# @param[Boolean] has_permission indicates whether actor has permission
|
93
|
+
# @return[Nil] nil, or raises AuthorizationError
|
79
94
|
def self.enforce_permissions(has_permission)
|
80
|
-
raise
|
95
|
+
raise Prepro::AuthorizationError unless has_permission
|
81
96
|
end
|
82
|
-
|
97
|
+
|
83
98
|
def self.make_processable(model_instance, processor_attrs)
|
84
99
|
# nothing to do here, override in specific processors
|
85
100
|
end
|
86
|
-
|
101
|
+
|
87
102
|
end
|
88
103
|
end
|
data/lib/prepro/version.rb
CHANGED
data/prepro-0.0.3.gem
ADDED
Binary file
|
data/readme.textile
CHANGED
@@ -2,3 +2,42 @@ Prepro gives your Rails app presenters and processors to slim down both controll
|
|
2
2
|
|
3
3
|
This is still a work in progress. I use it for production, however the API might change and it
|
4
4
|
requires a lot more documentation.
|
5
|
+
|
6
|
+
Requires Rails 3.1 or greater.
|
7
|
+
|
8
|
+
|
9
|
+
h1. How Prepro fits into the Rails picture
|
10
|
+
|
11
|
+
* Rails models, ActiveRecord based.
|
12
|
+
* Prepro Presenters: wrapped around a Rails model to take care of data output. You would typically
|
13
|
+
use a presenter in the following controller actions: index, show, new, edit
|
14
|
+
* Prepro Processors: wrapped around a Rails model to take care of data input.
|
15
|
+
|
16
|
+
|
17
|
+
h2. What to put into Rails Models
|
18
|
+
|
19
|
+
Try to encapsulate all but the simplest references to ActiveRecord in the model. Don't let AR spill
|
20
|
+
out into your entire app. This will make testing a lot simpler.
|
21
|
+
|
22
|
+
* Complex AR methods like composed AREL methods or scopes
|
23
|
+
* Data manipulation
|
24
|
+
* validation
|
25
|
+
* delegation
|
26
|
+
* conversion
|
27
|
+
* getter and setter overrides for DB column based attributes
|
28
|
+
|
29
|
+
h2. What to put into Presenters
|
30
|
+
|
31
|
+
Anything that is related to data output and display.
|
32
|
+
|
33
|
+
* Display related methods
|
34
|
+
* output in alternative formats like PDF, CSV, ATOM
|
35
|
+
* methods used for form population (e.g., Select options)
|
36
|
+
|
37
|
+
h2. What to put into Processors
|
38
|
+
|
39
|
+
Anything related to data input.
|
40
|
+
|
41
|
+
* methods to create/update records from complex data, e.g., params hash. This is comparable to DCI
|
42
|
+
contexts.
|
43
|
+
* form data processing
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prepro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jo Hund
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-02-02 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -28,11 +28,14 @@ extensions: []
|
|
28
28
|
extra_rdoc_files: []
|
29
29
|
|
30
30
|
files:
|
31
|
+
- doc/gem_workflow.textile
|
31
32
|
- lib/prepro.rb
|
33
|
+
- lib/prepro/authorization_error.rb
|
32
34
|
- lib/prepro/presenter.rb
|
33
35
|
- lib/prepro/processor.rb
|
34
36
|
- lib/prepro/version.rb
|
35
37
|
- prepro-0.0.2.gem
|
38
|
+
- prepro-0.0.3.gem
|
36
39
|
- prepro.gemspec
|
37
40
|
- readme.textile
|
38
41
|
has_rdoc: true
|