Pretty simple question, but I can't seem to figure out how to do this, even after scouring the Rails Routing guide.
Assume Topics has nested resource Posts.
The Posts for a Topic are all listed in Posts#index (/topics/:topic_id/messages). Topics#show does not serve any purpose. I would like Posts#index to be retrieved when the request is for /topics/:topic_id, without having to stick a redirect in the Topics controller.
Thank you!
UPDATE
I was able to get the desired result with this:
routes.rb
match 'forums/:forum_id' => 'topics#index', :as => 'forum_topics', :via => :get
match 'topics/:topic_id' => 'messages#index', :as => 'topic_messages', :via => :get
resources :forums, :shallow => true, :except => :show do
resources :topics, :shallow => true, :except => :show do
resources :messages
end
end
However, I'm not sure if this is the best method.
UPDATE 2
My method above breaks the other CRUD methods (like #create). Still looking for a solution to keep /messages out of the url.
add this route
get "/topics/:topic_id" => redirect("/topics/%{topic_id}/messages")
UPD
without redirecting:
get "/topics/:id" => "topic::Messages#index"
Or, if you're using shallow:
get "/topics/:id" => "messages#index"
resources :forums, :shallow => true, :except => :show do
resources :topics, :shallow => true, :except => :show do
resources :messages
end
end
Related
I need to figure out how to properly use routes to create a url structure like so:
items/page/2
items/expired/page/2
I have items/page/2 working and then I have this which I want to to correct:
items/expired?page=2
I am using Kaminari to provide pretty url structure for rails 4.2 with a concern.
https://github.com/amatsuda/kaminari/#creating-friendly-urls-and-caching
My controller has two actions: index and expired
My views under items are index.html.haml and expired.html.haml
routes.rb
concern :paginatable do
get '(page/:page)', :action => :index, :on => :collection, :as => ''
end
concern :expired_paginatable do
get '(page/:page)', :action => :expired, :on => :collection, :as => ''
end
get 'items/expired', to: "items#expired", :concerns => :expired_paginatable
resources :items, :concerns => :paginatable
my views both have:
= paginate #items
I know I do not need two concerns but thought I would try it.
I ended up changing my resources block to this:
resources :items do
collection do
get 'expired/page/:page', :action => :expired
get :expired
end
concerns :paginatable
end
dropping:
concern :expired_paginatable do
get '(page/:page)', :action => :expired, :on => :collection, :as => ''
end
get 'items/expired', to: "items#expired", :concerns => :expired_paginatable
resources :items, :concerns => :paginatable
ActionController::Routing::Routes.draw do
map.resources :users, :sent
map.resources :mailbox, :collection => { :trash => :get }
map.resources :messages, :member => { :reply => :get, :forward => :get, :reply_all => :get, :undelete => :put }
map.resource :session
map.inbox '', :controller => "mailbox", :action => "index"
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
I believe what you're looking for is this:
ActionController::Routing::Routes.draw do
root to: "mailbox#index"
resources :users
resources :sent
resources :mailbox do
collection do
get :trash
end
end
resources :messages do
member do
get :reply
get :forward
put :undelete
end
end
resource :session
end
The two connect routing definitions are no longer used in Rails, as they make all actions of all controllers available as GET requests. For instance, GET /users/1/destroy. If you find routes that that used to work are no longer working, you will need to define new routes in config/routes.rb for them.
I have the following resource block
resources :projects, :except => [:destroy] do
resources :tasks, :except => [:index]
get "tasks/:id/change_state" => "tasks#change_state", :as => "task_change_state"
get "tasks/:id/assign_user" => "tasks#assign_user", :as => "task_assign_user"
get "tasks/:id/unassign" => "tasks#unassign", :as => "task_unassign"
end
I'm wondering how I can refactor those routes a bit without touching the path. I tried doing the following:
resources :projects, :except => [:destroy] do
resources :tasks, :except => [:index] do
member do
get 'change_state'
get 'assign_user'
get 'task_unassign'
end
end
end
But that leaves the route method names with tasks as plural. I need the URL to be plural, much like in the original get method call. But I need the method name to be singular, as I would prefer to not change the implementation across the app.
I'm setting up my website such that
www.website.com/articles/2013/07 will list all articles from 2013 in July and
www.website.com/articles/2013 will list all articles in 2013
www.website.com/articles/2013/07/title-of-article will list just the specific article
However, I am able to get only the first and last of the above 3 to work. Entering the url
www.website.com/articles/2013 is not working properly. Specifically, I get a noMethodError in Articles#show which doesn't make sense to me because I have matched the route to Articles#index.
Can someone please explain what's going on here? I don't see where I am making a mistake.
Routes:
match "/articles/:year", :to => "articles#index",
:constraints => { :year => /\d{4}/ }, :as=> :posts_year
match "/articles/:year/:month", :to => "articles#index",
:constraints => { :year => /\d{4}/, :month => /\d{1,2}/ }, :as => :posts_month
match "/articles/:year/:month/:slug", :to => "articles#show",
:constraints => { :year => /\d{4}/, :month => /\d{1,2}/, :slug => /[a-z0-9\-]+/ }, :as => :posts_date
and in my model I have:
def year
created_at.year
end
def month
created_at.strftime("%m")
end
Do you have resources :articles in your routes file? If you do, that explains the error. Move resources :articles below the routes you mentioned in your question and everything should work fine. Alternatively you could change it to:
resources :articles, :except => :show
Guessing that if you've defined articles as a resource, then the default show/:id route is taking precedence over your :posts_year route. Maybe try resources :articles, :except => [:show]
I would like to add a url to my comments route so I can call "post_comments_latest_path". I added something like 'get "comments/latest" => "comments#latest", :as => "latest"' but the route adds and the :commend_id to the path that is not needed. Any suggestions?
resources :posts, :except => [:index] do
resources :comments, :except => [:index, :show] do
post "replies" => "comments#create_reply", :as => "create_reply"
get "replies/new" => "comments#new_reply", :as => "new_reply"
end
end
This should work:
resources :posts, :except => [:index] do
resources :comments, :except => [:index, :show] do
post "replies" => "comments#create_reply", :as => "create_rely"
get "replies/new" => "comments#new_reply", :as => "new_reply"
get "latest", :on => "collection"
end
end
A Member route is one that links to a specific resource; requires an id.
A Collection route is one that links to a resource collection; does not require an id.
See the Rails Routing Guide for more information.