aldous 1.0.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/README.md +20 -19
  4. data/examples/basic_todo/app/controller_actions/home_controller/show.rb +2 -2
  5. data/examples/basic_todo/app/controller_actions/shared/ensure_user_not_disabled_precondition.rb +1 -1
  6. data/examples/basic_todo/app/controller_actions/sign_ins_controller/create.rb +5 -5
  7. data/examples/basic_todo/app/controller_actions/sign_ins_controller/destroy.rb +2 -2
  8. data/examples/basic_todo/app/controller_actions/sign_ins_controller/new.rb +2 -2
  9. data/examples/basic_todo/app/controller_actions/sign_ups_controller/create.rb +4 -4
  10. data/examples/basic_todo/app/controller_actions/sign_ups_controller/new.rb +2 -2
  11. data/examples/basic_todo/app/controller_actions/todos/all_completed_controller/destroy.rb +3 -3
  12. data/examples/basic_todo/app/controller_actions/todos/completed_controller/create.rb +5 -5
  13. data/examples/basic_todo/app/controller_actions/todos_controller/create.rb +4 -4
  14. data/examples/basic_todo/app/controller_actions/todos_controller/destroy.rb +4 -4
  15. data/examples/basic_todo/app/controller_actions/todos_controller/edit.rb +4 -4
  16. data/examples/basic_todo/app/controller_actions/todos_controller/index.rb +2 -2
  17. data/examples/basic_todo/app/controller_actions/todos_controller/new.rb +2 -2
  18. data/examples/basic_todo/app/controller_actions/todos_controller/update.rb +6 -6
  19. data/examples/basic_todo/app/controller_actions/users_controller/index.rb +2 -2
  20. data/examples/basic_todo/app/views/base_view.rb +1 -1
  21. data/examples/basic_todo/app/views/todos/index_view.rb +1 -1
  22. data/examples/basic_todo/app/views/users/index_view.rb +1 -1
  23. data/lib/aldous/controller/action/precondition.rb +14 -20
  24. data/lib/aldous/controller/action/precondition/wrapper.rb +17 -3
  25. data/lib/aldous/controller/action/result_execution_service.rb +1 -0
  26. data/lib/aldous/controller/action/wrapper.rb +5 -1
  27. data/lib/aldous/controller/action_execution_service.rb +1 -0
  28. data/lib/aldous/controller/preconditions_execution_service.rb +7 -8
  29. data/lib/aldous/controller_action.rb +12 -10
  30. data/lib/aldous/respondable/base.rb +12 -4
  31. data/lib/aldous/version.rb +1 -1
  32. data/lib/aldous/view_builder.rb +21 -0
  33. data/spec/aldous/controller/action/precondition/wrapper_spec.rb +21 -9
  34. data/spec/aldous/controller/action/precondition_spec.rb +4 -25
  35. data/spec/aldous/controller/action/result_execution_service_spec.rb +13 -5
  36. data/spec/aldous/controller/action/wrapper_spec.rb +5 -4
  37. data/spec/aldous/controller/preconditions_execution_service_spec.rb +4 -3
  38. data/spec/aldous/controller_action_spec.rb +0 -22
  39. data/spec/aldous/{build_respondable_service_spec.rb → view_builder_spec.rb} +10 -16
  40. metadata +6 -6
  41. data/lib/aldous/build_respondable_service.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e396af4df13c405822eb290056947943e502c97b
4
- data.tar.gz: 62e3f8739b0a35e9f0c4911347f088763e003944
3
+ metadata.gz: b4ac11d7020bca30f4a28b5a3bca292e92ce4422
4
+ data.tar.gz: 4dc1ba4b25bd15301374d4715419803521af1949
5
5
  SHA512:
6
- metadata.gz: 8ab212817cec483cff3f3ae186eb74ca4f8b3dc499634e5c5ce8af68b92bf17a3fba96e3a043819527100d5c4e3fcdb472cf9e55621a933bf1dad3245e95f004
7
- data.tar.gz: 409b37981511c069505dcce476fde2bfa8d3eb9d723c06f9f8fec34f65c32f34ef93cad3224a26040f023d69c1c615ba2ebe98466510d18660b6dd72f4eab793
6
+ metadata.gz: 386504b64bb33f3f6f5471c28b45e0a4af9c94a2195da419ad6a7422f3314c95890e15faad9592d742132f9b9f327d3335f0cfa423e614e1084838ee955d059c
7
+ data.tar.gz: 8fc61614c1d8d1642da533849c96982fe64ac9ef59f86629438ef528e4af0c1058bf3ef0d2e27bafa50bbba9d84a18c320c7143e3c8bcafac2e0c9516226d30e
@@ -1 +1 @@
1
- 2.1.5
1
+ 2.2.1
data/README.md CHANGED
@@ -8,7 +8,7 @@ Aldous attempts to address this, by introducing a light convention for creating
8
8
 
9
9
  2) Big and bloated controllers (despite our best intentions) that contain business logic and are hard to test. Not to mention the logic that is spread among the various `before_actions` requiring mental compilation to understand a controller action fully. Lastly the instance variables spread all over the controller that get inherited by the view templates as global variables.
10
10
 
11
- Aldous addresses this by introducing the concept of a controller action object. The Rails controllers still exist by they contain no logic in them. All the logic moves to the action classes with one action per class. Instance variables from these don't automatically get inherited by the view templates and the job of `before_actions` is taken over by precondition objects. See below for a more detailed overview of Aldous controller actions.
11
+ Aldous addresses this by introducing the concept of a controller action object. The Rails controllers still exist, but they contain no logic in them. All the logic moves to the action classes with one action per class. Instance variables from these don't automatically get inherited by the view templates and the job of `before_actions` is taken over by precondition objects. See below for a more detailed overview of Aldous controller actions.
12
12
 
