How to map a new CRUD action in 'routes.rb'? - ruby-on-rails

In my 'routes.rb' file I have this code:
resources :users
that maps my user's controller like this.
If I want to map the "reset" view/url for users (Path: /users/reset) what code I have to insert in the 'routes.rb' file?

Two options - I'm assuming you're just going to act on the session user so you don't need to pass in an id to operate on? If so, you'll need to make a few additional changes...
Use an explicit route:
match "/users/reset" => 'users#reset', :as => 'reset_user'
The 'as' part is optional.
Add a new route that operations on a 'collection'. This gets you your route but feels like a hack, I wouldn't recommend it.
resources :users do
collection do
get 'reset'
end
end

Do this:
resources :user do
member do
get 'reset'
end
end
See this section in the Rails Guide you referred to.

Related

ruby on rails routing helper: how to create select_clients_path(client)

I have client standard resource with CRUD, but I would like to make extension with action select, so that I can have select_clients_path(client).
In clients_controller I have created action select, but I dont know how to create correct routing rule
for now I have created:
resources :clients do
get 'select'
end
but this generates /clients/select.2 but i would like somthing like /clients/select/2 or /clients/select?id=2
thank you
Dorijan
resources :clients do
collection do
get :select
end
end
will create a 'clients/select' route, to which you can pass parameters like '?client_ids=2...' and work with several client records.
alternatively,
resources :clients do
member do
get :select
end
end
will create a 'clients/:id/select' route to work with a single client record
Take a look at http://guides.rubyonrails.org/routing.html#adding-more-restful-actions for more about this functionality, but those blocks will get you pretty far.

Rails routes, how to specify this member proper

I currently have some routes that look like the following:
resources :contests do
member do
get :enter
end
end
This allows me to do an HTTP GET on a URL that looks like /contests/5/enter. Now, a user can go in, fill in some forms, and be able to submit an entry to the contest. So I'd also like to be able to POST to this URL. I tried doing the following:
resources :contests do
member do
get :enter
post :enter
end
end
This posts to the same controller#action as the GET member that I have specified, so it's not really intuitive. I'd like to be able to direct it to a separate action if at all possible. What's the best way of doing that? I am using Ruby on Rails 4 beta currently.
** UPDATE **
I tried the following but I get an ArgumentError exception when I start the server:
resources :contests do
member do
get :enter
post :enter => "contests#create_entry"
end
end
You can do something like this:
resources :contests do
member do
get :enter
post '/enter', to: "contests#create_entry", as: "create_entry"
end
end
However i agree with Ola Tuvesson, you should definitely create a new controller and routes for entries, even though you may not have a model, similiar to how you often have a session controller for login and logout. Something like this:
resources :contests do
resources :entries, only: [:new, :create]
end
You can specify the controller/action you want to point a route at.
get :enter => "controller#get_enter"
post :enter => "controller#post_enter"
I would suggest you make the entries for a contest a child model of contests. That would give you all the CRUD methods on entries and your routes would simply be:
resources :contests do
resources :entries
end
A GET of /contests/5/entries/new will give you the form for adding an entry and when this POSTs to /contests/5/entries it would create a new entry. It also makes it easy to list all entries for a competition etc. You can easily create the controller, model and the associated views with the scaffold generator, for example:
rails g scaffold Entry contest:references name:string email:string
The references column type tells the generator to link Contests to Entries in a one to many relationship. Job done.
Edit:
If you still want to rename your routes, here's how:
http://guides.rubyonrails.org/routing.html#overriding-the-named-helpers
HTH

Ruby on Rails Routes: Namespace with more params

