Rails routing optional prefix - ruby-on-rails

I have events which are accessible at /events/eventname I would also like the same events to be available at /events/PREFIX-eventname
I'm currently using the default:
resources :events in routes.rb
Initially idea was to add another routing statement
get "/events/prefix-:id" => "events#show"
Will adding an additional rule conflict with the resource statement? What's the best way of achieving this?

You're right! Just add another routing statement:
resources :events
get "/events/prefix-:id" => "events#show"
This will create two routes to #show action.

Related

rename rails route

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

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.

Ruby on Rails multiple methods per page in routes.rb?

Stupid question... I have two forms with two different functions on one page, my views/projects/new.html.erb file. So far I've only implemented one, with the option to "Create" a new project. I want to add another function to sort the records displayed on the same page, something like:
<%= link_to "Category", { :controller => "projects", :action => "sortTable", :filter => "Category" }, :remote => true %>
--
My routes.rb file:
Docside::Application.routes.draw do
resources :projects
resources :categories
#get "home/index"
root :to => "projects#new"
match 'project/new',:controller=>"projects",:action=>"create"
end
But I'm getting the error "No route matches {:action=>"sortTable", :controller=>"projects"}". When I tried adding " match 'project/new',:controller=>"projects",:action=>"sortTable" " my other function didn't work, and the create function got screwed up. What should I have instead?
Try that:
resources :projects do
collection do
post :sortTable
end
end
And look at this guide
You can only have one route for a given path and method combination. You're trying to define multiple routes on the same path, so only one of these will work (the first one). You should be ok if you use distinct paths for each of these actions (instead of project/new for all of them. Beware of collisions with your existing routes)
You'll also make you life easier if you stick to rails' conventions (and the code will be easier to read if someone else starts working on it). For example resources :projects already creates a route for the create action. Additional actions can be added like so
resources :projects do
collection do
get :sort_table
end
end
Sets up a collection route (ie one that isn't about a specific project) for the sort_table action and sets up a URL helper for you (sort_table_projects_path). There are alternative syntaxes you can use - I encourage you to have a look at the routing guide

Router for nested resources in a "not usual" Ruby on Rails way

I am using Ruby on Rails 3.0.7 and I am trying to set nested resource routing to make it to work in a "not regular" RoR way.
In my routes.rb file I have
resources :articles do
resources :categories, :only => [:index], :controller => 'articles/categories' # The related controller is Articles::CategoriesController
end
so that I can browse following URLs:
<my_site>/articles/1/categories
<my_site>/articles/2/categories
...
What I would to do is to access new, edit and show controller actions for categories by using the same articles/categories controller used for the nested resource stated above (that is, Articles::CategoriesController) and by accessing these URLs:
<my_site>/articles/categories/new
<my_site>/articles/categories/edit
<my_site>/articles/categories/1
<my_site>/articles/categories/2
...
How can I do that? How I must code the router?
Maybe I can do something by using the router collection method like this
resources :articles do
collection do
# match something here for the Articles::CategoriesController...
end
resources :categories, :only => [:index], :controller => 'articles/categories'
end
but I don't know how to do that.
I'm not real sure what you're trying to do with those routes, so I'm not quite sure how to answer your questions. If your intent is to be able to add a new category for a particular article, or edit all the categories for a particular article, you have to pass an ID for the article. If you're trying to create a new article and a new category all at once, you don't need category in the route, just the article and you can do something like form_for([#article,#category]) in your form and use the build method in your controller. If you can clarify, I might be able to help you further (in other words, it's not hard to construct those routes -- but it depends on what you want to do with them.

How to remove controller name in REST design in Rails3?

Given a User resource, it goes like this
/user/:shortname
But how can the controller name be removed to get just
/:shortname
How can I declare this in routes.rb while keeping all CRUD functionality instant?
Updated: After reading this I'm moving to Sinatra over Rails to handle this API-like design better.
Define a custom match:
match ':shortname' => 'users#action'
Replace action in users#action with the name of the action that is supposed to receive the request. Just remember to place it in the appropriate order in your routes file. Rails looks at each line of your routes file starting at the top and selects the first matching route. ':shortname' would match any first-level path, including /users! So put it below any routes using a first-level path, which would include all of your resource routes. Here's an example:
resources :users
resources :posts
match '/blog' => 'posts#index'
match ':shortname' => 'users#action'
In routes, you should be able to do something like
resource :users, :path => '/:shortname'
Try that out and rake routes to see if that comes out as expected.

Resources