13
13
  3) Views that are not really views, but are instead view templates that inherit instance variables from controllers as globals and leave no good place for view-specific logic making us resort to hacky solutions like view helpers.
14
14
 
@@ -220,9 +220,9 @@ class TodosController::Index < BaseAction
220
220
  end
221
221
 
222
222
  def perform
223
- return build_view(Home::ShowRedirect) unless current_user
223
+ return view_builder.build(Home::ShowRedirect) unless current_user
224
224
 
225
- build_view(Todos::IndexView)
225
+ view_builder.build(Todos::IndexView)
226
226
  end
227
227
 
228
228
  private
@@ -287,15 +287,15 @@ class TodosController::Update < BaseAction
287
287
  end
288
288
 
289
289
  def perform
290
- return build_view(Home::ShowRedirect) unless current_user
291
- return build_view(Defaults::BadRequestView, errors: [todo_params.error_message]) unless todo_params.fetch
292
- return build_view(Todos::NotFoundView, todo_id: params[:id]) unless todo
293
- return build_view(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
290
+ return view_builder.build(Home::ShowRedirect) unless current_user
291
+ return view_builder.build(Defaults::BadRequestView, errors: [todo_params.error_message]) unless todo_params.fetch
292
+ return view_builder.build(Todos::NotFoundView, todo_id: params[:id]) unless todo
293
+ return view_builder.build(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
294
294
 
295
295
  if todo.update_attributes(todo_params.fetch)
296
- build_view(Todos::IndexRedirect)
296
+ view_builder.build(Todos::IndexRedirect)
297
297
  else
298
- build_view(Todos::EditView)
298
+ view_builder.build(Todos::EditView)
299
299
  end
300
300
  end
301
301
 
@@ -316,14 +316,14 @@ Let's start with the `perform` method. As you can see it's fattish, but no fatte
316
316
  ```ruby
317
317
  class SignUpsController::Create < BaseAction
318
318
  def perform
319
- return build_view(Todos::IndexRedirect) if current_user
320
- return build_view(Defaults::BadRequestView, errors: [user_params.error_message]) unless user_params.fetch
319
+ return view_builder.build(Todos::IndexRedirect) if current_user
320
+ return view_builder.build(Defaults::BadRequestView, errors: [user_params.error_message]) unless user_params.fetch
321
321
 
322
322
  if create_user_result.success?
323
323
  SignInService.perform!(session, create_user_result.user)
324
- build_view(Todos::IndexRedirect)
324
+ view_builder.build(Todos::IndexRedirect)
325
325
  else
326
- build_view(SignUps::NewView)
326
+ view_builder.build(SignUps::NewView)
327
327
  end
328
328
  end
329
329
 
@@ -349,7 +349,7 @@ class Shared::EnsureUserNotDisabledPrecondition < BasePrecondition
349
349
 
350
350
  def perform
351
351
  if current_user && current_user.disabled && !current_ability.can?(:manage, :all)
352
- return build_view(Defaults::ForbiddenView, errors: ['Your account has been disabled'])
352
+ return view_builder.build(Defaults::ForbiddenView, errors: ['Your account has been disabled'])
353
353
  end
354
354
  end
355
355
  end
@@ -437,20 +437,21 @@ class BaseView < ::Aldous::Respondable::Renderable
437
437
  private
438
438
 
439
439
  def header_view
440
- build_view(Modules::HeaderView)
440
+ view_builder.build(Modules::HeaderView)
441
441
  end
442
442
  end
443
443
  ```
444
444
 
445
445
  As you can see a view object ultimately inherits from `Aldous::Respondable::Renderable` and the key method to override is `template_data`. This method needs to return a hash with template or partial that we want to render as well as the locals that we want to supply. If we have a `BaseView` which I recommend, then we can also override the `default_template_locals` method. When you do this, some Aldous magic will happen and all the things in that hash will be available in all the templates as locals which is very handy for data that's common across all or most templates. The key things here is that you control it.
446
446
 
447
- You construct view objects either in your controller actions or in other view objects, to do this you use the `build_view` method which is available in both of those places. The only place where you may have to construct view objects directly is in tests. The constructor signature of a view object is:
447
+ You construct view objects either in your controller actions or in other view objects, to do this you use the `view_builder` object `build` method. This object is always available and you don't need to worry about providing it, but if you ever want to override it (e.g. in tests), you can inject it also. The only place where you may have to construct view objects directly is in tests. The constructor signature of a view object is:
448
448
 
449
449
  ```ruby
450
- def initialize(status, view_data, view_context)
450
+ def initialize(status, view_data, view_context, view_builder)
451
451
  @status = status
452
452
  @view_data = view_data
453
453
  @view_context = view_context
454
+ @view_builder = view_builder
454
455
  end
455
456
  ```
456
457
 
@@ -484,7 +485,7 @@ class Todos::IndexView < BaseView
484
485
  end
485
486
 
486
487
  def todo_view(todo)
487
- build_view(Todos::IndexView::TodoView, todo: todo)
488
+ view_builder.build(Todos::IndexView::TodoView, todo: todo)
488
489
  end
489
490
  end
490
491
  ```
@@ -507,7 +508,7 @@ class BaseView < ::Aldous::Respondable::Renderable
507
508
  private
508
509
 
509
510
  def header_view
510
- build_view(Modules::HeaderView)
511
+ view_builder.build(Modules::HeaderView)
511
512
  end
512
513
  end
513
514
  ```
@@ -1,7 +1,7 @@
1
1
  class HomeController::Show < BaseAction
2
2
  def perform
3
- return build_view(Todos::IndexRedirect) if current_user
4
- build_view(Home::ShowView)
3
+ return view_builder.build(Todos::IndexRedirect) if current_user
4
+ view_builder.build(Home::ShowView)
5
5
  end
6
6
  end
7
7
 
@@ -3,7 +3,7 @@ class Shared::EnsureUserNotDisabledPrecondition < BasePrecondition
3
3
 
4
4
  def perform
5
5
  if current_user && current_user.disabled && !current_ability.can?(:manage, :all)
6
- return build_view(Defaults::ForbiddenView, errors: ['Your account has been disabled'])
6
+ return view_builder.build(Defaults::ForbiddenView, errors: ['Your account has been disabled'])
7
7
  end
8
8
  end
9
9
  end
@@ -1,14 +1,14 @@
1
1
  class SignInsController::Create < BaseAction
2
2
  def perform
3
- return build_view(Todos::IndexRedirect) if current_user
4
- return build_view(Defaults::BadRequestView, status: :bad_request, errors: [user_params.error_message]) unless user_params.fetch
5
- return build_view(SignIns::NewView, status: :not_found) unless user
3
+ return view_builder.build(Todos::IndexRedirect) if current_user
4
+ return view_builder.build(Defaults::BadRequestView, status: :bad_request, errors: [user_params.error_message]) unless user_params.fetch
5
+ return view_builder.build(SignIns::NewView, status: :not_found) unless user
6
6
 
7
7
  if user.authenticate(user_params.fetch[:password])
8
8
  SignInService.perform!(session, user)
9
- build_view(Todos::IndexRedirect)
9
+ view_builder.build(Todos::IndexRedirect)
10
10
  else
11
- build_view(SignIns::NewView, status: :unprocessable_entity, errors: ["Incorrect credentials"])
11
+ view_builder.build(SignIns::NewView, status: :unprocessable_entity, errors: ["Incorrect credentials"])
12
12
  end
13
13
  end
14
14
 
@@ -1,9 +1,9 @@
1
1
  class SignInsController::Destroy < BaseAction
2
2
  def perform
3
- return build_view(Home::ShowRedirect) unless current_user
3
+ return view_builder.build(Home::ShowRedirect) unless current_user
4
4
 
5
5
  SignOutService.perform!(session)
6
6
 
7
- build_view(Home::ShowRedirect)
7
+ view_builder.build(Home::ShowRedirect)
8
8
  end
9
9
  end
@@ -1,7 +1,7 @@
1
1
  class SignInsController::New < BaseAction
2
2
  def perform
3
- return build_view(Todos::IndexRedirect) if current_user
3
+ return view_builder.build(Todos::IndexRedirect) if current_user
4
4
 
5
- return build_view(SignIns::NewView)
5
+ return view_builder.build(SignIns::NewView)
6
6
  end
7
7
  end
@@ -1,13 +1,13 @@
1
1
  class SignUpsController::Create < BaseAction
2
2
  def perform
3
- return build_view(Todos::IndexRedirect) if current_user
4
- return build_view(Defaults::BadRequestView, errors: [user_params.error_message]) unless user_params.fetch
3
+ return view_builder.build(Todos::IndexRedirect) if current_user
4
+ return view_builder.build(Defaults::BadRequestView, errors: [user_params.error_message]) unless user_params.fetch
5
5
 
6
6
  if create_user_result.success?
7
7
  SignInService.perform!(session, create_user_result.user)
8
- build_view(Todos::IndexRedirect)
8
+ view_builder.build(Todos::IndexRedirect)
9
9
  else
10
- build_view(SignUps::NewView)
10
+ view_builder.build(SignUps::NewView)
11
11
  end
12
12
  end
13
13
 
@@ -1,7 +1,7 @@
1
1
  class SignUpsController::New < BaseAction
2
2
  def perform
3
- return build_view(Todos::IndexRedirect) if current_user
3
+ return view_builder.build(Todos::IndexRedirect) if current_user
4
4
 
5
- return build_view(SignUps::NewView)
5
+ return view_builder.build(SignUps::NewView)
6
6
  end
7
7
  end
@@ -1,11 +1,11 @@
1
1
  class Todos::AllCompletedController::Destroy < BaseAction
2
2
  def perform
3
- return build_view(Home::ShowRedirect) unless current_user
3
+ return view_builder.build(Home::ShowRedirect) unless current_user
4
4
 
5
5
  if todos.destroy_all
6
- build_view(Todos::IndexRedirect)
6
+ view_builder.build(Todos::IndexRedirect)
7
7
  else
8
- build_view(Defaults::ServerErrorView, errors: ['Unable to delete completed todos'])
8
+ view_builder.build(Defaults::ServerErrorView, errors: ['Unable to delete completed todos'])
9
9
  end
10
10
  end
11
11
 
@@ -4,16 +4,16 @@ class Todos::CompletedController::Create < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Home::ShowRedirect) unless current_user
8
- return build_view(Todos::NotFoundView, todo_id: todo_id) unless todo
9
- return build_view(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
7
+ return view_builder.build(Home::ShowRedirect) unless current_user
8
+ return view_builder.build(Todos::NotFoundView, todo_id: todo_id) unless todo
9
+ return view_builder.build(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
10
10
 
11
11
  todo.done = true
12
12
 
13
13
  if todo.save
14
- build_view(Todos::IndexRedirect)
14
+ view_builder.build(Todos::IndexRedirect)
15
15
  else
16
- build_view(Defaults::ServerErrorView, errors: ["Unable to mark todo completed"])
16
+ view_builder.build(Defaults::ServerErrorView, errors: ["Unable to mark todo completed"])
17
17
  end
18
18
  end
19
19
 
@@ -4,13 +4,13 @@ class TodosController::Create < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Home::ShowRedirect) unless current_user
8
- return build_view(Defaults::BadRequestView, errors: [todo_params.error_message]) unless todo_params.fetch
7
+ return view_builder.build(Home::ShowRedirect) unless current_user
8
+ return view_builder.build(Defaults::BadRequestView, errors: [todo_params.error_message]) unless todo_params.fetch
9
9
 
10
10
  if todo.save
11
- build_view(Todos::IndexRedirect)
11
+ view_builder.build(Todos::IndexRedirect)
12
12
  else
13
- build_view(Todos::NewView)
13
+ view_builder.build(Todos::NewView)
14
14
  end
15
15
  end
16
16
 
@@ -4,13 +4,13 @@ class TodosController::Destroy < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Home::ShowRedirect) unless current_user
8
- return build_view(Todos::NotFoundView, todo_id: params[:id]) unless todo
9
- return build_view(Defaults::ForbiddenView) unless current_ability.can?(:destroy, todo)
7
+ return view_builder.build(Home::ShowRedirect) unless current_user
8
+ return view_builder.build(Todos::NotFoundView, todo_id: params[:id]) unless todo
9
+ return view_builder.build(Defaults::ForbiddenView) unless current_ability.can?(:destroy, todo)
10
10
 
11
11
  todo.destroy
12
12
 
13
- build_view(Todos::IndexRedirect)
13
+ view_builder.build(Todos::IndexRedirect)
14
14
  end
15
15
 
16
16
  private
@@ -4,11 +4,11 @@ class TodosController::Edit < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Home::ShowRedirect) unless current_user
8
- return build_view(Todos::NotFoundView, todo_id: params[:id]) unless todo
9
- return build_view(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
7
+ return view_builder.build(Home::ShowRedirect) unless current_user
8
+ return view_builder.build(Todos::NotFoundView, todo_id: params[:id]) unless todo
9
+ return view_builder.build(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
10
10
 
11
- build_view(Todos::EditView)
11
+ view_builder.build(Todos::EditView)
12
12
  end
13
13
 
14
14
  private
@@ -4,9 +4,9 @@ class TodosController::Index < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Home::ShowRedirect) unless current_user
7
+ return view_builder.build(Home::ShowRedirect) unless current_user
8
8
 
9
- build_view(Todos::IndexView)
9
+ view_builder.build(Todos::IndexView)
10
10
  end
11
11
 
12
12
  private
@@ -4,9 +4,9 @@ class TodosController::New < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Home::ShowRedirect) unless current_user
7
+ return view_builder.build(Home::ShowRedirect) unless current_user
8
8
 
