dekorator 1.0.0.pre.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +4 -0
- data/.github/workflows/test.yml +40 -0
- data/CHANGELOG.md +44 -4
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +107 -40
- data/benchmarks/README.md +7 -0
- data/benchmarks/benchmark.rb +135 -0
- data/dekorator.gemspec +29 -15
- data/lib/dekorator/rails/controller.rb +17 -0
- data/lib/dekorator/rails/tasks/dekorator.rake +11 -0
- data/lib/dekorator/railtie.rb +9 -5
- data/lib/dekorator/version.rb +1 -1
- data/lib/dekorator.rb +79 -53
- data/lib/generators/decorator_generator.rb +7 -0
- data/lib/generators/{decorator → dekorator/decorator}/USAGE +1 -1
- data/lib/generators/dekorator/decorator/decorator_generator.rb +17 -0
- data/lib/generators/{decorator → dekorator/decorator}/templates/decorator.rb +0 -0
- data/lib/generators/dekorator/{install_generator.rb → install/install_generator.rb} +8 -6
- data/lib/generators/rspec/decorator_generator.rb +2 -0
- data/lib/generators/test_unit/decorator_generator.rb +2 -0
- metadata +60 -52
- data/.editorconfig +0 -14
- data/.gitignore +0 -11
- data/.rspec +0 -3
- data/.rubocop.yml +0 -114
- data/.simplecov +0 -5
- data/.travis.yml +0 -37
- data/Appraisals +0 -17
- data/Gemfile +0 -22
- data/Gemfile.lock +0 -157
- data/bin/console +0 -16
- data/bin/setup +0 -8
- data/gemfiles/.bundle/config +0 -2
- data/gemfiles/rails_5.0.x.gemfile +0 -21
- data/gemfiles/rails_5.0.x.gemfile.lock +0 -207
- data/gemfiles/rails_5.1.x.gemfile +0 -21
- data/gemfiles/rails_5.1.x.gemfile.lock +0 -207
- data/gemfiles/rails_5.2.x.gemfile +0 -21
- data/gemfiles/rails_5.2.x.gemfile.lock +0 -207
- data/gemfiles/rails_6.0.x.gemfile +0 -21
- data/gemfiles/rails_6.0.x.gemfile.lock +0 -220
- data/lib/dekorator/decorators_helper.rb +0 -5
- data/lib/dekorator/rspec.rb +0 -0
- data/lib/generators/decorator/decorator_generator.rb +0 -11
- data/lib/generators/decorator/templates/decorator_test.rb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 993e7223cde1fe170c2312e2a183536162e3deaa933e3dcabd0405bd1d5d1587
|
4
|
+
data.tar.gz: a4cf19afa975185a5a585d60045ced1e872ad02766bd2218091f4cdc1708ffa4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74e30fa63df10cc4f6a196f7fdade396e32ef202e58f1e477ca5096b709ad8166f558f55b58011043ac8f1b823f1b38dba34b0335627de57429a930b6ae1320a
|
7
|
+
data.tar.gz: 1851f7ba63d6962d298efb768d66d0c5aa88a12b6c5f2f596c6e7e9a51906ad5cf0b5d9b0db545c1aa6a0be82dadf00568d11cdadfd46269f06c103975965cab
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
name: Ruby ${{ matrix.versions.ruby }}, Rails ${{ matrix.versions.rails }}
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
strategy:
|
10
|
+
matrix:
|
11
|
+
versions:
|
12
|
+
- { ruby: "2.5", rails: "5.2.x" }
|
13
|
+
- { ruby: "2.6", rails: "5.2.x" }
|
14
|
+
- { ruby: "2.7", rails: "5.2.x" }
|
15
|
+
- { ruby: "2.5", rails: "6.0.x" }
|
16
|
+
- { ruby: "2.6", rails: "6.0.x" }
|
17
|
+
- { ruby: "2.7", rails: "6.0.x" }
|
18
|
+
- { ruby: "3.0", rails: "6.0.x" }
|
19
|
+
- { ruby: "2.5", rails: "6.1.x" }
|
20
|
+
- { ruby: "2.6", rails: "6.1.x" }
|
21
|
+
- { ruby: "2.7", rails: "6.1.x" }
|
22
|
+
- { ruby: "3.0", rails: "6.1.x" }
|
23
|
+
- { ruby: "2.7", rails: "head" }
|
24
|
+
- { ruby: "3.0", rails: "head" }
|
25
|
+
|
26
|
+
|
27
|
+
env:
|
28
|
+
BUNDLE_GEMFILE: gemfiles/rails_${{ matrix.versions.rails }}.gemfile
|
29
|
+
steps:
|
30
|
+
- uses: actions/checkout@v2
|
31
|
+
|
32
|
+
- name: Set up Ruby
|
33
|
+
uses: ruby/setup-ruby@v1
|
34
|
+
with:
|
35
|
+
ruby-version: ${{ matrix.versions.ruby }}
|
36
|
+
bundler-cache: true
|
37
|
+
|
38
|
+
- name: Test with Rake
|
39
|
+
run: |
|
40
|
+
bundle exec rake test:all_with_coverage
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# Changelog
|
2
|
+
|
2
3
|
All notable changes to this project will be documented in this file.
|
3
4
|
|
4
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
@@ -7,10 +8,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
8
|
## [Unreleased]
|
8
9
|
Nothing yet
|
9
10
|
|
11
|
+
## [1.2.1] - 2021-10-14
|
12
|
+
- Make decorated `Enumerable` not lazy anymore ([#46](https://github.com/komposable/dekorator/pull/46))
|
13
|
+
|
14
|
+
## [1.2.0] - 2021-10-14
|
15
|
+
### Added
|
16
|
+
- Add Rails 7.0 support ([#43](https://github.com/komposable/dekorator/pull/43))
|
17
|
+
### Fixes
|
18
|
+
- Avoid n+1 queries when decorate ActiveRecord::Relation ([#44](https://github.com/komposable/dekorator/pull/44))
|
19
|
+
|
20
|
+
## [1.1.0] - 2020-12-23
|
21
|
+
### Added
|
22
|
+
- Ruby 2.7 support ([#37](https://github.com/komposable/dekorator/pull/37))
|
23
|
+
- List decorators in Rails stats task ([#38](https://github.com/komposable/dekorator/pull/38))
|
24
|
+
- Add Rails 6.1 support and drop Rails 5.0 and 5.1 support ([#41](https://github.com/komposable/dekorator/pull/41))
|
25
|
+
### Changed
|
26
|
+
- Refactorisation ([#39](https://github.com/komposable/dekorator/pull/39))
|
27
|
+
### Removed
|
28
|
+
- Remove `DecoratedEnumerableProxy` ([#36](https://github.com/komposable/dekorator/pull/36))
|
29
|
+
- Drop Ruby 2.4 support ([#37](https://github.com/komposable/dekorator/pull/37))
|
30
|
+
- Drop Rails 5.0 and 5.1 support ([#41](https://github.com/komposable/dekorator/pull/41))
|
31
|
+
|
32
|
+
## [1.0.0] - 2019-12-02
|
33
|
+
### Added
|
34
|
+
- Avoid deep decoration ([#25](https://github.com/komposable/dekorator/pull/25))
|
35
|
+
- Make `decorate` accessible in ApplicationController ([#29](https://github.com/komposable/dekorator/pull/29))
|
36
|
+
|
37
|
+
### Changed
|
38
|
+
- Moved to Komposable organization ([#13](https://github.com/komposable/dekorator/pull/13))
|
39
|
+
- Replace Travis CI by Github Actions and remove ruby 2.3 support ([#23](https://github.com/komposable/dekorator/pull/23))
|
40
|
+
- Update railtie to prevent triggering initialization autoloaded constant deprecation warning ([#30](https://github.com/komposable/dekorator/pull/30))
|
41
|
+
- Improve generators ([#31](https://github.com/komposable/dekorator/pull/31))
|
42
|
+
|
43
|
+
### Fixes
|
44
|
+
- Fix DecoratedEnumerableProxy for Rails 6 ([5a656333](https://github.com/komposable/dekorator/commit/5a656333e9ca6321d0474f0e54de4332219b88d0))
|
45
|
+
|
10
46
|
## 1.0.0.pre.1 - 2019-01-30
|
11
47
|
### Added
|
12
|
-
- Create Dekorator::Base the base of decorators (a2a36d66)
|
13
|
-
- Create `dekorator:install` generator (a2a36d66)
|
14
|
-
- Create `decorator` generator (a2a36d66)
|
48
|
+
- Create Dekorator::Base the base of decorators ([a2a36d66](https://github.com/komposable/dekorator/commit/a2a36d66c6de6cb0a00f783794cd29f899bc04b6))
|
49
|
+
- Create `dekorator:install` generator ([a2a36d66](https://github.com/komposable/dekorator/commit/a2a36d66c6de6cb0a00f783794cd29f899bc04b6))
|
50
|
+
- Create `decorator` generator ([a2a36d66](https://github.com/komposable/dekorator/commit/a2a36d66c6de6cb0a00f783794cd29f899bc04b6))
|
15
51
|
|
16
|
-
[Unreleased]: https://github.com/
|
52
|
+
[Unreleased]: https://github.com/komposable/dekorator/compare/v1.2.1...master
|
53
|
+
[1.2.1]: https://github.com/komposable/dekorator/compare/v1.2.0...v1.2.1
|
54
|
+
[1.2.0]: https://github.com/komposable/dekorator/compare/v1.1.0...v1.2.0
|
55
|
+
[1.1.0]: https://github.com/komposable/dekorator/compare/v1.0.0...v1.1.0
|
56
|
+
[1.0.0]: https://github.com/komposable/dekorator/compare/v1.0.0.pre.1...v1.0.0
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|
55
55
|
## Enforcement
|
56
56
|
|
57
57
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
-
reported by contacting the project team at
|
58
|
+
reported by contacting the project team at oss@pantographe.studio. All
|
59
59
|
complaints will be reviewed and investigated and will result in a response that
|
60
60
|
is deemed necessary and appropriate to the circumstances. The project team is
|
61
61
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
data/README.md
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
# Dekorator
|
2
2
|
|
3
|
-
[](https://github.com/komposable/dekorator/actions)
|
4
4
|
[](https://rubygems.org/gems/dekorator)
|
5
|
-
[](https://codeclimate.com/github/komposable/dekorator/maintainability)
|
6
|
+
[](https://coveralls.io/github/komposable/dekorator)
|
7
|
+
[](https://inch-ci.org/github/komposable/dekorator)
|
8
|
+
[](https://www.rubydoc.info/github/komposable/dekorator/master)
|
8
9
|
|
9
|
-
**Dekorator** is
|
10
|
+
**Dekorator** is a lightweight library to implement _presenters_ and/or _decorators_ in your Rails app. It has less features than [`draper`](https://github.com/drapergem/draper) and aims at having a lower memory footprint.
|
10
11
|
|
11
|
-
|
12
|
+
This gem has been inspired by our Rails development practices at [Pantographe](https://pantographe.studio), and the [Ruby memory, ActiveRecord and Draper](https://medium.com/appaloosa-store-engineering/ruby-memory-activerecord-and-draper-64f06abeeb34) talk by [Benoit Tigeot](https://github.com/benoittgt).
|
12
13
|
|
13
14
|
## Compatibility
|
14
15
|
|
15
|
-
* Ruby 2.
|
16
|
-
* Rails 5.
|
17
|
-
|
16
|
+
* Ruby 2.5+
|
17
|
+
* Rails 5.2+
|
18
18
|
|
19
19
|
## Installation
|
20
20
|
|
21
|
-
Add this line to your application
|
21
|
+
Add this line to your application `Gemfile`:
|
22
22
|
|
23
23
|
```ruby
|
24
24
|
gem "dekorator"
|
@@ -28,7 +28,6 @@ And then execute:
|
|
28
28
|
|
29
29
|
$ bundle
|
30
30
|
|
31
|
-
|
32
31
|
## Getting started
|
33
32
|
|
34
33
|
Run the following command to set up your project:
|
@@ -37,7 +36,6 @@ Run the following command to set up your project:
|
|
37
36
|
|
38
37
|
This command will create an `ApplicationDecorator` file.
|
39
38
|
|
40
|
-
|
41
39
|
## Usage
|
42
40
|
|
43
41
|
Generate a new decorator with the `decorator` generator:
|
@@ -48,23 +46,55 @@ This command will generate the following file:
|
|
48
46
|
|
49
47
|
```ruby
|
50
48
|
class UserDecorator < ApplicationDecorator
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
49
|
+
include ActionView::Helpers::TextHelper
|
50
|
+
|
51
|
+
decorates_association :posts
|
52
|
+
|
53
|
+
def full_name
|
54
|
+
[first_name, last_name].join(" ")
|
55
|
+
end
|
56
|
+
|
57
|
+
def biography_summary
|
58
|
+
truncate(biography, length: 170)
|
59
|
+
end
|
62
60
|
end
|
63
61
|
```
|
64
62
|
|
63
|
+
### Decorate from a controller
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class UsersController < ApplicationController
|
67
|
+
def index
|
68
|
+
@users = decorate User.all
|
69
|
+
end
|
70
|
+
|
71
|
+
def show
|
72
|
+
@user = decorate User.find(params[:id])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
### Decorate from a view
|
78
|
+
|
79
|
+
```erb
|
80
|
+
# app/views/users/index.html.erb
|
81
|
+
|
82
|
+
<ul>
|
83
|
+
<% decorate(@users).each do |user| %>
|
84
|
+
<li><%= user.full_name %></li>
|
85
|
+
<% end %>
|
86
|
+
</ul>
|
87
|
+
```
|
88
|
+
|
89
|
+
### Decorate outside a controller/view
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
UserDecorate.decorate(User.first) # => UserDecorator
|
93
|
+
```
|
94
|
+
|
65
95
|
### Associations
|
66
96
|
|
67
|
-
If you want to automatically
|
97
|
+
If you want to automatically decorate an association for a decorated object,
|
68
98
|
you have to use `#decorates_association` as following:
|
69
99
|
|
70
100
|
```ruby
|
@@ -82,29 +112,34 @@ end
|
|
82
112
|
In this example, `UserDecorator#posts` will be decorated.
|
83
113
|
|
84
114
|
```ruby
|
85
|
-
decorated_user =
|
115
|
+
decorated_user = decorate(User.first)
|
86
116
|
decorated_user # => UserDecorator
|
87
117
|
decorated_user.posts.first # => PostDecorator
|
88
118
|
```
|
89
119
|
|
90
|
-
###
|
120
|
+
### Custom decorator
|
121
|
+
|
122
|
+
By default, Dekorator searches for the decorator class by adding `Decorator` at the end.
|
123
|
+
For `User`, Dekorator looks for the `UserDecorator` class, and for `User::Profile`
|
124
|
+
it looks for `User::ProfileDecorator`.
|
91
125
|
|
92
|
-
If you want to create specific decorator or sub-decorator, you
|
93
|
-
specify the decorator class that should be
|
126
|
+
If you want to create a specific decorator or sub-decorator, you can simply
|
127
|
+
specify the decorator class that should be used.
|
94
128
|
|
95
129
|
```ruby
|
96
130
|
class AdminDecorator < ApplicationDecorator
|
131
|
+
...
|
97
132
|
end
|
98
133
|
|
99
|
-
decorated_user =
|
134
|
+
decorated_user = decorate(User.first, with: AdminDecorator)
|
100
135
|
decorated_user # => AdminDecorator
|
101
136
|
```
|
102
137
|
|
103
|
-
You also
|
138
|
+
You can also specify the decorator for associations:
|
104
139
|
|
105
140
|
```ruby
|
106
141
|
class UserDecorator < ApplicationDecorator
|
107
|
-
decorates_association :posts, ArticleDecorator
|
142
|
+
decorates_association :posts, with: ArticleDecorator
|
108
143
|
|
109
144
|
...
|
110
145
|
end
|
@@ -112,7 +147,7 @@ end
|
|
112
147
|
class ArticleDecorator < ApplicationDecorator
|
113
148
|
end
|
114
149
|
|
115
|
-
decorated_user =
|
150
|
+
decorated_user = decorate(User.first)
|
116
151
|
decorated_user # => UserDecorator
|
117
152
|
decorated_user.posts.first # => ArticleDecorator
|
118
153
|
```
|
@@ -121,7 +156,8 @@ decorated_user.posts.first # => ArticleDecorator
|
|
121
156
|
|
122
157
|
### ActiveAdmin
|
123
158
|
|
124
|
-
This gem is compatible with [`activeadmin`][activeadmin].
|
159
|
+
This gem is compatible with [`activeadmin`][activeadmin] ([2.8+](https://github.com/activeadmin/activeadmin/pull/6249)).
|
160
|
+
For `activeadmin` before `2.8`, use `dekorator` `1.0.*`.
|
125
161
|
|
126
162
|
Simply use `#decorate_with`
|
127
163
|
|
@@ -140,10 +176,10 @@ end
|
|
140
176
|
|
141
177
|
### Devise
|
142
178
|
|
143
|
-
If you use [`
|
179
|
+
If you use the [`Devise`][devise] gem you may have an issue if you decorate your
|
144
180
|
`User` model.
|
145
181
|
|
146
|
-
You must define `#devise_scope` as following. Devise
|
182
|
+
You must define `#devise_scope` as following. Devise needs to manage with the
|
147
183
|
`User` model (https://github.com/plataformatec/devise/blob/369ba267efaa10d01c8dba59b09c3b94dd9e5551/lib/devise/mapping.rb#L35).
|
148
184
|
|
149
185
|
```ruby
|
@@ -156,24 +192,55 @@ class UserDecorator < ApplicationDecorator
|
|
156
192
|
end
|
157
193
|
```
|
158
194
|
|
195
|
+
## Testing
|
196
|
+
|
197
|
+
`rails generate decorator user` also generates a testing file based on your
|
198
|
+
configuration.
|
199
|
+
|
200
|
+
You can test a decorator the same way you do for helpers.
|
201
|
+
|
202
|
+
### RSpec
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
describe UserDecorator, type: :decorator do
|
206
|
+
let(:object) { User.new(first_name: "John", last_name: "Doe") }
|
207
|
+
let(:decorated_user) { described_class.new(object) }
|
208
|
+
|
209
|
+
describe "#full_name" do
|
210
|
+
it { expect(decorated_user.full_name).to eq("John Doe") }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
```
|
159
214
|
|
160
215
|
## Development
|
161
216
|
|
162
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
217
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
218
|
+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
219
|
+
prompt that will allow you to experiment.
|
163
220
|
|
164
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
221
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
222
|
+
To release a new version, update the version number in `version.rb`, then
|
223
|
+
run `bundle exec rake release`, which will create a git tag for the version,
|
224
|
+
push git commits and tags, and push the `.gem` file to [rubygems.org].
|
165
225
|
|
166
226
|
## Contributing
|
167
227
|
|
168
|
-
Bug reports and pull requests are welcome on GitHub at
|
228
|
+
Bug reports and pull requests are welcome on GitHub at
|
229
|
+
https://github.com/komposable/dekorator. This project is intended to be a safe,
|
230
|
+
welcoming space for collaboration, and contributors are expected to adhere to
|
231
|
+
the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
169
232
|
|
170
233
|
## License
|
171
234
|
|
172
|
-
The gem is available as open source under the terms of the [MIT License]
|
235
|
+
The gem is available as open source under the terms of the [MIT License].
|
173
236
|
|
174
237
|
## Code of Conduct
|
175
238
|
|
176
|
-
Everyone interacting in the Dekorator project
|
239
|
+
Everyone interacting in the Dekorator project codebases, issue trackers,
|
240
|
+
chat rooms and mailing lists is expected to follow the [code of conduct].
|
177
241
|
|
178
242
|
[activeadmin]: https://activeadmin.info/11-decorators.html
|
179
243
|
[devise]: https://github.com/plataformatec/devise/
|
244
|
+
[rubygems.org]: https://rubygems.org
|
245
|
+
[MIT License]: https://opensource.org/licenses/MIT
|
246
|
+
[code of conduct]: https://github.com/komposable/dekorator/blob/master/CODE_OF_CONDUCT.md
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
|
5
|
+
gemfile(true) do
|
6
|
+
source "https://rubygems.org"
|
7
|
+
|
8
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
9
|
+
|
10
|
+
gem "rails", "6.0.1"
|
11
|
+
gem "sqlite3"
|
12
|
+
gem "benchmark-ips"
|
13
|
+
gem "benchmark-memory"
|
14
|
+
|
15
|
+
gem "dekorator", path: "../", require: false
|
16
|
+
gem "draper", require: false
|
17
|
+
end
|
18
|
+
|
19
|
+
require "active_record"
|
20
|
+
require "logger"
|
21
|
+
|
22
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
23
|
+
ActiveRecord::Base.logger = nil # Logger.new(STDOUT)
|
24
|
+
|
25
|
+
ActiveRecord::Schema.define do
|
26
|
+
create_table :posts, force: true do |t|
|
27
|
+
t.string :title
|
28
|
+
t.text :body
|
29
|
+
end
|
30
|
+
|
31
|
+
create_table :comments, force: true do |t|
|
32
|
+
t.integer :post_id
|
33
|
+
t.string :author
|
34
|
+
t.text :body
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Models
|
39
|
+
class Post < ActiveRecord::Base
|
40
|
+
has_many :comments
|
41
|
+
|
42
|
+
def summary
|
43
|
+
@summary ||= body&.truncate(170)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Comment < ActiveRecord::Base
|
48
|
+
belongs_to :post
|
49
|
+
end
|
50
|
+
|
51
|
+
# Data
|
52
|
+
comments = 100.times.map { Comment.new(author: "John D.", body: "Great article") }
|
53
|
+
10.times.each { Post.create!(title: "Our first article!", body: "", comments: comments) }
|
54
|
+
|
55
|
+
# Decorators
|
56
|
+
require "dekorator"
|
57
|
+
|
58
|
+
class PostDecorator < Dekorator::Base
|
59
|
+
decorates_association :comments
|
60
|
+
|
61
|
+
def summary
|
62
|
+
@summary ||= body&.truncate(170)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class CommentDecorator < Dekorator::Base
|
67
|
+
end
|
68
|
+
|
69
|
+
require "draper"
|
70
|
+
|
71
|
+
class CommentDraperDecorator < Draper::Decorator
|
72
|
+
end
|
73
|
+
|
74
|
+
class PostDraperDecorator < Draper::Decorator
|
75
|
+
decorates_association :comments, with: CommentDraperDecorator
|
76
|
+
|
77
|
+
def summary
|
78
|
+
@summary ||= object.body&.truncate(170)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
require "delegate"
|
83
|
+
|
84
|
+
class PostDelegator < SimpleDelegator
|
85
|
+
def summary
|
86
|
+
@summary ||= body&.truncate(170)
|
87
|
+
end
|
88
|
+
|
89
|
+
def comments
|
90
|
+
@comments = __getobj__.comments.map { |comment| CommentDelegator.new(CommentDelegator) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class CommentDelegator < SimpleDelegator
|
95
|
+
end
|
96
|
+
|
97
|
+
# Benchmark
|
98
|
+
SCENARIOS = {
|
99
|
+
"#summary" => :summary,
|
100
|
+
"#comments" => :comments,
|
101
|
+
}
|
102
|
+
|
103
|
+
SCENARIOS.each_pair do |name, method|
|
104
|
+
puts
|
105
|
+
puts " #{name} ".center(80, "=")
|
106
|
+
puts
|
107
|
+
|
108
|
+
model = Post.all
|
109
|
+
|
110
|
+
puts " ips ".center(80, "-")
|
111
|
+
puts
|
112
|
+
|
113
|
+
Benchmark.ips do |x|
|
114
|
+
x.report("In model") { model.first.public_send(method) }
|
115
|
+
x.report("Dekorator") { PostDecorator.decorate(model).first.public_send(method) }
|
116
|
+
x.report("Dekorator.new") { PostDecorator.decorate(model).first.public_send(method) }
|
117
|
+
x.report("Draper") { PostDraperDecorator.decorate_collection(model).first.public_send(method) }
|
118
|
+
x.report("SimpleDelegator") { PostDelegator.new(model.first).public_send(method) }
|
119
|
+
|
120
|
+
x.compare!
|
121
|
+
end
|
122
|
+
|
123
|
+
puts " memory ".center(80, "-")
|
124
|
+
puts
|
125
|
+
|
126
|
+
Benchmark.memory do |x|
|
127
|
+
x.report("In model") { model.first.public_send(method) }
|
128
|
+
x.report("Dekorator") { PostDecorator.decorate(model).first.public_send(method) }
|
129
|
+
x.report("Dekorator.new") { PostDecorator.decorate(model).first.public_send(method) }
|
130
|
+
x.report("Draper") { PostDraperDecorator.decorate_collection(model).first.public_send(method) }
|
131
|
+
x.report("SimpleDelegator") { PostDelegator.new(model.first).public_send(method) }
|
132
|
+
|
133
|
+
x.compare!
|
134
|
+
end
|
135
|
+
end
|
data/dekorator.gemspec
CHANGED
@@ -1,34 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path("
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require "dekorator/version"
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name
|
9
|
-
spec.version
|
10
|
-
spec.authors
|
11
|
-
spec.email
|
12
|
-
|
13
|
-
spec.summary
|
14
|
-
spec.description
|
15
|
-
spec.
|
8
|
+
spec.name = "dekorator"
|
9
|
+
spec.version = Dekorator::VERSION
|
10
|
+
spec.authors = ["Pantographe"]
|
11
|
+
spec.email = ["oss@pantographe.studio"]
|
12
|
+
|
13
|
+
spec.summary = "An opinionated way of organizing model-view code in Ruby on Rails, based on decorators"
|
14
|
+
spec.description = "An opinionated way of organizing model-view code in Ruby on Rails, based on decorators"
|
15
|
+
spec.homepage = "http://komponent.io"
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.metadata = {
|
19
|
+
"homepage_uri" => "https://github.com/komposable/dekorator",
|
20
|
+
"changelog_uri" => "https://github.com/komposable/dekorator/blob/master/CHANGELOG.md",
|
21
|
+
"source_code_uri" => "https://github.com/komposable/dekorator",
|
22
|
+
"bug_tracker_uri" => "https://github.com/komposable/dekorator/issues",
|
23
|
+
}
|
16
24
|
|
17
25
|
# Specify which files should be added to the gem when it is released.
|
18
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
-
spec.files
|
20
|
-
`git ls-files -z`.split("\x0")
|
27
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
28
|
+
`git ls-files -z`.split("\x0")
|
29
|
+
.reject do |f|
|
30
|
+
f.match(%r{^(test|spec|features|gemfiles|bin)/}) \
|
31
|
+
|| %w[.editorconfig .gitignore .inch.yml .rspec .rubocop.yml .simplecov .travis.yml
|
32
|
+
.yardots Appraisals Gemfile Gemfile.lock].include?(f)
|
33
|
+
end
|
21
34
|
end
|
22
35
|
|
23
36
|
spec.require_paths = ["lib"]
|
24
37
|
|
25
38
|
spec.required_ruby_version = ">= 2.3"
|
26
39
|
|
27
|
-
spec.add_runtime_dependency "actionview", ">= 5.
|
28
|
-
spec.add_runtime_dependency "
|
29
|
-
spec.add_runtime_dependency "
|
40
|
+
spec.add_runtime_dependency "actionview", ">= 5.2", "< 7.1"
|
41
|
+
spec.add_runtime_dependency "activerecord", ">= 5.2", "< 7.1"
|
42
|
+
spec.add_runtime_dependency "activesupport", ">= 5.2", "< 7.1"
|
43
|
+
spec.add_runtime_dependency "railties", ">= 5.2", "< 7.1"
|
30
44
|
|
31
45
|
spec.add_development_dependency "bundler", "~> 2.0"
|
32
|
-
spec.add_development_dependency "rake", "
|
46
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
33
47
|
spec.add_development_dependency "rspec", "~> 3.0"
|
34
48
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Dekorator
|
6
|
+
module Controller
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
helper_method :decorate
|
11
|
+
end
|
12
|
+
|
13
|
+
def decorate(object_or_enumerable, with: nil)
|
14
|
+
Dekorator::Base.decorate(object_or_enumerable, with: with)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/dekorator/railtie.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dekorator/decorators_helper"
|
4
|
-
|
5
3
|
module Dekorator
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
require "dekorator/rails/controller"
|
5
|
+
|
6
|
+
class Railtie < ::Rails::Railtie
|
7
|
+
rake_tasks do
|
8
|
+
load "dekorator/rails/tasks/dekorator.rake"
|
9
|
+
end
|
10
|
+
|
11
|
+
config.to_prepare do |_app|
|
12
|
+
ActionController::Base.include Dekorator::Controller
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
data/lib/dekorator/version.rb
CHANGED