matid-resource_controller 0.6.5
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/LICENSE +23 -0
- data/README.rdoc +330 -0
- data/VERSION.yml +4 -0
- data/generators/scaffold_resource/USAGE +29 -0
- data/generators/scaffold_resource/scaffold_resource_generator.rb +179 -0
- data/generators/scaffold_resource/templates/controller.rb +2 -0
- data/generators/scaffold_resource/templates/fixtures.yml +10 -0
- data/generators/scaffold_resource/templates/functional_test.rb +57 -0
- data/generators/scaffold_resource/templates/helper.rb +2 -0
- data/generators/scaffold_resource/templates/migration.rb +15 -0
- data/generators/scaffold_resource/templates/model.rb +2 -0
- data/generators/scaffold_resource/templates/old_migration.rb +13 -0
- data/generators/scaffold_resource/templates/rspec/functional_spec.rb +255 -0
- data/generators/scaffold_resource/templates/rspec/helper_spec.rb +11 -0
- data/generators/scaffold_resource/templates/rspec/routing_spec.rb +61 -0
- data/generators/scaffold_resource/templates/rspec/unit_spec.rb +11 -0
- data/generators/scaffold_resource/templates/rspec/views/edit_spec.rb +28 -0
- data/generators/scaffold_resource/templates/rspec/views/index_spec.rb +26 -0
- data/generators/scaffold_resource/templates/rspec/views/new_spec.rb +30 -0
- data/generators/scaffold_resource/templates/rspec/views/show_spec.rb +25 -0
- data/generators/scaffold_resource/templates/shoulda_functional_test.rb +19 -0
- data/generators/scaffold_resource/templates/unit_test.rb +7 -0
- data/generators/scaffold_resource/templates/view__form.erb +6 -0
- data/generators/scaffold_resource/templates/view__form.haml +5 -0
- data/generators/scaffold_resource/templates/view_edit.erb +16 -0
- data/generators/scaffold_resource/templates/view_edit.haml +11 -0
- data/generators/scaffold_resource/templates/view_index.erb +22 -0
- data/generators/scaffold_resource/templates/view_index.haml +19 -0
- data/generators/scaffold_resource/templates/view_new.erb +12 -0
- data/generators/scaffold_resource/templates/view_new.haml +9 -0
- data/generators/scaffold_resource/templates/view_show.erb +9 -0
- data/generators/scaffold_resource/templates/view_show.haml +9 -0
- data/lib/resource_controller.rb +23 -0
- data/lib/resource_controller/accessors.rb +77 -0
- data/lib/resource_controller/base.rb +15 -0
- data/lib/resource_controller/controller.rb +38 -0
- data/lib/resource_controller/helpers.rb +27 -0
- data/lib/resource_controller/helpers/current_objects.rb +73 -0
- data/lib/resource_controller/helpers/nested.rb +67 -0
- data/lib/resource_controller/helpers/singleton_customizations.rb +64 -0
- data/lib/resource_controller/helpers/urls.rb +132 -0
- data/lib/resource_controller/singleton.rb +15 -0
- data/lib/urligence.rb +50 -0
- data/rails/init.rb +6 -0
- data/test/Rakefile +10 -0
- data/test/app/controllers/accounts_controller.rb +6 -0
- data/test/app/controllers/application_controller.rb +5 -0
- data/test/app/controllers/cms/options_controller.rb +3 -0
- data/test/app/controllers/cms/personnel_controller.rb +2 -0
- data/test/app/controllers/cms/photos_controller.rb +6 -0
- data/test/app/controllers/cms/products_controller.rb +3 -0
- data/test/app/controllers/comments_controller.rb +3 -0
- data/test/app/controllers/images_controller.rb +4 -0
- data/test/app/controllers/options_controller.rb +8 -0
- data/test/app/controllers/people_controller.rb +9 -0
- data/test/app/controllers/photos_controller.rb +12 -0
- data/test/app/controllers/posts_controller.rb +10 -0
- data/test/app/controllers/projects_controller.rb +3 -0
- data/test/app/controllers/somethings_controller.rb +3 -0
- data/test/app/controllers/tags_controller.rb +13 -0
- data/test/app/controllers/users_controller.rb +12 -0
- data/test/app/helpers/accounts_helper.rb +2 -0
- data/test/app/helpers/application_helper.rb +3 -0
- data/test/app/helpers/cms/products_helper.rb +2 -0
- data/test/app/helpers/comments_helper.rb +2 -0
- data/test/app/helpers/images_helper.rb +2 -0
- data/test/app/helpers/options_helper.rb +2 -0
- data/test/app/helpers/people_helper.rb +2 -0
- data/test/app/helpers/photos_helper.rb +2 -0
- data/test/app/helpers/posts_helper.rb +2 -0
- data/test/app/helpers/projects_helper.rb +2 -0
- data/test/app/helpers/somethings_helper.rb +2 -0
- data/test/app/helpers/tags_helper.rb +2 -0
- data/test/app/helpers/users_helper.rb +2 -0
- data/test/app/models/account.rb +4 -0
- data/test/app/models/comment.rb +3 -0
- data/test/app/models/image.rb +3 -0
- data/test/app/models/option.rb +3 -0
- data/test/app/models/personnel.rb +3 -0
- data/test/app/models/photo.rb +5 -0
- data/test/app/models/post.rb +3 -0
- data/test/app/models/product.rb +3 -0
- data/test/app/models/project.rb +2 -0
- data/test/app/models/something.rb +2 -0
- data/test/app/models/tag.rb +3 -0
- data/test/app/models/user.rb +3 -0
- data/test/app/views/accounts/_form.html.erb +4 -0
- data/test/app/views/accounts/edit.html.erb +14 -0
- data/test/app/views/accounts/new.html.erb +12 -0
- data/test/app/views/accounts/show.html.erb +5 -0
- data/test/app/views/cms/options/edit.rhtml +17 -0
- data/test/app/views/cms/options/index.rhtml +20 -0
- data/test/app/views/cms/options/new.rhtml +16 -0
- data/test/app/views/cms/options/show.rhtml +8 -0
- data/test/app/views/cms/photos/edit.rhtml +17 -0
- data/test/app/views/cms/photos/index.rhtml +20 -0
- data/test/app/views/cms/photos/new.rhtml +16 -0
- data/test/app/views/cms/photos/show.rhtml +8 -0
- data/test/app/views/cms/products/edit.rhtml +17 -0
- data/test/app/views/cms/products/index.rhtml +20 -0
- data/test/app/views/cms/products/new.rhtml +16 -0
- data/test/app/views/cms/products/show.rhtml +8 -0
- data/test/app/views/comments/edit.rhtml +27 -0
- data/test/app/views/comments/index.rhtml +24 -0
- data/test/app/views/comments/new.rhtml +26 -0
- data/test/app/views/comments/show.rhtml +18 -0
- data/test/app/views/images/_form.html.erb +4 -0
- data/test/app/views/images/edit.html.erb +14 -0
- data/test/app/views/images/new.html.erb +12 -0
- data/test/app/views/layouts/application.rhtml +17 -0
- data/test/app/views/layouts/comments.rhtml +17 -0
- data/test/app/views/layouts/options.rhtml +17 -0
- data/test/app/views/layouts/people.rhtml +17 -0
- data/test/app/views/layouts/photos.rhtml +17 -0
- data/test/app/views/layouts/projects.rhtml +17 -0
- data/test/app/views/layouts/somethings.rhtml +17 -0
- data/test/app/views/layouts/tags.rhtml +17 -0
- data/test/app/views/options/_form.html.erb +8 -0
- data/test/app/views/options/edit.html.erb +16 -0
- data/test/app/views/options/index.html.erb +21 -0
- data/test/app/views/options/new.html.erb +12 -0
- data/test/app/views/options/show.html.erb +10 -0
- data/test/app/views/people/edit.rhtml +17 -0
- data/test/app/views/people/index.rhtml +20 -0
- data/test/app/views/people/new.rhtml +16 -0
- data/test/app/views/people/show.rhtml +8 -0
- data/test/app/views/photos/edit.rhtml +17 -0
- data/test/app/views/photos/index.rhtml +20 -0
- data/test/app/views/photos/new.rhtml +16 -0
- data/test/app/views/photos/show.rhtml +8 -0
- data/test/app/views/posts/edit.rhtml +22 -0
- data/test/app/views/posts/index.rhtml +22 -0
- data/test/app/views/posts/new.rhtml +21 -0
- data/test/app/views/posts/show.rhtml +13 -0
- data/test/app/views/projects/edit.rhtml +17 -0
- data/test/app/views/projects/index.rhtml +20 -0
- data/test/app/views/projects/new.rhtml +16 -0
- data/test/app/views/projects/show.rhtml +8 -0
- data/test/app/views/somethings/edit.rhtml +17 -0
- data/test/app/views/somethings/index.rhtml +20 -0
- data/test/app/views/somethings/new.rhtml +16 -0
- data/test/app/views/somethings/show.rhtml +8 -0
- data/test/app/views/tags/edit.rhtml +17 -0
- data/test/app/views/tags/index.rhtml +20 -0
- data/test/app/views/tags/index.rjs +0 -0
- data/test/app/views/tags/new.rhtml +16 -0
- data/test/app/views/tags/show.rhtml +8 -0
- data/test/app/views/users/edit.rhtml +17 -0
- data/test/app/views/users/index.rhtml +20 -0
- data/test/app/views/users/new.rhtml +16 -0
- data/test/app/views/users/show.rhtml +8 -0
- data/test/config/boot.rb +110 -0
- data/test/config/database.yml +9 -0
- data/test/config/environment.rb +49 -0
- data/test/config/environments/development.rb +17 -0
- data/test/config/environments/test.rb +19 -0
- data/test/config/initializers/inflections.rb +14 -0
- data/test/config/routes.rb +61 -0
- data/test/db/migrate/001_create_posts.rb +12 -0
- data/test/db/migrate/002_create_products.rb +11 -0
- data/test/db/migrate/003_create_comments.rb +13 -0
- data/test/db/migrate/004_create_options.rb +13 -0
- data/test/db/migrate/005_create_photos.rb +11 -0
- data/test/db/migrate/006_create_tags.rb +17 -0
- data/test/db/migrate/007_create_somethings.rb +11 -0
- data/test/db/migrate/008_create_accounts.rb +11 -0
- data/test/db/migrate/009_add_account_id_to_photos.rb +9 -0
- data/test/db/migrate/010_create_projects.rb +11 -0
- data/test/db/migrate/011_create_images.rb +12 -0
- data/test/db/migrate/012_create_users.rb +11 -0
- data/test/db/migrate/013_create_personnel.rb +11 -0
- data/test/db/migrate/014_add_personnel_id_to_photos.rb +9 -0
- data/test/db/schema.rb +78 -0
- data/test/script/console +3 -0
- data/test/script/destroy +3 -0
- data/test/script/generate +3 -0
- data/test/script/server +3 -0
- data/test/test/fixtures/accounts.yml +7 -0
- data/test/test/fixtures/comments.yml +11 -0
- data/test/test/fixtures/images.yml +6 -0
- data/test/test/fixtures/options.yml +9 -0
- data/test/test/fixtures/personnel.yml +5 -0
- data/test/test/fixtures/photos.yml +9 -0
- data/test/test/fixtures/photos_tags.yml +3 -0
- data/test/test/fixtures/posts.yml +9 -0
- data/test/test/fixtures/products.yml +7 -0
- data/test/test/fixtures/projects.yml +7 -0
- data/test/test/fixtures/somethings.yml +7 -0
- data/test/test/fixtures/tags.yml +7 -0
- data/test/test/fixtures/users.yml +5 -0
- data/test/test/functional/cms/options_controller_test.rb +23 -0
- data/test/test/functional/cms/photos_controller_test.rb +43 -0
- data/test/test/functional/cms/products_controller_test.rb +23 -0
- data/test/test/functional/comments_controller_test.rb +19 -0
- data/test/test/functional/images_controller_test.rb +30 -0
- data/test/test/functional/people_controller_test.rb +27 -0
- data/test/test/functional/photos_controller_test.rb +123 -0
- data/test/test/functional/posts_controller_test.rb +27 -0
- data/test/test/functional/projects_controller_test.rb +21 -0
- data/test/test/functional/somethings_controller_test.rb +21 -0
- data/test/test/functional/tags_controller_test.rb +57 -0
- data/test/test/functional/users_controller_test.rb +17 -0
- data/test/test/test_helper.rb +13 -0
- data/test/test/unit/accessors_test.rb +110 -0
- data/test/test/unit/account_test.rb +7 -0
- data/test/test/unit/action_options_test.rb +109 -0
- data/test/test/unit/base_test.rb +11 -0
- data/test/test/unit/comment_test.rb +10 -0
- data/test/test/unit/failable_action_options_test.rb +77 -0
- data/test/test/unit/helpers/current_objects_test.rb +133 -0
- data/test/test/unit/helpers/internal_test.rb +106 -0
- data/test/test/unit/helpers/nested_test.rb +86 -0
- data/test/test/unit/helpers/singleton_current_objects_test.rb +68 -0
- data/test/test/unit/helpers/singleton_nested_test.rb +77 -0
- data/test/test/unit/helpers/singleton_urls_test.rb +67 -0
- data/test/test/unit/helpers/urls_test.rb +75 -0
- data/test/test/unit/helpers_test.rb +25 -0
- data/test/test/unit/image_test.rb +7 -0
- data/test/test/unit/option_test.rb +10 -0
- data/test/test/unit/photo_test.rb +10 -0
- data/test/test/unit/post_test.rb +10 -0
- data/test/test/unit/project_test.rb +10 -0
- data/test/test/unit/response_collector_test.rb +49 -0
- data/test/test/unit/something_test.rb +10 -0
- data/test/test/unit/tag_test.rb +10 -0
- data/test/test/unit/urligence_test.rb +203 -0
- metadata +379 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module ResourceController
|
|
2
|
+
# == ResourceController::Helpers
|
|
3
|
+
#
|
|
4
|
+
# Included in Base.
|
|
5
|
+
#
|
|
6
|
+
# These helpers are used internally to manage objects, generate urls, and manage parent resource associations.
|
|
7
|
+
#
|
|
8
|
+
# If you want to customize certain controller behaviour, like member-object, and collection fetching, overriding these methods is all it takes.
|
|
9
|
+
#
|
|
10
|
+
# See the docs below, and the README for examples
|
|
11
|
+
#
|
|
12
|
+
# *Please Note: many of these helpers build on top of each other, and require that behaviour to be maintained, in order for other functionality to work properly.*
|
|
13
|
+
#
|
|
14
|
+
# e.g. All fetching must be done on top of the method end_of_association_chain, or else parent resources (including polymorphic ones) won't function correctly.
|
|
15
|
+
#
|
|
16
|
+
# class PostsController < ResourceController::Base
|
|
17
|
+
# private
|
|
18
|
+
# def object
|
|
19
|
+
# @object ||= end_of_association_chain.find_by_permalink(param)
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
module Helpers
|
|
23
|
+
include ResourceController::Helpers::Urls
|
|
24
|
+
include ResourceController::Helpers::Nested
|
|
25
|
+
include ResourceController::Helpers::CurrentObjects
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module ResourceController
|
|
2
|
+
module Helpers
|
|
3
|
+
module CurrentObjects
|
|
4
|
+
protected
|
|
5
|
+
# Used internally to return the model for your resource.
|
|
6
|
+
#
|
|
7
|
+
def model
|
|
8
|
+
model_name.to_s.camelize.constantize
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Used to fetch the collection for the index method
|
|
13
|
+
#
|
|
14
|
+
# In order to customize the way the collection is fetched, to add something like pagination, for example, override this method.
|
|
15
|
+
#
|
|
16
|
+
def collection
|
|
17
|
+
end_of_association_chain.find(:all)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns the current param.
|
|
21
|
+
#
|
|
22
|
+
# Defaults to params[:id].
|
|
23
|
+
#
|
|
24
|
+
# Override this method if you'd like to use an alternate param name.
|
|
25
|
+
#
|
|
26
|
+
def param
|
|
27
|
+
params[:id]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Used to fetch the current member object in all of the singular methods that operate on an existing member.
|
|
31
|
+
#
|
|
32
|
+
# Override this method if you'd like to fetch your objects in some alternate way, like using a permalink.
|
|
33
|
+
#
|
|
34
|
+
# class PostsController < ResourceController::Base
|
|
35
|
+
# private
|
|
36
|
+
# def object
|
|
37
|
+
# @object ||= end_of_association_chain.find_by_permalink(param)
|
|
38
|
+
# end
|
|
39
|
+
# end
|
|
40
|
+
#
|
|
41
|
+
def object
|
|
42
|
+
@object ||= end_of_association_chain.find(param) unless param.nil?
|
|
43
|
+
@object
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Used internally to load the member object in to an instance variable @#{model_name} (i.e. @post)
|
|
47
|
+
#
|
|
48
|
+
def load_object
|
|
49
|
+
instance_variable_set "@#{parent_type}", parent_object if parent?
|
|
50
|
+
instance_variable_set "@#{object_name}", object
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Used internally to load the collection in to an instance variable @#{model_name.pluralize} (i.e. @posts)
|
|
54
|
+
#
|
|
55
|
+
def load_collection
|
|
56
|
+
instance_variable_set "@#{parent_type}", parent_object if parent?
|
|
57
|
+
instance_variable_set "@#{object_name.to_s.pluralize}", collection
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Returns the form params. Defaults to params[model_name] (i.e. params["post"])
|
|
61
|
+
#
|
|
62
|
+
def object_params
|
|
63
|
+
params["#{object_name}"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Builds the object, but doesn't save it, during the new, and create action.
|
|
67
|
+
#
|
|
68
|
+
def build_object
|
|
69
|
+
@object ||= end_of_association_chain.send parent? ? :build : :new, object_params
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Nested and Polymorphic Resource Helpers
|
|
2
|
+
#
|
|
3
|
+
module ResourceController
|
|
4
|
+
module Helpers
|
|
5
|
+
module Nested
|
|
6
|
+
protected
|
|
7
|
+
# Returns the relevant association proxy of the parent. (i.e. /posts/1/comments # => @post.comments)
|
|
8
|
+
#
|
|
9
|
+
def parent_association
|
|
10
|
+
@parent_association ||= parent_object.send(model_name.to_s.pluralize.to_sym)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Returns the type of the current parent
|
|
14
|
+
#
|
|
15
|
+
def parent_type
|
|
16
|
+
@parent_type ||= parent_type_from_params || parent_type_from_request
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns the type of the current parent extracted from params
|
|
20
|
+
#
|
|
21
|
+
def parent_type_from_params
|
|
22
|
+
[*belongs_to].find { |parent| !params["#{parent}_id".to_sym].nil? }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns the type of the current parent extracted form a request path
|
|
26
|
+
#
|
|
27
|
+
def parent_type_from_request
|
|
28
|
+
[*belongs_to].find { |parent| request.path.split('/').include? parent.to_s }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns true/false based on whether or not a parent is present.
|
|
32
|
+
#
|
|
33
|
+
def parent?
|
|
34
|
+
!parent_type.nil?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns true/false based on whether or not a parent is a singleton.
|
|
38
|
+
#
|
|
39
|
+
def parent_singleton?
|
|
40
|
+
!parent_type_from_request.nil? && parent_type_from_params.nil?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns the current parent param, if there is a parent. (i.e. params[:post_id])
|
|
44
|
+
def parent_param
|
|
45
|
+
params["#{parent_type}_id".to_sym]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Like the model method, but for a parent relationship.
|
|
49
|
+
#
|
|
50
|
+
def parent_model
|
|
51
|
+
parent_type.to_s.camelize.constantize
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Returns the current parent object if a parent object is present.
|
|
55
|
+
#
|
|
56
|
+
def parent_object
|
|
57
|
+
parent? && !parent_singleton? ? parent_model.find(parent_param) : nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# If there is a parent, returns the relevant association proxy. Otherwise returns model.
|
|
61
|
+
#
|
|
62
|
+
def end_of_association_chain
|
|
63
|
+
parent? ? parent_association : model
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Singleton Resource Helpers
|
|
2
|
+
#
|
|
3
|
+
# Used internally to transform a plural RESTful controller into a singleton
|
|
4
|
+
#
|
|
5
|
+
module ResourceController
|
|
6
|
+
module Helpers
|
|
7
|
+
module SingletonCustomizations
|
|
8
|
+
def self.included(subclass)
|
|
9
|
+
subclass.class_eval do
|
|
10
|
+
methods_to_undefine = [:param, :index, :collection, :load_collection, :collection_url,
|
|
11
|
+
:collection_path, :hash_for_collection_url, :hash_for_collection_path]
|
|
12
|
+
methods_to_undefine.each { |method| undef_method(method) if method_defined? method }
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
def singleton?
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
# Used to fetch the current object in a singleton controller.
|
|
24
|
+
#
|
|
25
|
+
# By defult this method is able to fetch the current object for resources nested with the :has_one association only. (i.e. /users/1/image # => @user.image)
|
|
26
|
+
# In other cases you should override this method and provide your custom code to fetch a singleton resource object, like using a session hash.
|
|
27
|
+
#
|
|
28
|
+
# class AccountsController < ResourceController::Singleton
|
|
29
|
+
# private
|
|
30
|
+
# def object
|
|
31
|
+
# @object ||= Account.find(session[:account_id])
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
def object
|
|
36
|
+
@object ||= parent? ? end_of_association_chain : nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns the :has_one association proxy of the parent. (i.e. /users/1/image # => @user.image)
|
|
40
|
+
#
|
|
41
|
+
def parent_association
|
|
42
|
+
@parent_association ||= parent_object.send(model_name.to_sym)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Used internally to provide the options to smart_url in a singleton controller.
|
|
46
|
+
#
|
|
47
|
+
def object_url_options(action_prefix = nil, alternate_object = nil)
|
|
48
|
+
[action_prefix] + namespaces + [parent_url_options, route_name.to_sym]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Builds the object, but doesn't save it, during the new, and create action.
|
|
52
|
+
#
|
|
53
|
+
def build_object
|
|
54
|
+
@object ||= singleton_build_object_base.send parent? ? "build_#{model_name}".to_sym : :new, object_params
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Singleton controllers don't build off of association proxy, so we can't use end_of_association_chain here
|
|
58
|
+
#
|
|
59
|
+
def singleton_build_object_base
|
|
60
|
+
parent? ? parent_object : model
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Thanks to Urligence, you get some free url helpers.
|
|
2
|
+
#
|
|
3
|
+
# No matter what your controller looks like...
|
|
4
|
+
#
|
|
5
|
+
# [edit_|new_]object_url # is the equivalent of saying [edit_|new_]post_url(@post)
|
|
6
|
+
# [edit_|new_]object_url(some_other_object) # allows you to specify an object, but still maintain any paths or namespaces that are present
|
|
7
|
+
#
|
|
8
|
+
# collection_url # is like saying posts_url
|
|
9
|
+
#
|
|
10
|
+
# Url helpers are especially useful when working with polymorphic controllers.
|
|
11
|
+
#
|
|
12
|
+
# # /posts/1/comments
|
|
13
|
+
# object_url #=> /posts/1/comments/#{@comment.to_param}
|
|
14
|
+
# object_url(comment) #=> /posts/1/comments/#{comment.to_param}
|
|
15
|
+
# edit_object_url #=> /posts/1/comments/#{@comment.to_param}/edit
|
|
16
|
+
# collection_url #=> /posts/1/comments
|
|
17
|
+
#
|
|
18
|
+
# # /products/1/comments
|
|
19
|
+
# object_url #=> /products/1/comments/#{@comment.to_param}
|
|
20
|
+
# object_url(comment) #=> /products/1/comments/#{comment.to_param}
|
|
21
|
+
# edit_object_url #=> /products/1/comments/#{@comment.to_param}/edit
|
|
22
|
+
# collection_url #=> /products/1/comments
|
|
23
|
+
#
|
|
24
|
+
# # /comments
|
|
25
|
+
# object_url #=> /comments/#{@comment.to_param}
|
|
26
|
+
# object_url(comment) #=> /comments/#{comment.to_param}
|
|
27
|
+
# edit_object_url #=> /comments/#{@comment.to_param}/edit
|
|
28
|
+
# collection_url #=> /comments
|
|
29
|
+
#
|
|
30
|
+
# Or with namespaced, nested controllers...
|
|
31
|
+
#
|
|
32
|
+
# # /admin/products/1/options
|
|
33
|
+
# object_url #=> /admin/products/1/options/#{@option.to_param}
|
|
34
|
+
# object_url(option) #=> /admin/products/1/options/#{option.to_param}
|
|
35
|
+
# edit_object_url #=> /admin/products/1/options/#{@option.to_param}/edit
|
|
36
|
+
# collection_url #=> /admin/products/1/options
|
|
37
|
+
#
|
|
38
|
+
# You get the idea. Everything is automagical! All parameters are inferred.
|
|
39
|
+
#
|
|
40
|
+
module ResourceController
|
|
41
|
+
module Helpers
|
|
42
|
+
module Urls
|
|
43
|
+
protected
|
|
44
|
+
['', 'edit_'].each do |type|
|
|
45
|
+
symbol = type.blank? ? nil : type.gsub(/_/, '').to_sym
|
|
46
|
+
|
|
47
|
+
define_method("#{type}object_url") do |*alternate_object|
|
|
48
|
+
smart_url *object_url_options(symbol, alternate_object.first)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
define_method("#{type}object_path") do |*alternate_object|
|
|
52
|
+
smart_path *object_url_options(symbol, alternate_object.first)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
define_method("hash_for_#{type}object_url") do |*alternate_object|
|
|
56
|
+
hash_for_smart_url *object_url_options(symbol, alternate_object.first)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
define_method("hash_for_#{type}object_path") do |*alternate_object|
|
|
60
|
+
hash_for_smart_path *object_url_options(symbol, alternate_object.first)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def new_object_url
|
|
65
|
+
smart_url *new_object_url_options
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def new_object_path
|
|
69
|
+
smart_path *new_object_url_options
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def hash_for_new_object_url
|
|
73
|
+
hash_for_smart_url *new_object_url_options
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def hash_for_new_object_path
|
|
77
|
+
hash_for_smart_path *new_object_url_options
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def collection_url
|
|
81
|
+
smart_url *collection_url_options
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def collection_path
|
|
85
|
+
smart_path *collection_url_options
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def hash_for_collection_url
|
|
89
|
+
hash_for_smart_url *collection_url_options
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def hash_for_collection_path
|
|
93
|
+
hash_for_smart_path *collection_url_options
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Used internally to provide the options to smart_url from Urligence.
|
|
97
|
+
#
|
|
98
|
+
def collection_url_options
|
|
99
|
+
namespaces + [parent_url_options, route_name.to_s.pluralize.to_sym]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Used internally to provide the options to smart_url from Urligence.
|
|
103
|
+
#
|
|
104
|
+
def object_url_options(action_prefix = nil, alternate_object = nil)
|
|
105
|
+
[action_prefix] + namespaces + [parent_url_options, [route_name.to_sym, alternate_object || object]]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Used internally to provide the options to smart_url from Urligence.
|
|
109
|
+
#
|
|
110
|
+
def new_object_url_options
|
|
111
|
+
[:new] + namespaces + [parent_url_options, route_name.to_sym]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def parent_url_options
|
|
115
|
+
if parent?
|
|
116
|
+
parent_singleton? ? parent_type.to_sym : [parent_type.to_sym, parent_object]
|
|
117
|
+
else
|
|
118
|
+
nil
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Returns all of the current namespaces of the current controller, symbolized, in array form.
|
|
123
|
+
#
|
|
124
|
+
def namespaces
|
|
125
|
+
names = self.class.name.split("::")
|
|
126
|
+
names.pop
|
|
127
|
+
|
|
128
|
+
names.map(&:underscore).map(&:to_sym)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module ResourceController
|
|
2
|
+
|
|
3
|
+
# == ResourceController::Singleton
|
|
4
|
+
#
|
|
5
|
+
# Inherit from this class to create your RESTful singleton controller. See the README for usage.
|
|
6
|
+
#
|
|
7
|
+
class Singleton < ::ApplicationController
|
|
8
|
+
unloadable
|
|
9
|
+
|
|
10
|
+
def self.inherited(subclass)
|
|
11
|
+
super
|
|
12
|
+
subclass.class_eval { resource_controller :singleton }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/urligence.rb
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Urligence
|
|
2
|
+
def smart_url(*objects)
|
|
3
|
+
urligence(*objects.push(:url))
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def smart_path(*objects)
|
|
7
|
+
urligence(*objects.push(:path))
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def hash_for_smart_url(*objects)
|
|
11
|
+
urligence(*objects.unshift(:hash_for).push(:url).push({:type => :hash}))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def hash_for_smart_path(*objects)
|
|
15
|
+
urligence(*objects.unshift(:hash_for).push(:path).push({:type => :hash}))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def urligence(*objects)
|
|
19
|
+
config = {}
|
|
20
|
+
config.merge!(objects.pop) if objects.last.is_a?(Hash)
|
|
21
|
+
|
|
22
|
+
objects.reject! { |object| object.nil? }
|
|
23
|
+
|
|
24
|
+
url_fragments = objects.collect do |obj|
|
|
25
|
+
if obj.is_a? Symbol
|
|
26
|
+
obj
|
|
27
|
+
elsif obj.is_a? Array
|
|
28
|
+
obj.first
|
|
29
|
+
else
|
|
30
|
+
obj.class.name.underscore.to_sym
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
unless config[:type] == :hash
|
|
35
|
+
send url_fragments.join("_"), *objects.flatten.select { |obj| !obj.is_a? Symbol }
|
|
36
|
+
else
|
|
37
|
+
params = {}
|
|
38
|
+
unparsed_params = objects.select { |obj| !obj.is_a? Symbol }
|
|
39
|
+
unparsed_params.each_with_index do |obj, i|
|
|
40
|
+
unless i == (unparsed_params.length-1)
|
|
41
|
+
params.merge!((obj.is_a? Array) ? {"#{obj.first}_id".to_sym => obj[1].to_param} : {"#{obj.class.name.underscore}_id".to_sym => obj.to_param})
|
|
42
|
+
else
|
|
43
|
+
params.merge!((obj.is_a? Array) ? {:id => obj[1].to_param} : {:id => obj.to_param})
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
send url_fragments.join("_"), params
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/rails/init.rb
ADDED
data/test/Rakefile
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
|
3
|
+
|
|
4
|
+
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
|
|
5
|
+
|
|
6
|
+
require 'rake'
|
|
7
|
+
require 'rake/testtask'
|
|
8
|
+
require 'rake/rdoctask'
|
|
9
|
+
|
|
10
|
+
require 'tasks/rails'
|