rails_presenter 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # Rails Presenter
2
+
3
+ [![Build Status](https://travis-ci.org/dfmonaco/rails_presenter.png?branch=master)](https://travis-ci.org/dfmonaco/rails_presenter)
4
+
5
+ ##Before:
6
+
7
+ ```haml
8
+ # app/views/purchase_orders/show.html.haml
9
+
10
+ %h1 Purchase Order
11
+ %div
12
+ %p
13
+ %strong Date:
14
+ %span= localize(@purchase_order.date, format: :long)
15
+ %p
16
+ %strong Number:
17
+ %span= @purchase_order.number
18
+
19
+ %h2 Customer
20
+ %div
21
+ %p
22
+ %strong Name:
23
+ %span= @purchase_order.customer.name
24
+ %p
25
+ %strong Phone:
26
+ %span= @purchase_order.customer.phone || '------'
27
+ %p
28
+ %strong Email:
29
+ %span= mail_to(@purchase_order.customer.email)
30
+
31
+ %table
32
+ %thead
33
+ %tr
34
+ %th N°
35
+ %th Quantity
36
+ %th Item
37
+ %th Unit Price
38
+ %th Discount
39
+ %th Amount
40
+
41
+ %tbody
42
+ - @purchase_order.items.includes(:product).each_with_index do |item, index|
43
+ %tr
44
+ %td= index + 1
45
+ %td= number_with_precision(item.quantity)
46
+ %td= item.product.name
47
+ %td= number_to_currency(item.unit_price)
48
+ %td= number_to_percentage(item.discount)
49
+ %td= number_to_currency(item.amount)
50
+
51
+ %div
52
+ %p
53
+ %strong Subtotal:
54
+ %span= number_to_currency(@purchase_order.subtotal)
55
+ %p
56
+ %strong Vat:
57
+ %span= number_to_currency(@purchase_order.vat)
58
+ %p
59
+ %strong Total:
60
+ %span= number_to_currency(@purchase_order.total)
61
+
62
+ ```
63
+
64
+ ##After:
65
+
66
+ ```haml
67
+ # app/views/purchase_orders/show.html.haml
68
+
69
+ - present(@purchase_order) do |order_presenter|
70
+
71
+ %h1 Purchase Order
72
+ = order_presenter.with_attrs :date, :number
73
+
74
+ %h2 Customer
75
+ = order_presenter.customer.with_attrs :name, :phone, :email
76
+
77
+ %table
78
+ %thead
79
+ %tr
80
+ %th N°
81
+ %th Quantity
82
+ %th Item
83
+ %th Unit Price
84
+ %th Discount
85
+ %th Amount
86
+
87
+ %tbody
88
+ - order_presenter.items.each_with_index do |item_presenter, index|
89
+ %tr
90
+ %td= index + 1
91
+ %td= item_presenter.quantity
92
+ %td= item_presenter.product
93
+ %td= item_presenter.unit_price
94
+ %td= item_presenter.discount
95
+ %td= item_presenter.amount
96
+
97
+ = order_presenter.with_attrs :subtotal, :vat, :total
98
+ ```
99
+
100
+ ## How did we get here?
101
+
102
+ ```ruby
103
+ # app/presenters/purchase_order_presenter.rb
104
+
105
+ class PurchaseOrderPresenter < RailsPresenter::Base
106
+ present :customer
107
+
108
+ present :items do
109
+ includes(:product)
110
+ end
111
+
112
+ format :subtotal, :vat, :total, with: :number_to_currency
113
+
114
+ def date
115
+ h.localize(super, format: :long)
116
+ end
117
+ end
118
+ ```
119
+
120
+ ```ruby
121
+ # app/presenters/customer_presenter.rb
122
+
123
+ class CustomerPresenter < RailsPresenter::Base
124
+ def email
125
+ h.mail_to super
126
+ end
127
+ end
128
+ ```
129
+
130
+ ```ruby
131
+ # app/presenters/item_presenter.rb
132
+
133
+ class ItemPresenter < RailsPresenter::Base
134
+ present :product
135
+
136
+ format :quantity, with: :number_with_precision
137
+ format :unit_price, :amount, with: :number_to_currency
138
+ format :discount, with: :number_to_percentage
139
+ end
140
+ ```
141
+
142
+ ```ruby
143
+ # app/presenters/product_presenter.rb
144
+
145
+ class ProductPresenter < RailsPresenter::Base
146
+ end
147
+ ```
148
+
149
+
@@ -1,18 +1,3 @@
1
1
  module PresenterHelper
2
- def present(object, template = self, &block)
3
- if [Array, ActiveRecord::Relation].include? object.class
4
- return object.map {|e| present(e)}
5
- end
6
-
7
- begin
8
- presenter_class = "#{object.class}Presenter".constantize
9
- rescue NameError
10
- return object
11
- end
12
-
13
- presenter = presenter_class.new(object, template)
14
-
15
- block.call(presenter) if block
16
- presenter
17
- end
2
+ include RailsPresenter::PresenterHelper
18
3
  end
@@ -1,7 +1,7 @@
1
1
  <div class="show-with-attrs">
2
2
  <% attrs_hash.each do |name, value| %>
3
3
  <p>
4
- <strong><%= name %></strong>
4
+ <strong><%= "#{name.to_s.titleize}: " %></strong>
5
5
  <span><%= value %></span>
6
6
  </p>
7
7
  <% end %>
@@ -0,0 +1,182 @@
1
+ require 'delegate'
2
+
3
+ module RailsPresenter
4
+ class Base < SimpleDelegator
5
+ include RailsPresenter::PresenterHelper
6
+
7
+ @@nil_formatter = '----'
8
+
9
+ class << self
10
+ def location(*args)
11
+ define_method(:self_location, ->(location=nil) do
12
+ location ||= args.map do |p|
13
+ p = p.to_s
14
+ if p.delete! "@"
15
+ public_send("get_#{p}")
16
+ else
17
+ p
18
+ end
19
+ end
20
+
21
+ super(location)
22
+ end)
23
+ end
24
+
25
+ def present(*args, &block)
26
+ module_name = "#{name}Associations"
27
+
28
+ unless const_defined? module_name
29
+ include const_set(module_name, Module.new)
30
+ end
31
+
32
+ associations_module = const_get(module_name)
33
+
34
+ block ||= proc { self }
35
+
36
+ associations_module.module_eval do
37
+ args.each do |assoc_name|
38
+ define_method(assoc_name) do
39
+ instance_variable_get("@#{assoc_name}") ||
40
+ begin
41
+ association = if super().is_a?(Array) && super().respond_to?(:scoped)
42
+ super().scoped
43
+ else
44
+ super()
45
+ end
46
+ instance_variable_set("@#{assoc_name}", present(association.instance_eval(&block)))
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+
54
+ def format(*attrs)
55
+ formatter = attrs.pop.values.first
56
+
57
+ module_name = formatter.to_s.camelize
58
+
59
+ unless const_defined? module_name
60
+ include const_set(module_name, Module.new)
61
+ end
62
+
63
+ formatter_module = const_get(module_name)
64
+
65
+ formatter_module.module_eval do
66
+ attrs.each do |attr|
67
+ define_method(attr) do
68
+ h.public_send(formatter, super())
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ def inherited(child_class)
75
+ child_class.instance_eval do
76
+ format_blank_attributes(*possible_blank_attributes) if based_on_active_record?
77
+ end
78
+ end
79
+
80
+ def format_blank_attributes(*attrs)
81
+ attr_module = Module.new do
82
+ attrs.each do |attr|
83
+ define_method(attr) do
84
+ return nil_formatter if super().blank?
85
+ super()
86
+ end
87
+ end
88
+ end
89
+
90
+ include const_set("BlankAttributes", attr_module)
91
+ end
92
+
93
+ private
94
+
95
+ def base_class
96
+ @base_class ||= to_s.chomp('Presenter').constantize
97
+ end
98
+
99
+ def based_on_active_record?
100
+ base_class.ancestors.include?(ActiveRecord::Base)
101
+ end
102
+
103
+ def possible_blank_attributes
104
+ base_class.column_names.reject do |attr|
105
+ ['id', 'created_at', 'updated_at'].include?(attr) ||
106
+ /_id\z/.match(attr) ||
107
+ base_class.validators_on(attr).any? {|v| !(v.options[:allow_nil] || v.options[:allow_blank])}
108
+ end
109
+ end
110
+ end
111
+
112
+ def initialize(base_object, template)
113
+ @template = template
114
+ super(base_object)
115
+ end
116
+
117
+ def present(object)
118
+ super(object, h)
119
+ end
120
+
121
+ def h
122
+ @template
123
+ end
124
+
125
+ def o
126
+ __getobj__
127
+ end
128
+
129
+ def to_s
130
+ respond_to?(:name) ? name : super
131
+ end
132
+
133
+ def with_attrs(*attrs)
134
+ attrs_hash = attrs.reduce({}) do |hash, attr|
135
+ if attr.is_a? Array
136
+ hash[attr.first]= attr.last.call(self)
137
+ else
138
+ hash[attr]= public_send(attr)
139
+ end
140
+ hash
141
+ end
142
+
143
+ h.render partial: 'shared/show_with_attrs', locals: {attrs_hash: attrs_hash}
144
+ end
145
+
146
+ def self_location(location = o)
147
+ h.polymorphic_path location
148
+ end
149
+
150
+ def link_to_self(options={})
151
+ text = options[:text] || self.to_s
152
+ path = options[:path] || self_location
153
+ h.link_to text, path
154
+ end
155
+
156
+ def nil_formatter
157
+ @@nil_formatter
158
+ end
159
+
160
+ def method_missing(method_name, *args)
161
+ case method_name.to_s
162
+ when /^h_(.*)$/
163
+ get_iv_from_view($1)
164
+ when /^get_(.*)$/
165
+ return o if o.is_a? $1.camelize.constantize
166
+ get_iv_from_view($1) || o.public_send($1)
167
+ else
168
+ super
169
+ end
170
+ end
171
+
172
+ private
173
+ def base_object_name
174
+ o.class.to_s.underscore
175
+ end
176
+
177
+ def get_iv_from_view(iv_name)
178
+ h.instance_variable_get("@#{iv_name}")
179
+ end
180
+
181
+ end
182
+ end
@@ -0,0 +1,20 @@
1
+ module RailsPresenter
2
+ module PresenterHelper
3
+ def present(object, template = self, &block)
4
+ if [Array, ActiveRecord::Relation].include? object.class
5
+ return object.map {|e| present(e)}
6
+ end
7
+
8
+ begin
9
+ presenter_class = "#{object.class}Presenter".constantize
10
+ rescue NameError
11
+ return object
12
+ end
13
+
14
+ presenter = presenter_class.new(object, template)
15
+
16
+ block.call(presenter) if block
17
+ presenter
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module RailsPresenter
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,4 +1,6 @@
1
- require "rails_presenter/engine"
1
+ require 'rails_presenter/engine'
2
+ require 'rails_presenter/presenter_helper'
3
+ require 'rails_presenter/base'
2
4
 
3
5
  module RailsPresenter
4
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-02 00:00:00.000000000 Z
12
+ date: 2013-04-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -82,17 +82,18 @@ executables: []
82
82
  extensions: []
83
83
  extra_rdoc_files: []
84
84
  files:
85
- - app/presenters/presenter.rb
86
85
  - app/helpers/presenter_helper.rb
87
86
  - app/views/shared/_show_with_attrs.html.erb
88
87
  - config/routes.rb
89
88
  - lib/tasks/rails_presenter_tasks.rake
90
89
  - lib/rails_presenter.rb
90
+ - lib/rails_presenter/base.rb
91
91
  - lib/rails_presenter/engine.rb
92
92
  - lib/rails_presenter/version.rb
93
+ - lib/rails_presenter/presenter_helper.rb
93
94
  - MIT-LICENSE
94
95
  - Rakefile
95
- - README.rdoc
96
+ - README.md
96
97
  homepage: https://github.com/dfmonaco/rails_presenter
97
98
  licenses: []
98
99
  post_install_message:
@@ -107,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
108
  version: '0'
108
109
  segments:
109
110
  - 0
110
- hash: 610965391
111
+ hash: 644764051
111
112
  required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  none: false
113
114
  requirements:
@@ -116,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
117
  version: '0'
117
118
  segments:
118
119
  - 0
119
- hash: 610965391
120
+ hash: 644764051
120
121
  requirements: []
121
122
  rubyforge_project:
122
123
  rubygems_version: 1.8.25
data/README.rdoc DELETED
@@ -1,3 +0,0 @@
1
- = RailsPresenter
2
-
3
- This project rocks and uses MIT-LICENSE.
@@ -1,180 +0,0 @@
1
- require 'delegate'
2
-
3
- class Presenter < SimpleDelegator
4
- include PresenterHelper
5
-
6
- @@nil_formatter = '----'
7
-
8
- class << self
9
- def location(*args)
10
- define_method(:self_location, ->(location=nil) do
11
- location ||= args.map do |p|
12
- p = p.to_s
13
- if p.delete! "@"
14
- public_send("get_#{p}")
15
- else
16
- p
17
- end
18
- end
19
-
20
- super(location)
21
- end)
22
- end
23
-
24
- def present(*args, &block)
25
- module_name = "#{name}Associations"
26
-
27
- unless const_defined? module_name
28
- include const_set(module_name, Module.new)
29
- end
30
-
31
- associations_module = const_get(module_name)
32
-
33
- block ||= proc { self }
34
-
35
- associations_module.module_eval do
36
- args.each do |assoc_name|
37
- define_method(assoc_name) do
38
- instance_variable_get("@#{assoc_name}") ||
39
- begin
40
- association = if super().is_a?(Array) && super().respond_to?(:scoped)
41
- super().scoped
42
- else
43
- super()
44
- end
45
- instance_variable_set("@#{assoc_name}", present(association.instance_eval(&block)))
46
- end
47
- end
48
- end
49
- end
50
- end
51
-
52
-
53
- def format(*attrs)
54
- formatter = attrs.pop.values.first
55
-
56
- module_name = formatter.to_s.camelize
57
-
58
- unless const_defined? module_name
59
- include const_set(module_name, Module.new)
60
- end
61
-
62
- formatter_module = const_get(module_name)
63
-
64
- formatter_module.module_eval do
65
- attrs.each do |attr|
66
- define_method(attr) do
67
- h.public_send(formatter, super())
68
- end
69
- end
70
- end
71
- end
72
-
73
- def inherited(child_class)
74
- child_class.instance_eval do
75
- format_blank_attributes(*possible_blank_attributes) if based_on_active_record?
76
- end
77
- end
78
-
79
- def format_blank_attributes(*attrs)
80
- attr_module = Module.new do
81
- attrs.each do |attr|
82
- define_method(attr) do
83
- return nil_formatter if super().blank?
84
- super()
85
- end
86
- end
87
- end
88
-
89
- include const_set("BlankAttributes", attr_module)
90
- end
91
-
92
- private
93
-
94
- def base_class
95
- @base_class ||= to_s.chomp('Presenter').constantize
96
- end
97
-
98
- def based_on_active_record?
99
- base_class.ancestors.include?(ActiveRecord::Base)
100
- end
101
-
102
- def possible_blank_attributes
103
- base_class.column_names.reject do |attr|
104
- ['id', 'created_at', 'updated_at'].include?(attr) ||
105
- /_id\z/.match(attr) ||
106
- base_class.validators_on(attr).any? {|v| !(v.options[:allow_nil] || v.options[:allow_blank])}
107
- end
108
- end
109
- end
110
-
111
- def initialize(base_object, template)
112
- @template = template
113
- super(base_object)
114
- end
115
-
116
- def present(object)
117
- super(object, h)
118
- end
119
-
120
- def h
121
- @template
122
- end
123
-
124
- def o
125
- __getobj__
126
- end
127
-
128
- def to_s
129
- respond_to?(:name) ? name : super
130
- end
131
-
132
- def with_attrs(*attrs)
133
- attrs_hash = attrs.reduce({}) do |hash, attr|
134
- if attr.is_a? Array
135
- hash[attr.first]= attr.last.call(self)
136
- else
137
- hash[attr]= public_send(attr)
138
- end
139
- hash
140
- end
141
-
142
- h.render partial: 'shared/show_with_attrs', locals: {attrs_hash: attrs_hash}
143
- end
144
-
145
- def self_location(location = o)
146
- h.polymorphic_path location
147
- end
148
-
149
- def link_to_self(options={})
150
- text = options[:text] || self.to_s
151
- path = options[:path] || self_location
152
- h.link_to text, path
153
- end
154
-
155
- def nil_formatter
156
- @@nil_formatter
157
- end
158
-
159
- def method_missing(method_name, *args)
160
- case method_name.to_s
161
- when /^h_(.*)$/
162
- get_iv_from_view($1)
163
- when /^get_(.*)$/
164
- return o if o.is_a? $1.camelize.constantize
165
- get_iv_from_view($1) || o.public_send($1)
166
- else
167
- super
168
- end
169
- end
170
-
171
- private
172
- def base_object_name
173
- o.class.to_s.underscore
174
- end
175
-
176
- def get_iv_from_view(iv_name)
177
- h.instance_variable_get("@#{iv_name}")
178
- end
179
-
180
- end