Missing :action key on routes definition Rails - ruby-on-rails

I am getting the following error:
Missing :action key on routes definition, please check your routes.
For this route
resources :groups do
post '/groups/:id/add', on: :member
end
I have looked at several other SO answers on this but am not able to find one that helps me. What action is it missing?

This is not the right way to define routes. Actually router's member/collection accepts a key-value pair to generate the route. As you are defining a member function it will be like:
resources :groups do
member do
post :add
end
end
It will generate a route like: groups/1/add
If you use collection then it will generate: /groups/add
resources :groups do
collection do
post :add
end
end
Hope you get the idea.
Or
You can define specific route for this particular action like below:
match "/groups/:id/add" => "groups#add", via: :post

Key action here means controller action. as in
resources :groups do
post '/groups/:id/add', on: :member, action: "add"
end
Rails can't infer the action from a path. But you can define the action instead and rails will automatically figure out the path:
resources :groups do
post :add, on: :member
end

Related

need help on rails nesting routes

I want to get a route like
GET /example/notifications/status, to: example/notification#status
POST /example/notifications/disable to: example/notification#disable
Here is what I did
resources :example, only => %i[index] do
collection do
resources :notifications, :only => [] do
collection do
get :status
post :disable
end
end
end
end
it get the right path but it point to notification#status not example/notification#status
is there any way I can get both right path and controller expect code like
get "notifications/status", :to => "example/notifications#status"
You can use namespace for this purpose like below,
in you config/routes.rb file
namespace :example do
collection do
get :status
post :disable
end
end
It will hit the example/notification#status action.
for more information see here
Don't use resources since you don't want (aparently) any param on your routes. Go for namespace instead:
namespace :example do
namespace :notifications do
get 'status'
post 'disable'
end
end
Gives you:
$ rails routes -g example
Prefix Verb URI Pattern Controller#Action
example_notifications_status GET /example/notifications/status(.:format) example/notifications#status
example_notifications_disable POST /example/notifications/disable(.:format) example/notifications#disable

Is there a succinct way to define custom routes within a resource?

Here's some code I have:
resources :things
post "/foo/bar" => "things#create"
Is there a more succinct/maintainable way to define the custom post route inside a block given to resources?
To answer the title question, use this in your routes file:
resources :things do
post 'foo/bar', on: :member, to: 'things#create'
end
If you want to create all the things routes under the foo path instead of things, use a path parameter to the resources call:
resources :things, path: 'foo'

Upgrading routes in Rails 3

Currently I have something like this:
resources :books do
collection do
get 'search'
end
end
and my controller name is also "books" and I have a action method called "search" inside it
I would like that "get search" part to also be a resource, kind of like nested resources... but I don't want to break other peoples codes that are using the current route that this generate, so need to update it in a passive way!
resources :books do
collection do
get 'search'
end
resources :searches
end
...if I'm understanding you correctly, that should be what you want. It won't break other routes, just add new ones.
Run rake routes to make sure you have all the routes you want/need.
Use shallow routes nesting like:
resources :books , :shallow => true do
resources :searches
end
Now you will get the following routes:
/books/1 => books_path(1)
/books/1/searches => books_searches_index_path(1)
/searches/2 => searches_path(2)
Similarly you can get separate routing for defined routes like:
get '(:books)/searches', :to => 'books#index'

rails custom rest route with parameter

I have a questions controller and an associated model and a number of rest routes. Here is how it's set up in routes.rb:
resources :questions
I want to add a custom route that has the format /questions/widget/ID (where ID is the id of the question for which I want to generate a widget). I want this to be processed by the "widget" action in my questions controller. I've tried a number of things such as:
resources :questions do
member do
get 'widget/:id'
end
end
But nothing is working. I'm sure I'm missing something simple. Any ideas? Thanks in advance.
You do not have to specify the id since you are inside resources. It should look like:
resources :questions do
member do
get 'widget'
end
end
You can get more information from the Rails Guide. Look at section 2.9.1.
Edit: I just noticed that you are trying to match get /questions/widget/:id. This will set up a route for get /questions/:id/widget. This is more in line with Rails convention. If you really want it the other way, you need to set up a custom match statement:
match "/questions/widget/:id" => "questions#widget"
However, I would stick with convention.
I know it is old, but looking to fix another routing problem I ended here, it is possible, to do what you are asking for, here is an example
resources :articles do
get 'by_tag/:tag' => :by_tag, on: :collection
get 'by_author/:author' => :by_author, on: :collection
resources :comments, except: :show
end
now you have /artices/by_tag/:tag . The trick was to use on:collection.
Obviously don't forget to add the by_tag action and by_author.
class ArticlesController < ApplicationController
.....
def by_tag
...
end
end
Check this route works with
melardev#local~$ rails routes
Why don't you use this routes:
resources :questions do
resources :widgets
end
it will create path like questions/:question_id/widgets/new for you to create new widget for question with specific id of question.
This is what ended up working for me:
resources :post do
get "author/:author", to: "posts#author", on: :collection, as: "author"
end
Which outputs the following route:
author_posts GET /posts/author/:author(.:format) posts#author
Then in your controller, you need to create the author action:
class PostsController < ApplicationController
def author
#roles = Post.where(author: params[:author])
render :index # to reuse the index view
end
end
Then in your view:
<%= link_to post.author, author_posts_path(post.author), data: { turbo_frame: "_top" } %>

Rails routes for get request with query params

I need a route to accept a request reports#show with an attached :query parameter and I can't figure out how to write it. It needs to respond to this link in my view:
= link_to report_path(query: params[:query]) do
config/routes.rb
resources :reports do
resources :chapters
resources :pages
end
Tried variations of: get '/reports/:id/:query', :as => 'reports_query' but I keep getting:
Routing Error
No route matches {:action=>"show", :controller=>"reports", :query=>"europe"}
Project is mostly RESTful but I'll take anything that works at this point. Thanks for any help.
You should define your route to query with code like this
# routes.rb
resources :reports do
get ':query', to: 'reports#show', on: :member, as: :query
end
It will generate path helper you can use that way
= link_to 'Query Report', query_report_path(#report, query)
I went through the same problem here, and I solved it using the default param while defining my routes.
get :twitter_form, defaults: { form: "twitter" }, as: :twitter_form, to: "campaigns#show"

Resources