resource_this 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +200 -0
- data/Rakefile +25 -0
- data/generators/resource_this/USAGE +24 -0
- data/generators/resource_this/resource_this_generator.rb +72 -0
- data/generators/resource_this/templates/controller.rb +3 -0
- data/generators/resource_this/templates/functional_test.rb +59 -0
- data/generators/resource_this/templates/helper.rb +2 -0
- data/init.rb +1 -0
- data/lib/resource_this.rb +208 -0
- data/resource_this.gemspec +25 -0
- data/test/resource_this_nesting_test.rb +134 -0
- data/test/resource_this_sorting_test.rb +51 -0
- data/test/resource_this_test.rb +96 -0
- data/test/resource_this_url_prefix_test.rb +39 -0
- data/test/test_helper.rb +81 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3d1ca98d91b7f77a27fd92f24d30117981c181d9
|
4
|
+
data.tar.gz: cb660dc5474ca506caa49a54c381ac8b44816450
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b59545fc746ce5d24ebdfd6b26d3dd6ef950ab0715ee6bfc63ea85eadc0a3cbebd5c622094e98865b06883364594ad5d98f627800e5fa844d28119d9e2e38a9c
|
7
|
+
data.tar.gz: c6f07405700cb3f79e0dc2fe1e3842508120d3e21a3438c9ef9ab3f2fcc0d40ad845817650c47577ba151e237937c9dda664e232fb1080255e29003f6663387b
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# 1.0.0
|
2
|
+
|
3
|
+
* Gem-ification work
|
4
|
+
* Revert returning true { ... }, since it no longer exists in Rails 3.2
|
5
|
+
|
6
|
+
# Pre 1.0.0
|
7
|
+
|
8
|
+
* Added resource_this generator
|
9
|
+
* Add support for :path_prefix options on resource_this. Useful for admin namespaced controllers
|
10
|
+
* wrap some before_filters in returning true { ... } do
|
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2004-2007 Jesse Newland
|
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.md
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
resouce_this
|
2
|
+
===========
|
3
|
+
|
4
|
+
Not scaffolding. Resourcing. Creates extremely customizable resource controllers with one line of code.
|
5
|
+
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
class PostsController < ActionController::Base
|
9
|
+
resource_this
|
10
|
+
end
|
11
|
+
```
|
12
|
+
|
13
|
+
...will generate the following code:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class PostsController < ActionController::Base
|
17
|
+
before_filter :load_post, :only => [ :show, :edit, :update, :destroy ]
|
18
|
+
before_filter :load_posts, :only => [ :index ]
|
19
|
+
before_filter :new_post, :only => [ :new ]
|
20
|
+
before_filter :create_post, :only => [ :create ]
|
21
|
+
before_filter :update_post, :only => [ :update ]
|
22
|
+
before_filter :destroy_post, :only => [ :destroy ]
|
23
|
+
|
24
|
+
protected
|
25
|
+
def load_post
|
26
|
+
@post = Post.find(params[:id])
|
27
|
+
end
|
28
|
+
|
29
|
+
def new_post
|
30
|
+
@post = Post.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_post
|
34
|
+
@post = Post.new(params[:post])
|
35
|
+
@created = @post.save
|
36
|
+
return true
|
37
|
+
end
|
38
|
+
|
39
|
+
def update_post
|
40
|
+
@updated = @post.update_attributes(params[:post])
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
|
44
|
+
def destroy_post
|
45
|
+
@post = @post.destroy
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_posts
|
49
|
+
@posts = Post.find(:all)
|
50
|
+
end
|
51
|
+
|
52
|
+
public
|
53
|
+
def index
|
54
|
+
respond_to do |format|
|
55
|
+
format.html
|
56
|
+
format.xml { render :xml => @posts }
|
57
|
+
format.js
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def show
|
62
|
+
respond_to do |format|
|
63
|
+
format.html
|
64
|
+
format.xml { render :xml => @post }
|
65
|
+
format.js
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def new
|
70
|
+
respond_to do |format|
|
71
|
+
format.html { render :action => :edit }
|
72
|
+
format.xml { render :xml => @post }
|
73
|
+
format.js
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def create
|
78
|
+
respond_to do |format|
|
79
|
+
if @created
|
80
|
+
flash[:notice] = 'Post was successfully created.'
|
81
|
+
format.html { redirect_to @post }
|
82
|
+
format.xml { render :xml => @post, :status => :created, :location => @post }
|
83
|
+
format.js
|
84
|
+
else
|
85
|
+
format.html { render :action => :new }
|
86
|
+
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
|
87
|
+
format.js
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def edit
|
93
|
+
respond_to do |format|
|
94
|
+
format.html
|
95
|
+
format.js
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def update
|
100
|
+
respond_to do |format|
|
101
|
+
if @updated
|
102
|
+
flash[:notice] = 'Post was successfully updated.'
|
103
|
+
format.html { redirect_to @post }
|
104
|
+
format.xml { head :ok }
|
105
|
+
format.js
|
106
|
+
else
|
107
|
+
format.html { render :action => :edit }
|
108
|
+
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
|
109
|
+
format.js
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def destroy
|
115
|
+
respond_to do |format|
|
116
|
+
format.html { redirect_to :action => posts_url }
|
117
|
+
format.xml { head :ok }
|
118
|
+
format.js
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
Nested Resources
|
125
|
+
===========
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
class CommentsController < ActionController::Base
|
129
|
+
resource_this :nested => [:posts]
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
This generates a very similar controller to the one above with adjusted redirects and one additional before_filter / loader method pair to grab the parent resource. In this case:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
before_filter :load_post
|
137
|
+
|
138
|
+
def load_post
|
139
|
+
@post = Post.find(params[:post_id])
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
143
|
+
Sorting, etc
|
144
|
+
===========
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
class CommentsController < ActionController::Base
|
148
|
+
resource_this :finder_options => {:order => 'created_on'}
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
...or, for lazily evaluated sorting options:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
class CommentsController < ActionController::Base
|
156
|
+
resource_this :finder_options => Proc.new { finder_options }
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
def finder_options
|
161
|
+
order = case params[:sort]
|
162
|
+
when 'date_reverse' then 'created_on desc'
|
163
|
+
else 'created_on'
|
164
|
+
end
|
165
|
+
{:order => order, :limit => params[:limit] || 10 }
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
will_paginate
|
172
|
+
===========
|
173
|
+
|
174
|
+
will_paginate support is baked right in:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
class CommentsController < ActionController::Base
|
178
|
+
resource_this :will_paginate => true
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
182
|
+
This works with the :finder_options option as well
|
183
|
+
|
184
|
+
Opinionated Software
|
185
|
+
===========
|
186
|
+
|
187
|
+
The separation of logic - DB operations in before_filters, rendering in the standard resource controller methods - makes this approach ridiculously easy to customize. Need to load an additional object for the :show action? Slap another before_filter on it. Need to change the path that the :update action redirects to? Override the :update action with your new rendering behavior.
|
188
|
+
|
189
|
+
Generator
|
190
|
+
===========
|
191
|
+
|
192
|
+
A resource_this generator is included - does the same thing as the 'resource' generator but adds 'resource_this' to the generated controller.
|
193
|
+
|
194
|
+
Questions? Comments? Flames? Patches?
|
195
|
+
===========
|
196
|
+
jnewland@gmail.com
|
197
|
+
|
198
|
+
Copyright
|
199
|
+
===========
|
200
|
+
Copyright (c) 2007 Jesse Newland, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "rake"
|
5
|
+
require "rake/testtask"
|
6
|
+
|
7
|
+
desc "Default: run unit tests."
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
desc "Test the resource_this plugin."
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
12
|
+
t.libs << "lib"
|
13
|
+
t.pattern = "test/**/*_test.rb"
|
14
|
+
t.verbose = true
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
gem 'rubygems-tasks', '~> 0.2'
|
19
|
+
require 'rubygems/tasks'
|
20
|
+
|
21
|
+
Gem::Tasks.new
|
22
|
+
rescue LoadError => e
|
23
|
+
warn e.message
|
24
|
+
warn "Run `gem install rubygems-tasks` to install Gem::Tasks."
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Description:
|
2
|
+
Stubs out a new resource including an empty model and controller suitable
|
3
|
+
for a restful, resource-oriented application. Pass the singular model name,
|
4
|
+
either CamelCased or under_scored, as the first argument, and an optional
|
5
|
+
list of attribute pairs.
|
6
|
+
|
7
|
+
Attribute pairs are column_name:sql_type arguments specifying the
|
8
|
+
model's attributes. Timestamps are added by default, so you don't have to
|
9
|
+
specify them by hand as 'created_at:datetime updated_at:datetime'.
|
10
|
+
|
11
|
+
You don't have to think up every attribute up front, but it helps to
|
12
|
+
sketch out a few so you can start working with the resource immediately.
|
13
|
+
|
14
|
+
This creates a model, controller, tests and fixtures for both, and the
|
15
|
+
corresponding map.resources declaration in config/routes.rb
|
16
|
+
|
17
|
+
This generates a DRY resource controller using resource_this:
|
18
|
+
|
19
|
+
http://jnewland.com/svn/public/ruby/rails/plugins/resource_this/README
|
20
|
+
|
21
|
+
Examples:
|
22
|
+
`./script/generate resource_this post` # no attributes
|
23
|
+
`./script/generate resource_this post title:string body:text published:boolean`
|
24
|
+
`./script/generate resource_this purchase order_id:integer amount:decimal`
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class ResourceThisGenerator < Rails::Generator::NamedBase
|
2
|
+
default_options :skip_migration => false
|
3
|
+
|
4
|
+
attr_reader :controller_name,
|
5
|
+
:controller_class_path,
|
6
|
+
:controller_file_path,
|
7
|
+
:controller_class_nesting,
|
8
|
+
:controller_class_nesting_depth,
|
9
|
+
:controller_class_name,
|
10
|
+
:controller_singular_name,
|
11
|
+
:controller_plural_name
|
12
|
+
alias_method :controller_file_name, :controller_singular_name
|
13
|
+
alias_method :controller_table_name, :controller_plural_name
|
14
|
+
|
15
|
+
def initialize(runtime_args, runtime_options = {})
|
16
|
+
super
|
17
|
+
|
18
|
+
@controller_name = @name.pluralize
|
19
|
+
|
20
|
+
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
|
21
|
+
@controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
|
22
|
+
|
23
|
+
if @controller_class_nesting.empty?
|
24
|
+
@controller_class_name = @controller_class_name_without_nesting
|
25
|
+
else
|
26
|
+
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def manifest
|
31
|
+
record do |m|
|
32
|
+
# Check for class naming collisions.
|
33
|
+
m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
|
34
|
+
m.class_collisions(class_path, "#{class_name}")
|
35
|
+
|
36
|
+
# Controller, helper, views, and test directories.
|
37
|
+
m.directory(File.join('app/models', class_path))
|
38
|
+
m.directory(File.join('app/controllers', controller_class_path))
|
39
|
+
m.directory(File.join('app/helpers', controller_class_path))
|
40
|
+
m.directory(File.join('app/views', controller_class_path, controller_file_name))
|
41
|
+
m.directory(File.join('test/functional', controller_class_path))
|
42
|
+
m.directory(File.join('test/unit', class_path))
|
43
|
+
|
44
|
+
m.dependency 'model', [singular_name] + @args, :collision => :skip
|
45
|
+
|
46
|
+
m.template(
|
47
|
+
'controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
|
48
|
+
)
|
49
|
+
|
50
|
+
m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
|
51
|
+
m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
|
52
|
+
|
53
|
+
m.route_resources controller_file_name
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
def banner
|
59
|
+
"Usage: #{$0} resource_this ModelName [field:type, field:type]"
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_options!(opt)
|
63
|
+
opt.separator ''
|
64
|
+
opt.separator 'Options:'
|
65
|
+
opt.on("--skip-migration",
|
66
|
+
"Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
|
67
|
+
end
|
68
|
+
|
69
|
+
def model_name
|
70
|
+
class_name.demodulize
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '<%= '/..' * controller_class_nesting_depth %>/../test_helper'
|
2
|
+
require '<%= controller_file_path %>_controller'
|
3
|
+
|
4
|
+
# Re-raise errors caught by the controller.
|
5
|
+
class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
|
6
|
+
|
7
|
+
class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
|
8
|
+
fixtures :<%= table_name %>
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@controller = <%= controller_class_name %>Controller.new
|
12
|
+
@request = ActionController::TestRequest.new
|
13
|
+
@response = ActionController::TestResponse.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_get_index
|
17
|
+
get :index
|
18
|
+
assert_response :success
|
19
|
+
assert assigns(:<%= table_name %>)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_get_new
|
23
|
+
@request.accept = 'application/xml'
|
24
|
+
get :new
|
25
|
+
assert_response :success
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_create_<%= file_name %>
|
29
|
+
assert_difference('<%= class_name %>.count') do
|
30
|
+
post :create, :<%= file_name %> => { }
|
31
|
+
end
|
32
|
+
|
33
|
+
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_show_<%= file_name %>
|
37
|
+
@request.accept = 'application/xml'
|
38
|
+
get :show, :id => 1
|
39
|
+
assert_response :success
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_should_get_edit
|
43
|
+
#TODO: replace this with a real test once views are in place
|
44
|
+
assert true
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_should_update_<%= file_name %>
|
48
|
+
put :update, :id => 1, :<%= file_name %> => { }
|
49
|
+
assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_should_destroy_<%= file_name %>
|
53
|
+
assert_difference('<%= class_name %>.count', -1) do
|
54
|
+
delete :destroy, :id => 1
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_redirected_to <%= table_name %>_path
|
58
|
+
end
|
59
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ActionController::Base.send :include, ResourceThis
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module ResourceThis # :nodoc:
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def resource_this(options = {})
|
8
|
+
options.assert_valid_keys(:class_name, :will_paginate, :finder_options, :nested, :path_prefix)
|
9
|
+
|
10
|
+
singular_name = controller_name.singularize
|
11
|
+
singular_name = options[:class_name].downcase.singularize unless options[:class_name].nil?
|
12
|
+
class_name = options[:class_name] || singular_name.camelize
|
13
|
+
plural_name = singular_name.pluralize
|
14
|
+
will_paginate_index = options[:will_paginate] || false
|
15
|
+
resource_url = "#{singular_name}_url(@#{singular_name})"
|
16
|
+
collection_url = "#{plural_name}_url"
|
17
|
+
resource_url = options[:path_prefix] + resource_url unless options[:path_prefix].nil?
|
18
|
+
collection_url = options[:path_prefix] + collection_url unless options[:path_prefix].nil?
|
19
|
+
|
20
|
+
class_attribute :resource_this_finder_options
|
21
|
+
self.resource_this_finder_options = options[:finder_options] || {}
|
22
|
+
|
23
|
+
unless options[:nested].nil?
|
24
|
+
nested = options[:nested].to_s.singularize
|
25
|
+
nested_class = nested.camelize
|
26
|
+
nested_resource_url = "#{nested}_#{singular_name}_url(" + [nested, singular_name].map { |route| "@#{route}"}.join(', ') + ')'
|
27
|
+
nested_collection_url = "#{nested}_#{plural_name}_url(@#{nested})"
|
28
|
+
nested_resource_url = options[:path_prefix] + nested_resource_url unless options[:path_prefix].nil?
|
29
|
+
nested_collection_url = options[:path_prefix] + nested_collection_url unless options[:path_prefix].nil?
|
30
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
31
|
+
before_filter :load_#{nested}
|
32
|
+
end_eval
|
33
|
+
end
|
34
|
+
|
35
|
+
#standard before_filters
|
36
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
37
|
+
before_filter :load_#{singular_name}, :only => [ :show, :edit, :update, :destroy ]
|
38
|
+
before_filter :load_#{plural_name}, :only => [ :index ]
|
39
|
+
before_filter :new_#{singular_name}, :only => [ :new ]
|
40
|
+
before_filter :create_#{singular_name}, :only => [ :create ]
|
41
|
+
before_filter :update_#{singular_name}, :only => [ :update ]
|
42
|
+
before_filter :destroy_#{singular_name}, :only => [ :destroy ]
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def finder_options
|
47
|
+
resource_this_finder_options.class == Proc ? resource_this_finder_options.call : {}
|
48
|
+
end
|
49
|
+
|
50
|
+
end_eval
|
51
|
+
|
52
|
+
if options[:nested].nil?
|
53
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
54
|
+
def finder_base
|
55
|
+
#{class_name}
|
56
|
+
end
|
57
|
+
|
58
|
+
def collection
|
59
|
+
#{class_name}.find(:all, finder_options)
|
60
|
+
end
|
61
|
+
|
62
|
+
def collection_url
|
63
|
+
#{collection_url}
|
64
|
+
end
|
65
|
+
|
66
|
+
def resource_url
|
67
|
+
#{resource_url}
|
68
|
+
end
|
69
|
+
end_eval
|
70
|
+
else
|
71
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
72
|
+
def load_#{nested}
|
73
|
+
@#{nested} = #{nested_class}.find(params[:#{nested}_id]) rescue nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def finder_base
|
77
|
+
@#{nested}.nil? ? #{class_name} : @#{nested}.#{plural_name}
|
78
|
+
end
|
79
|
+
|
80
|
+
def collection
|
81
|
+
@#{nested}.nil? ? #{class_name}.find(:all, finder_options) : @#{nested}.#{plural_name}.find(:all, finder_options)
|
82
|
+
end
|
83
|
+
|
84
|
+
def collection_url
|
85
|
+
@#{nested}.nil? ? #{collection_url} : #{nested_collection_url}
|
86
|
+
end
|
87
|
+
|
88
|
+
def resource_url
|
89
|
+
@#{nested}.nil? ? #{resource_url} : #{nested_resource_url}
|
90
|
+
end
|
91
|
+
end_eval
|
92
|
+
end
|
93
|
+
|
94
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
95
|
+
def load_#{singular_name}
|
96
|
+
@#{singular_name} = finder_base.find(params[:id])
|
97
|
+
end
|
98
|
+
|
99
|
+
def new_#{singular_name}
|
100
|
+
@#{singular_name} = finder_base.new
|
101
|
+
end
|
102
|
+
|
103
|
+
def create_#{singular_name}
|
104
|
+
@#{singular_name} = finder_base.new(params[:#{singular_name}])
|
105
|
+
@created = @#{singular_name}.save
|
106
|
+
return true
|
107
|
+
end
|
108
|
+
|
109
|
+
def update_#{singular_name}
|
110
|
+
@updated = @#{singular_name}.update_attributes(params[:#{singular_name}])
|
111
|
+
return true
|
112
|
+
end
|
113
|
+
|
114
|
+
def destroy_#{singular_name}
|
115
|
+
@#{singular_name} = @#{singular_name}.destroy
|
116
|
+
end
|
117
|
+
end_eval
|
118
|
+
|
119
|
+
if will_paginate_index
|
120
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
121
|
+
def load_#{plural_name}
|
122
|
+
@#{plural_name} = finder_base.paginate(finder_options.merge(:page => params[:page]))
|
123
|
+
end
|
124
|
+
end_eval
|
125
|
+
else
|
126
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
127
|
+
def load_#{plural_name}
|
128
|
+
@#{plural_name} = collection
|
129
|
+
end
|
130
|
+
end_eval
|
131
|
+
end
|
132
|
+
|
133
|
+
module_eval <<-"end_eval", __FILE__, __LINE__
|
134
|
+
public
|
135
|
+
def index
|
136
|
+
respond_to do |format|
|
137
|
+
format.html
|
138
|
+
format.xml { render :xml => @#{plural_name} }
|
139
|
+
format.js
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def show
|
144
|
+
respond_to do |format|
|
145
|
+
format.html
|
146
|
+
format.xml { render :xml => @#{singular_name} }
|
147
|
+
format.js
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def new
|
152
|
+
respond_to do |format|
|
153
|
+
format.html { render :action => :edit }
|
154
|
+
format.xml { render :xml => @#{singular_name} }
|
155
|
+
format.js
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def create
|
160
|
+
respond_to do |format|
|
161
|
+
if @created
|
162
|
+
flash[:notice] = '#{class_name} was successfully created.'
|
163
|
+
format.html { redirect_to(resource_url) }
|
164
|
+
format.xml { render :xml => @#{singular_name}, :status => :created, :location => resource_url }
|
165
|
+
format.js
|
166
|
+
else
|
167
|
+
format.html { render :action => :edit }
|
168
|
+
format.xml { render :xml => @#{singular_name}.errors, :status => :unprocessable_entity }
|
169
|
+
format.js
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def edit
|
175
|
+
respond_to do |format|
|
176
|
+
format.html
|
177
|
+
format.js
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def update
|
182
|
+
respond_to do |format|
|
183
|
+
if @updated
|
184
|
+
flash[:notice] = '#{class_name} was successfully updated.'
|
185
|
+
format.html { redirect_to(resource_url) }
|
186
|
+
format.xml { head :ok }
|
187
|
+
format.js
|
188
|
+
else
|
189
|
+
format.html { render :action => :edit }
|
190
|
+
format.xml { render :xml => @#{singular_name}.errors, :status => :unprocessable_entity }
|
191
|
+
format.js
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def destroy
|
197
|
+
respond_to do |format|
|
198
|
+
format.html { redirect_to(collection_url) }
|
199
|
+
format.xml { head :ok }
|
200
|
+
format.js
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end_eval
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
ActionController::Base.send :include, ResourceThis
|
@@ -0,0 +1,25 @@
|
|
1
|
+
spec = Gem::Specification.new do |s|
|
2
|
+
s.name = 'resource_this'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.summary = "Not scaffolding. Resourcing. Creates extremely customizable resource controllers with one line of code."
|
5
|
+
s.description = %{Not scaffolding. Resourcing. Creates extremely customizable resource controllers with one line of code.
|
6
|
+
|
7
|
+
class PostsController < ActionController::Base
|
8
|
+
resource_this
|
9
|
+
end}
|
10
|
+
s.authors = ["Hsiu-Fan Wang", "Jesse Newland"]
|
11
|
+
s.email = "hfwang@porkbuns.net"
|
12
|
+
s.homepage = "https://github.com/hfwang/resource_this"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split($/)
|
15
|
+
s.executables = s.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
16
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
|
20
|
+
s.add_runtime_dependency "rails", "~> 3.2"
|
21
|
+
|
22
|
+
s.add_development_dependency "rspec", "~> 2.4"
|
23
|
+
s.add_development_dependency "rubygems-tasks", "~> 0.2"
|
24
|
+
s.add_development_dependency "yard", "~> 0.8"
|
25
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ResourceThisNestingTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@controller = CommentsController.new
|
6
|
+
@request = ActionController::TestRequest.new
|
7
|
+
@request.accept = 'application/xml'
|
8
|
+
@response = ActionController::TestResponse.new
|
9
|
+
@first = Post.create(:title => "test", :body => "test")
|
10
|
+
@second = Post.create(:title => "test2", :body => "test2")
|
11
|
+
@first_comment = Comment.create(:post => @first, :body => "test")
|
12
|
+
@second_comment = Comment.create(:post => @second, :body => "test")
|
13
|
+
ActionController::Routing::Routes.draw do |map|
|
14
|
+
map.resources :posts do |post|
|
15
|
+
post.resources :comments
|
16
|
+
end
|
17
|
+
map.resources :comments
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
Post.find(:all).each { |post| post.destroy }
|
23
|
+
Comment.find(:all).each { |comment| comment.destroy }
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_get_index
|
27
|
+
get :index, :post_id => @first.id
|
28
|
+
assert_response :success
|
29
|
+
assert_equal @first.comments, assigns(:comments)
|
30
|
+
assert_equal @first, assigns(:post)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_get_index_without_post
|
34
|
+
get :index
|
35
|
+
assert_response :success
|
36
|
+
assert assigns(:post).nil?
|
37
|
+
assert_equal Comment.find(:all), assigns(:comments)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_get_new
|
41
|
+
get :new, :post_id => @first.id
|
42
|
+
assert_response :success
|
43
|
+
assert assigns(:comment)
|
44
|
+
assert assigns(:post)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_should_get_new_without_post
|
48
|
+
get :new
|
49
|
+
assert_response :success
|
50
|
+
assert assigns(:post).nil?
|
51
|
+
assert assigns(:comment)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_should_create_comment
|
55
|
+
assert_difference('Comment.count') do
|
56
|
+
post :create, :post_id => @first.id, :comment => { :body => "test" }
|
57
|
+
end
|
58
|
+
assert_response :created
|
59
|
+
assert assigns(:comment)
|
60
|
+
assert assigns(:post)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_create_comment_html
|
64
|
+
@request.accept = 'text/html'
|
65
|
+
assert_difference('Comment.count') do
|
66
|
+
post :create, :post_id => @first.id, :comment => { :body => "test" }
|
67
|
+
end
|
68
|
+
assert_redirected_to "posts/#{assigns(:post).id}/comments/#{assigns(:comment).id}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_should_create_comment_html_without_post
|
72
|
+
@request.accept = 'text/html'
|
73
|
+
assert_difference('Comment.count') do
|
74
|
+
post :create, :comment => { :body => "test" }
|
75
|
+
end
|
76
|
+
assert_redirected_to "/comments/#{assigns(:comment).id}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_should_show_comment
|
80
|
+
get :show, :post_id => @first.id, :id => @first_comment.id
|
81
|
+
assert_response :success
|
82
|
+
assert assigns(:comment)
|
83
|
+
assert assigns(:post)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_should_show_comment_without_post
|
87
|
+
get :show, :id => @first_comment.id
|
88
|
+
assert_response :success
|
89
|
+
assert_equal Comment.find(@first_comment.id), assigns(:comment)
|
90
|
+
assert assigns(:post).nil?
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_update_comment
|
94
|
+
put :update, :post_id => @first.id, :id => @first_comment.id, :comment => { :post => @first, :body => "test" }
|
95
|
+
assert_response :success
|
96
|
+
assert assigns(:comment)
|
97
|
+
assert assigns(:post)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_should_update_comment_html
|
101
|
+
@request.accept = 'text/html'
|
102
|
+
put :update, :post_id => @first.id, :id => @first_comment.id, :comment => { :post => @first, :body => "test" }
|
103
|
+
assert_redirected_to "posts/#{assigns(:post).id}/comments/#{assigns(:comment).id}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_should_update_comment_html_without_post
|
107
|
+
@request.accept = 'text/html'
|
108
|
+
put :update, :id => @first_comment.id, :comment => { :post => @first, :body => "test2" }
|
109
|
+
assert_redirected_to "/comments/#{assigns(:comment).id}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_should_destroy_comment
|
113
|
+
assert_difference('Comment.count', -1) do
|
114
|
+
delete :destroy, :post_id => @first.id, :id => @first_comment.id
|
115
|
+
end
|
116
|
+
assert_response :success
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_should_destroy_html
|
120
|
+
@request.accept = 'text/html'
|
121
|
+
assert_difference('Comment.count', -1) do
|
122
|
+
delete :destroy, :post_id => @first.id, :id => @first_comment.id
|
123
|
+
end
|
124
|
+
assert_redirected_to "posts/#{assigns(:post).id}/comments"
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_should_destroy_html_without_post
|
128
|
+
@request.accept = 'text/html'
|
129
|
+
assert_difference('Comment.count', -1) do
|
130
|
+
delete :destroy, :id => @first_comment.id
|
131
|
+
end
|
132
|
+
assert_redirected_to "/comments"
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ResourceThisSortingTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@controller = WidgetsController.new
|
6
|
+
@request = ActionController::TestRequest.new
|
7
|
+
@request.accept = 'application/xml'
|
8
|
+
@response = ActionController::TestResponse.new
|
9
|
+
@a = Widget.create(:title => "aaa", :body => "zzz")
|
10
|
+
@z = Widget.create(:title => "zzz", :body => "aaa")
|
11
|
+
100.times do
|
12
|
+
Widget.create(:title => "foo", :body => "bar")
|
13
|
+
end
|
14
|
+
ActionController::Routing::Routes.draw do |map|
|
15
|
+
map.resources :widgets
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
Widget.find(:all).each { |w| w.destroy }
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_should_get_index
|
24
|
+
get :index
|
25
|
+
assert_response :success
|
26
|
+
assert assigns(:widgets)
|
27
|
+
assert_equal @a, assigns(:widgets).first
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_get_index_sorted_with_inline_proc
|
31
|
+
@controller.resource_this_finder_options = Proc.new { { :order => 'body' } }
|
32
|
+
get :index
|
33
|
+
assert_response :success
|
34
|
+
assert assigns(:widgets)
|
35
|
+
assert_equal @z, assigns(:widgets).first
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_get_index_sorted_with_proc
|
39
|
+
@controller.resource_this_finder_options = Proc.new { finder_options }
|
40
|
+
get :index
|
41
|
+
assert_response :success
|
42
|
+
assert assigns(:widgets)
|
43
|
+
assert_equal 2, assigns(:widgets).size
|
44
|
+
assert_equal @z, assigns(:widgets).first
|
45
|
+
end
|
46
|
+
|
47
|
+
def finder_options
|
48
|
+
{:order => 'body', :limit => 2}
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ResourceThisTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@controller = PostsController.new
|
6
|
+
@request = ActionController::TestRequest.new
|
7
|
+
@request.accept = 'application/xml'
|
8
|
+
@response = ActionController::TestResponse.new
|
9
|
+
@first = Post.create(:title => "test", :body => "test")
|
10
|
+
ActionController::Routing::Routes.draw do |map|
|
11
|
+
map.resources :posts
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
Post.find(:all).each { |post| post.destroy }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_get_index
|
20
|
+
get :index
|
21
|
+
assert_response :success
|
22
|
+
assert assigns(:posts)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_should_get_new
|
26
|
+
get :new
|
27
|
+
assert_response :success
|
28
|
+
assert assigns(:post)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_create_post
|
32
|
+
assert_difference('Post.count') do
|
33
|
+
post :create, :post => { :title => "test", :body => "test" }
|
34
|
+
end
|
35
|
+
assert_response :created
|
36
|
+
assert assigns(:post)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_handle_invalid_post_on_create
|
40
|
+
assert_no_difference('Post.count') do
|
41
|
+
post :create, :post => { :title => "1" }
|
42
|
+
end
|
43
|
+
assert_response :unprocessable_entity
|
44
|
+
assert assigns(:post).errors
|
45
|
+
assert !assigns(:created)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def test_should_create_post_html
|
50
|
+
@request.accept = 'text/html'
|
51
|
+
assert_difference('Post.count') do
|
52
|
+
post :create, :post => { :title => "test", :body => "test" }
|
53
|
+
end
|
54
|
+
assert_redirected_to "/posts/#{assigns(:post).id}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_should_show_post
|
58
|
+
get :show, :id => @first.id
|
59
|
+
assert_response :success
|
60
|
+
assert assigns(:post)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_update_post
|
64
|
+
put :update, :id => @first.id, :post => { :title => "test", :body => "test" }
|
65
|
+
assert_response :success
|
66
|
+
assert assigns(:post)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_should_handle_invalid_post_on_update
|
70
|
+
post :update, :id => @first.id, :post => { :title => "1" }
|
71
|
+
assert_response :unprocessable_entity
|
72
|
+
assert assigns(:post).errors
|
73
|
+
assert !assigns(:updated)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_should_update_post_html
|
77
|
+
@request.accept = 'text/html'
|
78
|
+
put :update, :id => @first.id, :post => { :title => "test", :body => "test" }
|
79
|
+
assert_redirected_to "/posts/#{assigns(:post).id}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_should_destroy_post
|
83
|
+
assert_difference('Post.count', -1) do
|
84
|
+
delete :destroy, :id => @first.id
|
85
|
+
end
|
86
|
+
assert_response :success
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_destroy_post_html
|
90
|
+
@request.accept = 'text/html'
|
91
|
+
assert_difference('Post.count', -1) do
|
92
|
+
delete :destroy, :id => @first.id
|
93
|
+
end
|
94
|
+
assert_redirected_to "/posts"
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class ResourceThisUrlPrefixTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@controller = Admin::PostsController.new
|
6
|
+
@request = ActionController::TestRequest.new
|
7
|
+
@response = ActionController::TestResponse.new
|
8
|
+
@first = Post.create(:title => "test", :body => "test")
|
9
|
+
ActionController::Routing::Routes.draw do |map|
|
10
|
+
map.resources :posts
|
11
|
+
map.with_options :path_prefix => 'admin', :name_prefix => 'admin_' do |map|
|
12
|
+
map.resources :posts, :controller => 'admin/posts'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
Post.find(:all).each { |post| post.destroy }
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_create_post
|
22
|
+
assert_difference('Post.count') do
|
23
|
+
post :create, :post => { :title => "test", :body => "test" }
|
24
|
+
end
|
25
|
+
assert_redirected_to "/admin/posts/#{assigns(:post).id}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_update_post
|
29
|
+
put :update, :id => @first.id, :post => { :title => "test", :body => "test" }
|
30
|
+
assert_redirected_to "/admin/posts/#{assigns(:post).id}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_destroy_post
|
34
|
+
assert_difference('Post.count', -1) do
|
35
|
+
delete :destroy, :id => @first.id
|
36
|
+
end
|
37
|
+
assert_redirected_to "/admin/posts"
|
38
|
+
end
|
39
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
$LOAD_PATH.unshift 'lib/'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'multi_rails_init'
|
5
|
+
require 'action_controller/test_process'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'resource_this'
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'redgreen'
|
11
|
+
rescue LoadError
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
RAILS_ROOT = '.' unless defined? RAILS_ROOT
|
16
|
+
RAILS_ENV = 'test' unless defined? RAILS_ENV
|
17
|
+
|
18
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT) if ENV['DEBUG']
|
19
|
+
ActionController::Base.logger = Logger.new(STDOUT) if ENV['DEBUG']
|
20
|
+
|
21
|
+
ActionController::Base.send :include, ResourceThis
|
22
|
+
|
23
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
|
24
|
+
|
25
|
+
ActiveRecord::Schema.define(:version => 1) do
|
26
|
+
create_table :posts do |t|
|
27
|
+
t.column :title, :string
|
28
|
+
t.column :body, :text
|
29
|
+
t.column :created_at, :datetime
|
30
|
+
t.column :updated_at, :datetime
|
31
|
+
end
|
32
|
+
create_table :comments do |t|
|
33
|
+
t.column :body, :text
|
34
|
+
t.column :post_id, :integer
|
35
|
+
t.column :created_at, :datetime
|
36
|
+
t.column :updated_at, :datetime
|
37
|
+
end
|
38
|
+
create_table :widgets do |t|
|
39
|
+
t.column :title, :string
|
40
|
+
t.column :body, :text
|
41
|
+
t.column :created_at, :datetime
|
42
|
+
t.column :updated_at, :datetime
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Post < ActiveRecord::Base
|
47
|
+
has_many :comments
|
48
|
+
validates_length_of :title, :within => 2..100
|
49
|
+
def validate
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Comment < ActiveRecord::Base
|
54
|
+
belongs_to :post
|
55
|
+
def validate
|
56
|
+
end
|
57
|
+
validates_associated :post
|
58
|
+
end
|
59
|
+
|
60
|
+
class Widget < ActiveRecord::Base
|
61
|
+
def validate
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class PostsController < ActionController::Base
|
66
|
+
resource_this
|
67
|
+
end
|
68
|
+
|
69
|
+
class WidgetsController < ActionController::Base
|
70
|
+
resource_this
|
71
|
+
end
|
72
|
+
|
73
|
+
module Admin; end
|
74
|
+
|
75
|
+
class Admin::PostsController < ActionController::Base
|
76
|
+
resource_this :path_prefix => "admin_"
|
77
|
+
end
|
78
|
+
|
79
|
+
class CommentsController < ActionController::Base
|
80
|
+
resource_this :nested => [:posts]
|
81
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resource_this
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hsiu-Fan Wang
|
8
|
+
- Jesse Newland
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-08-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.2'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '3.2'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.4'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.4'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rubygems-tasks
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.2'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0.2'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: yard
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.8'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.8'
|
70
|
+
description: |-
|
71
|
+
Not scaffolding. Resourcing. Creates extremely customizable resource controllers with one line of code.
|
72
|
+
|
73
|
+
class PostsController < ActionController::Base
|
74
|
+
resource_this
|
75
|
+
end
|
76
|
+
email: hfwang@porkbuns.net
|
77
|
+
executables: []
|
78
|
+
extensions: []
|
79
|
+
extra_rdoc_files: []
|
80
|
+
files:
|
81
|
+
- ".gitignore"
|
82
|
+
- CHANGELOG.md
|
83
|
+
- Gemfile
|
84
|
+
- MIT-LICENSE
|
85
|
+
- README.md
|
86
|
+
- Rakefile
|
87
|
+
- generators/resource_this/USAGE
|
88
|
+
- generators/resource_this/resource_this_generator.rb
|
89
|
+
- generators/resource_this/templates/controller.rb
|
90
|
+
- generators/resource_this/templates/functional_test.rb
|
91
|
+
- generators/resource_this/templates/helper.rb
|
92
|
+
- init.rb
|
93
|
+
- lib/resource_this.rb
|
94
|
+
- resource_this.gemspec
|
95
|
+
- test/resource_this_nesting_test.rb
|
96
|
+
- test/resource_this_sorting_test.rb
|
97
|
+
- test/resource_this_test.rb
|
98
|
+
- test/resource_this_url_prefix_test.rb
|
99
|
+
- test/test_helper.rb
|
100
|
+
homepage: https://github.com/hfwang/resource_this
|
101
|
+
licenses: []
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 2.2.2
|
120
|
+
signing_key:
|
121
|
+
specification_version: 4
|
122
|
+
summary: Not scaffolding. Resourcing. Creates extremely customizable resource controllers
|
123
|
+
with one line of code.
|
124
|
+
test_files:
|
125
|
+
- test/resource_this_nesting_test.rb
|
126
|
+
- test/resource_this_sorting_test.rb
|
127
|
+
- test/resource_this_test.rb
|
128
|
+
- test/resource_this_url_prefix_test.rb
|
129
|
+
- test/test_helper.rb
|