9
- build_view(Todos::NewView)
9
+ view_builder.build(Todos::NewView)
10
10
  end
11
11
 
12
12
  private
@@ -4,15 +4,15 @@ class TodosController::Update < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Home::ShowRedirect) unless current_user
8
- return build_view(Defaults::BadRequestView, errors: [todo_params.error_message]) unless todo_params.fetch
9
- return build_view(Todos::NotFoundView, todo_id: params[:id]) unless todo
10
- return build_view(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
7
+ return view_builder.build(Home::ShowRedirect) unless current_user
8
+ return view_builder.build(Defaults::BadRequestView, errors: [todo_params.error_message]) unless todo_params.fetch
9
+ return view_builder.build(Todos::NotFoundView, todo_id: params[:id]) unless todo
10
+ return view_builder.build(Defaults::ForbiddenView) unless current_ability.can?(:update, todo)
11
11
 
12
12
  if todo.update_attributes(todo_params.fetch)
13
- build_view(Todos::IndexRedirect)
13
+ view_builder.build(Todos::IndexRedirect)
14
14
  else
15
- build_view(Todos::EditView)
15
+ view_builder.build(Todos::EditView)
16
16
  end
17
17
  end
18
18
 
@@ -4,9 +4,9 @@ class UsersController::Index < BaseAction
4
4
  end
5
5
 
6
6
  def perform
7
- return build_view(Defaults::ForbiddenView) unless current_ability.can?(:index, User)
7
+ return view_builder.build(Defaults::ForbiddenView) unless current_ability.can?(:index, User)
8
8
 
9
- build_view(Users::IndexView)
9
+ view_builder.build(Users::IndexView)
10
10
  end
11
11
 
12
12
  private
@@ -13,6 +13,6 @@ class BaseView < ::Aldous::Respondable::Renderable
13
13
  private
14
14
 
15
15
  def header_view
16
- build_view(Modules::HeaderView)
16
+ view_builder.build(Modules::HeaderView)
17
17
  end
18
18
  end
@@ -21,6 +21,6 @@ class Todos::IndexView < BaseView
21
21
  end
22
22
 
23
23
  def todo_view(todo)
24
- build_view(Todos::IndexView::TodoView, todo: todo)
24
+ view_builder.build(Todos::IndexView::TodoView, todo: todo)
25
25
  end
26
26
  end
@@ -21,6 +21,6 @@ class Users::IndexView < BaseView
21
21
  end
22
22
 
23
23
  def user_view(user)
24
- build_view(Users::IndexView::UserView, user: user).template
24
+ view_builder.build(Users::IndexView::UserView, user: user).template
25
25
  end
26
26
  end
@@ -1,5 +1,4 @@
1
1
  require 'aldous/controller/action/precondition/wrapper'
2
- require 'aldous/build_respondable_service'
3
2
 
4
3
  module Aldous
5
4
  module Controller
@@ -8,47 +7,42 @@ module Aldous
8
7
  include Aldous
9
8
 
10
9
  class << self
11
- def build(action)
12
- Aldous::Controller::Action::Precondition::Wrapper.new(new(action))
10
+ def build(action, controller, view_builder)
11
+ Aldous::Controller::Action::Precondition::Wrapper.new(new(action, controller, view_builder))
13
12
  end
14
13
 
15
- def perform(action)
16
- build(action).perform
14
+ def perform(action, controller, view_builder)
15
+ build(action, controller, view_builder).perform
17
16
  end
18
17
 
19
18
  def inherited(klass)
20
19
  ::Aldous.configuration.controller_methods_exposed_to_action.each do |method_name|
21
20
  unless klass.method_defined?(method_name)
22
21
  define_method method_name do
23
- action.controller.send(method_name)
22
+ controller.send(method_name)
24
23
  end
25
24
  end
26
25
  end
27
26
  end
28
27
  end
29
28
 
30
- attr_reader :action
29
+ attr_reader :action, :controller, :view_builder
31
30
 
32
- def initialize(action)
31
+ def initialize(action, controller, view_builder)
33
32
  @action = action
33
+ @controller = controller
34
+ @view_builder = view_builder
34
35
  end
35
36
 
36
37
  def perform
37
38
  raise NotImplementedError.new("#{self.class.name} must implement method #perform")
38
39
  end
39
40
 
40
- def controller
41
- action.controller
42
- end
43
-
44
- def build_view(respondable_class, extra_data = {})
45
- ::Aldous::BuildRespondableService.new(
46
- view_context: action.controller.view_context,
47
- default_view_data: action.default_view_data,
48
- respondable_class: respondable_class,
49
- status: extra_data[:status],
50
- extra_data: extra_data
51
- ).perform
41
+ ################################################
42
+ # NOTE deprecated
43
+ ################################################
44
+ def build_view(respondable_class, extra_data = {}) # deprecated
45
+ view_builder.build(respondable_class, extra_data)
52
46
  end
53
47
  end
54
48
  end
@@ -15,15 +15,29 @@ module Aldous
15
15
  precondition.action.default_view_data
16
16
  end
17
17
 
18
- def default_error_respondable
19
- precondition.action.default_error_respondable
18
+ def default_error_handler(error)
19
+ precondition.action.default_error_handler(error)
20
+ end
21
+
22
+ def controller
23
+ precondition.controller
24
+ end
25
+
26
+ def view_builder
27
+ precondition.view_builder
20
28
  end
21
29
 
22
30
  def perform
23
31
  precondition.perform
24
32
  rescue => e
25
33
  ::Aldous::LoggingWrapper.log(e)
26
- precondition.build_view(default_error_respondable, errors: [e])
34
+
35
+ error_handler = default_error_handler(e)
36
+
37
+ if error_handler.kind_of?(Class) &&
38
+ error_handler.ancestors.include?(Aldous::Respondable::Base)
39
+ view_builder.build(error_handler, errors: [e])
40
+ end
27
41
  end
28
42
  end
29
43
  end
@@ -1,3 +1,4 @@
1
+ require 'aldous/view_builder'
1
2
  require 'aldous/logging_wrapper'
2
3
 
3
4
  module Aldous
@@ -27,6 +27,10 @@ module Aldous
27
27
  controller_action.controller
28
28
  end
29
29
 
30
+ def view_builder
31
+ controller_action.view_builder
32
+ end
33
+
30
34
  def perform
31
35
  controller_action.perform
32
36
  rescue => e
@@ -36,7 +40,7 @@ module Aldous
36
40
 
37
41
  if error_handler.kind_of?(Class) &&
38
42
  error_handler.ancestors.include?(Aldous::Respondable::Base)
39
- controller_action.build_view(error_handler, errors: [e])
43
+ view_builder.build(error_handler, errors: [e])
40
44
  end
41
45
  end
42
46
  end
@@ -1,3 +1,4 @@
1
+ require 'aldous/view_builder'
1
2
  require 'aldous/controller/preconditions_execution_service'
2
3
  require 'aldous/controller/action/result_execution_service'
3
4
  require 'aldous/logging_wrapper'
@@ -4,19 +4,18 @@ require 'aldous/controller/action/precondition/wrapper'
4
4
  module Aldous
5
5
  module Controller
6
6
  class PreconditionsExecutionService
7
- attr_reader :action, :controller
7
+ attr_reader :action_wrapper, :controller
8
8
 
9
- def initialize(action, controller)
10
- @action = action
9
+ def initialize(action_wrapper, controller)
10
+ @action_wrapper = action_wrapper
11
11
  @controller = controller
12
12
  end
13
13
 
14
14
  def perform
15
- if action.respond_to?(:preconditions) && !action.preconditions.empty?
16
- action.preconditions.each do |precondition_class|
17
- # action here is actually an action wrapper hence the
18
- # action.controller_action below
19
- precondition = precondition_class.build(action.controller_action)
15
+ if action_wrapper.respond_to?(:preconditions) && !action_wrapper.preconditions.empty?
16
+ action_wrapper.preconditions.each do |precondition_class|
17
+ action = action_wrapper.controller_action
18
+ precondition = precondition_class.build(action, controller, action.view_builder)
20
19
  precondition_result = precondition.perform
21
20
 
22
21
  if precondition_result.kind_of?(::Aldous::Respondable::Base)
@@ -1,7 +1,7 @@
1
+ require 'aldous/view_builder'
1
2
  require 'aldous/controller/action/wrapper'
2
3
  require 'aldous/view/blank/html_view'
3
4
  require 'aldous/simple_dto'
4
- require 'aldous/build_respondable_service'
5
5
 
6
6
  module Aldous
7
7
  class ControllerAction
@@ -30,8 +30,9 @@ module Aldous
30
30
 
31
31
  attr_reader :controller
32
32
 
33
- def initialize(controller)
33
+ def initialize(controller, view_builder = nil)
34
34
  @controller = controller
35
+ @view_builder = view_builder
35
36
  end
36
37
 
37
38
  def perform
@@ -50,14 +51,15 @@ module Aldous
50
51
  ::Aldous::View::Blank::HtmlView
51
52
  end
52
53
 
53
- def build_view(respondable_class, extra_data = {})
54
- ::Aldous::BuildRespondableService.new(
55
- view_context: controller.view_context,
56
- default_view_data: default_view_data,
57
- respondable_class: respondable_class,
58
- status: extra_data[:status],
59
- extra_data: extra_data
60
- ).perform
54
+ def view_builder
55
+ @view_builder ||= Aldous::ViewBuilder.new(controller.view_context, default_view_data)
56
+ end
57
+
58
+ ################################################
59
+ # NOTE deprecated
60
+ ################################################
61
+ def build_view(respondable_class, extra_data = {}) # deprecated
62
+ view_builder.build(respondable_class, extra_data)
61
63
  end
62
64
  end
63
65
  end
@@ -1,3 +1,4 @@
1
+ require 'aldous/view_builder'
1
2
  require 'aldous/simple_dto'
2
3
 
3
4
  module Aldous
@@ -5,10 +6,11 @@ module Aldous
5
6
  class Base
6
7
  attr_reader :view_data, :view_context
7
8
 
8
- def initialize(status, view_data, view_context)
9
+ def initialize(status, view_data, view_context, view_builder = nil)
9
10
  @status = status
10
11
  @view_data = view_data
11
12
  @view_context = view_context
13
+ @view_builder = view_builder
12
14
  end
13
15
 
14
16
  def action(controller)
@@ -23,9 +25,15 @@ module Aldous
23
25
  :ok
24
26
  end
25
27
 
26
- def build_view(klass, extra_data = {})
27
- dto = Aldous::SimpleDto.new(view_data._data.merge(extra_data))
28
- klass.new(status, dto, view_context)
28
+ def view_builder
29
+ @view_builder ||= ViewBuilder.new(view_context, view_data._data)
30
+ end
31
+
32
+ ################################################
33
+ # NOTE deprecated
34
+ ################################################
35
+ def build_view(respondable_class, extra_data = {}) # deprecated
36
+ view_builder.build(respondable_class, extra_data)
29
37
  end
30
38
  end
31
39
  end
@@ -1,3 +1,3 @@
1
1
  module Aldous
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.2"
3
3
  end
@@ -0,0 +1,21 @@
1
+ require 'aldous/simple_dto'
2
+
3
+ module Aldous
4
+ class ViewBuilder
5
+ attr_reader :view_context, :default_view_data
6
+
7
+ def initialize(view_context, default_view_data)
8
+ @view_context = view_context
9
+ @default_view_data = default_view_data
10
+ end
11
+
12
+ def build(respondable_class, extra_view_data = {}, status = nil)
13
+ actual_status = status || extra_view_data[:status]
14
+ extra_view_data_no_status = extra_view_data.reject{|k, v| k == :status}
15
+ actual_extra_view_data = default_view_data.merge(extra_view_data_no_status)
16
+ view_data_dto = Aldous::SimpleDto.new(actual_extra_view_data)
17
+
18
+ respondable_class.new(actual_status, view_data_dto, view_context)
19
+ end
20
+ end
21
+ end
@@ -3,17 +3,18 @@ RSpec.describe Aldous::Controller::Action::Precondition::Wrapper do
3
3
 
4
4
  let(:precondition) {double 'precondition',
5
5
  action: controller_action,
6
- perform: nil,
7
- build_view: nil }
6
+ view_builder: view_builder,
7
+ perform: nil }
8
8
 