i have a namespace "shop". In that namespace i have a resource "news".
namespace :shop do
resources :news
end
What i now need, is that my "news" route can get a new parameter:
/shop/nike (landing page -> goes to "news#index", :identifier => "nike")
/shop/adidas (landing page -> goes to "news#index", :identifier => "adidas")
/shop/nike/news
/shop/adidas/news
So that i can get the shop and filter my news.
I need a route like:
/shop/:identfier/:controller/:action/:id
I tested many variations but i cant get it running.
Anyone can get me a hint? Thanks.
You can use scope.
scope "/shops/:identifier", :as => "shop" do
resources :news
end
You will get those routes below:
$ rake routes
shop_news_index GET /shops/:identifier/news(.:format) news#index
POST /shops/:identifier/news(.:format) news#create
new_shop_news GET /shops/:identifier/news/new(.:format) news#new
edit_shop_news GET /shops/:identifier/news/:id/edit(.:format) news#edit
shop_news GET /shops/:identifier/news/:id(.:format) news#show
PUT /shops/:identifier/news/:id(.:format) news#update
DELETE /shops/:identifier/news/:id(.:format) news#destroy
http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
If you have those nike, adidas etc. in the database then the most straightforward option is to use match.
namespace :shop
match "/:shop_name" => "news#index"
match "/:shop_name/news" => "news#news"
end
However it seems to me that shop should be a resource for you. Just create a ShopsController (you don't need a matching model for it, just a controller). Then you can do
resources :shops, :path => "/shop"
resources :news
end
Now you can access the news index page (/shop/adidas) like this:
shop_path("adidas")
In the NewsController use :shop_id to access the name of the shop (yes even though it's _id it can be a string). Depending on your setup you may want news to be a singular resource, or the news method to be a collection method.
Also are you sure just renaming the news resource isn't something you want?
resources :news, :path => "/shop" do
get "news"
end
Keep in mind also that controller names and the number of controllers need not match your models. For example you can have a News model without a NewsController and a ShopsController without a Shop model. You might even consider adding a Shop model to your database if that makes sense.
In case this is not your setup then you might have oversimplified your example and you should provide a more full description of your setup.

Rails 3 routes to wrong controller

I wanted to create a new action and I call it "showemployees". That's what I did already:
-> in the controller:
def showemployees
end
-> creating app/views/employees/showemployees.html.erb
-> in config/routes
match "/employees/showemployees" => "employees#showemployees"
I thought this is enough for opening the showemployees.html.erb now via localhost:3000/employees/showemployees , but it seems like Rails still routes through the show action (from resources :employees) and doesn't take the showemployees-action, because it tells me
ActiveRecord::RecordNotFound in EmployeesController#show
Couldn't find Employee with ID=showemployees
What do I need to change so Rails takes the showemployees-action?
the source code of my route:
System::Application.routes.draw do
match "/employees/showemployees" => "employees#showemployees" #für showemployees.html.erb
root :to => "employees#index"
resources :course_to_dos
resources :current_qualifications
resources :expected_qualifications
resources :skills
resources :employees
resources :positions
resources :admin
end
try to walk by Rails-way, if you want to get collection, use the collection
resources :employees do
collection do
get :showemployees
end
end
If you post your full routes file we can make a definitive call, but based on the error message, it looks like you have a broader route definition mapping to employees#show defined above this route in such a way that it is getting matched.
Routes are evaluated in the order they are defined, so if you have a very broad route pattern defined above a narrow one, your narrow route will never be called.
edit: you'll want to take the forward slash out of your route and add the showemployees to the actual URL, so that it reads
match "employees/showemployees" => "employees#showemployees"

Is it possible to specify a named route within a resourceful route?

I'm just upgrading my app to Rails 3 and as I have to rewrite my routing anyway, I'm taking some time to improve my named routes.
I have an invoices controller which has a trash action (/invoices/trash lists all invoices in trash). I want to access this through a named route (i.e. trash_url) for simplicity in my views.
I can achieve this easily enough with the following
match "/invoices/trash" => "invoices#trash", :as => :trash
What I want to know is if there is a way of doing this within the block where I define the routes for my invoice controller. I have tried the following and it doesn't work.
resources :invoices do
collection do
get :trash, :as => :trash
end
end
Is what I am trying to do possible or do I have to define my named route outside of this block?
Thanks.
The method you list (shown below) works fine for me, it generates trash_invoices_path and trash_invoices_url helper methods.
resources :invoices do
collection do
get :trash, :as => :trash
end
end
You can make methods in your application controller named trash_url and trash_path that just call and return the path from the generated methods mentioned above if you have a need to use those specific method names instead of the generated ones.

Resources