I have a big feature called 'press releases'.
Client wants URL to say /updates rather than /press_releases.
Basic CRUD.
Is it possible to change the URL without renaming everything?
For example, when I say resources_path - is it possible to make it generate link /updates ?
Routes look like this:
resources :press_releases, except: :new do
collection do
post 'sort'
end
end
You can use a combination of options to do this.
The controller option allows you to specify a controller to use for the routes, and the as option allows you to rename the helpers.
So, something like this should work:
resources :updates, controller: 'press_releases', as: 'press_releases', except: :new do
collection do
post 'sort'
end
end
Sure,
resources :press_releases, :path => "/updates", except: :new do
collection do
post 'sort'
end
end
Related
I am a beginner working with Rails: I have this routes.rb:
Rails.application.routes.draw do
resources :requirements
root "department#index"
get "department/about"
end
How can I create a view that has a path like requirements/major?
Thank you so much!
You can extend resources and add custom actions, like this:
resources :requirements do
collection do
get :major
end
end
You'll need an action in the RequirementsController that matches, e.g.
class RequirementsController < ApplicationController
def major
# set up whatever resource 'major' corresponds to
end
...
end
That's at least one way of doing it. You could also have a controller that directly supports the nested 'major' resource, which would be similar to above - just with a controller: 'name of controller' directive inline..
It'd probably pay to get your head around the "Rails Routing from the Outside In" guide: https://guides.rubyonrails.org/routing.html
I have a nested resource:
resources :res1 do
resources :res2
end
And I have a custom action in res2:
def my_action
end
which doesn't appear in the list of the pre-generated paths (there is no res1_res2_my_action_url url). I want to refer to my_action using controller and action notation but the following doesn't work:
url_for(controller: [:res1, :res2], action: :my_action)
Why is that?
The resources directive in your routes file will only create default routes for your controller.
#index
#new
#create
#show
#edit
#update
#destroy
If you want to add custom routes, you'll have to declare them like so:
resources :res1 do
resources :res2 do
get :my_action
end
end
you can hard code a specific route that points to action and controller:
get '/pathname', to: 'controller_name#my_action'
Try running rake routes and see what o/p you get,a try to apply in your view
get 'my_action' => "res2#my_action"
and then write
:url => my_action_path
Actually I don't understand how to correctly handle this. I have a situation where news could be managed with admin/edit admin/show admin/news... and similar paths, however I want to give users a page called news/show/1, because actually my news resources are routed under "admin" namespace, how should I handle the fact that I need to bind news routes outside "admin" namespace?
Actually I have only this:
namespace :admin do
resources :news
end
My Idea:
namespace :admin do
resources :news
end
resources :news
Then I'll have:
app/controllers/admin/news_controller.rb
app/controllers/news_controller.rb
Is this correct?
Seeing your answer, I can suggest more simpler routes.
#routes.rb
namespace :admin do
resources :news
end
resources :news, :only => [:show]
If you want index action too, rewrite the last line as:
resources :news, :only => [:index, :show]
You won't need the helper for news_path and news_url. You will get them already built for you.
Ok after working a bit on routes, I understood how to build what I wanted:
namespace :admin do
resources :news
end
get 'news/:id(.:format)' => 'news#show'
This because I don't need all routes for my news, but only show (well I may add index too, but not required at the moment). In this way I can handle everything on 2 different controllers, which is better, because I use somethings like redirects on the news controller which I don't use on Admin::NewsController.
I noticed another important thing, if you build routes in this way news_path and news_url won't be created. Because of this, I had to manually create them in this way in news_helpers:
module NewsHelper
def news_url(record)
url_for controller: 'news', action: 'show', only_path: false, id: record.slug
end
def news_path(record)
url_for controller: 'news', action: 'show', only_path: true, id: record.slug
end
end
(slug is for seo-friendly urls) Then I simply included the helper in my controller in this way:
class NewsController < ApplicationController
include NewsHelper
Everything is worked as I wanted and looks great too.
Let's say I have a receipts model, and I want to offer a controller action to print one... The un-restful way would be to do:
# receipt_controller.rb
def print
...
end
#routes.rb
resources :receipts do
get :print, :on => :member
end
... The restful way would be:
# receipt_printings_controller.rb
def create
...
end
#routes.rb
resources :receipts
resources :receipt_printings, :only => :create
My question is..... Let's say I wanted to have the following structure:
/app
/controllers
receipts_controller.rb
/receipt
printings_controller.rb
That would mean my class would look like:
class Receipt::PrintingsController < ActiveRecord::Base
def create
...
end
end
But I don't know how to properly route in this context because I still need to be able to do:
receipt_printings_path(123) to get /receipts/123/printings
The only way I know how to accomplish this is to do:
#routes.rb
match "/receipts/:id/printings" => "receipt/printings#create", :as => :receipt_printings
resources :receipts
But, I am wondering if there is a better way?
I think you can do something like this:
resources :receipts do
resources :printings, :controller => "receipt/printings", :only => :create
end
It will generate :
receipt_printings POST /receipts/:receipt_id/printings(.:format) receipt/printings#create
Then to access to your route :
receipt_printings_path(:receipt_id => #receipt.id)
I hope it helps
If i'm right, you need a nested resource, have look in this rails guide
You can use nest routes, but the way I read your question it sounds to me like you want namespaces. Namespaces might look like the following:
resources :receipts
namespace :receipts do
resources :printings
end
This would route /receipts/printings/:id to app/receipt/printings_controller.rb with an id for the printing (not the receipt).
You might really want nested routes. If you want to use the receipt id, and have only one print action (per receipt), you could use a singular resource.
resources :receipts do
resource :printing
end
This will route /receipts/:id/print to app/printings_controller.rb as show.
To organize the printings controller in a namespace, I would leave it out of the routes, because that will try to insert another receipts namespace in the URL. Instead, use,
resources :receipts do
resource :printing, :controller => "receipt/printings"
end
This is how to be RESTful. However, you might not have a RESTful case. Is printing really doing a create? Is it really doing a show or update? If it's a service which doesn't fit into a CRUD operation, then it's time to deviate from the golden path, and go ahead and use a non-RESTful verb.
Since I used scaffolding to create my Deposit model,
resources :deposits
generates a bunch of routes. i want to be able to delete some of those routes for particular models. For example I do not want a "deposts/23/edit" route. I know I can do a redirect in the controller or do a
match "deposits/:id/edit", :to => "deposit#new"
which just shows the new deposit page but does not change the url on the browser.
is there a way to completely remove a certain action through declaring something in the rails routes.rb file. so that particular actions are just not accessible.
I reccomend looking over the Ruby on Rails Guide for Routing it discuses important core concepts and presents you with some good information on how routes are wired the way they are.
If you still wish to remove the edit route you will find a useful part of the guide here the code you need is listed below:
resources :deposits, :except => :edit
resources :deposits, :only => { :create, :new }
resources :deposits, :except => :edit