It used to work but after some changes, Action Controller is catching an exception
Routing Error: No route matches [GET] "/clock_events/1/clock_in"
routes.rb file:
Rails.application.routes.draw do
root to: 'clock_events#index'
get '/register', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
get '/logout', to: 'sessions#destroy'
resources :clock_events, except: [:destroy] do
member do
post 'clock_in', to: 'clocks#clock_in'
post 'clock_out', to: 'clocks#clock_out'
end
end
resources :users, except: [:destroy]
end
You've defined clock_in with the post http verb, here:
resources :clock_events, except: [:destroy] do
member do
post 'clock_in', to: 'clocks#clock_in'
post 'clock_out', to: 'clocks#clock_out'
end
end
But, you're trying to use the get verb, as indicated here:
Routing Error: No route matches [GET] "/clock_events/1/clock_in"
You need to either change your path to use the get verb:
resources :clock_events, except: [:destroy] do
member do
get 'clock_in', to: 'clocks#clock_in'
post 'clock_out', to: 'clocks#clock_out'
end
end
Or modify your link (or whatever) to use the post method.
Also, your clock_in and clock_out actions are called on the clocks controller, not the clock_events controller, as indicated by your to: directive:
resources :clock_events, except: [:destroy] do
member do
post 'clock_in', to: 'clocks#clock_in'
post 'clock_out', to: 'clocks#clock_out'
end
end
Are you sure you don't want to use the ClockEventsController? If so, you could do:
resources :clock_events, except: [:destroy] do
member do
post :clock_in
post :clock_out
end
end
In which case you would get:
clock_in_clock_event POST /clock_events/:id/clock_in(.:format) clock_events#clock_in
clock_out_clock_event POST /clock_events/:id/clock_out(.:format) clock_events#clock_out
clock_events GET /clock_events(.:format) clock_events#index
POST /clock_events(.:format) clock_events#create
new_clock_event GET /clock_events/new(.:format) clock_events#new
edit_clock_event GET /clock_events/:id/edit(.:format) clock_events#edit
clock_event GET /clock_events/:id(.:format) clock_events#show
PATCH /clock_events/:id(.:format) clock_events#update
PUT /clock_events/:id(.:format) clock_events#update
Related
I'm using the friendly_id gem in a Rails application, to be able to view organisations at site.com/organisation-name
The problem is that I have a few static pages like "About" and "Contact" at site.com/about and friendly_id assumes these pages should point to a record, hence I get this error.
ActiveRecord::RecordNotFound in OrganisationsController#show
can't find record with friendly id: "about"
routes.rb
resources :organisations, path: "", except: [:index, :new, :create] do
resources :posts
end
get '/organise', to: 'home#organise'
get '/privacy', to: 'home#privacy'
get '/about', to: 'home#about'
get '/terms', to: 'home#terms'
Is there a way to ignore these routes at all, or do I need to prefix them with something else?
The solution was to simply reorder my routes to put the static page routes above my organisations route definition:-
get '/organise', to: 'home#organise'
get '/privacy', to: 'home#privacy'
get '/about', to: 'home#about'
get '/terms', to: 'home#terms'
resources :organisations, path: "", except: [:index, :new, :create] do
resources :posts
end
In my routes.rb file, I have the following code:
Rails.application.routes.draw do
get 'getTodos', to: 'todos#get'
get 'getUsers', to: 'users#get'
get 'getStates', to: 'states#get'
post 'addTodo', to: 'todos#add'
post 'addUser', to: 'users#add'
delete 'deleteTodo/*id', to: 'todos#delete'
delete 'deleteUsers/*IDs', to: 'users#delete'
delete 'deleteAllTodos', to: 'todos#delete_all'
put 'updateTodo', to: 'todos#update'
end
How can I modify this code to make it more beautiful and correct?
The biggest issue with this code is that its completely unidiomatic. In Rails you create, read, update and destroy (CRUD) resources through the following routes:
HTTP Method Path Controller#Action
GET /todos(.:format) todos#index
POST /todos(.:format) todos#create
GET /todos/new(.:format) todos#new
GET /todos/:id/edit(.:format) todos#edit GET /todos/:id(.:format) todos#show
PATCH /todos/:id(.:format) todos#update
PUT /todos/:id(.:format) todos#update
DELETE /todos/:id(.:format) todos#destroy
The key here is the combination of the HTTP method and path.
GET /todos gets you all the todos while GET /todos/:id shows you a specific resource.
GET /todos/new displays the form to create a new todo. POST /todos actually creates the resource from a form submission.
GET /todos/:id/edit displays the form to edit a todo. PATCH /todos/:id actually updates the resource from a form submission.
DELETE /todos/:id - You should be able to guess what this does.
You can generate these routes with:
Rails.application.routes.draw do
resources :todos
end
If you want to define a routes that deletes all the todos RESTfully it should be defined as DELETE /todos (without an id).
Rails.application.routes.draw do
resources :todos do
delete '/', on: :collection, action: :destroy_all
end
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
See:
Rails Routing from the Outside In
I would do something like this. Try to use default Rails REST actions instead of overwriting them
Rails.application.routes.draw do
resources :todos, only: [:index, :create, :update, :destroy] do
collection do
delete :delete_all, to: 'todos#delete_all'
end
end
resources :users, only: [:index, :create, :destroy]
resources :states, only: :index
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
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.