garnish 0.0.3 → 0.0.4
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/CHANGELOG.rdoc +5 -0
- data/Gemfile +5 -0
- data/Guardfile +1 -1
- data/LICENSE +20 -0
- data/README.rdoc +61 -4
- data/lib/garnish.rb +1 -0
- data/lib/garnish/collection.rb +51 -0
- data/lib/garnish/controller.rb +9 -0
- data/lib/garnish/presenter/relationships.rb +1 -2
- data/lib/garnish/version.rb +1 -1
- data/spec/garnish/collection_spec.rb +34 -0
- data/spec/garnish/controller_spec.rb +1 -1
- data/spec/garnish/converter_spec.rb +1 -1
- data/spec/garnish/presenter/relationships_spec.rb +3 -2
- data/spec/garnish/presenter_spec.rb +1 -1
- data/spec/garnish/responder_spec.rb +1 -1
- metadata +42 -63
data/CHANGELOG.rdoc
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -18,7 +18,7 @@ guard 'spin' do
|
|
18
18
|
watch('Guardfile')
|
19
19
|
end
|
20
20
|
|
21
|
-
guard 'rspec', :cli => "--
|
21
|
+
guard 'rspec', :cli => "--color --order random", :version => 2, :rvm => ['1.9.3'] do
|
22
22
|
watch(%r{^spec/.+_spec\.rb$})
|
23
23
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
24
24
|
watch('spec/spec_helper.rb') { "spec" }
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Brian Pearce
|
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.rdoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
RDocs[http://rdoc.info/projects/brianp/garnish]
|
4
4
|
|
5
|
-
Garnish is a Presenter / Decorator pattern for models in Rails. It gives a home to
|
5
|
+
Garnish is a Presenter / Decorator pattern for models in Rails. It gives a home to presentation level view logic that normally litters helpers and view files. Using it can help you:
|
6
6
|
|
7
7
|
* Keep helper files and views clean of if/else statements and other logic
|
8
8
|
* Better define an interface for views to interact with models
|
@@ -10,6 +10,13 @@ Garnish is a Presenter / Decorator pattern for models in Rails. It gives a home
|
|
10
10
|
* Keep you controller code clean by never having to instantiate the presenters
|
11
11
|
* Handle Decorating / Presenting standard Rails relationships
|
12
12
|
|
13
|
+
== Requirements
|
14
|
+
|
15
|
+
Garnish Has been tested with
|
16
|
+
|
17
|
+
* Rails 3
|
18
|
+
* Ruby 1.9.2, 1.9.3
|
19
|
+
|
13
20
|
== Installation
|
14
21
|
|
15
22
|
In <b>Rails 3</b>, add this to your Gemfile and run the +bundle+ command.
|
@@ -35,12 +42,11 @@ Define the user_presenter
|
|
35
42
|
|
36
43
|
module UserPresenter
|
37
44
|
include Garnish::Presenter
|
38
|
-
|
39
45
|
end
|
40
46
|
|
41
47
|
=== 2. Add methods to your presenter
|
42
48
|
|
43
|
-
Define
|
49
|
+
Define methods in your presenter as regular instance methods
|
44
50
|
|
45
51
|
module UserPresenter
|
46
52
|
include Garnish::Presenter
|
@@ -83,12 +89,59 @@ The only change you need to make to start using your presenters now is to use re
|
|
83
89
|
|
84
90
|
Garnish will now find and load presenters for any instance variables you set inside your action. *NOT* just the ivar passed to the respond_with block.
|
85
91
|
|
86
|
-
|
92
|
+
=== 5. Start using your presenter methods
|
87
93
|
|
88
94
|
<tt>app/views/users/show.html.erb</tt>
|
89
95
|
|
90
96
|
<span><%= @user.greeting %></span>
|
91
97
|
|
98
|
+
== View Helpers
|
99
|
+
|
100
|
+
Garnish plays very nicely when adding view helper methods into your presenter. Just treat them like a regular method.
|
101
|
+
|
102
|
+
module UserPresenter
|
103
|
+
include Garnish::Presenter
|
104
|
+
|
105
|
+
def profile_pic
|
106
|
+
image_tag profile_pic unless profile_pic.nil?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
== Relationships
|
111
|
+
|
112
|
+
The real reason I got down to business. If I'm using presenters in my views I probably have presenters for multiple objects.
|
113
|
+
|
114
|
+
class User < ActiveRecord::Base
|
115
|
+
has_many :items
|
116
|
+
end
|
117
|
+
|
118
|
+
class Item < ActiveRecord::Base
|
119
|
+
belongs_to :user
|
120
|
+
end
|
121
|
+
|
122
|
+
Assuming I have presenters for both of these models
|
123
|
+
|
124
|
+
module UserPresenter
|
125
|
+
include Garnish::Presenter
|
126
|
+
end
|
127
|
+
|
128
|
+
module ItemPresenter
|
129
|
+
include Garnish::Presenter
|
130
|
+
|
131
|
+
def picture
|
132
|
+
image_tag profile_pic unless profile_pic.nil?
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
In my view when I'm accessing a user's items via the association what I really want is an Item extended with presenter methods not just a regular item.
|
138
|
+
|
139
|
+
Garnish handles this for us. Anytime a relationship is accessed on a garnished resource the returned resources will also be extended with their presenter methods.
|
140
|
+
|
141
|
+
<%= @user.items.first.picture %>
|
142
|
+
|
143
|
+
Works with no effort what so ever.
|
144
|
+
|
92
145
|
== Questions or Problems?
|
93
146
|
|
94
147
|
If you have any issues with Garnish which you cannot find the solution to, please add an {issue on GitHub}[https://github.com/brianp/garnish/issues] or fork the project and send a pull request.
|
@@ -97,4 +150,8 @@ To get the specs running you should call +bundle+ and then +rake+. See the {spec
|
|
97
150
|
|
98
151
|
== Special Thanks
|
99
152
|
|
153
|
+
{Fraser Valley Ruby Brigade}[http://www.fvrb.org/]
|
154
|
+
|
155
|
+
The Ruby Moguls
|
156
|
+
|
100
157
|
Garnish was inspired by draper[https://github.com/jcasimir/draper/] and the RailsCast Pro episode #287 Presenters from Scratch. See the CHANGELOG[https://github.com/brianp/garnish/blob/master/CHANGELOG.rdoc] for the full list.
|
data/lib/garnish.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Garnish
|
2
|
+
class Collection
|
3
|
+
include Enumerable
|
4
|
+
include Garnish::Converter
|
5
|
+
|
6
|
+
attr_accessor :relation
|
7
|
+
attr_accessor :template
|
8
|
+
|
9
|
+
delegate :avg, :max, :min, :sum, :length, :size, :count, :to => :relation
|
10
|
+
|
11
|
+
def initialize(relation, template)
|
12
|
+
@relation = relation
|
13
|
+
@template = template
|
14
|
+
end
|
15
|
+
|
16
|
+
# Call the method on the relation object and then convert the results
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# blog.posts.each { |post| post.name }
|
20
|
+
#
|
21
|
+
# @return [Collection]
|
22
|
+
[:to_a, :each].map do |method|
|
23
|
+
define_method method do
|
24
|
+
records = @relation.send(method)
|
25
|
+
convert(records)
|
26
|
+
records
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def respond_to?(method)
|
31
|
+
@relation.respond_to?(method)
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def method_missing(method, *args, &block)
|
37
|
+
resp = @relation.send(method, *args, &block)
|
38
|
+
|
39
|
+
if resp.equal? @relation
|
40
|
+
self
|
41
|
+
elsif resp.instance_of? @relation.class
|
42
|
+
Garnish::Collection.new(resp, @template)
|
43
|
+
elsif resp.respond_to? :each
|
44
|
+
Garnish::Collection.new(resp, @template)
|
45
|
+
else
|
46
|
+
convert(resp)
|
47
|
+
resp
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/garnish/controller.rb
CHANGED
@@ -3,6 +3,15 @@ module Garnish
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
+
# Set the responder and respond_to formats
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class ApplicationController < ActionController::Base
|
10
|
+
# protect_from_forgery
|
11
|
+
# garnish
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @return [undefined]
|
6
15
|
def garnish(options = {}, &block)
|
7
16
|
self.responder = Garnish::Responder
|
8
17
|
respond_to :html
|
data/lib/garnish/version.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Garnish::Collection do
|
4
|
+
|
5
|
+
let(:relation) { stub(:relation) }
|
6
|
+
let(:template) { stub(:template) }
|
7
|
+
let(:collection) { Garnish::Collection.new(relation, template) }
|
8
|
+
|
9
|
+
it "should init with a relation record" do
|
10
|
+
collection.relation.should eq(relation)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should pass the each method to the relation" do
|
14
|
+
relation.should_receive(:each)
|
15
|
+
collection.each
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should pass the to_a method to the relation" do
|
19
|
+
relation.should_receive(:to_a)
|
20
|
+
collection.to_a
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "method chains should return the existing collection" do
|
24
|
+
it "should be the same collection" do
|
25
|
+
relation.stub(:limit => collection)
|
26
|
+
collection.limit(1).should eq(collection)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be the same collection" do
|
30
|
+
relation.stub(:limit => collection, :order => collection)
|
31
|
+
collection.limit(1).order(:desc).should eq(collection)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Garnish::Presenter::Relationships do
|
4
4
|
|
5
5
|
let(:test_class) { TestClass.new }
|
6
6
|
before { test_class.extend Garnish::Presenter::Relationships }
|
@@ -11,7 +11,8 @@ describe "A Presenter Relationship" do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should call convert on the records of the relationship" do
|
14
|
-
test_class.
|
14
|
+
test_class.stub(:template => stub)
|
15
|
+
Garnish::Collection.should_receive(:new)
|
15
16
|
test_class.users
|
16
17
|
end
|
17
18
|
|
metadata
CHANGED
@@ -1,71 +1,57 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: garnish
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 3
|
10
|
-
version: 0.0.3
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- brianp
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-02-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: activesupport
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70340124404820 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 7
|
29
|
-
segments:
|
30
|
-
- 3
|
31
|
-
- 0
|
32
|
-
- 0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
33
21
|
version: 3.0.0
|
34
22
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: rspec
|
38
23
|
prerelease: false
|
39
|
-
|
24
|
+
version_requirements: *70340124404820
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70340124404220 !ruby/object:Gem::Requirement
|
40
28
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
48
33
|
type: :development
|
49
|
-
|
50
|
-
|
51
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70340124404220
|
36
|
+
description: Provides an easy to use and transparent system for implementing the Decorator
|
37
|
+
Pattern
|
38
|
+
email:
|
52
39
|
- brian.o.pearce@gmail.com
|
53
40
|
executables: []
|
54
|
-
|
55
41
|
extensions: []
|
56
|
-
|
57
42
|
extra_rdoc_files: []
|
58
|
-
|
59
|
-
files:
|
43
|
+
files:
|
60
44
|
- .gitignore
|
61
45
|
- .travis.yml
|
62
46
|
- CHANGELOG.rdoc
|
63
47
|
- Gemfile
|
64
48
|
- Guardfile
|
49
|
+
- LICENSE
|
65
50
|
- README.rdoc
|
66
51
|
- Rakefile
|
67
52
|
- garnish.gemspec
|
68
53
|
- lib/garnish.rb
|
54
|
+
- lib/garnish/collection.rb
|
69
55
|
- lib/garnish/controller.rb
|
70
56
|
- lib/garnish/converter.rb
|
71
57
|
- lib/garnish/model_adapters/abstract_adapter.rb
|
@@ -77,47 +63,40 @@ files:
|
|
77
63
|
- lib/garnish/responder.rb
|
78
64
|
- lib/garnish/version.rb
|
79
65
|
- spec/README.rdoc
|
66
|
+
- spec/garnish/collection_spec.rb
|
80
67
|
- spec/garnish/controller_spec.rb
|
81
68
|
- spec/garnish/converter_spec.rb
|
82
69
|
- spec/garnish/presenter/relationships_spec.rb
|
83
70
|
- spec/garnish/presenter_spec.rb
|
84
71
|
- spec/garnish/responder_spec.rb
|
85
72
|
- spec/spec_helper.rb
|
86
|
-
homepage:
|
73
|
+
homepage: ''
|
87
74
|
licenses: []
|
88
|
-
|
89
75
|
post_install_message:
|
90
76
|
rdoc_options: []
|
91
|
-
|
92
|
-
require_paths:
|
77
|
+
require_paths:
|
93
78
|
- lib
|
94
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
80
|
none: false
|
96
|
-
requirements:
|
97
|
-
- -
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
|
100
|
-
|
101
|
-
- 0
|
102
|
-
version: "0"
|
103
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
86
|
none: false
|
105
|
-
requirements:
|
106
|
-
- -
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
|
109
|
-
segments:
|
110
|
-
- 0
|
111
|
-
version: "0"
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
112
91
|
requirements: []
|
113
|
-
|
114
92
|
rubyforge_project: garnish
|
115
93
|
rubygems_version: 1.8.10
|
116
94
|
signing_key:
|
117
95
|
specification_version: 3
|
118
96
|
summary: Provides the decorator design pattern
|
119
|
-
test_files:
|
97
|
+
test_files:
|
120
98
|
- spec/README.rdoc
|
99
|
+
- spec/garnish/collection_spec.rb
|
121
100
|
- spec/garnish/controller_spec.rb
|
122
101
|
- spec/garnish/converter_spec.rb
|
123
102
|
- spec/garnish/presenter/relationships_spec.rb
|