rectify 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 +4 -4
- data/lib/rectify/{controller.rb → controller_helpers.rb} +1 -1
- data/lib/rectify/form.rb +3 -1
- data/lib/rectify/presenter.rb +3 -1
- data/lib/rectify/version.rb +1 -1
- data/lib/rectify.rb +1 -1
- data/readme.md +145 -109
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7db41f0a655c68a1cc60f253b0bca46e049be1e
|
4
|
+
data.tar.gz: 18cff71a5e52be32ec14c25df243b3aa1bdb4338
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c014786d12349c161f38d17d5249156fc206e21fa43da1061d4237f72778a17ca2190353eb99d6a004ae39a2a5abbe9a9bbede7c0aaff187aa8fd62c2f3f3f4d
|
7
|
+
data.tar.gz: 16590d5c8313f1570612c1fc7d0308a0e3b848ed8cc8bb20c5afcb9ce073434abec5a68383c70f2e5896b51c77d5d242e62dcbfc583157655b23e79d03dfb1d5
|
data/lib/rectify/form.rb
CHANGED
@@ -7,7 +7,9 @@ module Rectify
|
|
7
7
|
|
8
8
|
def self.from_params(params, additional_params = {})
|
9
9
|
params = params.with_indifferent_access
|
10
|
-
attributes = params
|
10
|
+
attributes = params
|
11
|
+
.fetch(mimicked_model_name, {})
|
12
|
+
.merge(additional_params)
|
11
13
|
|
12
14
|
new(attributes).tap do |f|
|
13
15
|
f.id = params[:id]
|
data/lib/rectify/presenter.rb
CHANGED
data/lib/rectify/version.rb
CHANGED
data/lib/rectify.rb
CHANGED
data/readme.md
CHANGED
@@ -25,15 +25,17 @@ bundle install
|
|
25
25
|
|
26
26
|
Currently, Rectify consists of the following concepts:
|
27
27
|
|
28
|
-
* Form Objects
|
29
|
-
* Commands
|
30
|
-
* Presenters
|
28
|
+
* [Form Objects](#form-objects)
|
29
|
+
* [Commands](#commands)
|
30
|
+
* [Presenters](#presenters)
|
31
31
|
|
32
32
|
You can use these separately or together to improve the structure of your Rails
|
33
33
|
applications.
|
34
34
|
|
35
|
-
The main problem that Rectify tries to solve is where your logic should go.
|
36
|
-
business logic is either placed in the controller or the model and the
|
35
|
+
The main problem that Rectify tries to solve is where your logic should go.
|
36
|
+
Commonly, business logic is either placed in the controller or the model and the
|
37
|
+
views are filled with too much logic. The opinion of Rectify is that these
|
38
|
+
places are incorrect and that your models in particular are doing too much.
|
37
39
|
|
38
40
|
Rectify's opinion is that controllers should just be concerned with HTTP related
|
39
41
|
things and models should just be concerned with data access. The problem then
|
@@ -42,14 +44,16 @@ becomes, how and where do you place validations and other business logic.
|
|
42
44
|
Using Rectify, the Form Objects contain validations and represent the data input
|
43
45
|
of your system. Commands then take a Form Object (as well as other data) and
|
44
46
|
perform a single action which is invoked by a controller. Presenters contain the
|
45
|
-
presentation logic in a way that is easily testable and keeps your views as
|
46
|
-
as possible.
|
47
|
+
presentation logic in a way that is easily testable and keeps your views as
|
48
|
+
clean as possible.
|
47
49
|
|
48
|
-
Here's an example controller that shows details about a user and also allows a
|
50
|
+
Here's an example controller that shows details about a user and also allows a
|
51
|
+
user to register an account. This creates a user, sends some emails, does some
|
52
|
+
special auditing and integrates with a third party system:
|
49
53
|
|
50
54
|
```ruby
|
51
55
|
class UserController < ApplicationController
|
52
|
-
include Rectify::
|
56
|
+
include Rectify::ControllerHelpers
|
53
57
|
|
54
58
|
def show
|
55
59
|
present UserDetailsPresenter.new(:user => current_user)
|
@@ -71,9 +75,10 @@ class UserController < ApplicationController
|
|
71
75
|
end
|
72
76
|
```
|
73
77
|
|
74
|
-
The `RegistrationForm` Form Object encapsulates the relevant data that is
|
75
|
-
action and the `RegisterAccount` Command encapsulates the
|
76
|
-
a new account. The controller is clean and
|
78
|
+
The `RegistrationForm` Form Object encapsulates the relevant data that is
|
79
|
+
required for the action and the `RegisterAccount` Command encapsulates the
|
80
|
+
business logic of registering a new account. The controller is clean and
|
81
|
+
business logic now has a natural home:
|
77
82
|
|
78
83
|
```
|
79
84
|
HTTP => Controller (redirecting, rendering, etc)
|
@@ -88,6 +93,21 @@ and Presenters.
|
|
88
93
|
|
89
94
|
## Form Objects
|
90
95
|
|
96
|
+
The role of the Form Object is to mange the input data for a given action. It
|
97
|
+
validates data and only allows whitelisted attributes (replacing the need for
|
98
|
+
Strong Parameters). This is a departure from "The Rails Way" where the model
|
99
|
+
contains the validations. Form Objects help to reduce the weight of your models
|
100
|
+
for one, but also, in an app of reasonable complexity even simple things like
|
101
|
+
validations become harder because context is important.
|
102
|
+
|
103
|
+
For example, you can add validation for a `User` model but there are different
|
104
|
+
context where the validations change. When a user registers themselves you might
|
105
|
+
have one set of validations, when an admin edits that user you might have
|
106
|
+
another set, maybe even when a user edits themselves you may have a third. In
|
107
|
+
"The Rails Way" you would have to have conditional validation in your model.
|
108
|
+
With Rectify you can have a different Form Object per context and keep things
|
109
|
+
easier to manage.
|
110
|
+
|
91
111
|
Form objects in Rectify are based on [Virtus](https://github.com/solnic/virtus)
|
92
112
|
and make them compatible with Rails form builders, add ActiveModel validations
|
93
113
|
and all allow you to specify a model to mimic.
|
@@ -103,7 +123,8 @@ class UserForm < Rectify::Form
|
|
103
123
|
end
|
104
124
|
```
|
105
125
|
|
106
|
-
You can then set that up in your controller instead of a normal ActiveRecord
|
126
|
+
You can then set that up in your controller instead of a normal ActiveRecord
|
127
|
+
model:
|
107
128
|
|
108
129
|
```ruby
|
109
130
|
class UsersController < ApplicationController
|
@@ -133,13 +154,14 @@ You can use the form object with form builders such as
|
|
133
154
|
|
134
155
|
### Mimicking models
|
135
156
|
|
136
|
-
When the form is generated it uses the name of the form class to infer what
|
137
|
-
it should mimic. In the example above, it will mimic the `User` model
|
138
|
-
the `Form` suffix from the form class name by default.
|
157
|
+
When the form is generated it uses the name of the form class to infer what
|
158
|
+
"model" it should mimic. In the example above, it will mimic the `User` model
|
159
|
+
as it removes the `Form` suffix from the form class name by default.
|
139
160
|
|
140
161
|
The model being mimicked affects two things about the form:
|
141
162
|
|
142
|
-
1. The route path helpers to use as the url to post to, for example:
|
163
|
+
1. The route path helpers to use as the url to post to, for example:
|
164
|
+
`users_path`.
|
143
165
|
2. The parent key in the params hash that the controller receives, for example
|
144
166
|
`user` in this case:
|
145
167
|
|
@@ -178,15 +200,15 @@ You define your attributes for your form object just like you do in
|
|
178
200
|
[Virtus](https://github.com/solnic/virtus).
|
179
201
|
|
180
202
|
By default, Rectify forms include an `id` attribute for you so you don't need to
|
181
|
-
add that. We use this `id` attribute to
|
182
|
-
so your forms will work with form builders. For example, your form
|
183
|
-
`#persisted?` method. Your form object is never persisted so
|
184
|
-
should always return `false`.
|
203
|
+
add that. We use this `id` attribute to fulfill some of the requirements of
|
204
|
+
ActiveModel so your forms will work with form builders. For example, your form
|
205
|
+
object has a `#persisted?` method. Your form object is never persisted so
|
206
|
+
technically this should always return `false`.
|
185
207
|
|
186
208
|
However, you are normally representing something that is persistable. So we use
|
187
209
|
the value of `id` to workout if what this should return. If `id` is a number
|
188
|
-
greater than zero then we assume it is persisted otherwise we assume it isn't.
|
189
|
-
is important as it affects where your form is posted (to the `#create` or
|
210
|
+
greater than zero then we assume it is persisted otherwise we assume it isn't.
|
211
|
+
This is important as it affects where your form is posted (to the `#create` or
|
190
212
|
`#update` action in your controller).
|
191
213
|
|
192
214
|
#### Populating attributes
|
@@ -210,9 +232,9 @@ the data in the request:
|
|
210
232
|
form = UserForm.from_params(params)
|
211
233
|
```
|
212
234
|
|
213
|
-
When populating from params we will populate the built in `id` attribute from
|
214
|
-
root of the params hash and populate the rest of the form attributes from
|
215
|
-
the parent key. For example:
|
235
|
+
When populating from params we will populate the built in `id` attribute from
|
236
|
+
the root of the params hash and populate the rest of the form attributes from
|
237
|
+
within the parent key. For example:
|
216
238
|
|
217
239
|
```ruby
|
218
240
|
params = {
|
@@ -232,7 +254,8 @@ form.last_name # => "Pike"
|
|
232
254
|
|
233
255
|
The other thing to notice is that (thanks to Virtus), attribute values are cast
|
234
256
|
to the correct type. The params hash is actually all string based but when you
|
235
|
-
get values from the form, they are returned as the correct type (see `id`
|
257
|
+
get values from the form, they are returned as the correct type (see `id`
|
258
|
+
above).
|
236
259
|
|
237
260
|
In addition to the params hash, you may want to add additional contextual data.
|
238
261
|
This can be done by supplying a second hash to the `.from_params` method.
|
@@ -265,10 +288,12 @@ form.last_name # => "Pike"
|
|
265
288
|
|
266
289
|
One important thing that is different about Rectify forms is that they are not
|
267
290
|
bound by a model. You can use a model to populate the forms attributes but that
|
268
|
-
is all it will do. It does not keep a reference to the model or interact with
|
269
|
-
|
270
|
-
|
271
|
-
|
291
|
+
is all it will do. It does not keep a reference to the model or interact with
|
292
|
+
it.
|
293
|
+
|
294
|
+
Rectify forms are designed to be lightweight representations of the data you
|
295
|
+
want to collect or show in your forms, not something that is linked to a model.
|
296
|
+
This allows you to create any form that you like which doesn't need to match the
|
272
297
|
representation of the data in the database.
|
273
298
|
|
274
299
|
### Validations
|
@@ -276,14 +301,15 @@ representation of the data in the database.
|
|
276
301
|
Rectify includes `ActiveModel::Validations` for you so you can use all of the
|
277
302
|
Rails validations that you are used to within your models.
|
278
303
|
|
279
|
-
Your Form Object has a `#valid?` method that will validate the attributes of
|
280
|
-
form as well as any (deeply) nested form objects and array attributes that
|
281
|
-
form objects.
|
304
|
+
Your Form Object has a `#valid?` method that will validate the attributes of
|
305
|
+
your form as well as any (deeply) nested form objects and array attributes that
|
306
|
+
contain form objects. There is also an `#invalid?` method that returns the
|
307
|
+
opposite of `#valid?`.
|
282
308
|
|
283
309
|
### Strong Parameters
|
284
310
|
|
285
|
-
Did you notice in the example above that there was no mention of
|
286
|
-
|
311
|
+
Did you notice in the example above that there was no mention of Strong
|
312
|
+
Parameters. That's because with Form Objects you do not need strong parameters.
|
287
313
|
You only specify attributes in your form that are allowed to be accepted. All
|
288
314
|
other data in your params hash is ignored.
|
289
315
|
|
@@ -292,19 +318,27 @@ about how to build a form object.
|
|
292
318
|
|
293
319
|
## Commands
|
294
320
|
|
321
|
+
Commands (also known as Service Objects) are the home of your business logic.
|
322
|
+
They allow you to simplify your models and controllers and allow them to focus
|
323
|
+
on what they are responsible for. A Command should encapsulate a single user
|
324
|
+
task such as registering for a new account or placing an order. You of course
|
325
|
+
don't need to put all code for this task within the Command, you can (and
|
326
|
+
should) create other classes that your Command uses to perform it's work.
|
327
|
+
|
328
|
+
With regard to naming, Rectify suggests using verbs rather than nouns for
|
329
|
+
Command class names, for example `RegisterAccount`, `PlaceOrder` or
|
330
|
+
`GenerateEndOfYearReport`. Notice that we don't suffix commands with `Command`
|
331
|
+
or `Service` or similar.
|
332
|
+
|
295
333
|
Commands in Rectify are based on [Wisper](https://github.com/krisleech/wisper)
|
296
334
|
which allows classes to broadcast events for publish/subscribe capabilities.
|
297
|
-
`Rectify::Command` is a lightweight class that gives an alternate API and adds
|
298
|
-
helper methods to improve Command logic.
|
335
|
+
`Rectify::Command` is a lightweight class that gives an alternate API and adds
|
336
|
+
some helper methods to improve Command logic.
|
299
337
|
|
300
338
|
The reason for using the pub/sub model rather than returning a result means that
|
301
339
|
we can reduce the number of conditionals in our code as the outcome of a Command
|
302
340
|
might be more complex than just success or failure.
|
303
341
|
|
304
|
-
With regard to naming, Rectify suggests using verbs rather than nouns for Command
|
305
|
-
class names, for example `RegisterAccount`, `PlaceOrder` or `GenerateEndOfYearReport`.
|
306
|
-
Notice that we don't suffix commands with `Command` or `Service` or similar.
|
307
|
-
|
308
342
|
Here is an example Command with the structure Rectify suggests (as seen in the
|
309
343
|
overview above):
|
310
344
|
|
@@ -367,9 +401,9 @@ end
|
|
367
401
|
|
368
402
|
When you call the `.call` class method, Rectify will instantiate a new instance
|
369
403
|
of the command and will pass the parameters to it's constructor, it will then
|
370
|
-
call the instance method `#call` on the newly created command object. The
|
371
|
-
method also allows you to supply a block where you can handle the events
|
372
|
-
have been broadcast from the command.
|
404
|
+
call the instance method `#call` on the newly created command object. The
|
405
|
+
`.call` method also allows you to supply a block where you can handle the events
|
406
|
+
that may have been broadcast from the command.
|
373
407
|
|
374
408
|
The events that your Command broadcasts can be anything, Rectify suggests `:ok`
|
375
409
|
for success and `:invalid` if the form data is not valid, but it's totally up to
|
@@ -381,13 +415,13 @@ From here you can choose to implement your Command how you see fit. A
|
|
381
415
|
### Writing Commands
|
382
416
|
|
383
417
|
As your application grows and Commands get more complex we recommend using the
|
384
|
-
structure above. Within the `#call` method you first check that the input data
|
385
|
-
valid. If it is you then perform the various tasks that need to be completed.
|
418
|
+
structure above. Within the `#call` method you first check that the input data
|
419
|
+
is valid. If it is you then perform the various tasks that need to be completed.
|
386
420
|
We recommend using private methods for each step that are well named which makes
|
387
421
|
it very easy for anyone reading the code to workout what it does.
|
388
422
|
|
389
423
|
Feel free to use other classes and objects where appropriate to keep your code
|
390
|
-
well
|
424
|
+
well organized and maintainable.
|
391
425
|
|
392
426
|
### Events
|
393
427
|
|
@@ -420,17 +454,18 @@ controller.
|
|
420
454
|
|
421
455
|
You may occasionally want to expose a value within a handler block to the view.
|
422
456
|
You do this via the `expose` method within the handler block. If you want to
|
423
|
-
use `expose` then you must include the `Rectify::
|
424
|
-
controller. You pass a hash of the variables you wish to expose to the view
|
425
|
-
they will then be available. If you have set a Presenter for the view then
|
426
|
-
`expose` will try to set an attribute on that presenter. If there is no
|
427
|
-
or the Presenter doesn't have a matching attribute then `expose` will
|
428
|
-
instance variable of the same name. See below for more details about
|
457
|
+
use `expose` then you must include the `Rectify::ControllerHelpers` module in
|
458
|
+
your controller. You pass a hash of the variables you wish to expose to the view
|
459
|
+
and they will then be available. If you have set a Presenter for the view then
|
460
|
+
`expose` will try to set an attribute on that presenter. If there is no
|
461
|
+
Presenter or the Presenter doesn't have a matching attribute then `expose` will
|
462
|
+
set an instance variable of the same name. See below for more details about
|
463
|
+
Presenters.
|
429
464
|
|
430
465
|
```ruby
|
431
466
|
# within the controller:
|
432
467
|
|
433
|
-
include Rectify::
|
468
|
+
include Rectify::ControllerHelpers
|
434
469
|
|
435
470
|
def create
|
436
471
|
present HomePresenter.new(:name => "Guest")
|
@@ -448,27 +483,27 @@ end
|
|
448
483
|
# => <p>Hello Andy</p>
|
449
484
|
```
|
450
485
|
|
451
|
-
Take a look at [Wisper](https://github.com/krisleech/wisper) for more
|
452
|
-
around how to do publish/subscribe.
|
486
|
+
Take a look at [Wisper](https://github.com/krisleech/wisper) for more
|
487
|
+
information around how to do publish/subscribe.
|
453
488
|
|
454
489
|
## Presenters
|
455
490
|
|
456
|
-
A Presenter is a class that contains the presentational logic for your views.
|
457
|
-
are also known as an "exhibit", "view model", "view object" or just a
|
458
|
-
views are actually templates, but anyway). To avoid confusion
|
459
|
-
classes Presenters.
|
491
|
+
A Presenter is a class that contains the presentational logic for your views.
|
492
|
+
These are also known as an "exhibit", "view model", "view object" or just a
|
493
|
+
"view" (Rails views are actually templates, but anyway). To avoid confusion
|
494
|
+
Rectify calls these classes Presenters.
|
460
495
|
|
461
496
|
It's often the case that you need some logic that is just for the UI. The same
|
462
497
|
question comes up, where should this logic go? You could put it directly in the
|
463
498
|
view, add it to the model or create a helper. Rectify's opinion is that all of
|
464
499
|
these are incorrect. Instead, create a Presenter for the view (or component of
|
465
|
-
the view) and place your logic here. These classes are easily testable and
|
466
|
-
a more object oriented approach to the problem.
|
500
|
+
the view) and place your logic here. These classes are easily testable and
|
501
|
+
provide a more object oriented approach to the problem.
|
467
502
|
|
468
503
|
To create a Presenter just derive off of `Rectify::Presenter`, add attributes as
|
469
|
-
you do for Form Objects using [Virtus](https://github.com/solnic/virtus)
|
470
|
-
declaration. Inside a Presenter you have access to all view helper
|
471
|
-
it's easy to move the presetation logic here:
|
504
|
+
you do for Form Objects using [Virtus](https://github.com/solnic/virtus)
|
505
|
+
`attribute` declaration. Inside a Presenter you have access to all view helper
|
506
|
+
methods so it's easy to move the presetation logic here:
|
472
507
|
|
473
508
|
```ruby
|
474
509
|
class UserDetailsPresenter < Rectify::Presenter
|
@@ -482,9 +517,9 @@ class UserDetailsPresenter < Rectify::Presenter
|
|
482
517
|
end
|
483
518
|
```
|
484
519
|
|
485
|
-
Once you have a Presenter, you typically create it in your controller and make
|
486
|
-
accessible to your views. There are two ways to do that. The first way is to
|
487
|
-
treat it as a normal class:
|
520
|
+
Once you have a Presenter, you typically create it in your controller and make
|
521
|
+
it accessible to your views. There are two ways to do that. The first way is to
|
522
|
+
just treat it as a normal class:
|
488
523
|
|
489
524
|
```ruby
|
490
525
|
class UsersController < ApplicationController
|
@@ -497,20 +532,20 @@ end
|
|
497
532
|
```
|
498
533
|
|
499
534
|
You need to call `#for_controller` and pass it a controller instance which will
|
500
|
-
allow it access to the view helpers. You can then use the Presenter in your
|
501
|
-
as you would expect:
|
535
|
+
allow it access to the view helpers. You can then use the Presenter in your
|
536
|
+
views as you would expect:
|
502
537
|
|
503
538
|
```html
|
504
539
|
<p><%= @presenter.edit_link %></p>
|
505
540
|
```
|
506
541
|
|
507
542
|
The second way is a little cleaner as we have supplied a few helper methods to
|
508
|
-
clean up remove some of the boilerplate. You need to include the
|
509
|
-
module and then use the `present` helper:
|
543
|
+
clean up remove some of the boilerplate. You need to include the
|
544
|
+
`Rectify::ControllerHelpers` module and then use the `present` helper:
|
510
545
|
|
511
546
|
```ruby
|
512
547
|
class UsersController < ApplicationController
|
513
|
-
include Rectify::
|
548
|
+
include Rectify::ControllerHelpers
|
514
549
|
|
515
550
|
def show
|
516
551
|
user = User.find(params[:id])
|
@@ -533,14 +568,14 @@ method above or use the `present` method and add a `for` option with any key:
|
|
533
568
|
|
534
569
|
```ruby
|
535
570
|
class ApplicationController < ActionController::Base
|
536
|
-
include Rectify::
|
571
|
+
include Rectify::ControllerHelpers
|
537
572
|
|
538
573
|
before_action { present LayoutPresenter.new(:user => user), :for => :layout }
|
539
574
|
end
|
540
575
|
```
|
541
576
|
|
542
|
-
To access this Presenter in the view, just pass the Presenter key to the
|
543
|
-
method like so:
|
577
|
+
To access this Presenter in the view, just pass the Presenter key to the
|
578
|
+
`presenter` method like so:
|
544
579
|
|
545
580
|
```html
|
546
581
|
<p><%= presenter(:layout).login_link %></p>
|
@@ -548,12 +583,12 @@ method like so:
|
|
548
583
|
|
549
584
|
### Updating values of a Presenter
|
550
585
|
|
551
|
-
After a presenter has been instantiated you can update it's values
|
552
|
-
their attributes:
|
586
|
+
After a presenter has been instantiated you can update it's values by just
|
587
|
+
setting their attributes:
|
553
588
|
|
554
589
|
```ruby
|
555
590
|
class UsersController < ApplicationController
|
556
|
-
include Rectify::
|
591
|
+
include Rectify::ControllerHelpers
|
557
592
|
|
558
593
|
def show
|
559
594
|
user = User.find(params[:id])
|
@@ -574,15 +609,15 @@ end
|
|
574
609
|
```
|
575
610
|
|
576
611
|
As mentioned above in the Commands section, you can use the `expose` method (if
|
577
|
-
you include `Rectify::
|
578
|
-
action including the Command handler block. If you have set a
|
579
|
-
view then `expose` will try to set an attribute on that
|
580
|
-
no Presenter or the Presenter doesn't have a matching
|
581
|
-
will set an instance variable of the same name:
|
612
|
+
you include `Rectify::ControllerHelpers`). You can use this anywhere in the
|
613
|
+
controller action including the Command handler block. If you have set a
|
614
|
+
Presenter for the view then `expose` will try to set an attribute on that
|
615
|
+
presenter. If there is no Presenter or the Presenter doesn't have a matching
|
616
|
+
attribute then `expose` will set an instance variable of the same name:
|
582
617
|
|
583
618
|
```ruby
|
584
619
|
class UsersController < ApplicationController
|
585
|
-
include Rectify::
|
620
|
+
include Rectify::ControllerHelpers
|
586
621
|
|
587
622
|
def show
|
588
623
|
user = User.find(params[:id])
|
@@ -599,10 +634,10 @@ end
|
|
599
634
|
|
600
635
|
### Decorators
|
601
636
|
|
602
|
-
Another option for containing your UI logic is to use a Decorator. Rectify
|
603
|
-
ship with a built in way to create a decorator but we recommend either
|
604
|
-
[Draper](https://github.com/drapergem/draper) or you can roll your own
|
605
|
-
`SimpleDelegator`:
|
637
|
+
Another option for containing your UI logic is to use a Decorator. Rectify
|
638
|
+
doesn't ship with a built in way to create a decorator but we recommend either
|
639
|
+
using [Draper](https://github.com/drapergem/draper) or you can roll your own
|
640
|
+
using `SimpleDelegator`:
|
606
641
|
|
607
642
|
```ruby
|
608
643
|
class UserDecorator < SimpleDelegator
|
@@ -636,11 +671,12 @@ end
|
|
636
671
|
|
637
672
|
## Where do I put my files?
|
638
673
|
|
639
|
-
The next inevitable question is "Where do I put my Forms, Commands and
|
640
|
-
You could create `forms`, `commands` and `presenters` folders and
|
641
|
-
Rectify suggests grouping your classes by feature rather
|
642
|
-
create a folder called `core` (this can be
|
643
|
-
folder for each broad feature of your
|
674
|
+
The next inevitable question is "Where do I put my Forms, Commands and
|
675
|
+
Presenters?". You could create `forms`, `commands` and `presenters` folders and
|
676
|
+
follow the Rails Way. Rectify suggests grouping your classes by feature rather
|
677
|
+
than by pattern. For example, create a folder called `core` (this can be
|
678
|
+
anything) and within that, create a folder for each broad feature of your
|
679
|
+
application. Something like the following:
|
644
680
|
|
645
681
|
```
|
646
682
|
.
|
@@ -648,7 +684,7 @@ folder for each broad feature of your application. Something like the following:
|
|
648
684
|
├── controllers
|
649
685
|
├── core
|
650
686
|
│ ├── billing
|
651
|
-
│ ├──
|
687
|
+
│ ├── fulfillment
|
652
688
|
│ ├── ordering
|
653
689
|
│ ├── reporting
|
654
690
|
│ └── security
|
@@ -656,8 +692,8 @@ folder for each broad feature of your application. Something like the following:
|
|
656
692
|
└── views
|
657
693
|
```
|
658
694
|
|
659
|
-
Then you would place your classes in the appropriate feature folder. If you
|
660
|
-
this pattern remember to namespace your classes with a matching module:
|
695
|
+
Then you would place your classes in the appropriate feature folder. If you
|
696
|
+
follow this pattern remember to namespace your classes with a matching module:
|
661
697
|
|
662
698
|
```ruby
|
663
699
|
# in app/core/billing/send_invoice.rb
|
@@ -674,23 +710,23 @@ loaded automatically.
|
|
674
710
|
|
675
711
|
## Trade offs
|
676
712
|
|
677
|
-
This style of Rails architecture is not a silver bullet for all projects. If
|
678
|
-
app is pretty much just basic CRUD then you are unlikely to get much
|
679
|
-
this. However, if your app is more than just CRUD then you should
|
680
|
-
improvement in code structure and maintainability.
|
713
|
+
This style of Rails architecture is not a silver bullet for all projects. If
|
714
|
+
your app is pretty much just basic CRUD then you are unlikely to get much
|
715
|
+
benefit from this. However, if your app is more than just CRUD then you should
|
716
|
+
see an improvement in code structure and maintainability.
|
681
717
|
|
682
718
|
The downside to this approach is that there will be many more classes and files
|
683
|
-
to deal with. This can be tricky as the application gets bigger to hold the
|
684
|
-
system in your head. Personally I would prefer that as maintaining it will
|
685
|
-
easier as all code around a specific user task is on one place.
|
719
|
+
to deal with. This can be tricky as the application gets bigger to hold the
|
720
|
+
whole system in your head. Personally I would prefer that as maintaining it will
|
721
|
+
be easier as all code around a specific user task is on one place.
|
686
722
|
|
687
|
-
Before you use these methods in your project, consider the trade off and use
|
688
|
-
strategies where they make sense for you and your project.
|
723
|
+
Before you use these methods in your project, consider the trade off and use
|
724
|
+
these strategies where they make sense for you and your project.
|
689
725
|
|
690
726
|
## What's next?
|
691
727
|
|
692
728
|
We stated above that the models should be responsible for data access. We
|
693
729
|
may introduce a nice way to keep using the power of ActiveRecord but in a way
|
694
730
|
where your models don't end up as a big ball of queries. We're thinking about
|
695
|
-
Query Objects and a nice way to do this and we're also thinking about a nicer
|
696
|
-
to use raw SQL.
|
731
|
+
Query Objects and a nice way to do this and we're also thinking about a nicer
|
732
|
+
way to use raw SQL.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rectify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Pike
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: virtus
|
@@ -215,7 +215,7 @@ files:
|
|
215
215
|
- LICENSE.txt
|
216
216
|
- lib/rectify.rb
|
217
217
|
- lib/rectify/command.rb
|
218
|
-
- lib/rectify/
|
218
|
+
- lib/rectify/controller_helpers.rb
|
219
219
|
- lib/rectify/form.rb
|
220
220
|
- lib/rectify/presenter.rb
|
221
221
|
- lib/rectify/save_command.rb
|