Rails: custom url - ruby-on-rails

I am newbie in rails. In my demo app I can show all my products list in http://localhost:3000/products and each product has show, edit, delete option. When I click on the show link, I go to the specific product and I get a url for that product like
http://localhost:3000/products/5 (that is id after /products/) but I want two things to add
1) When I click on show button my url should be something like this
http://localhost:3000/products/display
Id should not be after products. Only display should be.
2)and I want to add another button from where I can show all the products list in another url like http://localhost:3000/products/displayall that is my all products will show both in http://localhost:3000/products and http://localhost:3000/products/displayall

You could use this to overwrite the default CRuD behavior
resource :products do
get ':id/show', :to => :show
get ':id/display', :to => :show
get 'displayall', :to => :index, :on => :collection
end
http://guides.rubyonrails.org/routing.html
As in the link below described under 2.10.1 use :on => :member to add a restful link who is able to recognize /products/:id/display otherwise the example below.

You've cited the show, edit, and delete actions, so you're presumably defining resourceful routes. If this is correct, you will be able to add custom routes to your Product routes via a collection block:
# config/routes.rb
resources :products do
collection do
get 'display'
get 'displayall'
end
end
This adds the following two set of named routes:
display_products GET /products/display(.:format) products#display
displayall_products GET /products/displayall(.:format) products#displayall
These routes point to the products#display and products#displayall controller actions, respectively.

Related

How to set route for a rendered action? Rails

i'm new to mvc, rails and web development and i'm facing a problem:
I have an action(show) and a view for this action.
The view for show submits a form_tag to another action, that renders the action show.
The problem is, I have no idea how to set a route for the action that renders show.
Right now my routes.rb is:
resources :meals do
collection do
get "meals/:id", to: "meals#show"
end
end
Tried to add these but didn't work:
match "meals/:id/calculate" , :to => "meals#calculate",:via => [:get]
and:
get "meals/:id/calculate", to => "meals#calculate"
resources :meals generate path to show action.
Run rake routes or open in a browser 'http://localhost:3000/rails/info/routes` to see list of generated routes.
To add calculate use member:
resources :meals do
get :calculate, on: :member
end

Rails custom route not working

Feel like I'm doing this right, but apparently not.
I have a restful resource, Posts, with index, show, new, update, edit, etc actions in the controller. In routes, I have
resources :posts
I wanted to make the index action occur at the URL '/archive' instead of '/posts'
So I added this line in the routes.rb file, after the resources one:
match '/archive', to: "posts#index"
But when I click on a link to posts_path, it still goes to /post (though if I type in /archive as a url, it works -- not ideal, though). Confused. Could this have to do with my having installed friendly_id?
resources :posts, except: [:index]
get 'archive' => 'posts#index', as: :posts
You need to use something like match '/archive', :to => 'posts#index', :as => 'archived'. Then you will have a new route to the tune of archived_posts_path. The method posts_path does not dynamically changed based on custom matchers. You can always run rake routes to see a list of routes for your site.

Rails Routing: Remove the edit suffix to url

I am creating a website with a blog module. A blog post can either be a draft or published.
A published post can no longer be edited, and a draft cannot be viewed (only edit)
I currently have a resource defined as
resources :posts, :path => "blog" do
collection do
get 'drafts'
end
end
I can access the drafts list using blog/drafts, creating new ones posts using blog/new, and editing drafts through blog/:id/edit.
However, I'd like new drafts to be created using blog/drafts/new and edited using blog/drafts/:id
I need to define the new, create, edit and update routes to use this new scheme. The new and create routes seem quite simple. However I do not know how to handle the edit route in order to remove the action name part.
Also, while looking at the default routes definition, I found in actionpack-3.2.9/lib/action_dispatch/routing/mapper.rb the following :
member do
get :edit if parent_resource.actions.include?(:edit)
get :show if parent_resource.actions.include?(:show)
[...]
end
I do not understand how rails differentiates the :edit and the :show routes, and map the urls accordingly.
Thanks
You can use the following routes. Keep in mind that it requires different file hierarchy, rake routes should be your friend in this.
namespace :blog do
resources :drafts, :controller => :posts, only: [:new, :edit]
resources :posts, only: :show
end

How to redirect when ActionNotFound in Rails

I have a controller SubscriptionsController with only actions new and create. How would I redirect to new if say someone tries to visit GET /subscriptions which would normally trigger the index action?
config/routes.rb
resource :subscriptions, :only => [:new, :create]
Using rails3 you can do it from a route, something like:
match "/subscriptions", :to => redirect("/subscriptions/new")
Edit:
From the comments it was made clear you want to capture more than that, using a wild card you can make it more generic. You may need to combine this form with the previous to deal with the non-slash form (or try the below form without a slash, I havent tried that). Also make sure to put these "catch all" routes below your other ones since routes are matched from top to bottom.
match "/subscriptions/*other", :to => redirect("/subscriptions/new")

named route (RESTful) for actions other than index, delete, create, and edit

To illustrate:
class Customer
has_many :sales_orders
end
class SalesOrder
belongs_to :customer
end
i want to have customer to list sales_order which is ready to be sent, should i:
put the routing http://.../sales_orders/can_be_delivered or
create a new controller for reporting http://.../reports/sales_orders_can_be_delivered
for the 1st one, what should goes in the route.rb?
for the 2nd one, nothing goes in route.rb, we can use the last defined route which is :controller/:action.. <-- but this isn't named route
any ideas for this kind of problem?
I would go with the first option as the view you want is just another view on sales orders for which you already have a resource/controller.
The routes would be:
map.resources :sales_orders, :collection => {:can_be_delivered => :get}
This will give you .../sales_orders/can_be_delivered and the helpers can_be_delivered_sales_orders_path + can_be_delivered_sales_orders_url
Side notes
Along with the option :collection you could also add :only => [:new, :create, :destroy] if for example your controller only needed new, create and destroy from the standard restful actions.
ps. Make sure you put this above catch all route at the bottom which I would recommend you commenting out if all your actions are restful.
Finally this guide is a great start for routing in rails:
http://guides.rubyonrails.org/routing.html

Resources