simple_exposure 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +167 -0
- data/Rakefile +1 -0
- data/lib/simple_exposure.rb +8 -0
- data/lib/simple_exposure/before_render.rb +42 -0
- data/lib/simple_exposure/core.rb +94 -0
- data/lib/simple_exposure/extensions/decorate.rb +11 -0
- data/lib/simple_exposure/extensions/paginate.rb +11 -0
- data/lib/simple_exposure/version.rb +3 -0
- data/simple_exposure.gemspec +24 -0
- data/spec/dummy/.gitignore +16 -0
- data/spec/dummy/Gemfile +40 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +1 -0
- data/spec/dummy/app/assets/stylesheets/application.css +1 -0
- data/spec/dummy/app/controllers/application_controller.rb +22 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/application/index.html.erb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +8 -0
- data/spec/dummy/bin/rake +8 -0
- data/spec/dummy/bin/spring +18 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +27 -0
- data/spec/dummy/config/boot.rb +4 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +82 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/lib/tasks/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/test/controllers/.keep +0 -0
- data/spec/dummy/test/fixtures/.keep +0 -0
- data/spec/dummy/test/helpers/.keep +0 -0
- data/spec/dummy/test/integration/.keep +0 -0
- data/spec/dummy/test/mailers/.keep +0 -0
- data/spec/dummy/test/models/.keep +0 -0
- data/spec/dummy/test/test_helper.rb +10 -0
- data/spec/dummy/vendor/assets/javascripts/.keep +0 -0
- data/spec/dummy/vendor/assets/stylesheets/.keep +0 -0
- data/spec/integration/simple_exposure_spec.rb +21 -0
- data/spec/simple_exposure/core_spec.rb +9 -0
- data/spec/spec_helper.rb +13 -0
- metadata +220 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1d56dca6e52b4aca0a6e0997d31b63a947a8be86
|
4
|
+
data.tar.gz: d702aab2f42718b45b9d66f2fe6cdbcfabdb7f96
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ce2a6f63cc872a0279129c09bd632b006c9440568da9ef0feacf2c53e778e0de977e2a947c9b9d4ce9b5356907002818656ca68ee8f437f12274e5802fe20685
|
7
|
+
data.tar.gz: 4190b607787e3c58ea15db46baa2ed31e0075efb221f85d29295174a5aec7cd9176466f681b8fba2cb645714be578197a81390e524a5d1bd435cfde51012ea9e
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
simple-exposure
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.1
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Michal Krejčí
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
# SimpleExposure
|
2
|
+
|
3
|
+
Simplify sharing state between Rails controllers and views and reduce noise in Rails controllers for those who are tired of writing the same code over and over again.
|
4
|
+
|
5
|
+
Based on the idea behind [view_accessor](https://github.com/invisiblefunnel/view_accessor) borrowing features I like from [decent_exposure](https://github.com/voxdolo/decent_exposure).
|
6
|
+
|
7
|
+
## Basic example
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
# controllers/projects_controller.rb
|
11
|
+
class ProjectsController < ApplicationController
|
12
|
+
expose(:projects) { Project.all }
|
13
|
+
end
|
14
|
+
|
15
|
+
# views/projects/index.html.slim
|
16
|
+
- projects.each do |project|
|
17
|
+
p = project.title
|
18
|
+
```
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
gem 'simple_exposure'
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
|
32
|
+
$ gem install simple_exposure
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
### Share controller's state to the views:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# controllers/projects_controller.rb
|
40
|
+
class ProjectsController < ApplicationController
|
41
|
+
expose :projects
|
42
|
+
|
43
|
+
def index
|
44
|
+
self.projects = Project.all
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# views/projects/index.html.slim
|
49
|
+
- projects.each do |project|
|
50
|
+
p = project.title
|
51
|
+
```
|
52
|
+
|
53
|
+
### Provide default values
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
class ProjectsController < ApplicationController
|
57
|
+
expose(:projects) { Project.all }
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
### Remove common noise with extensions
|
62
|
+
|
63
|
+
Before:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class ProjectsController < ApplicationController
|
67
|
+
|
68
|
+
def index
|
69
|
+
@projects = Project.page(params[:page])
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
After:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class ProjectsController < ApplicationController
|
79
|
+
expose :projects, extend: :paginate
|
80
|
+
|
81
|
+
def index
|
82
|
+
self.projects = Project.all
|
83
|
+
end
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
### Combine multiple extensions
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
class ProjectsController < ApplicationController
|
91
|
+
expose :projects, extend: %i(paginate decorate)
|
92
|
+
|
93
|
+
def index
|
94
|
+
self.projects = Project.all
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
### Combine it all together for a greater good
|
100
|
+
|
101
|
+
Before:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
class ProjectsController < ApplicationController
|
105
|
+
|
106
|
+
def index
|
107
|
+
@projects = current_user.projects.ordered
|
108
|
+
@completed_projects = @projects.completed.page(params[:page])
|
109
|
+
@current_user = current_user.decorate
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
After:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
class ProjectsController < ApplicationController
|
119
|
+
expose :current_user, extend: :decorate
|
120
|
+
|
121
|
+
expose :projects do
|
122
|
+
current_user.projects.ordered
|
123
|
+
end
|
124
|
+
|
125
|
+
expose :completed_projects, extend: :paginate do
|
126
|
+
projects.completed
|
127
|
+
end
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
## Extensions
|
132
|
+
|
133
|
+
### Built-in extensions
|
134
|
+
|
135
|
+
Library provides two built-in extensions:
|
136
|
+
|
137
|
+
+ paginate (Kaminari)
|
138
|
+
+ decorate (Draper)
|
139
|
+
|
140
|
+
### Writing your own extensions
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
module SimpleExposure
|
144
|
+
module Extensions
|
145
|
+
module MyExtension
|
146
|
+
extend self
|
147
|
+
|
148
|
+
def apply(value, controller)
|
149
|
+
# Do something with the value here
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class ProjectsController < ApplicationController
|
156
|
+
expose :projects, extend: :my_extension
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
|
161
|
+
## Contributing
|
162
|
+
|
163
|
+
1. Fork it
|
164
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
165
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
166
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
167
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module SimpleExposure
|
4
|
+
module BeforeRender
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
alias_method_chain :render, :before_render_action
|
9
|
+
define_callbacks :render
|
10
|
+
end
|
11
|
+
|
12
|
+
def render_with_before_render_action(*options, &block)
|
13
|
+
run_callbacks :render do
|
14
|
+
render_without_before_render_action(*options, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def append_before_render_action(*names, &block)
|
20
|
+
_insert_callbacks(names, block) do |name, options|
|
21
|
+
set_callback :render, :before, name, options
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def prepend_before_render_action(*names, &block)
|
26
|
+
_insert_callbacks(names, block) do |name, options|
|
27
|
+
set_callback :render, :before, name, options.merge(prepend: true)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def skip_before_render_action(*names, &block)
|
32
|
+
_insert_callbacks(names, block) do |name, options|
|
33
|
+
skip_callback :render, :before, name, options
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
alias_method :before_render, :append_before_render_action
|
38
|
+
alias_method :prepend_before_render, :prepend_before_render_action
|
39
|
+
alias_method :skip_before_render, :skip_before_render_action
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'simple_exposure/extensions/paginate'
|
2
|
+
require 'simple_exposure/extensions/decorate'
|
3
|
+
|
4
|
+
module SimpleExposure
|
5
|
+
module Core
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
UnknownExtension = Class.new(NameError)
|
9
|
+
|
10
|
+
included do
|
11
|
+
delegate :_exposure_extensions, to: :class
|
12
|
+
before_render :_apply_exposure_extensions
|
13
|
+
end
|
14
|
+
|
15
|
+
def _apply_exposure_extensions
|
16
|
+
_exposure_extensions.each do |attribute, extensions|
|
17
|
+
extensions.each do |extension|
|
18
|
+
_apply_exposure_extension(attribute, extension)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def _apply_exposure_extension(attribute, extension)
|
24
|
+
value = send(attribute)
|
25
|
+
extension = _exposure_extension_class(extension)
|
26
|
+
send :"#{attribute}=", extension.apply(value, self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def _exposure_extension_class(extension)
|
30
|
+
Extensions.const_get(extension.camelize)
|
31
|
+
rescue NameError
|
32
|
+
raise UnknownExtension, "Unknown extension: #{extension}"
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
|
37
|
+
def expose(*attributes, &block)
|
38
|
+
options = attributes.extract_options!
|
39
|
+
|
40
|
+
extensions = options.fetch(:extend, nil)
|
41
|
+
extensions = Array(extensions)
|
42
|
+
|
43
|
+
_define_exposure_accessors(attributes, &block)
|
44
|
+
_define_exposure_extensions(attributes, extensions)
|
45
|
+
end
|
46
|
+
|
47
|
+
def _exposure_extensions
|
48
|
+
@_exposure_extensions ||= HashWithIndifferentAccess.new([])
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def _define_exposure_accessors(attributes, &block)
|
54
|
+
_define_exposure_readers(attributes, &block)
|
55
|
+
_define_exposure_writers(attributes)
|
56
|
+
end
|
57
|
+
|
58
|
+
def _define_exposure_readers(attributes, &block)
|
59
|
+
attributes.each do |attribute|
|
60
|
+
_define_exposure_reader(attribute, &block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def _define_exposure_reader(attribute, &block)
|
65
|
+
if block
|
66
|
+
_define_exposure_reader_with_defaults(attribute, &block)
|
67
|
+
else
|
68
|
+
attr_reader(attribute)
|
69
|
+
end
|
70
|
+
|
71
|
+
helper_method(attribute)
|
72
|
+
hide_action(attribute)
|
73
|
+
end
|
74
|
+
|
75
|
+
def _define_exposure_reader_with_defaults(attribute, &block)
|
76
|
+
define_method(attribute) do
|
77
|
+
value = instance_variable_get("@#{attribute}")
|
78
|
+
return value if value
|
79
|
+
send :"#{attribute}=", instance_eval(&block)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def _define_exposure_writers(attributes)
|
84
|
+
attr_writer(*attributes)
|
85
|
+
end
|
86
|
+
|
87
|
+
def _define_exposure_extensions(attributes, extensions)
|
88
|
+
attributes.each do |attribute|
|
89
|
+
_exposure_extensions[attribute] += extensions
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'simple_exposure/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'simple_exposure'
|
8
|
+
spec.version = SimpleExposure::VERSION
|
9
|
+
spec.authors = ['Michal Krejčí']
|
10
|
+
spec.email = ['work@mikekreeki.com']
|
11
|
+
spec.description = 'Cleanup your Rails controllers'
|
12
|
+
spec.summary = 'Cleanup your Rails controllers'
|
13
|
+
spec.homepage = 'https://github.com/mikekreeki/simple_exposure'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'rails', ['>= 3.2.3', '< 5']
|
22
|
+
spec.add_development_dependency 'rspec-rails', '~> 3.0.0'
|
23
|
+
spec.add_development_dependency 'capybara'
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
# Ignore bundler config.
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore the default SQLite database.
|
11
|
+
/db/*.sqlite3
|
12
|
+
/db/*.sqlite3-journal
|
13
|
+
|
14
|
+
# Ignore all logfiles and tempfiles.
|
15
|
+
/log/*.log
|
16
|
+
/tmp
|