magic-presenter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c2d9f852b05ac3df9f02d0a6f43256155d36f0aa54c9b94887017c6695040000
4
+ data.tar.gz: 07f21527902b18f58d4ffc88655b3e37317a331fa8db2f37addaa421478a523b
5
+ SHA512:
6
+ metadata.gz: 3d230e25c5b5a5bfaef1e941df5388cdcc71315287fbf71177fa7ebe1ca13ff4fa16a2e6a07e358bbed35213053262e6900b390cdc9572f5e33ea5ae59161626
7
+ data.tar.gz: 36e3545b509b62c1c68f22d156adec1ef46ddf34ff0efeb9875aedf13bac1856a6387006211ad9c93a9dc118aa55f98a6a0db09133172d8b6453ed6f81e968e1
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright Alexander Senko
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # 🧙 Magic Presenter
2
+
3
+ ![Code Climate maintainability](
4
+ https://img.shields.io/codeclimate/maintainability-percentage/Alexander-Senko/magic-presenter
5
+ )
6
+ ![Code Climate coverage](
7
+ https://img.shields.io/codeclimate/coverage/Alexander-Senko/magic-presenter
8
+ )
9
+
10
+ A bit of history: this gem was inspired by digging deeper into [Draper](https://github.com/drapergem/draper) with an eye on a refactoring.
11
+
12
+ Based on [Magic Decorator](https://github.com/Alexander-Senko/magic-decorator), it implements a presenter logic.
13
+
14
+ ## Installation
15
+
16
+ Install the gem and add to the application's Gemfile by executing:
17
+
18
+ $ bundle add magic-presenter
19
+
20
+ If bundler is not being used to manage dependencies, install the gem by executing:
21
+
22
+ $ gem install magic-presenter
23
+
24
+ ## Usage
25
+
26
+ `Magic::Presenter::Base` is a basic presenter class to be inherited by any other presenter.
27
+ It further inherits from [`SimpleDelegator`](
28
+ https://docs.ruby-lang.org/en/master/SimpleDelegator.html
29
+ ).
30
+
31
+ ```ruby
32
+ class PersonPresenter < Magic::Presenter::Base
33
+ def name = "#{first_name} #{last_name}"
34
+ end
35
+
36
+ class Person
37
+ include ActiveModel::Model
38
+ attr_accessor :first_name, :last_name
39
+ end
40
+
41
+ person = Person.new(first_name: 'John', last_name: 'Smith').decorate
42
+ person.name # => "John Smith"
43
+ ```
44
+
45
+ ### `Magic::Presentable`
46
+
47
+ This module includes `Magic::Decoratable` and allows a descendant to be decorated by presenters only.
48
+ Presenter class is being inferred automatically.
49
+ When no presenter is found,
50
+ - `#decorate` returns `nil`,
51
+ - `#decorate!` raises `Magic::Lookup::Error`,
52
+ - `#decorated` returns the original object.
53
+
54
+ ## Magic
55
+
56
+ It’s based on [Magic Decorator](
57
+ https://github.com/Alexander-Senko/magic-decorator#magic
58
+ ), so get familiar with that one as well.
59
+
60
+ ### Presentable scope
61
+
62
+ `Magic::Presentable` is mixed into `ActiveModel::Model` by default.
63
+ It means that any model, be it `ActiveRecord::Base`, `Mongoid::Document` or whatever else, is _magically presentable_.
64
+
65
+ ### Presenter class inference
66
+
67
+ Presenters provide automatic class inference for any model based on its class name powered by [Magic Lookup](
68
+ https://github.com/Alexander-Senko/magic-lookup
69
+ ).
70
+
71
+ For example, `MyNamespace::MyModel.new.decorate` looks for `MyNamespace::MyModelPresenter` first.
72
+ When missing, it further looks for decorators for its ancestor classes, up to `ObjectPresenter`.
73
+
74
+ ## Development
75
+
76
+ 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.
77
+
78
+ To install this gem onto your local machine, run `bundle exec rake install`.
79
+
80
+ ## Contributing
81
+
82
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Alexander-Senko/magic-presenter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/Alexander-Senko/magic-presenter/blob/main/CODE_OF_CONDUCT.md).
83
+
84
+ ## License
85
+
86
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
87
+
88
+ ## Code of Conduct
89
+
90
+ Everyone interacting in the Magic Presenter project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Alexander-Senko/magic-presenter/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ APP_RAKEFILE = File.expand_path 'spec/internal/Rakefile', __dir__
6
+ load 'rails/tasks/engine.rake'
7
+ load 'rails/tasks/statistics.rake'
8
+
9
+ require 'bundler/gem_tasks'
10
+ require 'rspec/core/rake_task'
11
+
12
+ RSpec::Core::RakeTask.new(:spec)
13
+
14
+ task default: :spec
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveSupport.on_load :active_model do
4
+ include Magic::Presentable
5
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magic
4
+ # This module includes `Magic::Decoratable` and allows a descendant
5
+ # to be decorated by presenters only. Presenter class is being
6
+ # inferred automatically.
7
+ module Presentable
8
+ include Decoratable
9
+
10
+ private
11
+
12
+ def decorator = Presenter.for self.class
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Author ||= Struct.new(
4
+ :name,
5
+ :email,
6
+ :github,
7
+ ) do
8
+ def github_url = github && "https://github.com/#{github}"
9
+ end
10
+
11
+ module Magic
12
+ module Presenter # :nodoc:
13
+ AUTHORS = [ # rubocop:disable Style/MutableConstant
14
+ Gem::Author.new(
15
+ name: 'Alexander Senko',
16
+ email: 'Alexander.Senko@gmail.com',
17
+ github: 'Alexander-Senko',
18
+ ),
19
+ ]
20
+
21
+ class << AUTHORS
22
+ def names = filter_map &:name
23
+ def emails = filter_map &:email
24
+ def github_url = filter_map(&:github_url).first
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+
5
+ module Magic
6
+ module Presenter
7
+ # = Magic Presenter
8
+ #
9
+ # Any presenter should inherit `Magic::Presenter::Base`.
10
+ # It further inherits from `SimpleDelegator` and behaves like that.
11
+ #
12
+ # == Presenter class inference
13
+ #
14
+ # Presenters provide automatic class inference for any model based
15
+ # on its class name powered by Magic Lookup.
16
+ # For example, `MyModel.new` looks for `MyModelPresenter` first.
17
+ # If not found, it looks for presenters of its ancestor classes,
18
+ # up to `ObjectPresenter`.
19
+ class Base < Decorator::Base
20
+ class << self
21
+ def name_for(object_class) = "#{object_class}Presenter"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magic
4
+ module Presenter
5
+ class Engine < ::Rails::Engine # :nodoc:
6
+ isolate_namespace Magic::Presenter
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magic
4
+ module Presenter
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'magic/decorator'
4
+
5
+ require_relative 'presenter/version'
6
+ require_relative 'presenter/engine'
7
+
8
+ module Magic
9
+ autoload :Presentable, 'magic/presentable'
10
+
11
+ # Presentation layer for Rails models
12
+ module Presenter
13
+ autoload :Base, 'magic/presenter/base'
14
+
15
+ module_function
16
+
17
+ def for(...) = Base.for(...)
18
+ def name_for(...) = Base.name_for(...)
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # desc "Explaining what the task does"
4
+ # task :magic_presenter do
5
+ # # Task goes here
6
+ # end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: magic-presenter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Senko
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2024-10-19 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7.2'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '9'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '7.2'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '9'
32
+ - !ruby/object:Gem::Dependency
33
+ name: magic-decorator
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Based on Magic Decorator, it’s meant to replace Draper.
47
+ email:
48
+ - Alexander.Senko@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - MIT-LICENSE
54
+ - README.md
55
+ - Rakefile
56
+ - config/initializers/presentable.rb
57
+ - lib/magic/presentable.rb
58
+ - lib/magic/presenter.rb
59
+ - lib/magic/presenter/authors.rb
60
+ - lib/magic/presenter/base.rb
61
+ - lib/magic/presenter/engine.rb
62
+ - lib/magic/presenter/version.rb
63
+ - lib/tasks/magic/presenter_tasks.rake
64
+ homepage: https://github.com/Alexander-Senko/magic-presenter
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ homepage_uri: https://github.com/Alexander-Senko/magic-presenter
69
+ source_code_uri: https://github.com/Alexander-Senko/magic-presenter
70
+ changelog_uri: https://github.com/Alexander-Senko/magic-presenter/blob/v0.1.0/CHANGELOG.md
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - "~>"
77
+ - !ruby/object:Gem::Version
78
+ version: '3.2'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubygems_version: 3.6.0.dev
86
+ specification_version: 4
87
+ summary: Presentation layer for Rails models
88
+ test_files: []