9
9
  let(:controller_action) { double 'controller action',
10
10
  default_view_data: default_view_data,
11
- default_error_respondable: default_error_respondable,
12
- perform: nil,
13
- build_view: nil }
11
+ default_error_handler: default_error_handler,
12
+ view_builder: view_builder,
13
+ perform: nil }
14
14
 
15
15
  let(:default_view_data) { {default_view_data: true} }
16
- let(:default_error_respondable) {double 'default_error_respondable'}
16
+ let(:default_error_handler) {double 'default_error_handler'}
17
+ let(:view_builder) {double 'view_builder'}
17
18
 
18
19
  before do
19
20
  allow(Aldous::LoggingWrapper).to receive(:log)
@@ -34,9 +35,20 @@ RSpec.describe Aldous::Controller::Action::Precondition::Wrapper do
34
35
  allow(precondition).to receive(:perform).and_raise(e)
35
36
  end
36
37
 
37
- it "builds a default error view with errors" do
38
- expect(precondition).to receive(:build_view).with(default_error_respondable, errors: [e])
39
- perform
38
+ context "when the default error handler is not a respondable" do
39
+ it "calls the default error handler" do
40
+ allow(controller_action).to receive(:default_error_handler).with(e)
41
+ perform
42
+ end
43
+ end
44
+
45
+ context "when the default error handler is a respondable" do
46
+ let(:default_error_handler) {Aldous::Respondable::Renderable}
47
+
48
+ it "builds the default error handler" do
49
+ allow(view_builder).to receive(:build).with(default_error_handler, errors: [e])
50
+ perform
51
+ end
40
52
  end
