Is there a way to return the number of devise users currently logged in?
Since all of the information related to being logged in is handled in the session, there's no simple way out of the box. I would recommend doing something in ApplicationController to manage this information.
We use a before_filter in a number of our applications to track very specific information about each page request. You could do something similar to track what page they hit, when they hit it, and who they were.
Then determining logged in users would be as simple as determining how long ago their last page load would have to be for them to count as logged in, then select on your table of views based on that. Something like
MyPageView.select(["DISTINCT user WHERE created_at > ?", my_threshold_time]) would give you the distinct users.
indicate which users are currently logged in
It depends what you mean by "currently on the site".
Adding a currently_logged_in
column like you described works IF you want to mark users that are currently logged in. However most users don't log out when leaving a website these days so that probably won't do what you want.
A better solution would be to add a last_active_at
column which you can update with the current time whenever a user performs some action. Then determine a threshold that makes sense for your website, let's say 15 minutes, and only mark users in your list that have a last_active_at
value less than 15 minutes in the past.
Assuming the definition of "active user" for your website involves hitting authenticated endpoints it would be as simple as changing your authenticate method to:
def self.authenticate(email, password)
user = User.find_by(email: email) # returns user or nil value
if user && user.authenticate(password)
user.update!(last_active_at: Time.now)
true
else
false
end
end
Who's Online using Devise in Rails
https://github.com/ctide/devise_lastseenable
You can use this gem that I wrote to store the 'last_seen' timestamp of a user. From there, it's pretty trivial to display the users who were last_seen in the last 5 or 10 minutes.
Devise user owns account, account has many users
You would do better by having Account
as the parent and User
as the child like so:
Account has_many Users
So what you could do is in your User
model create a callback to check for the presence of an account and create one if it's blank.
before_validation :create_account_if_blank
def create_account_if_blank
if self.account.blank?
ApplicationRecord.transaction do
account = Account.create!(name: self.full_name)
some_other_thing = Something.create!(name: 'test')
end
end
end
Then when you create another user from your "Admin" account, just set the the current account from the controller.
You could even do something like this:
current_account.users.create(your parameters here)
Put the current_account
function in your application controller.
The current_account
function would look like this:
def current_account
return current_user.account
end
How to return to previous page after Devise sign in
You can get the previous url using request.referrer
as is explained in this SO question: How to redirect to previous page in Ruby On Rails?
Ruby on Rails devise return role of user
You may do well using the delegate
method
Other Model Data
Problem is, you're trying to load another model's data object into your current model. This would have to work like this:
@user.role.name # -> "role" is another object, not a naked piece of data
The way around this will be to add this:
class User < ActiveRecord::Base
...
belongs_to :role
delegate :name, to: :role, prefix: true #-> yields @user.role_name
before_create :set_default_role
private
def set_default_role
self.role ||= Role.find_by_name('contractor')
end
end
Relational Data
If you're beginning with Rails (welcome, by the way), you should look into how relational database structures work
Essentially, you do everything with id
's (called a primary_key
). This allows different models to call data from related models by calling the respective ID's. That's why you had to add role_id
to your user model
I think you'll benefit from learning about how to use the data objects called back from the relational models. I.E @user.role_id
will have to be a corresponding ID of the roles
db
Specify Return URL for Devise Login as a Query String Parameter
You can just extend the Devise::SessionsController
to suit your need. If you look at the source code, Devise uses after_sign_in_path_for
to redirect the user to a specific path after a successful sign in.
Assuming the resource you have is a User
In your routes.rb
, specify which router Devise should use:
devise_for :users, controllers: {sessions: 'sessions'}
Then create a controller in app/controllers/sessions_controller
that inherits from Devise::SessionsController
and override the after_sign_in_path_for
:
class SessionsController < Devise::SessionsController
protected
def after_sign_in_path_for(resource)
params[:redirect_path].presence || stored_location_for(resource)
end
end
In your new session form (app/views/devise/sessions/new.html.erb
), add a hidden tag that relays the redirect_path
param to the controller:
<%= hidden_field_tag :redirect_path, params[:redirect_path].presence %>
Now if the user visits new_user_session_path(redirect_path: some_path)
, they should be redirected to the desired path after a successful sign in.
Devise - How to trigger a sign_in on page user already has access to
This sounds like you need some controller specific code.
When a user clicks on the link, have the corresponding action do something like this:
def image_action # Whatever the action name is
if current_user # current user is given to you by devise
# Do stuff that a logged in user would do
else
# redirect to login page
end
end
The idea being that you leave the logic out of the view, and instead either have the controller serve the logged in user the appropriate data / page or have an unauthenticated user redirected to the login page.
current_user
is a method given to you by devise that evaluates either to the currently logged in user making the request or nil
if the user is not logged in.
If you post your controller code, I'll file out more of my example code, I just didn't want to make it too specific at risk of being confusing.
Related Topics
Why Must I Explicitly Call Self on Accessor When Using the Array Union Operator |= in Ruby
Editing JSON Array Contents in Ruby
Issue with Precision of Ruby Math Operations
How to Marshal a Hash with Arrays
Mongomapper Association Skips Duplicates
Making a Pie-Chart of the User Age in Rails
Finding Parenthesis via Regular Expression
How to Upgrade My Ruby 1.9.2-P0 to the Latest Patch Level Using Rvm
Sorting an Array of Objects in Ruby by Object Attribute
Rails 4 Use Application Helpers Inside Initializers
Ruby Devise, Sessionscontroller.Create, JSON - Getting Nameerror: Undefined 'Build_Resource'
Error: Missing Rvm Environment File After Doing Rvm Upgrade Command - Passenger 4.0.23
Define a Class Method in a Module
Rally Ruby Toolkit: How to Get Url of Portfolio Item's State
Ruby, No Implicit Conversion of Symbol into Integer
How to Send Notifications to the User Whose Post Received a Comment