tasteful_routes 0.1.2

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/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,74 @@
1
+ = Tasteful Routes
2
+
3
+ An opinionated variation of the standard Rails RESTful routes that has singular member action URLs.
4
+
5
+ == Usage
6
+
7
+ Simply define your routes with tasteful_resources as you normally would with the {resources method}[http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Resources.html#method-i-resources]:
8
+
9
+ YourApp::Application.routes.draw do
10
+ tasteful_resources :jobs
11
+ end
12
+
13
+ This results in the following routes:
14
+
15
+ jobs GET /jobs(.:format) {:controller=>"jobs", :action=>"index"}
16
+ POST /jobs(.:format) {:controller=>"jobs", :action=>"create"}
17
+ new_job GET /job/new(.:format) {:controller=>"jobs", :action=>"new"}
18
+ edit_job GET /job/:id/edit(.:format) {:controller=>"jobs", :action=>"edit"}
19
+ job GET /job/:id(.:format) {:controller=>"jobs", :action=>"show"}
20
+ PUT /job/:id(.:format) {:controller=>"jobs", :action=>"update"}
21
+ DELETE /job/:id(.:format) {:controller=>"jobs", :action=>"destroy"}
22
+
23
+ It should work with all the same options as resources, including nesting:
24
+
25
+ YourApp::Application.routes.draw do
26
+ tasteful_resources :jobs do
27
+ tasteful_resources :items
28
+ end
29
+ end
30
+
31
+ This time resulting in:
32
+
33
+ job_items GET /job/:job_id/items(.:format) {:controller=>"items", :action=>"index"}
34
+ POST /job/:job_id/items(.:format) {:controller=>"items", :action=>"create"}
35
+ new_job_item GET /job/:job_id/item/new(.:format) {:controller=>"items", :action=>"new"}
36
+ edit_job_item GET /job/:job_id/item/:id/edit(.:format) {:controller=>"items", :action=>"edit"}
37
+ job_item GET /job/:job_id/item/:id(.:format) {:controller=>"items", :action=>"show"}
38
+ PUT /job/:job_id/item/:id(.:format) {:controller=>"items", :action=>"update"}
39
+ DELETE /job/:job_id/item/:id(.:format) {:controller=>"items", :action=>"destroy"}
40
+ jobs GET /jobs(.:format) {:controller=>"jobs", :action=>"index"}
41
+ POST /jobs(.:format) {:controller=>"jobs", :action=>"create"}
42
+ new_job GET /job/new(.:format) {:controller=>"jobs", :action=>"new"}
43
+ edit_job GET /job/:id/edit(.:format) {:controller=>"jobs", :action=>"edit"}
44
+ job GET /job/:id(.:format) {:controller=>"jobs", :action=>"show"}
45
+ PUT /job/:id(.:format) {:controller=>"jobs", :action=>"update"}
46
+ DELETE /job/:id(.:format) {:controller=>"jobs", :action=>"destroy"}
47
+
48
+
49
+ == Maintainers
50
+
51
+ * {Hugh Evans}[http://github.com/hughevans]
52
+
53
+ == License
54
+
55
+ Copyright 2011 Icelab http://icelab.com.au
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining
58
+ a copy of this software and associated documentation files (the
59
+ "Software"), to deal in the Software without restriction, including
60
+ without limitation the rights to use, copy, modify, merge, publish,
61
+ distribute, sublicense, and/or sell copies of the Software, and to
62
+ permit persons to whom the Software is furnished to do so, subject to
63
+ the following conditions:
64
+
65
+ The above copyright notice and this permission notice shall be
66
+ included in all copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
69
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
71
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
72
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
73
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
74
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :default => :spec
5
+
6
+ desc "Run specs."
7
+ RSpec::Core::RakeTask.new do |t|
8
+ end
@@ -0,0 +1,51 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+ module TastefulResources
4
+ class TastefulResource < ActionDispatch::Routing::Mapper::Resource
5
+ def member_scope
6
+ "#{path.singularize}/:id"
7
+ end
8
+
9
+ def new_scope(new_path)
10
+ "#{path.singularize}/#{new_path}"
11
+ end
12
+
13
+ def nested_scope
14
+ "#{path.singularize}/:#{singular}_id"
15
+ end
16
+ end
17
+
18
+ def tasteful_resources(*resources, &block)
19
+ options = resources.extract_options!
20
+
21
+ if apply_common_behavior_for(:tasteful_resources, resources, options, &block)
22
+ return self
23
+ end
24
+
25
+ resource_scope(TastefulResource.new(resources.pop, options)) do
26
+ yield if block_given?
27
+
28
+ collection do
29
+ get :index if parent_resource.actions.include?(:index)
30
+ post :create if parent_resource.actions.include?(:create)
31
+ end
32
+
33
+ new do
34
+ get :new
35
+ end if parent_resource.actions.include?(:new)
36
+
37
+ member do
38
+ get :edit if parent_resource.actions.include?(:edit)
39
+ get :show if parent_resource.actions.include?(:show)
40
+ put :update if parent_resource.actions.include?(:update)
41
+ delete :destroy if parent_resource.actions.include?(:destroy)
42
+ end
43
+ end
44
+
45
+ self
46
+ end
47
+
48
+ end
49
+ include TastefulResources
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module TastefulRoutes
2
+ VERSION = "0.1.2"
3
+ end
@@ -0,0 +1,3 @@
1
+ require "rails"
2
+ require "tasteful_routes/version"
3
+ require "tasteful_routes/mapper"
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe :tasteful_routes do
4
+ before(:all) do
5
+ @set = ActionDispatch::Routing::RouteSet.new
6
+ @set.draw do
7
+ resources :clients
8
+
9
+ resources :posts do
10
+ resources :comments
11
+ end
12
+
13
+ tasteful_resources :projects
14
+
15
+ tasteful_resources :jobs do
16
+ tasteful_resources :items
17
+ end
18
+ end
19
+
20
+ class RouteTesting; end
21
+ RouteTesting.send :include, @set.url_helpers
22
+
23
+ @routes = RouteTesting.new
24
+ end
25
+
26
+ context "Not breaking existing behavior" do
27
+ context "of resources" do
28
+ specify "collection paths" do
29
+ @routes.send(:clients_path).should == "/clients"
30
+ end
31
+
32
+ specify "member paths" do
33
+ @routes.send(:client_path, 1).should == "/clients/1"
34
+ end
35
+ end
36
+
37
+ context "of nested resources" do
38
+ specify "collection paths" do
39
+ @routes.send(:post_comments_path, 1).should == "/posts/1/comments"
40
+ end
41
+
42
+ specify "member paths" do
43
+ @routes.send(:post_comment_path, 1, 12).should == "/posts/1/comments/12"
44
+ end
45
+ end
46
+ end
47
+
48
+ context "#tasteful_resources" do
49
+ context "for non-nested resources" do
50
+ it "should pluralize the collection paths" do
51
+ @routes.send(:projects_path).should == "/projects"
52
+ end
53
+
54
+ it "should singularize the member paths" do
55
+ @routes.send(:new_project_path).should == "/project/new"
56
+ @routes.send(:project_path, 1).should == "/project/1"
57
+ @routes.send(:edit_project_path, 1).should == "/project/1/edit"
58
+ end
59
+ end
60
+
61
+ context "for the parent of nested resources" do
62
+ it "should pluralize the collection paths" do
63
+ @routes.send(:jobs_path).should == "/jobs"
64
+ end
65
+
66
+ it "should singularize the member paths" do
67
+ @routes.send(:new_job_path).should == "/job/new"
68
+ @routes.send(:job_path, 1).should == "/job/1"
69
+ @routes.send(:edit_job_path, 1).should == "/job/1/edit"
70
+ end
71
+ end
72
+
73
+ context "for the child of nested resources" do
74
+ it "should pluralize the collection paths" do
75
+ @routes.send(:job_items_path, 1).should == "/job/1/items"
76
+ end
77
+
78
+ it "should singularize the member paths" do
79
+ @routes.send(:new_job_item_path, 1).should == "/job/1/item/new"
80
+ @routes.send(:job_item_path, 1, 12).should == "/job/1/item/12"
81
+ @routes.send(:edit_job_item_path, 1, 12).should == "/job/1/item/12/edit"
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec'
4
+
5
+ require 'rails'
6
+ require 'action_controller'
7
+ require 'action_dispatch'
8
+ require 'rack/mount'
9
+ require 'active_support/core_ext/hash/slice.rb'
10
+
11
+ require 'tasteful_routes'
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "tasteful_routes/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "tasteful_routes"
7
+ s.version = TastefulRoutes::VERSION
8
+ s.authors = ["Icelab", "Hugh Evans"]
9
+ s.email = "hugh@artpop.com.au"
10
+ s.homepage = "http://github.com/icelab/tasteful_routes"
11
+ s.summary = %q{An opinionated variation of the standard Rails
12
+ RESTful routes that has singular member action URLs.}
13
+ s.description = %q{An opinionated variation of the standard Rails
14
+ RESTful routes that has singular member action URLs. For
15
+ example, /job/1 instead of /jobs/1. The collection
16
+ methods continue to operate on the plural /jobs (index
17
+ and create).}
18
+
19
+ s.rubyforge_project = "tasteful_routes"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.require_path = "lib"
23
+
24
+ s.add_dependency "rails", "~> 3.0.0"
25
+
26
+ s.add_development_dependency "rspec", "~> 2.6.0"
27
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tasteful_routes
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.2
6
+ platform: ruby
7
+ authors:
8
+ - Icelab
9
+ - Hugh Evans
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2011-06-05 00:00:00 +10:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: rails
19
+ prerelease: false
20
+ requirement: &id001 !ruby/object:Gem::Requirement
21
+ none: false
22
+ requirements:
23
+ - - ~>
24
+ - !ruby/object:Gem::Version
25
+ version: 3.0.0
26
+ type: :runtime
27
+ version_requirements: *id001
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ prerelease: false
31
+ requirement: &id002 !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: 2.6.0
37
+ type: :development
38
+ version_requirements: *id002
39
+ description: |-
40
+ An opinionated variation of the standard Rails
41
+ RESTful routes that has singular member action URLs. For
42
+ example, /job/1 instead of /jobs/1. The collection
43
+ methods continue to operate on the plural /jobs (index
44
+ and create).
45
+ email: hugh@artpop.com.au
46
+ executables: []
47
+
48
+ extensions: []
49
+
50
+ extra_rdoc_files: []
51
+
52
+ files:
53
+ - Gemfile
54
+ - README.rdoc
55
+ - Rakefile
56
+ - lib/tasteful_routes.rb
57
+ - lib/tasteful_routes/mapper.rb
58
+ - lib/tasteful_routes/version.rb
59
+ - spec/routing_spec.rb
60
+ - spec/spec_helper.rb
61
+ - tastful_routes.gemspec
62
+ has_rdoc: true
63
+ homepage: http://github.com/icelab/tasteful_routes
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options: []
68
+
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project: tasteful_routes
86
+ rubygems_version: 1.6.2
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: An opinionated variation of the standard Rails RESTful routes that has singular member action URLs.
90
+ test_files: []
91
+