magic-presenter 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/README.md +37 -5
- data/config/initializers/loading.rb +7 -0
- data/config/initializers/presentable.rb +2 -2
- data/config/initializers/rspec.rb +7 -0
- data/lib/generators/magic/presenter/generator.rb +24 -0
- data/lib/generators/magic/presenter/install/USAGE +10 -0
- data/lib/generators/magic/presenter/install/install_generator.rb +21 -0
- data/lib/generators/magic/presenter/install/templates/application_presenter.rb.tt +6 -0
- data/lib/generators/presenter/USAGE +28 -0
- data/lib/generators/presenter/presenter_generator.rb +26 -0
- data/lib/generators/presenter/templates/presenter.rb.tt +5 -0
- data/lib/generators/rspec/presenter/presenter_generator.rb +20 -0
- data/lib/generators/rspec/presenter/templates/presenter_spec.rb.tt +7 -0
- data/lib/generators/test_unit/presenter/presenter_generator.rb +22 -0
- data/lib/generators/test_unit/presenter/templates/presenter_test.rb.tt +9 -0
- data/lib/magic/presentable.rb +1 -1
- data/lib/magic/presenter/base.rb +8 -2
- data/lib/magic/presenter/engine.rb +4 -0
- data/lib/magic/presenter/version.rb +1 -1
- data/lib/magic/presenter.rb +3 -2
- metadata +18 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04a88e0f222913a774946299ef036231cb1628baaa980111b5bb058cb77f69a4
|
4
|
+
data.tar.gz: 9a5d28343913ebae389a941153d49d6c3d04acb2e6e61891ada49404a2e1d49f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a572d9c94e5b75cb65c23e029d524f19d48457d1ea57bf6185d4ed463757296c2917d77e7210ab67021347b111136e34c1cbcdb15ae47c6d67445623ff13508
|
7
|
+
data.tar.gz: 41c4b6afee8ffb1b89aedbba4f619d94ddc04d3c4201afa6ae7c34fec7d1fe52a746eb3fc29463d316fc446c4e1a7b9458395c473c18af02b388caae0f2dabaa
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# 🧙 Magic Presenter
|
2
2
|
|
3
|
+

|
3
6
|

