Rails - Devise - How to Handle Landing Pages Versus App Pages - ruby-on-rails

I have a Rails 3 App.
When the user is not signed in... I want devise to show non-signed in pages: SignIn, register, about us, blog etc...
When a user is signed in I want it to go to the web app
where do I make this switch and how do I set it up? thanks

This is easy! I just finished a Rails 3 app with devise, so my pain can be your gain. Just include the before_filter at the beginning of the controllers you want to protect. Let's use the example of a Videos controller:
class VideosController < ApplicationController
before_filter :authenticate_user!
# all your actions go here: index, new, create, etc #
end
You can also pick and choose what actions in the controller are filtered:
class VideosController < ApplicationController
before_filter :authenticate_user!, :only => [:edit, :update, :destroy]
# all your actions go here: index, new, create, etc #
end
Devise gives you the authenticate_user! method, and redirects for you.

Related

Using Devise, how can I set the root page to not redirect to the "sign_in" page if the user is logged out?

I would like to populate the root page with certain items from my database and just have a link to sign in somewhere on the page. Basically I don't want to make the content exclusive to those who are logged in.
In your root controller, just add:
skip_before_filter :authenticate_user!
Example:
class RootController < ApplicationController
skip_before_filter :authenticate_user!
def index
#some logic here
end
end
You can also limit it to just the index action:
skip_before_filter :authenticate_user!, only: [:index]
Good luck!

Ruby - Automatically running helper method

I have a login page saving a session to allow users to navigate subsequent pages. If you're not logged, I want to redirect you to the log in page. I have a SessionsHelper method for checking if the user is logged in and then if not, redirecting them back to the login page, But I don't want to have to call this in every controller action. Is there a way to easily run this method globally?
Traditionally this is done via a before_action filter. Something along these lines:
class ApplicationController
before_action :require_current_user
def require_current_user
redirect_to login_path unless current_user
end
end
class SessionsController < ApplicationController
# do not cause endless redirect loop
skip_before_action :require_current_user, only: [:new, :create]
end
Also, helpers are for simplifying views (currency formatting, styling, etc.). They are not to be used for this kind of functionality (session management, in this case).

Using Devise before_action :authenticate_user! doesn't do anything

I am trying to require login on all pages on my Rails 4 web site.
In the ApplicationController I have added before_action :authenticate_user!, but it simply doesn't do anything. I have tried to add the same before_action :authenticate_user! to another controller, and it works fine.
Do I need to do something else to the ApplicationController, to make the login be required on all actions (Except signup/signin)?
Here's the actual code we use:
#app/controllers/application_controller.rb
Class ApplicationController < ActionController::Base
#Actions
before_action :authenticate_user! #-> routes to the login / signup if not authenticated
end
The problem you probably have is two-fold:
--
Make sure your other controllers are inheriting from application_controller:
#app/controllers/other_controller.rb
Class OtherController < ApplicationController
...
end
--
You're somehow "skipping" the before_action callback
If you're using skip_before_action anywhere, you need to remove it. It will likely cause a problem with your authenticate_user! method. To fix this, I would firstly test without any skip_before_action callbacks, and then see what gets it working correctly
A further note - signin / signup won't matter. They all inherit from the Devise controllers; they'll just run as required.
UPDATED 2019
In your routes.rb file you may have mentioned only authenticated_user path like below
authenticated :user do
root to: 'home#index', as: :root_app
end
You should mention unauthenticated_user path too to make it work or just root path without unauthenticated_user or authenticated_user

How to setup a default current_user for demo purposes

I've set a fake user to demo my app. The idea is that visitors, who won't be signing in, should still be able to see all the functionality that a real user would have. When a non-logged-in visitor hits the site, the app will sign in the demo user and visitors will see fake data belonging to this demo user.
With this goal in mind, I setup my application controller like this.
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_current_user
def demo_user
#demo_user ||= User.find_by_email("demo#example.com")
end
protected
def set_current_user
if current_user.nil?
sign_in(demo_user)
end
end
end
My problem is that I accidentally made it impossible for real users to sign in. Anytime a real user presses the "sign in" link, they're told that they're already signed in (as the demo user).
So clearly, what I've done is nowhere close to a "best practice." What would a smart programmer do in this situation? How do I keep my nifty automatically signed in demo user but still leave the door open to real users to sign in?
You need to add an :except to your :before_filter so that it doesn't run on the sign_in action, whatever it may be. Assuming you're using devise, that would be SessionsController#new, so it would look like:
before_filter :set_current_user, :except => :new
Note that this will skip the filter for all 'new' actions, so a more targetted way of doing it would be (again, assuming you are using Devise) to create a custom SessionsController which inherits from Devise::SessionsController and leave it blank except for:
skip_before_filter :set_current_user, :only => [:new, create]
Your set_current_user function is in a before_filter which means it runs once for every request. The current_user will be nil the first time anyone visits and so they will be signed in as the demo user. You can skip the before_filter for your sessions_controller#create action (or whatever it's called in your app. For example, if you are using Devise:
class SessionsController < Devise::SessionsController
skip_before_filter :set_current_user, :only => :create
end
Here's what I ended up with. I started off with Omnikron's solution, but I needed a little more.
This post helped: https://groups.google.com/forum/#!msg/plataformatec-devise/0WylcwjSAJY/ITDF6kFjJvwJ.
class SessionsController < Devise::SessionsController
skip_before_filter :set_current_user, only: [:new, :create]
skip_before_filter :require_no_authentication, :only => [:new, :create]
def new
if user_signed_in?
sign_out current_user
redirect_to new_user_session_path
else
super
end
end
end

How to Redirect using Devise

So i've built my first app using Devise! I'm pretty stoked, but I would like to know how one goes about having the app re-direct to a specific page after logging in?
In other words,
Instead of logging in, and remaining at the home page, how do I get rails to redirect to a microposts page for example?
In my case specifically it only redirects to the posts page sometimes, and other times it just stays at the initial home page.
Here is my posts controller:
class PostsController < ApplicationController
before_filter :authenticate_user!, :except => [:show, :index]
def posts
#title = "Posts"
end
end
By default, devise redirects you to the root, you can customize after_sign_in_path_for method anyway you like. There's also after_sign_out_path_for method at your disposal to customize.
ApplicationController < ActionController::Base
# extra stuff
def after_sign_in_path_for(user)
if something
posts_path
else
root_path
end
end
def after_sign_out_path_for(user)
new_some_other_path
end
end

Resources