41
53
 
42
54
  it 'reports the error' do
@@ -8,10 +8,11 @@ RSpec.describe Aldous::Controller::Action::Precondition do
8
8
  Object.send :remove_const, 'ExamplePrecondition'
9
9
  end
10
10
 
11
- let(:precondition) {ExamplePrecondition.new(action)}
11
+ let(:precondition) {ExamplePrecondition.new(action, controller, view_builder)}
12
12
 
13
13
  let(:action) {double 'action', controller: controller, default_view_data: default_view_data}
14
14
  let(:controller) {double 'controller', view_context: view_context}
15
+ let(:view_builder) {double 'view_builder'}
15
16
  let(:view_context) {double "view_context"}
16
17
  let(:default_view_data) {double "default_view_data"}
17
18
 
@@ -23,7 +24,7 @@ RSpec.describe Aldous::Controller::Action::Precondition do
23
24
 
24
25
  it "wraps a controller action instance" do
25
26
  expect(Aldous::Controller::Action::Precondition::Wrapper).to receive(:new).with(precondition)
26
- ExamplePrecondition.build(action)
27
+ ExamplePrecondition.build(action, controller, view_builder)
27
28
  end
28
29
  end
29
30
 
@@ -37,7 +38,7 @@ RSpec.describe Aldous::Controller::Action::Precondition do
37
38
 
