In my routes file I have the following:
Rails.application.routes.draw do
namespace :foobarbazz do
resource :blog, only: [:index]
end
end
Currently the blog resource will only be directed to the #index action on GET requests. Is there a way to make this namespaced controller action also respond to POST requests?
Create a custom router:
namespace :foobarbazz do
resource :blog, only: [:index]
post "/blogs", to: "blogs#index"
end
Also:
namespace :foobarbazz do
match 'blog', to: 'blog#index', via: [:get, :post]
end
See http://guides.rubyonrails.org/routing.html#http-verb-constraints
Related
I'm having some issues with custom routing. What I'm looking to do is remove the model from the route and dynamically use the record name.
so instead of:
site.com/events/my-event
I would like it to be:
site.com/my-event
I hacked this to work with the below code, only issue is I can't access my admin namespace as it's being treated as an event record (and any other route):
get('/:id', to: redirect do |params, request|
id = request.path.gsub("/", "")
"/events/#{id}"
end)
I know this redirect is not right, I'm just not well versed in routing options. How should this be done properly?
routes.rb
Rails.application.routes.draw do
resources :events, param: :id, path: "" do
get 'login', to: 'sessions#new', as: :login
get 'logout', to: 'sessions#destroy', as: :logout
post 'sessions', to: 'sessions#create', as: :session_create
end
namespace 'admin' do
root "events#index"
resources :sessions, only: [:create]
get 'login', to: 'sessions#new', as: :login
get 'logout', to: 'sessions#destroy', as: :logout
resources :events
end
end
Rails lets you specify what a routing URL should look like:
https://guides.rubyonrails.org/routing.html#translated-paths
You don't need redirect.
You need to match all requests to one controller/action.
get '/(*all)', to: 'home#app'
Inside this action check what is coming in params and render appropriate view.
PS: it will capture all requests, even for not found images, js, etc.
(1) To fix /admin to go to the right path, move the namespace line above the events resources so that it is matched first:
Rails routes are matched in the order they are specified 2.2 CRUD, Verbs, and Actions
# routes.rb
namespace :admin do
root "events#index"
#...
resources :events
end
resources :events, param: :name, path: ""
Use :param and :path to match for site.com/myevent instead of site.com/events/:id
Your events controller:
# events_controller.rb
class EventsController < ApplicationController
# ...
private
def set_event
#event = Event.find_by(name: params[:name])
end
end
Your admin events controller:
# admin/events_controller.rb
class Admin::EventsController < ApplicationController
# ...
private
def set_event
#event = Event.find params[:id]
end
end
TIP: To get a complete list of the available routes use rails routes in your terminal 5.1 Listing Existing Routes
I'm trying to define custom routes to my controller and I need to use some of the default routes too. Is there any simple solution?
So far I've something like this
resources :users do
member do
get 'users/:id', to: 'users#show'
delete 'users/:id', to: 'users#destroy'
end
collection do
post 'users', to: 'users#create'
post 'users/login', to: 'users#login'
end
end
resources :users, :only => [:show, :destroy, :create, :login]
I don't need nor want the index route but with this settings it's still trying to route GET users/ to user_controller index method.
I know that there is probably some simple and obvious answer but I'm not able to find it.
Thank's in advance.
You got your routes wrong. The resources :users generates seven default routes which include the index route as well. You need to tweak the code to below
resources :users, :only => [:show, :destroy, :create] do
collection do
post 'login', to: 'users#login'
end
end
Note:
If you noticed, I've removed the custom routes for show,create and delete as they are generated by default.
Your first line defines the route to the index action. Define a resource once only. Read the routing guide.
resources :users, :except => [:index] do
collection do
post 'users/login', to: 'users#login'
end
end
Run rake routes from the command line in your project root folder to see all your route definitions.
I am getting this error and can not figure out why. All my other routes work in local and remote when I open in browser but users. I am totally new to ruby and Xcode
thanks for any help
Looks to me like you need to also specify the :index action when defining the users routes:
ParkApp::Application.routes.draw do
namespace :api do
namespace :v1 do
resources :users, only: [:index, :create, :update] do
collection do
match '/me', to: 'users#show', via: :get
end
end
## Needed to allow cross origin request from webapp
match '/users/:id', to: 'users#update', via: :post
resources :sweetches, only: [:create, :update, :index]
match '/sweetches/:id', to: 'sweetches#update', via: :post
# Get the messages to display on the views
match '/message_views', to: 'message_views#index', as: :message_views, via: :get
resources :posts
end
end
match '/admin', to: 'admin#index', via: :get
match '/admin', to: 'admin#create', via: :post
match '/admin/:id', to: 'admin#destroy', as: :delete_fake, via: :delete
end
This should make the route you are trying to follow valid. If you take a look at the last snippet in your question you will see that the api/v1/users GET route isn't defined, my change to your routes will fix that.
You are getting the error because, as the error says, your application does not have a route that matches "/users".
See api_v1_users_path POST /api/v1/users(.:format) api/v1/users#create in your post. This means that the POST request to path /api/v1/users invokes the create method of your API::V1::UsersController. So send request to /api/v1/users, but not to '/users`.
I've never used Objective-C, but I guess you need to replace NSString stringWithFormat:#"/users" with NSString stringWithFormat:#"/api/v1/users".
Note that you need to send a POST request. Opening the above path in browser sends a GET request to your application, resulting in 404 not found error.
I am using the Rails-Api (4) and I want only three routes for my namespaced routes file.
In my routes.rb file, I am trying to do this:
namespace :api do
namespace :v1 do
resources :documents, only: [:get, :create]
resource :system_status, only: [:get]
end
end
rake routes gets me only this:
Prefix Verb URI Pattern Controller#Action
api_v1_documents POST /api/v1/documents(.:format) api/v1/documents#create
If a take the the only: off, it works and gives me all the routes (which I don't want).
I also tried this:
namespace :api do
namespace :v1 do
post '/documents', to: 'documents#create'
get '/documents/:id', to: 'documents#show'
get '/system_status', to: 'system_status#show'
end
end
Gets me this odd output in rake routes:
Prefix Verb URI Pattern Controller#Action
api_v1_documents POST /api/v1/documents(.:format) api/v1/documents#create
api_v1 GET /api/v1/documents/:id(.:format) api/v1/documents#show
api_v1_system_status GET /api/v1/system_status(.:format) api/v1/system_status#show
Not sure what's up with documents#show getting me only api_v1 as it's prefix.
Looks like you're getting mixed up between HTTP verbs and their corresponding Rails actions. There is no resource route for :get, but there are two routes for a GET request, which are :index, and :show
Change your original resource-based routing to this instead:
namespace :api do
namespace :v1 do
resources :documents, only: [:show, :create]
resource :system_status, only: [:show]
end
end
And that should give you the proper routes, plus the correct URL helper prefixes.
I'm trying to set up routes for a mobile API, which should have a versioned api-path. I already could make the mobile Auth work, which is implemented in a separate Controller AuthController located in /controllers/api/v1/mobile/.
Usage example:
myapp.com/api/v1/mobile/auth
But now I want to register my existing ressources-Controllers to this path-pattern as additional api-routes. Concrete: this would be the TasksController located at /controllers/tracker/tasks_controller.rb. So I added a mobile route to the routes-definition:
# routes.rb
namespace :tracker, path: 'timetracking' do
resources :tasks, 'jobs'
end
namespace :api do
namespace :v1 do
namespace :mobile do
resources :auth, :only => [:create, :destroy]
namespace :tracker do #added mobile route
resource :tasks, controller: 'tracker/tasks', as: :mobile_tasks
end
end
end
end
But when I call myapp.com/api/v1/mobile/tracker/tasks it results in an error-message:
Routing Error
uninitialized constant Api::V1::Mobile::Tracker
I especially added the alias :mobile_tasks to this route, to avoid any conflicts with the original tasks-route above. Any ideas, how to set the controller properly for this route?
Update#1
Defining this route as a scope instead of a namespace, didn't work aswell.
scope "/api/v1/mobile/tracker" do
resources :tasks, controller: 'tracker/tasks', as: :mobile_tasks
end
But this time, it didn't even resolve the route-path itself.
Routing Error
No route matches [GET] "/api/v1/mobile/tracker/tasks"
I assume it might be a problem, that my additional mobile-api route tries to point to a completely different namespace tracker.
According to http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing you should use scope instead of namespace.
If you want to route /admin/posts to PostsController (without the Admin:: module prefix), you could use:
scope "/admin" do
resources :posts, :comments
end
Adding this answer to get clarity on namespace & scope.
When you use namespace, it will prefix the URL path for the specified resources, and try to locate the controller under a module named in the same manner as the namespace.
# config/routes.rb
namespace :admin do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) admin/posts#index
When we add scope, it will just map the controller action for the given scope patterns. No need to define controller under any module.
# config/routes.rb
scope :admin do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) posts#index
Note that, controller is just posts controller without any module namespace.
If we add a path option to scope it will map to the controller with the path option specified as follows
# config/routes.rb
scope module: 'admin', path: 'admin' do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) admin/posts#index
Note that the controller now is under admin module.
Now, if we want to change the name of path method to identify resource, we can add as option to scope.
# config/routes.rb
namespace module: 'admin', path: 'admin', as: 'root' do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
root_posts GET /admin/posts(.:format) admin/posts#index
You can see the change in the Prefix Verb.
Hope it helps others.
Late answer, but still might be helpful:
scope '/v1' do
resources :articles, module: 'v1'
end
controller
# app/controller/v1/articles_controller.rb
class V1::ArticlesController < ApplicationController
end
Now you should be able to access this url:
http://localhost:3000/v1/articles