Jonathan
Jonathan

Reputation: 683

No Route Matches - Devise User ID in Route

I'm trying to put the user id's from Devise within my application's routes. e.g. (www.test.com/users/1/offers)

My application works fine but I'm getting route matching errors when trying to call a redirect_to within my controller which doesn't have a 'user'.

Error

No route matches {:action=>"index", :controller=>"offers", :user_id=>nil} missing required keys: [:user_id]

welcome_controller.rb (Doesn't need the user to be logged in)

class WelcomeController < ApplicationController
  def index
    @skip_footer = true
    if user_signed_in?
        redirect_to user_offers_path(@user)
    else

    end
  end
end

routes.rb

 devise_for :users
 resources :users do
    resources :offers do
      member do
         put :tourcomplete
      end   
    end
  end

Any help would be brilliant!

EDIT

Controller

  def index
    if current_user.present?
      @offers = Offer.all
    else
      redirect_to root_url
    end

    def tourcomplete
      current_user.update_attributes(tourcomplete: true)
      redirect_to root_url
    end

    @featured_offers = Offer.where(featured: true)

  end

Category Controller

resources :categories, only: :show

Upvotes: 2

Views: 460

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

Firstly, I must point out that you're not calling a Devise user ID in this case, you're just using standard Rails resource routing:

#config/routes.rb
resources :users do
   resources :categories do #-> url.com/users/:user_id/categories
     get :test, on: :collection
   end
   resources :offers do #-> url.com/users/:user_id/offers
      put :tourcomplete #-> you don't need member do
   end
end

#app/controllers/offers_controller.rb
class OffersController < ApplicationController
   def index
      @user = User.find params[:user_id]
      @offers = @user.offers
   end
end

This is how your code should be used.


Thus if you wanted to use it with the Welcome controller, you'd be able to use it as follows:

#app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
   def index
      redirect_to user_offers_path(current_user) if user_signed_in? 
   end
end

Your offers controller could be improved as follows:

#app/controllers/offers_controller.rb
class OffersController < ApplicationController
   before_action :authenticate_user!

   def index
      @offers = Offer.all
   end
end

Upvotes: 2

Caillou
Caillou

Reputation: 1500

You can to add a before_action in your controller, which will fetch the @user you need, in order to be able to redirect to user_offers_path(@user).

Something like :

class WelcomeController < ApplicationController
  before_action :set_user, only: [:index]

  def index
    @skip_footer = true
    if user_signed_in?
        redirect_to user_offers_path(@user)
    else

    end
  end

  private

  def set_user
    @user = User.find(params[:user_id])
  end
end

Of course, you'll also need to put the user_id in the GET or POST params when calling the index of WelcomeController.

Upvotes: 1

Related Questions