simple_exposure 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +71 -7
- data/lib/simple_exposure/core.rb +33 -9
- data/lib/simple_exposure/version.rb +1 -1
- data/simple_exposure.gemspec +0 -1
- data/spec/controllers/application_controller_spec.rb +71 -0
- data/spec/dummy/app/controllers/application_controller.rb +27 -3
- data/spec/dummy/app/views/application/index.html.erb +0 -7
- data/spec/spec_helper.rb +0 -6
- metadata +5 -20
- data/spec/integration/simple_exposure_spec.rb +0 -21
- data/spec/simple_exposure/core_spec.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4ac6213c3f38471d413641334b633e9f930c36a
|
4
|
+
data.tar.gz: cffbf6e5672dbf1ec8feebb49ecd3f0e5396441b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28f0a6fbac384b2adc6ed468e9c82ae0835c86ab8c3107093364166c93d43811c5329d6489aa2c752bd5da224ccd85d5afc8be6a36a98a91b44a34f6af5b54ad
|
7
|
+
data.tar.gz: 73217785155e4003aa33ebe131b90d1807341d320624dec4ef9efc1c612a5a5f74f9ab1f625196b53062bfce3f398d05f0016f6969d0af4e3cd2b50dcf46cad5
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
## v0.1.0
|
2
|
+
|
3
|
+
+ Added extension shortcuts (e.g. `paginate :users`)
|
4
|
+
+ Moved UnknownExtension exception directly to SimpleExposure namespace (SimpleExposure::UnknownExtension)
|
5
|
+
|
6
|
+
## v0.0.2
|
7
|
+
|
8
|
+
+ Don't apply extensions when no value is provided
|
9
|
+
|
10
|
+
## v0.0.1
|
11
|
+
|
12
|
+
+ Initial impementation
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SimpleExposure
|
2
2
|
|
3
|
-
![Gem version](http://img.shields.io/gem/v/simple_exposure.svg)
|
3
|
+
![Gem version](http://img.shields.io/gem/v/simple_exposure.svg)
|
4
4
|
![Code Climate](http://img.shields.io/codeclimate/github/mikekreeki/simple_exposure.svg)
|
5
5
|
![Travis CI](http://img.shields.io/travis/mikekreeki/simple_exposure.svg)
|
6
6
|
![Github Issues](http://img.shields.io/github/issues/mikekreeki/simple_exposure.svg)
|
@@ -22,6 +22,8 @@ end
|
|
22
22
|
p = project.title
|
23
23
|
```
|
24
24
|
|
25
|
+
Wait, there's more!
|
26
|
+
|
25
27
|
## Installation
|
26
28
|
|
27
29
|
Add this line to your application's Gemfile:
|
@@ -43,11 +45,15 @@ Or install it yourself as:
|
|
43
45
|
```ruby
|
44
46
|
# controllers/projects_controller.rb
|
45
47
|
class ProjectsController < ApplicationController
|
46
|
-
expose :projects
|
48
|
+
expose :projects, :project
|
47
49
|
|
48
50
|
def index
|
49
51
|
self.projects = Project.all
|
50
52
|
end
|
53
|
+
|
54
|
+
def show
|
55
|
+
self.project = Project.find(1)
|
56
|
+
end
|
51
57
|
end
|
52
58
|
|
53
59
|
# views/projects/index.html.slim
|
@@ -55,6 +61,21 @@ end
|
|
55
61
|
p = project.title
|
56
62
|
```
|
57
63
|
|
64
|
+
Expose controller methods to the views:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
# controllers/projects_controller.rb
|
68
|
+
class ProjectsController < ApplicationController
|
69
|
+
expose :project
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def project
|
74
|
+
@project ||= Project.find(1)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
58
79
|
### Provide default values
|
59
80
|
|
60
81
|
```ruby
|
@@ -73,12 +94,23 @@ class ProjectsController < ApplicationController
|
|
73
94
|
def index
|
74
95
|
@projects = Project.page(params[:page])
|
75
96
|
end
|
76
|
-
|
77
97
|
end
|
78
98
|
```
|
79
99
|
|
80
100
|
After:
|
81
101
|
|
102
|
+
```ruby
|
103
|
+
class ProjectsController < ApplicationController
|
104
|
+
paginate :projects
|
105
|
+
|
106
|
+
def index
|
107
|
+
self.projects = Project.all
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
Which is the same as:
|
113
|
+
|
82
114
|
```ruby
|
83
115
|
class ProjectsController < ApplicationController
|
84
116
|
expose :projects, extend: :paginate
|
@@ -91,6 +123,31 @@ end
|
|
91
123
|
|
92
124
|
### Combine multiple extensions
|
93
125
|
|
126
|
+
Before:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
class ProjectsController < ApplicationController
|
130
|
+
|
131
|
+
def index
|
132
|
+
@projects = Project.page(params[:page]).decorate
|
133
|
+
end
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
After:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
class ProjectsController < ApplicationController
|
141
|
+
paginate :projects, extend: :decorate
|
142
|
+
|
143
|
+
def index
|
144
|
+
self.projects = Project.all
|
145
|
+
end
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
Which is the same as:
|
150
|
+
|
94
151
|
```ruby
|
95
152
|
class ProjectsController < ApplicationController
|
96
153
|
expose :projects, extend: %i(paginate decorate)
|
@@ -121,15 +178,13 @@ After:
|
|
121
178
|
|
122
179
|
```ruby
|
123
180
|
class ProjectsController < ApplicationController
|
124
|
-
|
181
|
+
decorate :current_user
|
125
182
|
|
126
183
|
expose :projects do
|
127
184
|
current_user.projects.ordered
|
128
185
|
end
|
129
186
|
|
130
|
-
|
131
|
-
projects.completed
|
132
|
-
end
|
187
|
+
paginate(:completed_projects) { projects.completed }
|
133
188
|
end
|
134
189
|
```
|
135
190
|
|
@@ -158,10 +213,19 @@ module SimpleExposure
|
|
158
213
|
end
|
159
214
|
|
160
215
|
class ProjectsController < ApplicationController
|
216
|
+
my_extension :projects
|
217
|
+
# or
|
161
218
|
expose :projects, extend: :my_extension
|
162
219
|
end
|
163
220
|
```
|
164
221
|
|
222
|
+
Note that extensions are applied at the time of `render`, not immediately when the value is assigned.
|
223
|
+
|
224
|
+
## Similar projects
|
225
|
+
|
226
|
+
+ [view_accessor](https://github.com/invisiblefunnel/view_accessor)
|
227
|
+
+ [obviews](https://github.com/elia/obviews)
|
228
|
+
+ [decent_exposure](https://github.com/voxdolo/decent_exposure)
|
165
229
|
|
166
230
|
## Contributing
|
167
231
|
|
data/lib/simple_exposure/core.rb
CHANGED
@@ -2,20 +2,21 @@ require 'simple_exposure/extensions/paginate'
|
|
2
2
|
require 'simple_exposure/extensions/decorate'
|
3
3
|
|
4
4
|
module SimpleExposure
|
5
|
+
UnknownExtension = Class.new(NameError)
|
6
|
+
|
5
7
|
module Core
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
8
|
-
UnknownExtension = Class.new(NameError)
|
9
|
-
|
10
10
|
included do
|
11
11
|
delegate :_exposure_extensions, to: :class
|
12
|
+
delegate :_exposure_extension_class, to: :class
|
12
13
|
before_render :_apply_exposure_extensions
|
13
14
|
end
|
14
15
|
|
15
16
|
def _apply_exposure_extensions
|
16
17
|
_exposure_extensions.each do |attribute, extensions|
|
17
18
|
extensions.each do |extension|
|
18
|
-
_apply_exposure_extension(attribute, extension)
|
19
|
+
_apply_exposure_extension(attribute, extension.to_s)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -29,12 +30,6 @@ module SimpleExposure
|
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
32
|
-
def _exposure_extension_class(extension)
|
33
|
-
Extensions.const_get(extension.camelize)
|
34
|
-
rescue NameError
|
35
|
-
raise UnknownExtension, "Unknown extension: #{extension}"
|
36
|
-
end
|
37
|
-
|
38
33
|
module ClassMethods
|
39
34
|
|
40
35
|
def expose(*attributes, &block)
|
@@ -51,6 +46,12 @@ module SimpleExposure
|
|
51
46
|
@_exposure_extensions ||= HashWithIndifferentAccess.new([])
|
52
47
|
end
|
53
48
|
|
49
|
+
def _exposure_extension_class(extension)
|
50
|
+
Extensions.const_get(extension.camelize)
|
51
|
+
rescue NameError
|
52
|
+
raise UnknownExtension, "Unknown extension: #{extension}"
|
53
|
+
end
|
54
|
+
|
54
55
|
private
|
55
56
|
|
56
57
|
def _define_exposure_accessors(attributes, &block)
|
@@ -92,6 +93,29 @@ module SimpleExposure
|
|
92
93
|
_exposure_extensions[attribute] += extensions
|
93
94
|
end
|
94
95
|
end
|
96
|
+
|
97
|
+
def method_missing(extension, *attributes, &block)
|
98
|
+
extension_class = _exposure_extension_class(extension.to_s)
|
99
|
+
if extension_class
|
100
|
+
options = attributes.extract_options!
|
101
|
+
|
102
|
+
extensions = options.fetch(:extend, nil)
|
103
|
+
extensions = Array(extensions)
|
104
|
+
extensions = extensions.prepend(extension)
|
105
|
+
|
106
|
+
options = options.merge(extend: extensions)
|
107
|
+
|
108
|
+
expose(*attributes, options, &block)
|
109
|
+
end
|
110
|
+
rescue UnknownExtension
|
111
|
+
super
|
112
|
+
end
|
113
|
+
|
114
|
+
def respond_to_missing?(extension, include_private = false)
|
115
|
+
_exposure_extension_class(extension.to_s)
|
116
|
+
rescue UnknownExtension
|
117
|
+
false
|
118
|
+
end
|
95
119
|
end
|
96
120
|
end
|
97
121
|
end
|
data/simple_exposure.gemspec
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ApplicationController, type: :controller do
|
4
|
+
let(:view) { controller.view_context }
|
5
|
+
|
6
|
+
it 'loads the modules' do
|
7
|
+
expect(described_class.ancestors).to include(SimpleExposure::Core)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'responds to #expose' do
|
11
|
+
expect(described_class).to respond_to(:expose)
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
get :index
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Inline definition of multiple exposed attributes' do
|
19
|
+
it 'exposes multiple attributes defined inline' do
|
20
|
+
expect(view.my_name).to eq 'Jane Doe'
|
21
|
+
expect(view.your_name).to eq 'Jane Doe'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'Default values' do
|
26
|
+
it 'assigns default value' do
|
27
|
+
expect(view.message).to eq 'Hello!'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'does not override provided values with default one' do
|
31
|
+
expect(view.other_message).to eq 'Other message'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'Exposing controllers instance variables' do
|
36
|
+
it 'exposes the value in ivar' do
|
37
|
+
expect(view.ivar_message).to eq 'Hello!'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'Exposing private methods' do
|
42
|
+
it 'exposes controllers private methods' do
|
43
|
+
expect(view.current_user).to eq 'mikekreeki'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'Extensions' do
|
48
|
+
it 'applies extension when value provided' do
|
49
|
+
expect(view.decoratable_message).to eq 'Hello!'
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'does not apply extension when value not provided' do
|
53
|
+
expect(view.nil_value).to be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'Extension shortcuts' do
|
58
|
+
it 'quacks like a shortcut' do
|
59
|
+
expect(described_class).to respond_to :decorate
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'applies the extension when specified using a shortcut' do
|
63
|
+
expect(view.second_user).to eq 'Andrew Bennett'
|
64
|
+
expect(view.third_user).to eq 'Andrew Bennett'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'takes additional extensions' do
|
68
|
+
expect(view.combined_extension).to eq 'HELLO'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -1,18 +1,42 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
class ApplicationController < ActionController::Base
|
2
4
|
# Prevent CSRF attacks by raising an exception.
|
3
5
|
# For APIs, you may want to use :null_session instead.
|
4
6
|
protect_from_forgery with: :exception
|
5
7
|
|
6
|
-
expose(:
|
8
|
+
expose(:my_name, :your_name) { 'Jane Doe' }
|
9
|
+
|
10
|
+
expose(:message) { 'Hello!' }
|
11
|
+
expose(:other_message) { 'Hello!' }
|
12
|
+
expose(:ivar_message)
|
7
13
|
|
8
14
|
expose(:current_user)
|
9
15
|
|
10
|
-
expose(:
|
16
|
+
expose(:decoratable_message, extend: :decorate) do
|
17
|
+
OpenStruct.new(decorate: 'Hello!')
|
18
|
+
end
|
11
19
|
|
12
20
|
expose(:nil_value, extend: :decorate)
|
13
21
|
|
22
|
+
decorate(:second_user, :third_user) { OpenStruct.new(decorate: 'Andrew Bennett') }
|
23
|
+
|
24
|
+
paginate :combined_extension, extend: :decorate do
|
25
|
+
Class.new do
|
26
|
+
def page(*)
|
27
|
+
@name = 'Hello'
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def decorate
|
32
|
+
@name.upcase
|
33
|
+
end
|
34
|
+
end.new
|
35
|
+
end
|
36
|
+
|
14
37
|
def index
|
15
|
-
|
38
|
+
self.other_message = 'Other message'
|
39
|
+
@ivar_message = 'Hello!'
|
16
40
|
end
|
17
41
|
|
18
42
|
private
|
data/spec/spec_helper.rb
CHANGED
@@ -2,12 +2,6 @@ ENV['RAILS_ENV'] ||= 'test'
|
|
2
2
|
require File.expand_path('../dummy/config/environment', __FILE__)
|
3
3
|
|
4
4
|
require 'rspec/rails'
|
5
|
-
require 'capybara/rspec'
|
6
|
-
|
7
|
-
# Requires supporting ruby files with custom matchers and macros, etc,
|
8
|
-
# in spec/support/ and its subdirectories.
|
9
|
-
Dir[Rails.root.join('spec/support/**/*.rb')].each {|f| require f}
|
10
5
|
|
11
6
|
RSpec.configure do |config|
|
12
|
-
config.include Capybara::DSL, type: :integration
|
13
7
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_exposure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michal Krejčí
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -44,20 +44,6 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 3.0.0
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: capybara
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - ">="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - ">="
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '0'
|
61
47
|
description: Cleanup your Rails controllers
|
62
48
|
email:
|
63
49
|
- work@mikekreeki.com
|
@@ -69,6 +55,7 @@ files:
|
|
69
55
|
- ".ruby-gemset"
|
70
56
|
- ".ruby-version"
|
71
57
|
- ".travis.yml"
|
58
|
+
- CHANGELOG.md
|
72
59
|
- Gemfile
|
73
60
|
- LICENSE.txt
|
74
61
|
- README.md
|
@@ -80,6 +67,7 @@ files:
|
|
80
67
|
- lib/simple_exposure/extensions/paginate.rb
|
81
68
|
- lib/simple_exposure/version.rb
|
82
69
|
- simple_exposure.gemspec
|
70
|
+
- spec/controllers/application_controller_spec.rb
|
83
71
|
- spec/dummy/.gitignore
|
84
72
|
- spec/dummy/Gemfile
|
85
73
|
- spec/dummy/README.rdoc
|
@@ -134,8 +122,6 @@ files:
|
|
134
122
|
- spec/dummy/test/test_helper.rb
|
135
123
|
- spec/dummy/vendor/assets/javascripts/.keep
|
136
124
|
- spec/dummy/vendor/assets/stylesheets/.keep
|
137
|
-
- spec/integration/simple_exposure_spec.rb
|
138
|
-
- spec/simple_exposure/core_spec.rb
|
139
125
|
- spec/spec_helper.rb
|
140
126
|
homepage: https://github.com/mikekreeki/simple_exposure
|
141
127
|
licenses:
|
@@ -162,6 +148,7 @@ signing_key:
|
|
162
148
|
specification_version: 4
|
163
149
|
summary: Cleanup your Rails controllers
|
164
150
|
test_files:
|
151
|
+
- spec/controllers/application_controller_spec.rb
|
165
152
|
- spec/dummy/.gitignore
|
166
153
|
- spec/dummy/Gemfile
|
167
154
|
- spec/dummy/README.rdoc
|
@@ -216,6 +203,4 @@ test_files:
|
|
216
203
|
- spec/dummy/test/test_helper.rb
|
217
204
|
- spec/dummy/vendor/assets/javascripts/.keep
|
218
205
|
- spec/dummy/vendor/assets/stylesheets/.keep
|
219
|
-
- spec/integration/simple_exposure_spec.rb
|
220
|
-
- spec/simple_exposure/core_spec.rb
|
221
206
|
- spec/spec_helper.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe SimpleExposure, type: :integration do
|
4
|
-
it 'loads the modules' do
|
5
|
-
expect(ActionController::Base.ancestors).to include(SimpleExposure::Core)
|
6
|
-
end
|
7
|
-
|
8
|
-
let(:controller) { ApplicationController.new }
|
9
|
-
|
10
|
-
it 'can see the content' do
|
11
|
-
visit '/'
|
12
|
-
|
13
|
-
controller.index
|
14
|
-
|
15
|
-
expect(page).to have_content controller.send(:message)
|
16
|
-
expect(page).to have_content controller.send(:current_user)
|
17
|
-
expect(page).to have_content controller.send(:posts_count)
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
end
|