Pergunta

I have two models:

Reservation:

class Reservation < ActiveRecord::Base
  has_one :car_emission
end

CarEmission:

class CarEmission < ActiveRecord::Base
  belongs_to :reservation
end

and following routes:

resources :reservations do 
  resources :car_emissions
end

Now when I want to create new car_emission i must visit url like this:

http://localhost:3000/reservations/1/car_emissions/new

and when i want to edit I must visit:

http://localhost:3000/reservations/1/car_emissions/1/edit

Is there anyway to change routes that my car_emission edit link will look like this:

http://localhost:3000/reservations/1/car_emission
Foi útil?

Solução

You want to do several things:

1. Create singular resource
2. Change the `edit` path for your controller

Singular Resource

As suggested by @sreekanthGS, you'll firstly be best creating a singular resource. This works in the same way as the resources method, except it treats your route as a single record; doing away with the index route etc:

#config/routes.rb
resources :reservations do
    resource :car_emission # -> localhost:3000/reservations/1/car_emission
end

Edit

This will create a set of RESTful routes for your car_emission , but it will still take you to the car_emissions#show action when you hit the "naked" link

You'll be best doing this:

#config/routes.rb
resources :reservations do
    resource :car_emission, except: :show, path_names: { edit: "" }
end

This will take you to the edit action when you hit the "naked" link

Outras dicas

Try:

resources :reservations do 
  resource :car_emissions
end

There is something called Singular Resources:

http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default

Quoted:

Section: 2.5 Singular Resources

Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like /profile to always show the profile of the currently logged in user. In this case, you can use a singular resource to map /profile (rather than /profile/:id) to the show action:

get 'profile', to: 'users#show'

Passing a String to get will expect a controller#action format, while passing a Symbol will map directly to an action:

get 'profile', to: :show

This resourceful route:

resource :geocoder

creates six different routes in your application, all mapping to the Geocoders controller.

shallow: true might be what you want

resources :reservations, shallow: true do 
  resources :car_emissions
end

shallow: truewill nest index, create and new actions of :car_emissions inside the :reservations. update action will not be nested inside.

This will give you routes that look like this:

GET  /reservations/:reservation_id/car_emissions(.:format)   caremissions#index
POST     /reservations/:reservation_id/car_emissions(.:format)   caremissions#create
GET  /reservations/:reservation_id/car_emission/new(.:format) caremissions#new

GET  /reservations/:id/edit(.:format)    reservations#edit
PATCH    /reservations/:id(.:format)     reservations#update
PUT  /reservations/:id(.:format)     reservations#update
DELETE   /reservations/:id(.:format)     reservations#destroy
GET  /reservations/:id(.:format)     reservations#show

Link of this type

http://localhost:3000/reservations/1/car_emission

is given to show car emissions for restful resources and so using it for simple edit like the one you used above may clash with restful resources.

You may optionally make a separate Singular resource and and direct it to your desired route.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top