38
39
  it "calls perform on the wrapper" do
39
40
  expect(wrapper).to receive(:perform)
40
- ExamplePrecondition.perform(action)
41
+ ExamplePrecondition.perform(action, controller, view_builder)
41
42
  end
42
43
  end
43
44
 
@@ -56,26 +57,4 @@ RSpec.describe Aldous::Controller::Action::Precondition do
56
57
  expect{precondition.perform}.to raise_error
57
58
  end
58
59
  end
59
-
60
- describe "#build_view" do
61
- before do
62
- allow(Aldous::BuildRespondableService).to receive(:new).with(
63
- view_context: view_context,
64
- default_view_data: default_view_data,
65
- respondable_class: respondable_class,
66
- status: nil,
67
- extra_data: extra_data
68
- ).and_return(build_respondable_service)
69
- end
70
-
71
- let(:respondable_class) {double "respondable_class"}
72
- let(:extra_data) { {hello: 1} }
73
-
74
- let(:build_respondable_service) {double "build_respondable_service", perform: nil}
75
-
76
- it "executes the BuildRespondableService" do
77
- expect(build_respondable_service).to receive(:perform)
78
- precondition.build_view(respondable_class, extra_data)
79
- end
80
- end
81
60
  end
@@ -1,9 +1,17 @@
1
1
  RSpec.describe Aldous::Controller::Action::ResultExecutionService do
