Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Routing: Combining resources and nested resources

/items should list all items
/user/items should list only items for the current user

I have defined a relationship between users and items, so current_user.items works fine.

My question is:
How does the items#index action know whether it has been called directly or via a user resource in order to know what to populate @items with?

# routes.rb
resources :items
resource :user do
  resources :items
end

# items_controller.rb
class ItemsController < ApplicationController
  def index
    @items = Item.all
  end
end

# users_controller.rb
class UsersController < ApplicationController
  def show
    @user = current_user
  end
end
like image 575
gjb Avatar asked Feb 19 '26 07:02

gjb


2 Answers

It looks hacky, but it was my first idea :)

resource :user do
  resources :items, :i_am_nested_resource => true
end

class ItemsController < ApplicationController
  def index
    if params[:i_am_nested_resource]
      @items = current_user.items
    else
      @items = Item.all
    end
  end
end

Or you can go brute way: parse your request url :).

like image 161
fl00r Avatar answered Feb 22 '26 01:02

fl00r


I solved this by separating the code into two controllers (one namespaced). I think this is cleaner than adding conditional logic to a single controller.

# routes.rb
resources :items
namespace 'user' do
  resources :items
end

# items_controller.rb
class ItemsController < ApplicationController
  def index
    @items = Item.all
  end
end

# user/items_controller.rb
class User::ItemsController < ApplicationController
  def index
    @items = current_user.items
  end
end
like image 40
gjb Avatar answered Feb 22 '26 00:02

gjb