Renaming path helpers in Rails 3 routing - ruby-on-rails

I have a projects controller/model. Instead of listing projects on the #index page, I show a list of drop downs, which submits to projects#select, which finds the right Project (I've made sure there can only be 1 for each combination of options) and forwards the user to the #show page for that Project.
So for my routes I do this...
resources :projects, :only => [:index, :show] do
collection do
get 'select'
end
end
And thats fine, but the helper method for #select is 'select_projects', which is understandable but in my case I really want 'select_project'. And I really don't want to alias this in another file. No problem I can use :as...
resources :projects, :only => [:index, :show] do
collection do
get 'select', :as => 'select_project'
end
end
But now my helper is 'select_project_projects'. So I cheat a little (still better than aliasing in another file)...
resources :projects, :only => [:index, :show]
match '/projects/select', :to => 'projects#select', :as => 'select_project'
This looks like it might work, but it doesn't because /project/select actually matches the route for 'project#show'. Changing the order of the lines does the trick.
match '/projects/select', :to => 'projects#select', :as => 'select_project'
resources :projects, :only => [:index, :show]
But is there a more elegant way of handling this? I realize this is borderline OCD, but I'd like to be able to have complete control over the route name within the resources block.

use resource instead of resources

you probably don't want to make it a collection route but a member route:
resources :projects, :only => [:index, :show] do
member do
get 'select'
end
end
This way you'll have the select_project helper.

For those that want to rename the helper method side of things (as the title suggests):
resources :posts, as: "articles"

Related

How to create a custom route inside resource without overwrite path

I’ve this on routes.rb
resources :questions, except: [:show] do
get '/resource/:subject/:id', to: 'resource#show', as: "resource", param: [:name, :id]
It says that:
Invalid route name, already in use: ‘resource' You may have defined two routes with the same name using the :as option, or you may be overriding a route already defined by a resource with the same naming
I know that resources create two routes with the same path, show and destroy both uses resource_path, how does it is being created internally? and how i can generate my route for show wihtout overwrite the one in destroy?
A good way to eliminate routes unneeded is by specifying the :only option
resources :user, :only => [:edit]
instead of
resources :user, :except => [:new, :create, :edit, :update, :show, :destroy]
It seems to me that you could take out show and then define the route that you want separately. See if this works:
resources :questions, except: :show
get '/resource/:subject/:id',
to: 'resource#show',
as: "resource", # This is where the error is.
param: [:name, :id]
EDIT: Ah, yes. The :as parameter needs a different name. This will work:
resources :questions, except: :show
get '/resource/:subject/:id',
to: 'resource#show',
as: "resource_show",
param: [:name, :id]

Two routes with multiple parameters to single controller's method?

Let's assume I have models: Article, Post, and Comment. For these models I need to map CommentsController#show in articles and posts. Something like this:
resources :articles do
resources :comments, :only => [:show]
end
resources :posts do
resources :comments, :only => [:show]
end
And this works perfectly, i.e. it'll generate routes something like this:
/articles/:article_id/comments/:id
/posts/:post_id/comments/:id
Both pointing to the same controller's single method: CommentsController#show
What I need is to include more/multiple parameters for posts while retaining the same URL routes to CommentsController:
/articles/:article_id/comments/:id
/posts/:post_id/:post_title/:post_year/comments/:id
I tried match but first occurrence at resources :articles do... overrides it.
resources :articles do
resources :comments, :only => [:show]
end
match '/posts/:post_id/:post_title/:post_year/comments/:id', :to => 'comments#show', :as => :show_post_comments
It throws an error:
No route matches {:controller=>"comments", :action=>"show",
:post_id=>10, :post_title=>"some title", :post_year=>"1995", :id=>"1"}
So, is it possible to create such a route with multiple parameters to single controller's method in two resources using get or something?

Rails Adding New Page to Resource (with parameter)

I am trying to add a few new pages to a rails resource that I am creating.
What I am doing in my routes file is as follows:
resources :users, :only => [:index, :show] do
collection do
get :show_subpage1
end
end
When I look at my routes, show_subpage1 shows up, but not in the format I want. What shows up in the routes is:
show_subpage1_users GET /users/show_subpage1(.:format)
When what I WANT the route to be is:
show_subpage1_users GET /users/:id/show_subpage1(.:format)
(with the ID).
How would I go about doing that in rails?
To get:
show_subpage1_users GET /users/:id/show_subpage1(.:format)
do not define :show_subpage1 as a collection route:
resources :users, :only => [:index, :show] do
get :show_subpage1
end
or you could define it as a member route as follows:
resources :users, :only => [:index, :show] do
member do
get :show_subpage1
end
end
Also, I'm unsure why you have :only => [:index, :show] defined if you are also going to have a member route :show_subpage1. I assume you do want to add add :show_subpage1 to the only array, i.e. resources :users, :only => [:index, :show, :show_subpage1] do.
Please take a read on "Adding More RESTful Actions"
there are two ways with resources member or collection
resources :users, :only => [ :index, :show ] do
# /users/:id/profile
get 'profile', :on => :member
# /users/profile
get 'profile', :on => :collection
end
hope this helps

Resource route members. Plural url with singular method name?

I have the following resource block
resources :projects, :except => [:destroy] do
resources :tasks, :except => [:index]
get "tasks/:id/change_state" => "tasks#change_state", :as => "task_change_state"
get "tasks/:id/assign_user" => "tasks#assign_user", :as => "task_assign_user"
get "tasks/:id/unassign" => "tasks#unassign", :as => "task_unassign"
end
I'm wondering how I can refactor those routes a bit without touching the path. I tried doing the following:
resources :projects, :except => [:destroy] do
resources :tasks, :except => [:index] do
member do
get 'change_state'
get 'assign_user'
get 'task_unassign'
end
end
end
But that leaves the route method names with tasks as plural. I need the URL to be plural, much like in the original get method call. But I need the method name to be singular, as I would prefer to not change the implementation across the app.

How do I make my UsersController work nicely with current_user?

Users can view and edit account information in my app using UsersController
This controller only ever shows information about the current user.
I want to adjust the routes so that:
get /account accesses UsersController#show, user_id is retrieved from a current_user variable
get /account/edit similarly accesses UsersController#edit
put /account/ will hit UsersController#update, again using current_user instead of an ID
Basically I want to refer to UsersController as 'account' in my URLs and I don't want to use IDs because I'm always just using the current user. I also don't want URLs like /users/1 to function at all.
How can I achieve this?
I think that you are talking about singular resources.
http://guides.rubyonrails.org/routing.html#singular-resources
# Not sure if you need this
resource :users, :only => [:index, :create, :destroy]
# This is what you are looking for
resource :user, :as => :account, :only => [:show, :edit, :update]
Update
Since you need "/account" instead of "/user", you should do
resource :account, :controller => :users, :only => [:show, :edit, :update]
Given your setup, you probably have something like this in your routes.rb:
resources :users
You should be able to just change it to this:
resources :users, :as => "account"
I haven't tested it but this should work. For more info, check the Rails guides on Routing.
Two ways to do it:
In your route.rb:
resources :users, :as=>'accounts'
In your route.rb, remove resources :users and add:
match '/account'=>'users#show'
match '/account/edit'=>'users#edit'
match '/account/'=>'users#update'

Resources