model_loader 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +29 -0
- data/init.rb +3 -0
- data/lib/model_loader/railtie.rb +19 -0
- data/lib/model_loader/version.rb +1 -1
- data/lib/model_loader.rb +20 -14
- data/rails/init.rb +0 -0
- data/test/app/models/post.rb +2 -0
- data/test/app/models/user.rb +2 -0
- data/test/db/database.yml +3 -0
- data/test/db/test.sqlite3 +0 -0
- data/test/model_loader_test.rb +82 -0
- data/test/public/404.html +26 -0
- data/test/test_helper.rb +52 -0
- metadata +24 -6
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Adam Vaughan
|
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
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
== Model Loader
|
2
|
+
|
3
|
+
ModelLoader abstracts a common (at least for me) pattern in Rails applications.
|
4
|
+
When creating controllers that interact with models it is common to have
|
5
|
+
methods called <tt>find_<model_name></tt> for your models. This module defines those
|
6
|
+
<tt>find_*</tt> methods for you.
|
7
|
+
|
8
|
+
When executing the <tt>find_*</tt> methods, if a matching record can not be found, the
|
9
|
+
user is redirected to the 404 page.
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
Include the gem using bundler in your Gemfile:
|
14
|
+
|
15
|
+
gem "model_loader"
|
16
|
+
|
17
|
+
== Usage
|
18
|
+
|
19
|
+
The module is activated by calling the <tt>can_find_models</tt> method:
|
20
|
+
|
21
|
+
class ApplicationController < ActionController::Base
|
22
|
+
can_find_models
|
23
|
+
end
|
24
|
+
|
25
|
+
Valid options are <tt>:only</tt> and <tt>:except</tt>:
|
26
|
+
|
27
|
+
class ApplicationController < ActionController
|
28
|
+
can_find_models :only => 'Person'
|
29
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module ModelLoader
|
2
|
+
if defined?(Rails::Railtie)
|
3
|
+
require 'rails'
|
4
|
+
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
initializer 'model_loader.extend_action_controller' do
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
ModelLoader::Railtie.insert
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Railtie
|
15
|
+
def self.insert
|
16
|
+
ActionController::Base.send(:include, ModelLoader)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/model_loader/version.rb
CHANGED
data/lib/model_loader.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
# Abstracts a common (at least for me) pattern in Rails applications. When
|
2
2
|
# creating controllers that interact with models it is common to have methods
|
3
|
-
# called find_<model_name> for your models. This module defines those
|
4
|
-
# methods for you.
|
3
|
+
# called <tt>find_<model_name></tt> for your models. This module defines those
|
4
|
+
# <tt>find_*</tt> methods for you.
|
5
5
|
#
|
6
|
-
# When executing the find_
|
7
|
-
# user is redirected to the 404 page.
|
6
|
+
# When executing the <tt>find_*</tt> methods, if a matching record can not be
|
7
|
+
# found, the user is redirected to the 404 page. The find method first tries to
|
8
|
+
# find the object using the <tt><model_name>_id</tt> parameter if it exists. If
|
9
|
+
# not, it tries to find the object using the <tt>id</tt> parameter.
|
10
|
+
#
|
11
|
+
# For example, given a model named Post, <tt>find_post</tt> will first check to
|
12
|
+
# see if <tt>params[:post_id]</tt> exists. If it does, it will look up the
|
13
|
+
# model with the value of that parameter. If it doesn't exist,
|
14
|
+
# <tt>params[:id]</tt> will be used insted.
|
8
15
|
#
|
9
16
|
# The module is activated by calling the +can_find_models+ method:
|
10
17
|
#
|
@@ -26,21 +33,23 @@ module ModelLoader
|
|
26
33
|
def can_find_models(options = {})
|
27
34
|
options.symbolize_keys!
|
28
35
|
|
29
|
-
raise ArgumentError, "The :only option to can_find_models must be an array." if options[:only] && !options[:only].is_a?(Array)
|
30
|
-
raise ArgumentError, "The :except option to can_find_models must be an array." if options[:except] && !options[:except].is_a?(Array)
|
31
|
-
|
32
36
|
if options[:only]
|
37
|
+
options[:only] = [options[:only]].flatten.compact
|
33
38
|
models = options[:only].map &:to_s
|
34
39
|
else
|
35
40
|
models = Dir["#{::Rails.root.to_s}/app/models/*"].map do |file|
|
36
41
|
File.basename(file, ".*").classify
|
37
42
|
end
|
38
43
|
|
39
|
-
|
44
|
+
if options[:except]
|
45
|
+
options[:except] = [options[:except]].flatten.compact
|
46
|
+
models -= options[:except].map &:to_s
|
47
|
+
end
|
40
48
|
end
|
41
49
|
|
42
50
|
models.each do |model|
|
43
51
|
name = model.underscore
|
52
|
+
next if self.respond_to? "find_#{name}"
|
44
53
|
self.class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
45
54
|
def find_#{name}
|
46
55
|
if params[:#{name}_id]
|
@@ -49,15 +58,12 @@ module ModelLoader
|
|
49
58
|
@#{name} = #{name.capitalize}.find(params[:id])
|
50
59
|
end
|
51
60
|
rescue
|
52
|
-
|
61
|
+
render :file => "#{::Rails.root.to_s}/public/404.html", :layout => false, :status => 404
|
53
62
|
end
|
54
63
|
METHOD
|
55
64
|
end
|
56
65
|
end
|
57
|
-
|
58
|
-
# Renders the application's 404 page.
|
59
|
-
def resource_not_found
|
60
|
-
render :file => "#{::Rails.root.to_s}/public/404.html", :layout => false, :status => 404
|
61
|
-
end
|
62
66
|
end
|
63
67
|
end
|
68
|
+
|
69
|
+
require 'model_loader/railtie'
|
data/rails/init.rb
ADDED
File without changes
|
Binary file
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'app/models/post'
|
3
|
+
|
4
|
+
class TestController < ApplicationController
|
5
|
+
can_find_models
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestOnlyController < ApplicationController
|
9
|
+
can_find_models :only => 'Post'
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestExceptController < ApplicationController
|
13
|
+
can_find_models :except => 'Post'
|
14
|
+
end
|
15
|
+
|
16
|
+
class TestExistingMethodController < ApplicationController
|
17
|
+
can_find_models
|
18
|
+
|
19
|
+
def find_post
|
20
|
+
"Test passed"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class ModelLoaderTest < Test::Unit::TestCase
|
25
|
+
def setup
|
26
|
+
reset_database
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_should_have_can_find_models_method
|
30
|
+
assert ApplicationController.respond_to?(:can_find_models)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_create_find_methods
|
34
|
+
assert TestController.new.respond_to?(:find_post)
|
35
|
+
assert TestController.new.respond_to?(:find_user)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_create_find_methods_with_only
|
39
|
+
assert TestOnlyController.new.respond_to?(:find_post)
|
40
|
+
assert !TestOnlyController.new.respond_to?(:find_user)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_create_find_methods_with_except
|
44
|
+
assert !TestExceptController.new.respond_to?(:find_post)
|
45
|
+
assert TestExceptController.new.respond_to?(:find_user)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_find_model
|
49
|
+
post = Post.create(:title => 'Test')
|
50
|
+
controller = TestController.new
|
51
|
+
controller.params = { :id => post.id }
|
52
|
+
assert_equal post, controller.find_post
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_should_not_find_model
|
56
|
+
controller = TestController.new
|
57
|
+
controller.response = ActionController::TestResponse.new
|
58
|
+
controller.params = { :id => 1 }
|
59
|
+
controller.find_post
|
60
|
+
assert_equal 404, controller.response.status
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_find_associated_model
|
64
|
+
post = Post.create(:title => 'Test')
|
65
|
+
controller = TestController.new
|
66
|
+
controller.params = { :post_id => post.id }
|
67
|
+
assert_equal post, controller.find_post
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_should_not_find_associated_model
|
71
|
+
controller = TestController.new
|
72
|
+
controller.response = ActionController::TestResponse.new
|
73
|
+
controller.params = { :post_id => 1 }
|
74
|
+
controller.find_post
|
75
|
+
assert_equal 404, controller.response.status
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_should_not_overwrite_existing_method
|
79
|
+
controller = TestExistingMethodController.new
|
80
|
+
assert_equal "Test passed", controller.find_post
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/404.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/deprecation'
|
5
|
+
require 'action_controller'
|
6
|
+
require 'action_controller/test_case'
|
7
|
+
require 'active_record'
|
8
|
+
require 'rails'
|
9
|
+
|
10
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
11
|
+
require File.join(File.dirname(__FILE__), '..', 'init')
|
12
|
+
|
13
|
+
config = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'db', 'database.yml')))
|
14
|
+
ActiveRecord::Base.configurations = { 'test' => config['sqlite3'] }
|
15
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
16
|
+
|
17
|
+
class MockApplication
|
18
|
+
def config
|
19
|
+
MockConfig.new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class MockConfig
|
24
|
+
def root
|
25
|
+
File.dirname(__FILE__)
|
26
|
+
end
|
27
|
+
|
28
|
+
def cache_classes
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Rails.application = MockApplication.new
|
34
|
+
|
35
|
+
class ApplicationController < ActionController::Base
|
36
|
+
end
|
37
|
+
|
38
|
+
class Test::Unit::TestCase
|
39
|
+
def reset_database
|
40
|
+
silence_stream(STDOUT) do
|
41
|
+
ActiveRecord::Schema.define(:version => 1) do
|
42
|
+
create_table :posts, :force => true do |t|
|
43
|
+
t.string :title
|
44
|
+
end
|
45
|
+
|
46
|
+
create_table :users, :force => true do |t|
|
47
|
+
t.string :name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model_loader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Vaughan
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-18 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -31,10 +31,22 @@ extra_rdoc_files: []
|
|
31
31
|
files:
|
32
32
|
- .gitignore
|
33
33
|
- Gemfile
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.rdoc
|
34
36
|
- Rakefile
|
37
|
+
- init.rb
|
35
38
|
- lib/model_loader.rb
|
39
|
+
- lib/model_loader/railtie.rb
|
36
40
|
- lib/model_loader/version.rb
|
37
41
|
- model_loader.gemspec
|
42
|
+
- rails/init.rb
|
43
|
+
- test/app/models/post.rb
|
44
|
+
- test/app/models/user.rb
|
45
|
+
- test/db/database.yml
|
46
|
+
- test/db/test.sqlite3
|
47
|
+
- test/model_loader_test.rb
|
48
|
+
- test/public/404.html
|
49
|
+
- test/test_helper.rb
|
38
50
|
has_rdoc: true
|
39
51
|
homepage: https://github.com/adamvaughan/model_loader
|
40
52
|
licenses: []
|
@@ -69,5 +81,11 @@ rubygems_version: 1.4.2
|
|
69
81
|
signing_key:
|
70
82
|
specification_version: 3
|
71
83
|
summary: Automatically generate find method for models.
|
72
|
-
test_files:
|
73
|
-
|
84
|
+
test_files:
|
85
|
+
- test/app/models/post.rb
|
86
|
+
- test/app/models/user.rb
|
87
|
+
- test/db/database.yml
|
88
|
+
- test/db/test.sqlite3
|
89
|
+
- test/model_loader_test.rb
|
90
|
+
- test/public/404.html
|
91
|
+
- test/test_helper.rb
|