|
@@ -15,11 +18,15 @@ Based on [Magic Decorator](https://github.com/Alexander-Senko/magic-decorator),
|
|
15
18
|
|
16
19
|
Install the gem and add to the application's Gemfile by executing:
|
17
20
|
|
18
|
-
|
21
|
+
$ bundle add magic-presenter
|
19
22
|
|
20
23
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
21
24
|
|
22
|
-
|
25
|
+
$ gem install magic-presenter
|
26
|
+
|
27
|
+
After all the gems are `bundle`d run the installer in the project directory to generate the necessary files:
|
28
|
+
|
29
|
+
$ bin/rails generate magic:presenter:install
|
23
30
|
|
24
31
|
## Usage
|
25
32
|
|
@@ -51,7 +58,17 @@ When no presenter is found,
|
|
51
58
|
- `#decorate!` raises `Magic::Lookup::Error`,
|
52
59
|
- `#decorated` returns the original object.
|
53
60
|
|
54
|
-
|
61
|
+
### Generators
|
62
|
+
|
63
|
+
A generator can be used to generate a presenter:
|
64
|
+
|
65
|
+
$ bin/rails generate presenter Person
|
66
|
+
|
67
|
+
See the help for more info:
|
68
|
+
|
69
|
+
$ bin/rails generate presenter --help
|
70
|
+
|
71
|
+
## 🧙 Magic
|
55
72
|
|
56
73
|
It’s based on [Magic Decorator](
|
57
74
|
https://github.com/Alexander-Senko/magic-decorator#magic
|
@@ -59,7 +76,7 @@ It’s based on [Magic Decorator](
|
|
59
76
|
|
60
77
|
### Presentable scope
|
61
78
|
|
62
|
-
`Magic::Presentable` is mixed into `ActiveModel::
|
79
|
+
`Magic::Presentable` is mixed into `ActiveModel::API` by default.
|
63
80
|
It means that any model, be it `ActiveRecord::Base`, `Mongoid::Document` or whatever else, is _magically presentable_.
|
64
81
|
|
65
82
|
### Presenter class inference
|
@@ -68,9 +85,24 @@ Presenters provide automatic class inference for any model based on its class na
|
|
68
85
|
https://github.com/Alexander-Senko/magic-lookup
|
69
86
|
).
|
70
87
|
|
71
|
-
For example, `MyNamespace::MyModel.new.decorate` looks for `MyNamespace::
|
88
|
+
For example, `MyNamespace::MyModel.new.decorate` looks for `MyNamespace::MyPresenter` first.
|
72
89
|
When missing, it further looks for decorators for its ancestor classes, up to `ObjectPresenter`.
|
73
90
|
|
91
|
+
#### Mapping rules
|
92
|
+
|
93
|
+
- `MyObject` → `MyObjectPresenter`
|
94
|
+
- `MyModel` → `MyPresenter`
|
95
|
+
- `MyRecord` → `MyPresenter`
|
96
|
+
|
97
|
+
> [!TIP]
|
98
|
+
> That’s why `ApplicationPresenter` presents `ApplicationRecord` alongside all its descendants automagically with no extra code.
|
99
|
+
|
100
|
+
When in doubt, one can use `Magic::Presenter.name_for`:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
Magic::Presenter.name_for Person # => "PersonPresenter"
|
104
|
+
```
|
105
|
+
|
74
106
|
## Development
|
75
107
|
|
76
108
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Magic
|
4
|
+
module Presenter
|
5
|
+
module Generator # :nodoc:
|
6
|
+
require 'generators/presenter/presenter_generator'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def file_name name = super()
|
11
|
+
name
|
12
|
+
.camelize
|
13
|
+
.then { Magic::Presenter.name_for _1 }
|
14
|
+
.underscore
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_path path = super(), root: target_root
|
18
|
+
root / 'presenters' / path
|
19
|
+
end
|
20
|
+
|
21
|
+
def presenter_path(*) = file_path(*, root: PresenterGenerator.target_root)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Description:
|
2
|
+
Generates application files used by Magic Presenter:
|
3
|
+
ApplicationPresenter: a base class for other presenters to
|
4
|
+
inherit from.
|
5
|
+
|
6
|
+
Example:
|
7
|
+
bin/rails generate magic:presenter:install
|
8
|
+
|
9
|
+
This will create:
|
10
|
+
ApplicationPresenter: app/presenters/application_presenter.rb
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Magic
|
4
|
+
module Presenter
|
5
|
+
class InstallGenerator < Rails::Generators::Base # :nodoc:
|
6
|
+
include Generator
|
7
|
+
|
8
|
+
source_root File.expand_path('templates', __dir__)
|
9
|
+
|
10
|
+
def create_files
|
11
|
+
template 'application_presenter.rb', "#{presenter_path namespaced_file_name 'ApplicationRecord'}.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def namespaced_file_name(*)
|
17
|
+
File.join *(namespaced_path if namespaced?), file_name(*)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Description:
|
2
|
+
Generates a new presenter for a model. Pass the model name, either
|
3
|
+
CamelCased or under_scored, as an argument.
|
4
|
+
|
5
|
+
This generator invokes your configured test framework, which
|
6
|
+
defaults to TestUnit. It supports both TestUnit and RSpec.
|
7
|
+
|
8
|
+
If a `--parent` option is given, it’s used as a superclass of the
|
9
|
+
created presenter.
|
10
|
+
|
11
|
+
Example:
|
12
|
+
bin/rails generate presenter account
|
13
|
+
|
14
|
+
This will create:
|
15
|
+
Presenter: app/presenters/account_presenter.rb
|
16
|
+
for TestUnit:
|
17
|
+
Test: test/presenters/account_presenter_test.rb
|
18
|
+
for RSpec:
|
19
|
+
Spec: spec/presenters/account_presenter_spec.rb
|
20
|
+
|
21
|
+
bin/rails generate presenter admin/account
|
22
|
+
|
23
|
+
This will create:
|
24
|
+
Presenter: app/presenters/admin/account_presenter.rb
|
25
|
+
for TestUnit:
|
26
|
+
Test: test/presenters/admin/account_presenter_test.rb
|
27
|
+
for RSpec:
|
28
|
+
Spec: spec/presenters/admin/account_presenter_spec.rb
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class PresenterGenerator < Rails::Generators::NamedBase # :nodoc:
|
4
|
+
include Magic::Presenter::Generator
|
5
|
+
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
|
8
|
+
check_class_collision suffix: 'Presenter'
|
9
|
+
|
10
|
+
class_option :parent,
|
11
|
+
type: :string,
|
12
|
+
default: 'ApplicationPresenter',
|
13
|
+
desc: 'The parent class for the generated presenter'
|
14
|
+
|
15
|
+
cattr_reader :target_root, default: Pathname('app')
|
16
|
+
|
17
|
+
def create_presenter_file
|
18
|
+
template 'presenter.rb', "#{file_path}.rb"
|
19
|
+
end
|
20
|
+
|
21
|
+
hook_for :test_framework
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parent_class_name = options[:parent].classify
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'generators/rspec'
|
4
|
+
require 'generators/magic/presenter/generator'
|
5
|
+
|
6
|
+
module Rspec # :nodoc:
|
7
|
+
module Generators # :nodoc:
|
8
|
+
class PresenterGenerator < Base # :nodoc:
|
9
|
+
include Magic::Presenter::Generator
|
10
|
+
|
11
|
+
source_root File.expand_path('templates', __dir__)
|
12
|
+
|
13
|
+
cattr_reader :target_root, default: Pathname('spec')
|
14
|
+
|
15
|
+
def create_test_file
|
16
|
+
template 'presenter_spec.rb', "#{file_path}_spec.rb"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/test_unit'
|
4
|
+
require 'generators/magic/presenter/generator'
|
5
|
+
|
6
|
+
module TestUnit # :nodoc:
|
7
|
+
module Generators # :nodoc:
|
8
|
+
class PresenterGenerator < Base # :nodoc:
|
9
|
+
include Magic::Presenter::Generator
|
10
|
+
|
11
|
+
source_root File.expand_path('templates', __dir__)
|
12
|
+
|
13
|
+
check_class_collision suffix: 'PresenterTest'
|
14
|
+
|
15
|
+
cattr_reader :target_root, default: Pathname('test')
|
16
|
+
|
17
|
+
def create_test_file
|
18
|
+
template 'presenter_test.rb', "#{file_path}_test.rb"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/magic/presentable.rb
CHANGED
data/lib/magic/presenter/base.rb
CHANGED
@@ -13,12 +13,18 @@ module Magic
|
|
13
13
|
#
|
14
14
|
# Presenters provide automatic class inference for any model based
|
15
15
|
# on its class name powered by Magic Lookup.
|
16
|
-
# For example, `MyModel.new` looks for `
|
16
|
+
# For example, `MyModel.new` looks for `MyPresenter` first.
|
17
17
|
# If not found, it looks for presenters of its ancestor classes,
|
18
18
|
# up to `ObjectPresenter`.
|
19
19
|
class Base < Decorator::Base
|
20
20
|
class << self
|
21
|
-
def name_for
|
21
|
+
def name_for object_class
|
22
|
+
object_class
|
23
|
+
.to_s
|
24
|
+
.delete_suffix('Model')
|
25
|
+
.delete_suffix('Record')
|
26
|
+
.then { "#{_1}Presenter" }
|
27
|
+
end
|
22
28
|
end
|
23
29
|
end
|
24
30
|
end
|
data/lib/magic/presenter.rb
CHANGED
@@ -5,12 +5,13 @@ require 'magic/decorator'
|
|
5
5
|
require_relative 'presenter/version'
|
6
6
|
require_relative 'presenter/engine'
|
7
7
|
|
8
|
-
module Magic
|
8
|
+
module Magic # :nodoc:
|
9
9
|
autoload :Presentable, 'magic/presentable'
|
10
10
|
|
11
11
|
# Presentation layer for Rails models
|
12
12
|
module Presenter
|
13
|
-
autoload :Base,
|
13
|
+
autoload :Base, 'magic/presenter/base'
|
14
|
+
autoload :Generator, 'generators/magic/presenter/generator'
|
14
15
|
|
15
16
|
module_function
|
16
17
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magic-presenter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Senko
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2024-10-
|
10
|
+
date: 2024-10-26 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rails
|
@@ -35,14 +35,14 @@ dependencies:
|
|
35
35
|
requirements:
|
36
36
|
- - ">="
|
37
37
|
- !ruby/object:Gem::Version
|
38
|
-
version:
|
38
|
+
version: 0.3.0.alpha
|
39
39
|
type: :runtime
|
40
40
|
prerelease: false
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 0.3.0.alpha
|
46
46
|
description: Based on Magic Decorator, it’s meant to replace Draper.
|
47
47
|
email:
|
48
48
|
- Alexander.Senko@gmail.com
|
@@ -53,7 +53,20 @@ files:
|
|
53
53
|
- MIT-LICENSE
|
54
54
|
- README.md
|
55
55
|
- Rakefile
|
56
|
+
- config/initializers/loading.rb
|
56
57
|
- config/initializers/presentable.rb
|
58
|
+
- config/initializers/rspec.rb
|
59
|
+
- lib/generators/magic/presenter/generator.rb
|
60
|
+
- lib/generators/magic/presenter/install/USAGE
|
61
|
+
- lib/generators/magic/presenter/install/install_generator.rb
|
62
|
+
- lib/generators/magic/presenter/install/templates/application_presenter.rb.tt
|
63
|
+
- lib/generators/presenter/USAGE
|
64
|
+
- lib/generators/presenter/presenter_generator.rb
|
65
|
+
- lib/generators/presenter/templates/presenter.rb.tt
|
66
|
+
- lib/generators/rspec/presenter/presenter_generator.rb
|
67
|
+
- lib/generators/rspec/presenter/templates/presenter_spec.rb.tt
|
68
|
+
- lib/generators/test_unit/presenter/presenter_generator.rb
|
69
|
+
- lib/generators/test_unit/presenter/templates/presenter_test.rb.tt
|
57
70
|
- lib/magic/presentable.rb
|
58
71
|
- lib/magic/presenter.rb
|
59
72
|
- lib/magic/presenter/authors.rb
|
@@ -67,7 +80,7 @@ licenses:
|
|
67
80
|
metadata:
|
68
81
|
homepage_uri: https://github.com/Alexander-Senko/magic-presenter
|
69
82
|
source_code_uri: https://github.com/Alexander-Senko/magic-presenter
|
70
|
-
changelog_uri: https://github.com/Alexander-Senko/magic-presenter/blob/v0.
|
83
|
+
changelog_uri: https://github.com/Alexander-Senko/magic-presenter/blob/v0.2.0/CHANGELOG.md
|
71
84
|
rdoc_options: []
|
72
85
|
require_paths:
|
73
86
|
- lib
|