exposant 0.1.1 → 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/.rubocop.yml +1 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +27 -9
- data/README.md +54 -33
- data/exposant.gemspec +2 -3
- data/lib/exposant/base.rb +92 -0
- data/lib/exposant/concerns/collection.rb +16 -0
- data/lib/exposant/concerns/contextualizable.rb +13 -0
- data/lib/exposant/model.rb +82 -0
- data/lib/exposant/version.rb +1 -1
- data/lib/exposant.rb +4 -5
- metadata +15 -15
- data/lib/exposant/collection_exhibitor.rb +0 -25
- data/lib/exposant/concerns/exhibitor.rb +0 -34
- data/lib/exposant/concerns/exposable.rb +0 -56
- data/lib/exposant/model_exhibitor.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b348ab3f3c0d4c3d274469598cd72c5d234d9a832348ec4824fbfc8936a5957
|
4
|
+
data.tar.gz: 94ee91f4ae16555a4161e22f4075d2f83293f72af04f5f0c834e9a351634c072
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b51a4907d36637a6d86d209b9577539a2e21ae8cc7c0bdd72c17395927acfe26981e19e7503d04de0677f7036609fadecada2c6ded173cb9d85492144748c842
|
7
|
+
data.tar.gz: 467b366ac5b9c5ea8f6a60f4bf3e55a32d5049c3b89c1be222836df651a6b7e12194fe5c5160df38c1855507473d9f8328fae896e3eb0685f82b5db5ec1fa3cb
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,29 +1,45 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
exposant (0.
|
5
|
-
activemodel (
|
6
|
-
activesupport (
|
4
|
+
exposant (0.2.0)
|
5
|
+
activemodel (> 5.0)
|
6
|
+
activesupport (> 5.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activemodel (7.
|
12
|
-
activesupport (= 7.
|
13
|
-
activesupport (7.
|
11
|
+
activemodel (7.1.1)
|
12
|
+
activesupport (= 7.1.1)
|
13
|
+
activesupport (7.1.1)
|
14
|
+
base64
|
15
|
+
bigdecimal
|
14
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
|
+
connection_pool (>= 2.2.5)
|
18
|
+
drb
|
15
19
|
i18n (>= 1.6, < 2)
|
16
20
|
minitest (>= 5.1)
|
21
|
+
mutex_m
|
17
22
|
tzinfo (~> 2.0)
|
18
23
|
ast (2.4.2)
|
19
|
-
|
20
|
-
|
24
|
+
base64 (0.1.1)
|
25
|
+
bigdecimal (3.1.4)
|
26
|
+
coderay (1.1.3)
|
27
|
+
concurrent-ruby (1.2.2)
|
28
|
+
connection_pool (2.4.1)
|
29
|
+
drb (2.1.1)
|
30
|
+
ruby2_keywords
|
31
|
+
i18n (1.14.1)
|
21
32
|
concurrent-ruby (~> 1.0)
|
22
33
|
json (2.6.1)
|
34
|
+
method_source (1.0.0)
|
23
35
|
minitest (5.16.3)
|
36
|
+
mutex_m (0.1.2)
|
24
37
|
parallel (1.22.1)
|
25
38
|
parser (3.1.2.1)
|
26
39
|
ast (~> 2.4.1)
|
40
|
+
pry (0.14.2)
|
41
|
+
coderay (~> 1.1)
|
42
|
+
method_source (~> 1.0)
|
27
43
|
rainbow (3.1.1)
|
28
44
|
rake (13.0.6)
|
29
45
|
regexp_parser (2.5.0)
|
@@ -41,7 +57,8 @@ GEM
|
|
41
57
|
rubocop-ast (1.21.0)
|
42
58
|
parser (>= 3.1.1.0)
|
43
59
|
ruby-progressbar (1.11.0)
|
44
|
-
|
60
|
+
ruby2_keywords (0.0.5)
|
61
|
+
tzinfo (2.0.6)
|
45
62
|
concurrent-ruby (~> 1.0)
|
46
63
|
unicode-display_width (2.2.0)
|
47
64
|
|
@@ -51,6 +68,7 @@ PLATFORMS
|
|
51
68
|
DEPENDENCIES
|
52
69
|
exposant!
|
53
70
|
minitest (~> 5.0)
|
71
|
+
pry
|
54
72
|
rake (~> 13.0)
|
55
73
|
rubocop (~> 1.21)
|
56
74
|
|
data/README.md
CHANGED
@@ -2,9 +2,14 @@
|
|
2
2
|
|
3
3
|
In a Rails application, it is often required to fill a gap between Models and
|
4
4
|
Views. There are of course, many differents ways to fill this gap, one of these
|
5
|
-
is
|
5
|
+
is decorators and its variants exhibits or presenters.
|
6
6
|
|
7
|
-
|
7
|
+
The main difference between decorators, exhibits and presenters are their
|
8
|
+
proximity with the rendering layer. Typically a decorator is not meant to be
|
9
|
+
contextualized, whereas an exhibit is intended to have access to rendering
|
10
|
+
context.
|
11
|
+
|
12
|
+
This gem provide an easy way to create theese concepts in Ruby.
|
8
13
|
|
9
14
|
## Installation
|
10
15
|
|
@@ -16,74 +21,90 @@ gem 'exposant'
|
|
16
21
|
|
17
22
|
And then execute:
|
18
23
|
|
19
|
-
|
24
|
+
```ruby
|
25
|
+
$ bundle install
|
26
|
+
```
|
20
27
|
|
21
28
|
Or install it yourself as:
|
22
29
|
|
23
|
-
|
30
|
+
```
|
31
|
+
$ gem install exposant
|
32
|
+
```
|
24
33
|
|
25
34
|
## Usage
|
26
35
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
encapsulation of resulting objects.
|
36
|
+
Exposant objects are intended to overload class (scopes) and instance methods
|
37
|
+
of any other object. The default type is exposant, choosing between decorator,
|
38
|
+
exhibit or any other type name is up to you. There is no magic involved for the
|
39
|
+
context, you just have to call contextualize and provide the required context.
|
32
40
|
|
33
|
-
|
34
|
-
related methods to an ActiveRecord object for example.
|
35
|
-
|
36
|
-
To use this gem in a Rails application, create a folder `app/exhibitors`.
|
37
|
-
Create pluralized exhibitors for collections and singularized exhibitors for
|
38
|
-
models.
|
39
|
-
|
40
|
-
### Example:
|
41
|
+
### Basic example
|
41
42
|
|
42
43
|
Consider having a User model with `first_name` and `last_name`
|
43
44
|
|
44
45
|
```ruby
|
45
|
-
# app/models/
|
46
|
-
class
|
47
|
-
include Exposant::
|
46
|
+
# app/models/user.rb
|
47
|
+
class User < ActiveRecord::Base
|
48
|
+
include Exposant::Model
|
49
|
+
has_exposant type: :decorator
|
48
50
|
end
|
49
51
|
|
50
|
-
# app/
|
51
|
-
class
|
52
|
+
# app/decorators/user_decorator.rb
|
53
|
+
class UserDecorator < Exposant::Base
|
54
|
+
exposant_type :decorator
|
55
|
+
|
52
56
|
def full_name
|
53
57
|
"#{first_name} #{last_name}"
|
54
58
|
end
|
55
59
|
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Then you may want to use your brand new decorator in your controller
|
56
63
|
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
```ruby
|
65
|
+
# app/controllers/users_controller.rb
|
66
|
+
class UsersController < DefaultController
|
67
|
+
def index
|
68
|
+
@users = User.decorator(User.all)
|
69
|
+
end
|
70
|
+
|
71
|
+
def show
|
72
|
+
@user = User.find(...).decorator
|
73
|
+
end
|
60
74
|
end
|
61
75
|
```
|
62
76
|
|
63
|
-
|
77
|
+
### Contextualization example
|
78
|
+
|
79
|
+
If you want to contextualize a presenter, for example in a Rails application.
|
80
|
+
|
64
81
|
```ruby
|
65
82
|
# app/controllers/users_controller.rb
|
66
83
|
class UsersController < DefaultController
|
67
84
|
def index
|
68
|
-
@users = User.
|
85
|
+
@users = User.presenter(User.all)
|
86
|
+
@users.contextualize(self)
|
69
87
|
end
|
70
88
|
|
71
89
|
def show
|
72
|
-
@user = User.find(...).
|
90
|
+
@user = User.find(...).presenter
|
91
|
+
@user.contextualize(self)
|
73
92
|
end
|
74
93
|
end
|
75
94
|
```
|
76
95
|
|
77
96
|
## Development
|
78
97
|
|
79
|
-
After checking out the repo, run `bin/setup` to install dependencies. You can
|
80
|
-
|
81
|
-
|
98
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can
|
99
|
+
also run `bin/console` for an interactive prompt that will allow you to
|
100
|
+
experiment.
|
82
101
|
|
83
102
|
## Contributing
|
84
103
|
|
85
|
-
Bug reports and pull requests are welcome on GitHub at
|
104
|
+
Bug reports and pull requests are welcome on GitHub at
|
105
|
+
https://github.com/kmmndr/exposant.
|
86
106
|
|
87
107
|
## License
|
88
108
|
|
89
|
-
The gem is available as open source under the terms of the
|
109
|
+
The gem is available as open source under the terms of the
|
110
|
+
[MIT License](https://opensource.org/licenses/MIT).
|
data/exposant.gemspec
CHANGED
@@ -30,9 +30,8 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ['lib']
|
32
32
|
|
33
|
-
|
34
|
-
spec.add_dependency '
|
35
|
-
spec.add_dependency 'activesupport', '~> 7.0'
|
33
|
+
spec.add_dependency 'activemodel', '> 5.0'
|
34
|
+
spec.add_dependency 'activesupport', '> 5.0'
|
36
35
|
|
37
36
|
# For more information and examples about making a new gem, check out our
|
38
37
|
# guide at: https://bundler.io/guides/creating_gem.html
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Exposant
|
2
|
+
class Base < SimpleDelegator
|
3
|
+
include Exposant::Contextualizable
|
4
|
+
extend ActiveModel::Naming
|
5
|
+
|
6
|
+
def initialize(*)
|
7
|
+
super
|
8
|
+
|
9
|
+
extend(Exposant::Collection) if __getobj__.is_a?(Enumerable)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_model
|
13
|
+
__getobj__
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.respond_to_missing?(name, *)
|
17
|
+
klass.respond_to?(name) || super
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.method_missing(name, *args, &block)
|
21
|
+
klass.send(name, *args, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.human_attribute_name(*args)
|
25
|
+
exposed_class.human_attribute_name(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.klass
|
29
|
+
@klass ||= exposed_class
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.belongs_to_model(name)
|
33
|
+
exposed_class(name)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.exposed_class(value = nil)
|
37
|
+
@exposed_class = value.constantize if value.present?
|
38
|
+
return @exposed_class if @exposed_class.present?
|
39
|
+
|
40
|
+
return ancestors[1].exposed_class unless ancestors[1] == Exposant::Base || ancestors[1].exposant_base?
|
41
|
+
|
42
|
+
klass_name = name.gsub(/#{type_name}$/, '')
|
43
|
+
|
44
|
+
klass_name.constantize
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.exposant_type(value = nil)
|
48
|
+
@exposant_type = value if value.present?
|
49
|
+
return @exposant_type if @exposant_type.present?
|
50
|
+
|
51
|
+
return ancestors[1].exposant_type unless ancestors[1] == Exposant::Base
|
52
|
+
|
53
|
+
:exposant
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.type_name
|
57
|
+
exposant_type.to_s.camelcase
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.custom_type?
|
61
|
+
exposant_type != :exposant
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.exposant_base?
|
65
|
+
!!@exposant_base
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.exposant_base
|
69
|
+
@exposant_base = true
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.exposant_variant
|
73
|
+
exposed_name = exposed_class.name.demodulize
|
74
|
+
|
75
|
+
variant = name
|
76
|
+
.split('::')
|
77
|
+
.tap { |arr| arr.last.gsub!(/#{exposed_name}#{type_name}$/, '') }
|
78
|
+
.last
|
79
|
+
.downcase
|
80
|
+
|
81
|
+
return nil if variant.blank?
|
82
|
+
|
83
|
+
variant.to_sym
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.parent_exposant
|
87
|
+
return ancestors[1].parent_exposant unless ancestors[1] == Exposant::Base
|
88
|
+
|
89
|
+
name.constantize
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Exposant
|
2
|
+
module Collection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def each
|
6
|
+
return enum_for(:each) unless block_given?
|
7
|
+
|
8
|
+
super do |obj|
|
9
|
+
exposant = obj.exposant(self.class.exposant_variant, self.class.exposant_type)
|
10
|
+
exposant.contextualize(context) if contextualized?
|
11
|
+
|
12
|
+
yield exposant
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'pry'
|
2
|
+
module Exposant
|
3
|
+
module Model
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def exposant(variant = nil, type = nil)
|
7
|
+
self.class.exposant_class(variant, type).new(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def has_exposant(name: nil, type: nil)
|
12
|
+
@exposant_class = name
|
13
|
+
@exposant_type = type
|
14
|
+
|
15
|
+
if type.present? && type != :exposant
|
16
|
+
raise 'Type must be a symbol' unless type.is_a?(Symbol)
|
17
|
+
|
18
|
+
define_method type do |variant = nil|
|
19
|
+
exposant(variant, type)
|
20
|
+
end
|
21
|
+
|
22
|
+
define_singleton_method type do |obj, variant = nil|
|
23
|
+
exposant(obj, variant, type)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def exposant_type
|
31
|
+
@exposant_type || :exposant
|
32
|
+
end
|
33
|
+
|
34
|
+
def exposant(obj, variant = nil, type = nil)
|
35
|
+
obj.extend(ExposantMethods)
|
36
|
+
obj.model_klass = self
|
37
|
+
|
38
|
+
if type.present? && type != :exposant
|
39
|
+
raise 'Type must be a symbol' unless type.is_a?(Symbol)
|
40
|
+
|
41
|
+
obj.singleton_class.class_eval do
|
42
|
+
define_method type do |var = nil|
|
43
|
+
exposant(var, type)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
obj.exposant(variant, type)
|
49
|
+
end
|
50
|
+
|
51
|
+
def exposant_class(variant = nil, type = nil)
|
52
|
+
type_name = (type || exposant_type).to_s.camelcase
|
53
|
+
klass = if @exposant_class.present?
|
54
|
+
@exposant_class
|
55
|
+
else
|
56
|
+
name.dup.concat(type_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
klass = klass
|
60
|
+
.split('::')
|
61
|
+
.tap { |arr| arr.last.prepend(variant&.to_s&.downcase&.capitalize || '') }
|
62
|
+
.join('::')
|
63
|
+
|
64
|
+
raise "Missing exposant #{klass}" unless const_defined?(klass)
|
65
|
+
|
66
|
+
klass.constantize
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module ExposantMethods
|
72
|
+
attr_accessor :model_klass
|
73
|
+
|
74
|
+
def exposant(variant = nil, type = nil)
|
75
|
+
exposant_class(variant, type).new(self)
|
76
|
+
end
|
77
|
+
|
78
|
+
def exposant_class(variant = nil, type = nil)
|
79
|
+
model_klass.exposant_class(variant, type)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/exposant/version.rb
CHANGED
data/lib/exposant.rb
CHANGED
@@ -4,13 +4,12 @@ require 'delegate'
|
|
4
4
|
require 'active_support'
|
5
5
|
require 'active_model'
|
6
6
|
|
7
|
-
require_relative 'exposant/concerns/
|
8
|
-
require_relative 'exposant/concerns/
|
9
|
-
require_relative 'exposant/
|
10
|
-
require_relative 'exposant/
|
7
|
+
require_relative 'exposant/concerns/contextualizable'
|
8
|
+
require_relative 'exposant/concerns/collection'
|
9
|
+
require_relative 'exposant/model'
|
10
|
+
require_relative 'exposant/base'
|
11
11
|
require_relative 'exposant/version'
|
12
12
|
|
13
13
|
module Exposant
|
14
14
|
class Error < StandardError; end
|
15
|
-
# Your code goes here...
|
16
15
|
end
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exposant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Kienlen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '5.0'
|
41
41
|
description:
|
42
42
|
email:
|
43
43
|
- kommander@laposte.net
|
@@ -54,10 +54,10 @@ files:
|
|
54
54
|
- Rakefile
|
55
55
|
- exposant.gemspec
|
56
56
|
- lib/exposant.rb
|
57
|
-
- lib/exposant/
|
58
|
-
- lib/exposant/concerns/
|
59
|
-
- lib/exposant/concerns/
|
60
|
-
- lib/exposant/
|
57
|
+
- lib/exposant/base.rb
|
58
|
+
- lib/exposant/concerns/collection.rb
|
59
|
+
- lib/exposant/concerns/contextualizable.rb
|
60
|
+
- lib/exposant/model.rb
|
61
61
|
- lib/exposant/version.rb
|
62
62
|
homepage: http://127.0.0.1:3000
|
63
63
|
licenses:
|
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '0'
|
82
82
|
requirements: []
|
83
|
-
rubygems_version: 3.
|
83
|
+
rubygems_version: 3.4.10
|
84
84
|
signing_key:
|
85
85
|
specification_version: 4
|
86
86
|
summary: Simple way to create decorators and presenters
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Exposant
|
2
|
-
class CollectionExhibitor < SimpleDelegator
|
3
|
-
include Exhibitor
|
4
|
-
extend ActiveModel::Naming
|
5
|
-
include Enumerable
|
6
|
-
|
7
|
-
def self.exhibitor_variant
|
8
|
-
self::MODEL_PRESENTER_VARIANT if const_defined?('MODEL_PRESENTER_VARIANT')
|
9
|
-
end
|
10
|
-
|
11
|
-
def each
|
12
|
-
return enum_for(:each) unless block_given?
|
13
|
-
|
14
|
-
__getobj__.each do |o|
|
15
|
-
exh = o.exhibitor(self.class.exhibitor_variant)
|
16
|
-
exh.contextualize(context) if contextualized?
|
17
|
-
yield exh
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_model
|
22
|
-
self
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module Exhibitor
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
attr_accessor :context
|
4
|
-
|
5
|
-
def obj
|
6
|
-
__getobj__
|
7
|
-
end
|
8
|
-
|
9
|
-
def exhibitor_for(obj)
|
10
|
-
self.class.exhibitor_for(obj)
|
11
|
-
end
|
12
|
-
|
13
|
-
def contextualize(context)
|
14
|
-
self.context = context
|
15
|
-
end
|
16
|
-
|
17
|
-
def contextualized?
|
18
|
-
context.present?
|
19
|
-
end
|
20
|
-
|
21
|
-
module ClassMethods
|
22
|
-
|
23
|
-
def exhibitor_for_super(method, klass = nil)
|
24
|
-
define_method(method) do |*args|
|
25
|
-
klass ||= self.class
|
26
|
-
klass.new(super(*args))
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def exhibitor_for(obj)
|
31
|
-
new(obj)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
module Exposant
|
2
|
-
module Exposable
|
3
|
-
module Model
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
def exhibitor(variant = nil)
|
7
|
-
self.class.exhibitor_class(variant).new(self)
|
8
|
-
end
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
def exhibitor(obj, variant = nil)
|
12
|
-
obj.extend(Exposable::Collection)
|
13
|
-
obj.model_klass = self
|
14
|
-
|
15
|
-
obj.exhibitor(variant)
|
16
|
-
end
|
17
|
-
|
18
|
-
def exhibitor_class(variant = nil)
|
19
|
-
klass = [
|
20
|
-
name,
|
21
|
-
variant&.downcase&.capitalize,
|
22
|
-
'Exhibitor'
|
23
|
-
].join
|
24
|
-
|
25
|
-
raise "Missing exhibitor #{klass}" unless const_defined?(klass)
|
26
|
-
|
27
|
-
klass.constantize
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
module Collection
|
33
|
-
attr_accessor :model_klass
|
34
|
-
|
35
|
-
def exhibitor(variant = nil)
|
36
|
-
exhibitor_class(variant).new(self)
|
37
|
-
end
|
38
|
-
|
39
|
-
def exhibitor_class(variant = nil)
|
40
|
-
klass_name = model_klass.name
|
41
|
-
|
42
|
-
klass = [
|
43
|
-
klass_name.pluralize,
|
44
|
-
variant&.downcase&.capitalize,
|
45
|
-
'Exhibitor'
|
46
|
-
].join
|
47
|
-
|
48
|
-
begin
|
49
|
-
klass.constantize
|
50
|
-
rescue NameError
|
51
|
-
raise "Missing exhibitor #{klass}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module Exposant
|
2
|
-
class ModelExhibitor < SimpleDelegator
|
3
|
-
include Exhibitor
|
4
|
-
extend ActiveModel::Naming
|
5
|
-
|
6
|
-
def to_model
|
7
|
-
obj
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.human_attribute_name(*args)
|
11
|
-
exhibited_class.human_attribute_name(*args)
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.exhibited_class
|
15
|
-
return ancestors[1].exhibited_class unless ancestors[1] == ModelExhibitor
|
16
|
-
|
17
|
-
name.gsub(/Exhibitor$/, '').constantize
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.exhibitor_variant
|
21
|
-
variant = name[parent_exhibitor.exhibited_class.name.length..].gsub(/Exhibitor$/, '').downcase
|
22
|
-
|
23
|
-
return nil if variant.blank?
|
24
|
-
|
25
|
-
variant.to_sym
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.parent_exhibitor
|
29
|
-
return ancestors[1].parent_exhibitor unless ancestors[1] == ModelExhibitor
|
30
|
-
|
31
|
-
name.constantize
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|