Upgrading routes in Rails 3 - ruby-on-rails

Currently I have something like this:
resources :books do
collection do
get 'search'
end
end
and my controller name is also "books" and I have a action method called "search" inside it
I would like that "get search" part to also be a resource, kind of like nested resources... but I don't want to break other peoples codes that are using the current route that this generate, so need to update it in a passive way!

resources :books do
collection do
get 'search'
end
resources :searches
end
...if I'm understanding you correctly, that should be what you want. It won't break other routes, just add new ones.
Run rake routes to make sure you have all the routes you want/need.

Use shallow routes nesting like:
resources :books , :shallow => true do
resources :searches
end
Now you will get the following routes:
/books/1 => books_path(1)
/books/1/searches => books_searches_index_path(1)
/searches/2 => searches_path(2)
Similarly you can get separate routing for defined routes like:
get '(:books)/searches', :to => 'books#index'

Related

Custom Route to Custom Page in Rails 4

I have an app with a parent resource (has_many) of patterns and a child resource (belongs_to) of snippets. My desire is to build a couple custom routes to specific pages and I am wondering the best way to do that. For now, here is what I have that is working, but I am wondering if there is a better way since the article I read on custom routing tells me this is not good practice.
I have purposefully not nested the resources because the snippets need to stand alone as well as be viewed within the context of their parent pattern.
The goal is to be able to create a few custom views like the following:
http://patterns.dev/patterns/:id/snippets //Got this one working, but incorrectly I believe
http://patterns.dev/patterns/:id/snippets/sort // Show all snippets for pattern to sort
http://patterns.dev/patterns/:id/images // Show all the images for patterns to moderate
routes.rb
Rails.application.routes.draw do
devise_for :users, :path => '', :path_names => {:sign_in => 'login', :sign_out => 'logout'}
resources :patterns
get 'patterns/:id/snippets' => 'patterns#snippets', as: 'pattern_snippets'
resources :snippets
root 'welcome#index'
end
I guess nested resources is what you need. You can specify just index action for nesting and keep all the snippets resources separately. Also you are to add some logic to snippets#index action to check params[:pattern_id]'s existance:
resources :patterns do
# this line will generate the `patterns/:id/snippets` route
# referencing to snippents#index action but within specific pattern.
# Also you have to add pattern_id column to snippets table to define the relation
resources :snippets, only: :index
end
resources :snippets
Use Collection Routes to make Rails to recognize paths like /patterns/:id/snippets/sort
resources :patterns do
resources :snippets, only: :index do
# this line will generate the `patterns/:id/snippets/sort` route
# referencing to snippets#sort action but again within specific pattern.
get :sort, on: :collection
end
end
resources :snippets
If you have Image model you can nest resources the same way like with snippets:
resources :patterns do
resources :images, only: :index
end
If it's just an action in patterns controller you can do:
resources :patterns do
get :images, on: :member
end

how to fill twice id from routes rails

