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.
@@ -0,0 +1,8 @@
1
+ h1. How to cut a new version
2
+
3
+ # after all changes are made
4
+ # update the version in lib/version.rb, following semantic versioning
5
+ # cd into prepro root dir
6
+ # gem build prepro.gemspec
7
+ # gem push prepro-x.x.x.gem
8
+ # commit all changes to git
@@ -0,0 +1,6 @@
1
+ # Defines an error to raise when permissions are transgressed.
2
+ module Prepro
3
+
4
+ class AuthorizationError < StandardError; end
5
+
6
+ end
@@ -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(:actor => actor, :view_context => view_context, :options => options)
42
- enforce_permissions(model_class.listable_by?(actor))
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(model_instance.viewable_by?(actor))
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
- # Override this in your concrete presenters with your own permission handling code.
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 "Implement me in concrete presenter"
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
@@ -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
- processor_attrs = OpenStruct.new(:attributes => model_attrs, :actor => actor, :options => options)
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(model_instance.creatable_by?(actor))
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(model_instance.updatable_by?(actor))
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(model_instance.destroyable_by?(actor))
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
- # Override this in your concrete processors with your own permission handling code.
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 "Implement me in concrete processor"
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
@@ -1,3 +1,3 @@
1
1
  module Prepro
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
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: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
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-01-25 00:00:00 -08:00
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