Alex Rivera | Logout

Rails: Nested resources conflict, how to scope the index action depending on the called route

Asked 2009-11-28T00:44:55.510
13

Imagine you have two defined routes:

map.resources articles
map.resources categories, :has_many => :articles

both accessible by helpers/paths

articles_path # /articles
category_articles_path(1) # /category/1/articles

if you visit /articles, index action from ArticlesController is executed.

if you visit /category/1/articles, index action from ArticlesController is executed too.

So, what is the best approach for conditionally selecting only the scoped articles depending on the calling route?

#if coming from the nested resource route
@articles = Articles.find_by_category_id(params[:category_id])
#else
@articles = Articles.all
Edit
Report

2 Answers

3

I often like to separate those actions. When the resulting actions are very similar you can separate the scopes inside the controller easy by seeing if params[:category_id] is present etc (see @SimoneCarletti answer).

Normally separating actions in the controller by using custom routes gives you most flexibility and clear results. Following code results in normal route helper names but the routes are directed to specific actions in controller.

In routes.rb:

resources categories do
  resources articles, :except => [:index] do
    get :index, :on => :collection, :action => 'index_articles'
  end
end
resources articles, :except => [:index] do
  get :index, :on => :collection, :action => 'index_all'
end

Then you can have in ArticlesController.rb

def index_all
  @articles = @articles = Articles.all
  render :index # or something else
end

def index_categories
  @articles = Articles.find_by_category_id(params[:category_id])
  render :index # or something else
end
answered 2011-09-29T15:59:00.817
1
if params[:category_id].blank?
  # all
else
  # find by category_id
end

I like to consider the action independent from the route. No matter how they get there, make a reasonable decision as to what to do.

answered 2009-11-28T02:13:55.207

Your Answer