rename rails route - ruby-on-rails

I have a route/path using CcpaAcknowledgmentsController
/ccpa_acknowledgments
I would like the route to be, BUT I would still like it to use the CcpaAcknowledgmentsController
/customers/ccpa_acknowledgments
Since I have these two routes...
resources :customers
resources :ccpa_acknowledgments
match '/customers/ccpa_acknowledgments', to: 'ccpa_acknowledgments#index', via: [:get]
I keep getting a conflict stating
NoMethodError in CustomersController.
Is there a way to get the desired route I want without putting the method/code in the CustomersController?

This is the way to do that
resources :customers do
get :ccpa_acknowledgments, to: 'ccpa_acknowledgments#index', on: :collection
end
Inside the customers block for two reasons:
we are fine with the beginning of the path /customers
we don't want to mess with the other customers' routes. In this way your route inside the block is before the customers default routes and it's not seen as you are calling customers/:id with ccpa_acknowledgments as id because rails takes care of that for you defining that route before the show
Then
get :ccpa_acknowledgments
because we need the second part of the path /ccpa_acknowledgments
to: 'ccpa_acknowledgments#index'
we want to specify the controller and action pair, because we want to use the CcpaAcknowledgmentsController even though we're inside the customers block
on: :collection
because we don't want any :id inside our route. It's a route defined on the customers collection
alternative using resources as asked in the comment. Try
scope :customers do
resources :ccpa_acknowledgments, only: :index
end
but you need to put this before the resources :customers

Related

Can I customize the `resources` helper in my routes to use a parameter other than \:id?

I have a route that looks like this:
get '/sell/:ticker', to: 'sell#new', as: 'sell'
That does what I want, which is allows get requests to myapp.com/sell/ABC.
I have another route, resources :stocks that I would also like to be able to specify for it to use /:ticker, rather than /:id in all the routes.
Is there some way for me to modify the resources helper to use \:ticker rather than \:id, without having to write every route individually?
I believe you should be able to use the param in routes file as,
resources :stocks, param: :ticker

What's the "Rails way" to route a "diff" between two instances of the same model?

I'm building a "Brand personality" tool that gives you a report based on the text you share on social media.
I have a model PersonalityReport and in routes I have resources :personality_reports.
A new feature is to offer a "diff" between two reports and I'm trying to work out the most "guessable" way to model this in routes.
Ideally I'd like GET /personality_reports/:personality_report_id/diff/:id or something along those lines, and while I could simply put that into routes as a GET route, is there a more Railsy way of specifying a route using the resources / collections style so that my routes.rb file is more easy to understand?
The 'neatest' way can think of is:
resources :personality_reports, param: 'personality_report' do
member do
get 'diff/:id', to: 'personality_reports#action', as: 'diff_route'
end
end
Where obviously to: is your controller#action, and as: is the name of your route. After running rake routes you will see this generates:
diff_route_personality_report GET /personality_reports/:personality_report_id/diff/:id(.:format) personality_reports#action
I think whatever you mentioned is good enough,
resources : personality_reports do
resources :diffs, only: [:show]
end
So, routes like below,
personality_report_diff GET /personality_reports/:personality_report_id/diffs/:id(.:format) diffs#show
NOTE: You can also make diff route in singular resource :diff if you want to make it as singular resource.

Rails: in controller, a new view is always rendered by `show`?

I want to implement a search function in the controller, which contains "show, new, create, etc..."
I added in route.rb:
get 'apps/search' => 'apps#search'
and in apps_controller.rb:
def show
#app_info = App.find(params[:id])
end
def search
# get parameter and do search function
end
but each time when i request the /apps/search?xxx=xxx then it will be rendered by show... and then search?xxx=xxx is the parameter for method show...
should I rather create a new controller for search? Or is it possible to implement search as my requirements?
Your routes are incorrectly prioritized - somewhere else in your routes file (before the get 'apps/search' line) you have resources :apps, which defines a route that matches the same regex as apps/search.
Routes match from top to bottom, so if you check the output of rake routes, you'll see that your request to apps/search is actually matching apps/:id - which is the show route of your apps resource.
Either move the apps/search route above the resources :apps declaration, or alternatively declare your search route as part of the apps resource, eg.
resources :apps do
get :search, on: :collection
end
(this will define apps/search in the way you want).
For more information on routing: http://guides.rubyonrails.org/routing.html
I think you should edit route.rb as the following:
get 'apps/search' => 'apps#show'
The Rails' way to "say" search is a new route to the apps controller is using collection. So, for example, supposing you already have a resources :apps, you can do:
resources :apps do
get 'search', on: :collection #or you can use another HTTP verb instead of get
end
And that would give you:
search_apps GET /apps/search(.:format) apps#search

Rails routing not giving wanted result

I have the following route:
#routes.rb
get "(/questions_groups/:group_id)/questions/new" => "questions#new", as: "new_question"
resources :questions
Id like calling the new_question_path(#question_group) where #question_group.id = 1 to return the path:
/questions_group/1/questions/new
Yet it returns:
/questions/new?group_id=1
When I remove the resources :questions I get the correct path but lose all my routes, how can I solve this problem?
Just call it something different. When you define the resource it comes loaded with a whole bunch of url helpers, in your case one of them is new_question, which is the same name as your custom route. If you're trying to replace the route for the new question then tell the resource not to define its own with:
resource :questions, except: :new
Try this
match "/questions_groups/:group_id/questions/new" => "questions#new", as: "new_question"

How should I route to actions that are not nested that are in a controller that is nested?

I have a resource - activities, that is nested under provider. everything is working great for all my restful resources.
I'd like to add a new action to list all activities regardless of provider. So I think that should not be nested.
I tried to do this like so:
resources :activities, only: [:list]
But this doesn't create a route when i rake routes, and I get the error:
No route matches [GET] "/activities/list"
How do I do this? Is this the right way to go about what I want to do - show a list of all providers activities with a different view / layout than the nested provider#activities action.
OK. I (re) read the manual and did what it said, and that worked. Go figure.
resources :activities do
get 'list', :on => :collection
end
So that adds the list action to the routes with path & url methods & the nested resources still work.

Resources