Search code examples
ruby-on-railshttp-redirectsorcery

Sorcery gem - how to use the redirect_or_back_to method


When a non-logged-in user clicks on the 'Deja Tu Opinion' button on this page:

https://github.com/Yorkshireman/pamplona_english_teacher2/blob/create_testimonials/app/views/static_pages/home.html.erb

...the user is redirected to the login page, with a message saying "you must login or signup before continuing". I've done this - no problem here.

The 'Deja Tu Opinion' button directs to the new_testimonial_path. However, if they are not logged in, they get redirected to the login page. I achieved this by writing a "require_login" method and putting in the Application Controller:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception


  private
  def require_login
    if !logged_in?
      redirect_to('/user_sessions/new')
      flash[:notice] = "Necesitas entrar o salir antes de continuar"
    end
  end

end

I then declared it in my testimonials controller:

class TestimonialsController < ApplicationController

  before_action :set_testimonial, only: [:show, :edit, :update, :destroy]
  # before_action :correct_user, only: [:edit, :update, :destroy]
  before_action :require_login, except: [:index, :show]

When they then login, they are redirected to the root_path:

class UserSessionsController < ApplicationController

  # skip_before_filter :require_login, except: [:destroy]

  def new
    @user = User.new
  end

  def create
    if @user = login(params[:email], params[:password])
      redirect_to root_url, notice: 'Login successful!'
    else
      flash.now[:alert] = 'Login failed'
      render action: 'new'
    end
  end

  def destroy
    logout
    redirect_to(root_url, notice: 'Logged out!')
  end
end

HOWEVER... what I want to happen is for them to be directed to the new_testimonial_path in this situation, not just back to the root_path.

So, to summarise, a non-logged-in user clicks on the 'Deja tu opinion' button (which means 'write your own testimonial') and, because they are not logged-in, they are directed to the new_user_session_path. They then login and are taken back to the root_path, where they will then have to scroll down the page again and click on the 'Deja tu opinion' button, which will then take them to the new_testimonial_path.

What want to happen is for a non-logged-in user to click on the 'Deja tu opinion' button and, because they are not logged-in, are directed to the new_user_session_path. They then login and are directed to the new_testimonial_path (because that's what they wanted in the first place).

I used the Sorcery gem, and I'm pretty sure there is a method to achieve this, called 'redirect_back_or_to', but I just can't work out how to use it from the documentation.

The entire app's code here (create_testimonials branch): https://github.com/Yorkshireman/pamplona_english_teacher2/tree/create_testimonials

Sorcery's documentation: https://github.com/NoamB/sorcery

Hope you can help!


Solution

  • SOLVED:

    Sorcery has its own method called require_login, so my require_login method seemed to be preventing the redirect_back_or_to method from functioning properly. Therefore, I simply deleted my require_login method.

    When the redirect_back_or_to method is triggered in the before_filter (or 'before_action' - same thing), Sorcery calls another one of its native methods: not_authenticated. Its default action seems to be to direct you to your root_path. You can override this in your Application Controller (just write a method called 'not_authenticated' in the private section and tell it what to do (in my case, "redirect_to new_user_session").

    These changes achieved the desired result.

    Some great info here: http://railscasts.com/episodes/283-authentication-with-sorcery?view=asciicast