i try to fill twice id in url, but when i send params twice id just one id fill the url id.
My route :
namespace :admin do
resources :stores
get "/:id/new_items"=> 'stores#new_items', as: :store_new_items
post "/:id/create_items"=> 'stores#create_items', as: :store_create_items
get "/:id/show_items/:id"=> 'stores#show_items', as: :store_show_items
get "/:id/items/:id/new_items_sub" => 'stores#new_items_sub', as: :store_new_items_sub
post "/:id/items/:id/create_items_sub" => 'stores#create_items_sub', as: :store_create_items_sub
get "/:id/items/:id/show_items_sub/:id" => 'stores#show_items_sub', as: :store_show_items_sub
end
my view :
<%= link_to "add new items", admin_store_new_items_sub_path(#store.id, #items.id), :class=> "btn" %>
i hope my url like this :
http://localhost:3000/admin/#{store.id}/items/#{items.id}/new_items_sub
but i get same id like this :
http://localhost:3000/admin/#{store.id}/items/#{store.id}/new_items_sub
please tell me when i'm wrong? thanks
you have to create neseted routes for that .have a look at
http://guides.rubyonrails.org/routing.html#nested-resources
for example
resources :publishers do
resources :magazines do
resources :photos
end
end
will accept routes /publishers/1/magazines/2/photos/3
Your params should be unique, so you can't pass more than one different :id params. Instead. you can do something like:
get '/:store_id/show_items/:id', as: :store_show_items
and in view:
<%= link_to 'show items', store_show_items_path(#store.id, #item.id) %>
Also, you should read more about Resources and Nested Resources in Rails, there's probably no need to complicate your life by creating each route independently.
You could refactor this to use nested routes like this (you may have to change controller method names):
namespace :admin do
resources :stores do
resources :items, :only => [:new, :create, :show] do
resources :subs, :only => [:new, :create, :show]
end
end
end
This would give you a few url helpers like this: new_store_item_sub_path(#store.id, #item.id) for the new action and store_item_sub_path(#store.id, #item.id, #sub.id) for the show action.
Run rake routes to see what helpers and routes you have access to.
Have a look here to find out more about nested routes.
Your code can be DRYed up significantly. Hopefully this works; might need some tweaking:
namespace :admin do
resources :stores do
member do
get :new_items, as: :store_new_items
post :create_items, as: :store_create_items
end
get "show_items/:id"=> 'stores#show_items', as: :store_show_items
resources :items do
get :new_items_stub => 'stores#new_items_sub', as: :store_new_items_sub
post :create_items_stub => 'stores#create_items_sub', as: :store_create_items_sub
get "show_items_sub/:id" => 'stores#show_items_sub', as: :store_show_items_sub
end
end
end
Uses Member Routes (see 2.10) & Nested Resources
Nested Resources
The crux of your issue is that you're trying to pass the :id param twice
Fortunately, Rails has a solution to this, in the form of Nested Resources. These work by taking the "parent" id and prepending a singular prefix, such as :store_id, allowing you to use the :id param for another set of methods

routing is too verbose - rails

Suppose I have a model User and I want to add some dashboard namespace. So I create dashbord directory and put inside private_users_controller.rb. Now for routing I put
namespace "dashboard" do
resources :users do
member do
get "show" => "private_users#show"
end
end
end
the problem is that I only want to route the get request having this route /dashboard/users/:id/show. But rake routes shows a bunch of post, delete... routes.
How can I cut those ?
seems like you don't need any of the method from resources definition, so just add a match will be ok.
namespace "dashboard" do
match 'users/:id/show', :to => 'private_users#show'
end
if you insist using resource, then the following will work
scope '/dashboard' do
resources :users, :only => :show, :module => 'private'
end
the 'rake routes' output is like this
GET /dashboard/users/:id(.:format) private/users#show
the trailing 'show' inside the url is not needed.
namespace "dashboard" do
get "users/:id/show" => "private_users#show"
end

Rails 3 route appends _index to route name

I am migrating a Rails 2.3.8 version to Rails 3.0 and so ive rewritten my routes file. When i list the routes using rake routes, i see some route names have _index appended to them. I cant figure out why this is.
Relevant routes:
Rails 2.3.8:
map.namespace "tracker", :path_prefix => "" do |planner|
planner.resources :planner, :collection => {:step1 => :get,
:add => :get,
:unsubscribe => [:get, :post] }
end
Rails 3.0 route:
namespace "tracker", :path => "" do
resources :planner do
collection do
get :step1
get :add
get :unsubscribe
post :unsubscribe
end
end
end
Output from rake routes
Rails 2.3.8
step1_tracker_planner GET /planner/step1(.:format)
add_tracker_planner GET /planner/add(.:format)
unsubscribe_tracker_planner GET /planner/unsubscribe(.:format)
POST /planner/unsubscribe(.:format)
Rails 3.0
step1_tracker_planner_index GET /planner/step1(.:format)
add_tracker_planner_index GET /planner/add(.:format)
unsubscribe_tracker_planner_index GET /planner/unsubscribe(.:format)
POST /planner/unsubscribe(.:format)
Any ideas as to why this _index is being added would be much appreciated.
It is because your resource is named :planner instead of :planners that Rails decided to add the _index to any collection nested underneath. My guess it is there for readability.
The action named in the collection normally translates to a verb, so I can see why this makes sense. Take the typical photos resource example given in the routing docs:
resources :photos do
collection do
get 'search'
end
end
search_photos GET /photos/search(.:format)
But if instead we called the resources 'photo'...
resources :photo do
collection do
get 'search'
end
end
search_photo_index GET /photo/search(.:format)
In the first case, you search the "photos", and in the second case you search the "photo index".
You should be using either resource :planner either resources :planners depending on what you need. To learn about singular resource and it differences check out Rails Guides.
Following on from Semyon Perepelitsa's response, note that resource :planner expects the controller's name is PlannersController, whereas resources :planners expects PlannerController.
If you don't want to rename your controller when changing from resources to resource, you can override the default by specifying resource :planner, controller: :planner.

Rails: How to set params on some paths with scope and set them to nil on some others?

I'm using some routes with scopes, and some without. See below.
resources :cities
resources :categories
devise_for :clients
namespace :clients do
resources :account
resources :dashboard
resources :offers
end
scope "/:current_city" do
scope "/:current_category" do
match 'articles/last_articles' => 'articles#index_last_articles', :as => "last_articles"
resources :articles do
resources :comments
end
end
end
root :to => "home#index"
I am using that params :current_city and :current_category and it gives me a URL like
http://localhost:3000/warszawa/all/articles/last_articles when I'm accessing articles.
**PROBLEM**
I have now such a problem that if I click on a link_to cities_path or root_path, then it adds those two parameters to the URL as http://localhost:3000/?current_category=all&current_city=warszawa.
I don't want these two parameters destroying the beauty of my URL :o(
The only way I found was to pass :current_city => nil, :current_category => nil for each link, but that's really heavy. I tried also the same but in my routes, which is working for normal resources, but not for namespaces, root_path, devise_for routes, and to be honest, that looks horrible in the routes.rb.
**QUESTIONS**
First I do not understand why these params are passed everywhere if I ask them only in the section with scope?!
Secondly, is there a way to make it work like I want or I should modify my routes?
I wish you understand my problem and if you have any comment or idea, please do not hesitate!
Thx

Resources