Increment a users login count - ruby-on-rails

I have an existing application where a user can log in etc. This does not use devise works fine. I wanted to create a feature that counts the users login attempts and as such increments this by one each time they log in. I am aware of active record and increment as i have put below.
def increment_login_count!
update_attribute(:login_count, login_count + 1)
end
Could anyone offer any other advice as to how to do this logic. I wanted to start with a controller spec and work from this but i am a little unsure.

Try this
def increment_login_count
increment! :login_count
end
And you can call this method whenever a new session is created for the user
You can refer to docs for more information

Related

Recording activities of every controller in rails

I have created a log model and a method in every controller to keep record of action performed in every controller. that method populate logs modle. But i don't know how keep record of user creation, deletion and update using this function.
The method that i have created is:-
def keep_record(msg)
#log = Log.new
#log.user_id = current_user.id
#log.description = msg
#log.save
end
How can i use this method to keep record of creating, editing and removing user in devise gem.
Can anyone suggest me how to modify Registration_controller to keep record of creating, deleting and updating user.
I'm not sure what you mean by "track the activities", but it sounds like you want to track when a user changes those attributes. I would suggest looking into ActionCable, which the user will make a connection with, and basically subscribe to a channel, and you can record what they are doing.
Here is a good place to start:
Actioncable connected users list

Pass Account ID to New User During Sign Up

Currenntly, my application is designed using Devise for authentication. I have it so when the first user signs up, an account is created in an Accounts table and the account_id is passed to the User table. I also have it set so that each time a new account is created that user is tagged as an admin. Finally, I have it working where the admin can create new users.
My problem is that at the time the new users are created I need to have these users be assigned the same account_id as the admin to tie the users together. I can do this if I add an account_id field on the form and have the admin manually enter it. What I want to have is that this is automated in the background.
I tried many varieties without success. This is one of the unsuccesful attempts where I put the following in the user.rb
before_save :add_account_id_from_parent
def add_account_id_from_parent
return true unless self.users.present?
self.users.update_attribute(:account_id, 1)
end
I used the number "1" just to see if I could get anything automated and placed in that field.
Like I said manually everything works, but I want it so the acocunt_id is automatically added during sign up based on the admins account_id.
I'm a bit confused why you are calling self.users. If I understand correctly, you want to assign account_id to 1 after a new user is created (as a test). You can do that like this:
before_save :add_account_id_from_parent
def add_account_id_from_parent
self.account_id = 1
end
You don't need to actually update the record since this is assigned before save, and save will write the new value to the db.
Again I might be missing something, if so please clarify.
UPDATE:
If you're validating that account is present, you'll need to change the callback to a before_validation instead of before_save, like so:
before_validation :add_account_id_from_parent

Steps to create my own authentication system, need some guidance

I want to learn how to create my own authentication system, please provide some guidance if am doing this wrong.
I will create a Module in my /lib folder /lib/auth.rb
I will require this module in my ApplicationController.
when a user enters their email + password, I will call a method that will do a lookup in the user's table for a user with the same email, I will then compare the passwords. (i'll add encryption with salt later).
If the user entered the correct credentials, I will create a row in the Sessions table, and then write the session GUID to a cookie.
Now whenever I need to check if the user is logged in, or I need the user object, I will check if the cookie exists, if it does, I will lookup the session table for a row with the same guid, if it exists, I will return the session row and then load the User object.
I realize there are many suggestions one can give, but in a nutshell does this sound like a workable solution?
Now to make this usable, I will have to make some helper methods in my ApplicationController right?
How will I access the current_user from within my views?
P.S I know of other authentication systems, I just want to learn how to create my own.
The basic logic you're following is correct. Of course you can always expand on this with features that you need. For instance, you'll need helper methods for things like "logged_in?" and "current_user". Also, you might want to add session expiry, or session retention as a "remember me" feature.
Go for it, you won't learn authentication systems better than building your own then figuring what's wrong with it.
You should really check out the authlogic gem on github.
http://github.com/binarylogic/authlogic
It also has great instructions on how to set up your users.
After Faisal said what I would say, I only give you answer to the last part of your question:
"How will I access the current_user from within my views?"
try something like this:
class User < ...
def self.current=(u)
#current = u
end
def self.current
#current
end
end
In your views (or any part of your code) you can call User.current. Your controller has to assign a validated user to User.current. Your filters can react to "if User.current.nil?" and so on.
If you want to be thread safe, you may use a thread variable instead of #current:
Thread.current[:current_user] = u

Rails 3 + Devise: user_signed_in? for a different user in the database?

I'm building an app where I want to add an online status for a given user.
I know that Devise has a method user_signed_in? built in to check if the user who is using the app is signed in or not. But when I try to use it for a different user like this:
user_signed_in?(user)
user.user_signed_in?
I obviously get an undefined method error.
Does Devise have a method for this or do I have to write my own?
One approach was to store the online status of a given user in the user model.
What's the best solution to this?
I have used Devise on my applications and experienced some of the same problems as you when I first began working with it. You are merely using the helper methods incorrectly. If you'd like to check if the current user has a session and is signed in, you use the helper as such:
if user_signed_in?
which is essentially the same statement as:
if !current_user.nil? && current_user.signed_in
If you'd like to check if a user object is signed in, then you call this: (where user is a User Model Object)
if user.signed_in?
I'm not the author of Devise, but from what I can tell of Warden / Devise neither keep track of who is logged in.
The problem with having an is_online column in the User table is that it is difficult to see who is active on the website. I would add a column to your User model called last_seen as a date-time, and update that with Devise every time the user requests a page. You could then easily add a User.online_count method or also see if a user has been seen at the website in the last 5 minutes.
Use devise_for :user in your routes.rb.

Finding last active time for logged in user

I am using ruby on rails session to store a user cookie to keep them logged in, so I can't just update a last_seen column after they login. I'm trying to figure out the best way to find out if a user has been active in the last day. This is what I have so far but I'm wondering if there's a better way:
class ApplicationController
before_filter :update_last_seen
private
def update_last_seen
if (DateTime.now - 1.day) < current_user.last_seen
current_user.last_seen = DateTime.now
current_user.save
end
end
end
The problem with this is that it is going to get called with every request. Is there any way to avoid this? Does the session cookie get updated somehow when a user is active?
No, that is exactly how you should go about it. before_filters are a great way to keep track of things like that, and are how authlogic implements it's authentication system as well. There's no way to do processing on one request "per day". If you use Authlogic as your authentication method, it has last-login time built in. You can see an example of it here.

Resources