2
2
  let(:result_execution_service) {described_class.new(controller, respondable, default_view_data)}
3
3
 
4
- let(:controller) {double "controller"}
5
- let(:respondable) {double "respondable", action: action}
6
- let(:default_view_data) {'hello'}
4
+ let(:controller) {double "controller", view_context: view_context}
5
+
6
+ let(:view_context) {double "view_context"}
7
+
8
+ let(:respondable) do
9
+ double "respondable", {
10
+ action: action
11
+ }
12
+ end
13
+
14
+ let(:default_view_data) { {hello: 'world'} }
7
15
 
8
16
  let(:action) {double 'action', execute: nil}
9
17
 
@@ -30,12 +38,12 @@ RSpec.describe Aldous::Controller::Action::ResultExecutionService do
30
38
  describe "#perform" do
31
39
  subject(:perform) {result_execution_service.perform}
32
40
 
33
- it "fetches the action from the respondable" do
41
+ it "fetches the action from the complete respondable" do
34
42
  expect(respondable).to receive(:action).with(controller)
35
43
  perform
36
44
  end
37
45
 
38
- it "executes the respondable action" do
46
+ it "executes the complete respondable action" do
39
47
  expect(action).to receive(:execute)
40
48
  perform
41
49
  end
@@ -5,12 +5,13 @@ RSpec.describe Aldous::Controller::Action::Wrapper do
5
5
  default_view_data: default_view_data,
6
6
  preconditions: preconditions,
7
7
  default_error_handler: default_error_handler,
8
- perform: nil,
9
- build_view: nil }
8
+ view_builder: view_builder,
9
+ perform: nil }
10
10
 
11
11
  let(:default_view_data) { {default_view_data: true} }
12
12
  let(:preconditions) { double 'preconditions' }
13
13
  let(:default_error_handler) {double 'default_error_handler'}
14
+ let(:view_builder) {double 'view_builder'}
14
15
 
15
16
  before do
16
17
  allow(Aldous::LoggingWrapper).to receive(:log)
@@ -40,14 +41,14 @@ RSpec.describe Aldous::Controller::Action::Wrapper do
40
41
  let(:default_error_handler) {Aldous::Respondable::Renderable}
41
42
 
42
43
  it "builds a default error view with errors" do
43
- expect(controller_action).to receive(:build_view).with(default_error_handler, errors: [e])
44
+ expect(view_builder).to receive(:build).with(default_error_handler, errors: [e])
44
45
  perform
45
46
  end
46
47
  end
47
48
 
48
49
  context "and the default error handler is not a respondable" do
49
50
  it "doesn't need to do anything" do
50
- expect(controller_action).to_not receive(:build_view)
51
+ expect(default_error_handler).to_not receive(:build)
51
52
  perform
52
53
  end
53
54
  end
@@ -3,7 +3,8 @@ RSpec.describe Aldous::Controller::PreconditionsExecutionService do
3
3
 
4
4
  let(:controller) {double "controller"}
5
5
  let(:action_wrapper) {double 'action wrapper', preconditions: preconditions, controller_action: action}
6
- let(:action) {double 'action'}
6
+ let(:action) {double 'action', view_builder: view_builder}
7
+ let(:view_builder) {double 'view_builder'}
7
8
 
8
9
  let(:preconditions) { [] }
9
10
 
@@ -21,8 +22,8 @@ RSpec.describe Aldous::Controller::PreconditionsExecutionService do
21
22
  let(:precondition_class) {double 'precondition_class', build: precondition}
22
23
  let(:precondition) {double "precondition", perform: nil}
23
24
 
24
- it "builds the precondition with the controller_aciont" do
25
- expect(precondition_class).to receive(:build).with(action)
25
+ it "builds the precondition with the controller_action" do
26
+ expect(precondition_class).to receive(:build).with(action, controller, view_builder)
26
27
  perform
27
28
  end
28
29
 
@@ -72,26 +72,4 @@ RSpec.describe Aldous::ControllerAction do
72
72
  expect(action.default_error_handler('foo')).to eq Aldous::View::Blank::HtmlView
73
73
  end
74
74
  end
75
-
76
- describe "#build_view" do
77
- before do
78
- allow(Aldous::BuildRespondableService).to receive(:new).with(
79
- view_context: view_context,
80
- default_view_data: Hash.new,
81
- respondable_class: respondable_class,
82
- status: nil,
83
- extra_data: extra_data
84
- ).and_return(build_respondable_service)
85
- end
86
-
87
- let(:respondable_class) {double "respondable_class"}
88
- let(:extra_data) { {hello: 1} }
89
-
90
- let(:build_respondable_service) {double "build_respondable_service", perform: nil}
91
-
92
- it "executes the BuildRespondableService" do
93
- expect(build_respondable_service).to receive(:perform)
94
- action.build_view(respondable_class, extra_data)
95
- end
96
- end
97
75
  end
