resubject 0.0.2 → 0.0.3
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.
- data/Gemfile +1 -0
- data/README.md +1 -1
- data/Rakefile +5 -0
- data/lib/resubject/builder.rb +49 -19
- data/lib/resubject/naming.rb +10 -0
- data/lib/resubject/presenter.rb +35 -13
- data/lib/resubject/rails/extensions.rb +15 -12
- data/lib/resubject/rails/helpers.rb +7 -1
- data/lib/resubject/version.rb +1 -1
- data/resubject.gemspec +1 -0
- metadata +20 -3
data/Gemfile
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rspec/core/rake_task'
|
3
|
+
require 'yard'
|
3
4
|
|
4
5
|
desc 'Default: run specs.'
|
5
6
|
task :default => :spec
|
6
7
|
|
7
8
|
desc 'Run all specs'
|
8
9
|
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
|
11
|
+
YARD::Rake::YardocTask.new do |t|
|
12
|
+
t.files = ['lib/**/*.rb']
|
13
|
+
end
|
data/lib/resubject/builder.rb
CHANGED
@@ -1,26 +1,36 @@
|
|
1
1
|
module Resubject
|
2
2
|
module Builder
|
3
|
-
|
3
|
+
# Raised when a invalid presenter is received
|
4
|
+
class InvalidPresenterArgument < StandardError
|
4
5
|
end
|
5
6
|
|
6
7
|
# Presents a object or a collection of objects
|
7
8
|
#
|
8
|
-
#
|
9
|
+
# @param [Object, Array<Object>] objects objects to be instantiated with related presenter
|
10
|
+
# @param template then HTML template context
|
11
|
+
# @param [Presenter] presenters one or multiple presenters
|
9
12
|
#
|
10
|
-
#
|
11
|
-
# => <BoxPresenter>
|
13
|
+
# @return [Presenter, Array<Presenter>] either the presenter or a collection of presenter
|
12
14
|
#
|
13
|
-
#
|
14
|
-
# Builder.present box, template, CustomPresenter
|
15
|
-
# => <CustomPresenter>
|
15
|
+
# @example
|
16
16
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# => <OnePresenter<CustomPresenter>>
|
17
|
+
# Builder.present box, template
|
18
|
+
# # => <BoxPresenter>
|
20
19
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
20
|
+
# # Using a custom presenter
|
21
|
+
# Builder.present box, template, CustomPresenter
|
22
|
+
# # => <CustomPresenter>
|
23
|
+
#
|
24
|
+
# # Using multiple presenters
|
25
|
+
# Builder.present box, template, OnePresenter, CustomPresenter
|
26
|
+
# # => <OnePresenter<CustomPresenter>>
|
27
|
+
#
|
28
|
+
# # Using a collection
|
29
|
+
# Builder.present [box, box], template
|
30
|
+
# # => [<BoxPresenter>, <BoxPresenter>]
|
31
|
+
#
|
32
|
+
# @see .present_one
|
33
|
+
# @see .present_all
|
24
34
|
#
|
25
35
|
def self.present(objects, template, *presenters)
|
26
36
|
if objects.respond_to?(:each)
|
@@ -32,10 +42,21 @@ module Resubject
|
|
32
42
|
|
33
43
|
# Presents a single object (see .present)
|
34
44
|
#
|
35
|
-
#
|
45
|
+
# @param [Object] object object to be instantiated with related presenter
|
46
|
+
# @param template then HTML template context
|
47
|
+
# @param [Presenter] presenters one or multiple presenters
|
48
|
+
#
|
49
|
+
# @raise [InvalidPresenterArgument] if a presenter was not received in presenters param
|
50
|
+
#
|
51
|
+
# @return [Presenter] either instance of the presenter related to the object
|
36
52
|
#
|
37
|
-
#
|
38
|
-
#
|
53
|
+
# @example
|
54
|
+
#
|
55
|
+
# Builder.present_one box, context # => <BoxPresenter>
|
56
|
+
# Builder.present_one box, context, CustomPresenter # => <CustomPresenter>
|
57
|
+
# Builder.present_one box, context, OnePresenter, TwoPresenter # => <TwoPresenter<OnePresenter>>
|
58
|
+
#
|
59
|
+
# @see .present
|
39
60
|
#
|
40
61
|
def self.present_one(object, template, *presenters)
|
41
62
|
presenters = [Naming.presenter_for(object)] unless presenters.any?
|
@@ -51,10 +72,19 @@ module Resubject
|
|
51
72
|
|
52
73
|
# Presents a collection of objects (see .present)
|
53
74
|
#
|
54
|
-
#
|
75
|
+
# @param [Array<Object>] objects objects to be instantiated with related presenter
|
76
|
+
# @param template then HTML template context
|
77
|
+
# @param [Presenter] presenters one or multiple presenters
|
78
|
+
#
|
79
|
+
# @return [Array<Presenter>] collection of instances of the related presenter
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
#
|
83
|
+
# Builder.present [box, box], template
|
84
|
+
# # => [<BoxPresenter>, <BoxPresenter>]
|
55
85
|
#
|
56
|
-
#
|
57
|
-
#
|
86
|
+
# @see .present
|
87
|
+
# @see .present_one
|
58
88
|
#
|
59
89
|
def self.present_all(objects, template, *presenters)
|
60
90
|
objects.map do |o|
|
data/lib/resubject/naming.rb
CHANGED
@@ -2,6 +2,16 @@ require 'active_support/core_ext/string/inflections'
|
|
2
2
|
|
3
3
|
module Resubject
|
4
4
|
module Naming
|
5
|
+
# Discover the presenter class given the class name or string/symbol passed
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
#
|
9
|
+
# Naming.presenter_for :post # => PostPresenter
|
10
|
+
# Naming.presenter_for "post" # => PostPresenter
|
11
|
+
# Naming.presenter_for Post.new # => PostPresenter
|
12
|
+
#
|
13
|
+
# @param [Object, String, Symbol] presentable the reference object
|
14
|
+
# @return [Presenter] the related presenter class based on the object
|
5
15
|
def self.presenter_for(presentable)
|
6
16
|
klass = case presentable
|
7
17
|
when Symbol
|
data/lib/resubject/presenter.rb
CHANGED
@@ -2,9 +2,20 @@ require 'delegate'
|
|
2
2
|
|
3
3
|
module Resubject
|
4
4
|
class Presenter < SimpleDelegator
|
5
|
+
# the HTML helpers context
|
5
6
|
attr_reader :context
|
6
7
|
alias_method :template, :context
|
7
8
|
|
9
|
+
# Create a new presenter
|
10
|
+
#
|
11
|
+
# @param model any object that can be presented
|
12
|
+
# @param context a context of HTML helpers
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
#
|
16
|
+
# PostPresenter.new(post)
|
17
|
+
# PostPresenter.new(post, view_context)
|
18
|
+
#
|
8
19
|
def initialize(model, context = nil)
|
9
20
|
@context = context
|
10
21
|
super(model)
|
@@ -14,39 +25,50 @@ module Resubject
|
|
14
25
|
|
15
26
|
# Builds a collection of presenters given an array of objects
|
16
27
|
#
|
17
|
-
#
|
28
|
+
# @param [Array<Object>] collection
|
29
|
+
# @param context the HTML helpers context
|
30
|
+
# @return [Array<Presenter>] instances of a presenter for each item in the collection
|
31
|
+
#
|
32
|
+
# @example
|
18
33
|
#
|
19
34
|
# boxes = [box1, box2, box3]
|
20
35
|
# BoxPresenter.all boxes
|
21
36
|
# # => [<BoxPresenter>, <BoxPresenter>, <BoxPresenter>]
|
22
37
|
#
|
38
|
+
# PostPresenter.all Post.all
|
39
|
+
# # => [<PostPresenter>, ...]
|
40
|
+
#
|
23
41
|
def self.all(collection, context = nil)
|
24
42
|
collection.map { |c| new(c, context) }
|
25
43
|
end
|
26
44
|
|
27
45
|
# Creates a presenter from object or collection of objects
|
28
|
-
# See Builder.present for more details
|
29
|
-
# Example:
|
30
46
|
#
|
31
|
-
#
|
32
|
-
#
|
47
|
+
# @example
|
48
|
+
#
|
49
|
+
# present box # => <BoxPresenter>
|
50
|
+
# present [box, box] # => [<BoxPresenter>, <BoxPresenter>]
|
51
|
+
# present [box, box], CustomPresenter # => <CustomPresenter>
|
52
|
+
#
|
53
|
+
# @param [Object, Array<Object>] objects objects to be instantiated with related presenter
|
54
|
+
# @param [Presenter] presenters one or multiple presenters
|
55
|
+
# @return [Presenter, Array<Presenter>] either the presenter or a collection of presenter
|
33
56
|
#
|
57
|
+
# @see Builder.present
|
34
58
|
def present(objects, *presenters)
|
35
59
|
Builder.present objects, context, *presenters
|
36
60
|
end
|
37
61
|
|
38
62
|
# Generates a instance method with the attribute presented
|
39
63
|
#
|
40
|
-
#
|
64
|
+
# @example
|
41
65
|
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
# end
|
66
|
+
# class BoxPresenter < Resubject::Presenter
|
67
|
+
# presents :name
|
68
|
+
# # or presents :name, CustomPresenter
|
69
|
+
# end
|
47
70
|
#
|
48
|
-
#
|
49
|
-
# => <NamePresenter>
|
71
|
+
# BoxPresenter.new(box).name # => <NamePresenter>
|
50
72
|
#
|
51
73
|
def self.presents(attribute, *presenters)
|
52
74
|
define_method attribute do
|
@@ -1,25 +1,28 @@
|
|
1
1
|
module Resubject
|
2
|
-
module Rails
|
2
|
+
module Rails
|
3
|
+
# All Rails extensions
|
3
4
|
module Extensions
|
4
5
|
# Generates an attribute using `number_to_currency` helper from rails
|
5
6
|
#
|
6
|
-
#
|
7
|
+
# @example
|
7
8
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# class ProductPresenter < Resubject::Presenter
|
10
|
+
# currency :price
|
11
|
+
# end
|
11
12
|
#
|
12
|
-
#
|
13
|
+
# # Will create a `price` attribute using `number_to_currency`
|
13
14
|
#
|
14
|
-
#
|
15
|
-
#
|
15
|
+
# product.price
|
16
|
+
# # => '$10.00'
|
16
17
|
#
|
17
|
-
#
|
18
|
+
# @example Also, any number_to_currency options are accepted
|
18
19
|
#
|
19
|
-
#
|
20
|
-
#
|
20
|
+
# currency :price, precision: 3 # => '$123.456'
|
21
|
+
# currency :price, locale: :fr # => '123,51 €'
|
21
22
|
#
|
22
|
-
#
|
23
|
+
# @param [Symbol] attribute the name of the presented attribute to be generated
|
24
|
+
# @param [Hash] options the options for `number_to_currency` method
|
25
|
+
# @see http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_currency
|
23
26
|
def currency(attribute, options = {})
|
24
27
|
define_method attribute do
|
25
28
|
template.number_to_currency to_model.send(attribute), options
|
@@ -1,9 +1,15 @@
|
|
1
1
|
module Resubject
|
2
|
+
# ActionController helpers
|
3
|
+
#
|
4
|
+
# In case you have Rails, these helpers will be automatically included
|
5
|
+
#
|
2
6
|
module Helpers
|
3
|
-
|
7
|
+
# adds present as a helper method in the controller
|
8
|
+
def self.included(base)
|
4
9
|
base.send(:helper_method, :present)
|
5
10
|
end
|
6
11
|
|
12
|
+
# @see Builder.present
|
7
13
|
def present(objects, *presenters)
|
8
14
|
presenters = Builder.present(objects, view_context, *presenters)
|
9
15
|
|
data/lib/resubject/version.rb
CHANGED
data/resubject.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resubject
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -60,6 +60,22 @@ dependencies:
|
|
60
60
|
- - ~>
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: 2.12.0
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
type: :development
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 0.8.3
|
71
|
+
name: yard
|
72
|
+
prerelease: false
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 0.8.3
|
63
79
|
description: Uber simple presenters
|
64
80
|
email:
|
65
81
|
- felipe@applicake.com
|
@@ -106,7 +122,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
122
|
segments:
|
107
123
|
- 0
|
108
124
|
version: '0'
|
109
|
-
hash:
|
125
|
+
hash: 3846405687038123926
|
110
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
127
|
none: false
|
112
128
|
requirements:
|
@@ -115,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
131
|
segments:
|
116
132
|
- 0
|
117
133
|
version: '0'
|
118
|
-
hash:
|
134
|
+
hash: 3846405687038123926
|
119
135
|
requirements: []
|
120
136
|
rubyforge_project:
|
121
137
|
rubygems_version: 1.8.24
|
@@ -128,3 +144,4 @@ test_files:
|
|
128
144
|
- spec/resubject/presenter_spec.rb
|
129
145
|
- spec/resubject/rails/extensions_spec.rb
|
130
146
|
- spec/spec_helper.rb
|
147
|
+
has_rdoc:
|