Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional route helpers #86

Merged
merged 3 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions lib/rage/router/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def namespace(path, **options, &block)
# @param [Hash] opts scope options.
# @option opts [String] :module module option
# @option opts [String] :path path option
# @option opts [String] :controller controller option
# @example Route `/photos` to `Api::PhotosController`
# scope module: "api" do
# get "photos", to: "photos#index"
Expand All @@ -217,6 +218,11 @@ def namespace(path, **options, &block)
# scope path: "admin" do
# get "photos", to: "photos#index"
# end
# @example Route `/like` to `photos#like` and `/dislike` to `photos#dislike`
# scope controller: "photos" do
# post "like"
# post "dislike"
# end
# @example Nested calls
# scope module: "admin" do
# get "photos", to: "photos#index"
Expand Down Expand Up @@ -252,6 +258,19 @@ def defaults(defaults, &block)
@defaults.pop
end

# Scopes routes to a specific controller.
#
# @example
# controller "photos" do
# post "like"
# post "dislike"
# end
def controller(controller, &block)
@controllers << controller
instance_eval &block
@controllers.pop
end

# Add a route to the collection.
#
# @example Add a `photos/search` path instead of `photos/:photo_id/search`
Expand All @@ -267,6 +286,27 @@ def collection(&block)
@path_prefixes = orig_path_prefixes
end

# Add a member route.
#
# @example Add a `photos/:id/preview` path instead of `photos/:photo_id/preview`
# resources :photos do
# member do
# get "preview"
# end
# end
def member(&block)
orig_path_prefixes = @path_prefixes

if (param_prefix = @path_prefixes.last)&.start_with?(":") && @controllers.any?
member_prefix = param_prefix.delete_prefix(":#{to_singular(@controllers.last)}_")
@path_prefixes = [*@path_prefixes[0...-1], ":#{member_prefix}"]
end

instance_eval &block

@path_prefixes = orig_path_prefixes
end

# Automatically create REST routes for a resource.
#
# @example Create five REST routes, all mapping to the `Photos` controller:
Expand Down
51 changes: 51 additions & 0 deletions spec/router/dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,27 @@
end
end

context "with controller scope" do
it "correctly adds handlers" do
expect(router).to receive(:on).with("POST", "/api/v1/like", "api/v1/photos#like", instance_of(Hash))
expect(router).to receive(:on).with("POST", "/api/v1/dislike", "api/v1/photos#dislike", instance_of(Hash))
expect(router).to receive(:on).with("GET", "/api/v1/index", "api/v1/all_photos#index", instance_of(Hash))

dsl.draw do
namespace "api/v1" do
scope controller: "photos" do
post "like"
post "dislike"
end

controller "all_photos" do
get "index"
end
end
end
end
end

context "with root helper inside a scope" do
it "correctly adds handlers" do
expect(router).to receive(:on).with("GET", "/api/v1/internal", "api/test#index", a_hash_including(constraints: {}))
Expand Down Expand Up @@ -575,6 +596,31 @@ def call(env)
end
end

it "correctly creates nested routes on member" do
expect(router).to receive(:on).with("GET", "/photos/:id", "photos#show", instance_of(Hash))
expect(router).to receive(:on).with("POST", "/photos/:id/like", "photos#like", instance_of(Hash))

dsl.draw do
resources :photos, only: :show do
member do
post :like
end
end
end
end

it "correctly creates nested routes on member with a custom param" do
expect(router).to receive(:on).with("POST", "/photos/:photo_uuid/like", "photos#like", instance_of(Hash))

dsl.draw do
resources :photos, only: [], param: :photo_uuid do
member do
post :like
end
end
end
end

it "correctly creates nested resources" do
expect(router).to receive(:on).with("GET", "/albums", "albums#index", instance_of(Hash))
expect(router).to receive(:on).with("POST", "/albums", "albums#create", instance_of(Hash))
Expand Down Expand Up @@ -606,6 +652,7 @@ def call(env)
expect(router).to receive(:on).with("DELETE", "/albums/:album_slug/my_photos/:id", "photos#destroy", instance_of(Hash))
expect(router).to receive(:on).with("POST", "/albums/:album_slug/my_photos/:photo_id/add_to_album", "photos#add_to_album", instance_of(Hash))
expect(router).to receive(:on).with("POST", "/albums/:album_slug/my_photos/like_all", "photo_likes#create", instance_of(Hash))
expect(router).to receive(:on).with("GET", "/albums/:album_slug/my_photos/:id/keywords", "photos#keywords", instance_of(Hash))

expect(router).to receive(:on).with("POST", "/albums/sort", "albums#sort", instance_of(Hash))
expect(router).to receive(:on).with("PATCH", "/albums/:album_slug/tag", "albums#tag", instance_of(Hash))
Expand All @@ -618,6 +665,10 @@ def call(env)
collection do
post "like_all", to: "photo_likes#create"
end

member do
get :keywords
end
end

collection do
Expand Down
Loading