@@ -1,24 +1,18 @@
1
- RSpec.describe Aldous::BuildRespondableService do
2
- let(:service) do
3
- described_class.new(
4
- view_context: view_context,
5
- default_view_data: default_view_data,
6
- respondable_class: respondable_class,
7
- status: status,
8
- extra_data: extra_data
9
- )
10
- end
1
+ RSpec.describe Aldous::ViewBuilder do
2
+ let(:view_builder) { described_class.new(view_context, default_view_data) }
11
3
 
12
4
  let(:view_context) { double "view_context" }
13
5
  let(:default_view_data) { {hello: 1} }
14
6
  let(:respondable_class) { double "respondable_class"}
15
- let(:status) { :foo }
16
7
  let(:extra_data) { {world: 2} }
8
+ let(:status) { :foo }
17
9
 
18
10
  let(:simple_dto) {instance_double(Aldous::SimpleDto)}
19
11
  let(:respondable_instance) {double "respondable_instance"}
20
12
 
21
- describe "#perform" do
13
+ describe "#build" do
14
+ subject(:build) {view_builder.build(respondable_class, extra_data)}
15
+
22
16
  let(:view_data) { {hello: 1, world: 2} }
23
17
 
24
18
  before do
@@ -31,18 +25,18 @@ RSpec.describe Aldous::BuildRespondableService do
31
25
 
32
26
  it "creates a dto with the correct data" do
33
27
  expect(Aldous::SimpleDto).to receive(:new).with(view_data).and_return(simple_dto)
34
- service.perform
28
+ build
35
29
  end
36
30
  end
37
31
 
38
32
  it "creates a dto with the correct data" do
39
33
  expect(Aldous::SimpleDto).to receive(:new).with(view_data).and_return(simple_dto)
40
- service.perform
34
+ build
41
35
  end
42
36
 
43
37
  it "returns a respondable instance" do
44
- expect(respondable_class).to receive(:new).with(status, simple_dto, view_context)
45
- service.perform
38
+ expect(respondable_class).to receive(:new).with(nil, simple_dto, view_context)
39
+ build
46
40
  end
47
41
  end
48
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aldous
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Skorkin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-13 00:00:00.000000000 Z
11
+ date: 2015-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -202,7 +202,6 @@ files:
202
202
  - examples/basic_todo/vendor/assets/javascripts/.keep
203
203
  - examples/basic_todo/vendor/assets/stylesheets/.keep
204
204
  - lib/aldous.rb
205
- - lib/aldous/build_respondable_service.rb
206
205
  - lib/aldous/configuration.rb
207
206
  - lib/aldous/controller.rb
208
207
  - lib/aldous/controller/action/precondition.rb
@@ -236,7 +235,7 @@ files:
236
235
  - lib/aldous/view/blank/atom_view.rb
237
236
  - lib/aldous/view/blank/html_view.rb
238
237
  - lib/aldous/view/blank/json_view.rb
239
- - spec/aldous/build_respondable_service_spec.rb
238
+ - lib/aldous/view_builder.rb
240
239
  - spec/aldous/configuration_spec.rb
241
240
  - spec/aldous/controller/action/precondition/wrapper_spec.rb
242
241
  - spec/aldous/controller/action/precondition_spec.rb
@@ -269,6 +268,7 @@ files:
269
268
  - spec/aldous/view/blank/atom_view_spec.rb
270
269
  - spec/aldous/view/blank/html_view_spec.rb
271
270
  - spec/aldous/view/blank/json_view_spec.rb
271
+ - spec/aldous/view_builder_spec.rb
272
272
  - spec/spec_helper.rb
273
273
  homepage: ''
274
274
  licenses:
@@ -290,12 +290,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
290
290
  version: '0'
291
291
  requirements: []
292
292
  rubyforge_project:
293
- rubygems_version: 2.2.2
293
+ rubygems_version: 2.4.5
294
294
  signing_key:
295
295
  specification_version: 4
296
296
  summary: Rails brave new world
297
297
  test_files:
298
- - spec/aldous/build_respondable_service_spec.rb
299
298
  - spec/aldous/configuration_spec.rb
300
299
  - spec/aldous/controller/action/precondition/wrapper_spec.rb
301
300
  - spec/aldous/controller/action/precondition_spec.rb
@@ -328,4 +327,5 @@ test_files:
328
327
  - spec/aldous/view/blank/atom_view_spec.rb
329
328
  - spec/aldous/view/blank/html_view_spec.rb
330
329
  - spec/aldous/view/blank/json_view_spec.rb
330
+ - spec/aldous/view_builder_spec.rb
331
331
  - spec/spec_helper.rb
@@ -1,23 +0,0 @@
1
- require 'aldous/simple_dto'
2
-
3
- module Aldous
4
- class BuildRespondableService
5
- attr_reader :view_context, :default_view_data
6
- attr_reader :respondable_class, :status, :extra_data
7
-
8
- def initialize(view_context:, default_view_data:, respondable_class:, status: nil, extra_data: {})
9
- @view_context = view_context
10
- @default_view_data = default_view_data
11
- @respondable_class = respondable_class
12
- @status = status
13
- @extra_data = extra_data
14
- end
15
-
16
- def perform
17
- # we don't need the status as a local
18
- actual_extra_data = extra_data.reject{|k, v| k == :status}
19
- view_data = SimpleDto.new(default_view_data.merge(actual_extra_data))
20
- respondable_class.new(status, view_data, view_context)
21
- end
22
- end
23
- end