Rapidfire and Devise - ruby-on-rails

I implemented Devise and went through the instructions to install Rapidfire
and for the application controller I have
def current_user
current_user #rb:7
end
def can_administer
true # just for right now...
end
but on the page I get a something went wrong and if I look in the console it says
ActionView::Template::Error (stack level too deep)
app/controllers/application_controller.rb:7
which is the current_user line.
Can anyone tell me whats going on?

You are creating a method called current_user, and you are returning the value of current_user.
Ruby doesn't require that you use parenthesis when calling methods.
current_user
is the same thing as
current_user()
You are calling the current_user function over and over and over again.
There is no reason for you to define a method called current_user, when devise gives that to you.

Related

How to implement a login counter for Ruby on Rails?

So in my ruby on rails project, I want to track how many times a user has logged in. I am using devise for authentication. Right now, I think what I have is sufficient for my current project, I am just having an issue incrementing the login_count column from my db.
Application.rb snippet:
def after_sign_in_path_for(resource)
if current_user.login_count == 0
new_user_profile_path(user_id: current_user.id)
else
root_path
end
User.user_id.increment_counter(:login_count, 1)
end
Right now User.user_id.increment_counter(:login_count,1) gives me undefined method `to_model' for 1:Integer Did you mean? to_yaml.
You’d be much better off providing a custom SessionsController and modifying the create action to perform the actions you require.
Use the devise generator to create controllers for you to work with, if you haven’t already. Then in your sessions_controller.rb add something like this:
def create
super do |resource|
# at this point, resource is your logged in user (or whatever model)
resource.class.increment_counter(:login_count, resource.id)
end
end

Defining a method on current_user without it throwing a no method error on non logged in users

I made a moderator method thats in the user model
def mod_of_game?(guide_id)
game_mods_relationships.exists?(game_category_id: guide_id)
end
Problem is that whenever the user isn't logged in it just throws a no method error on the page.
I'll be making more user methods in the future and i can only assume i'll come across this problem every time.
I haven't tried it but i guess i could put an if else statement in the method
def mod_of_game?(guide_id)
if current_user.nil?
#empty method
else
game_mods_relationships.exists?(game_category_id: guide_id)
end
But I feel there is a more efficient way that i'm not aware of. I'm Building an app to learn rails better so i guess this is one of the things I just dont know.
The problem is that if no user is logged in, current_user will be nil, not an instance of the User class. So, there is no way to fix this inside the User model, as current_user is not a User if it is nil. Also, current_user is generally not available in the model, just in the controller and view.
What I would recommend is to add a filter in the controller, to make sure that if no user is logged in, the visitor will be redirected to the log in page. This can be done with a before_action filter in the controller, something like:
class YourController < ApplicationController
before_filter :authenticate_user!
...
end
Otherwise you can always check if current_user is nil before calling .mod_of_game?, like so:
current_user.mod_of_game?(#guide) unless current_user.nil?
Try following:
# It will return `nil` if user is not logged in
def mod_of_game?(guide_id)
game_mods_relationships.exists?(game_category_id: guide_id) if current_user
end
Your pattern is wrong.
Calling mod_of_game? is an instance method, which means it's got to be called on an instance of User.
By the nature of current_user, you wouldn't be able to call this method unless the user was logged in, or at least invoked.
You'll have to use all the conditions on the front-end to determine firstly whether current_user exists, and then to call mod_of_game? on it...
<% if user_signed_in? && current_user.mod_of_game?(#guide) %>
--
A much better way would be to either create your own helper method, or to use the .try method:
#app/helpers/application_helper.rb
class ApplicationHelper
def mod? guide
return false unless current_user
current_user.mod_of_game? guide
end
end
This would allow you to call:
<% if mod? #guide %>
... which will return false if the user is not signed in, or the user is not a mod.
The reason the pattern is bad is because you're having to base logic on two conditions: user signed in? AND are they a mod?
What you want is a single point of logic, which will return true or false:
<% if current_user.try(:mod_of_game?, #guide) %>

undefined method `update_attribute' for nil:NilClass, signing out

I have been stuck on this problem for a while, but still can't figure out what the problem is
def sign_out
#return unless signed_in? # you are already signed out
current_user.update_attribute(:remember_token,User.digest(User.new_remember_token))
cookies.delete(:remember_token)
self.current_user = nil
end
rails returns me a error on #current_user, saying the update attribute undefined?
As far as i understand, my current user is already defined by this method
def current_user
remember_token = User.digest(cookies[:remember_token])
current_user ||= User.find_by(remember_token: remember_token)
end
Am i missing something here? I'm following the rails tutorials if it helps, but I kind of strayed off and added a additional page after the user creates a profile..... but I'm sure its ok because i saved the #user by doing
User.find(params[:id])
Or can someone explain to me the error in better detail?
Thank you
The method current_user will define the #current_user instance variable, but this is for it's own purposes - to stop it having to do a db query every time it's called.
You can access #current_user in your own code, but it won't exist if current_user hasn't been called yet, and will therefore evaluate to nil.
It's therefore safer to always use current_user and never use #current_user.
Can someone explain to me the error in better detail?
--
current_user
update_attribute' for nil:NilClass
This error is nothing to do with update_attribute, and everything to do with the object you're trying to call the method on - in your case current_user (basically means current_user is not defined)
The answers & comments you've been given basically are trying to help define the object you're calling the method on - I.E that current_user needs to be defined somewhere
From looking at your code, there are two things you need to consider:
Is current_user method being created / called?
Is the correct object being defined in this method?
--
Data
You've provided the following method:
def current_user
remember_token = User.digest(cookies[:remember_token])
current_user ||= User.find_by(remember_token: remember_token)
end
As pointed out by sevenseacat, the first thing I would do is ensure you've got a user who can be located with the remember_token. An important point actually - what's .digest?. Is it a class method in your model?
The likely problem you've got is trying to use the User.digest and User.find_by with the remember_token. Do you know where / how the remember_token will be set?
--
Method
Secondly, you need to make sure you're calling the current_user method. I'm guessing this is a helper method? If so, are you sure you're calling include xxxHelper in your controller?
never mind, found the bug.Had some unwanted code in my application controller

Current user not persisting across one controller action

I've got a Rails 3.2.8 app using Sorcery for authentication. Sorcery provides a current_user method, pretty standard stuff.
My app has subscriptions, they work pretty much in the standard resourceful way. Here's the abridged version of the controller:
class SubscriptionsController < ApplicationController
before_filter :require_login
force_ssl
def show
#subscription = SubscriptionPresenter.new( current_user )
end
def create
handler = StripeHandler.new( current_user )
...
end
def destroy
handler = StripeHandler.new( current_user )
...
end
end
The #show action works fine, current_user loads. However, right now #create does not work, because current_user ends up being nil in that action.
So, why is current_user nil when a logged in user posts to this action? My guess is something about the way sessions work over SSL, but I don't know what I'm missing here...
I figured this out. It turns out that I was actually getting a silent exception in a 3rd-party library that I was interacting with, and that exception was causing an 'unauthorized' request which logged the user out. After patching that it turns out there was nothing wrong with my controller specifically. Thanks for the pointers, all.

current_user returns nil even when user_signed_in? returns true

I have devise 2.1.2 and cancan 1.6.8 installed.
The current_user helper from devise works fine in my controllers, but is not working the view templates. I'm confused why this is happening. I've been able to use current_user in my view files before.
I tried adding the before_filter authenticate_user! and that didn't help.
Worse comes to worse, I'll add a before filter to the application_controller that says #current_user = current_user but that seems silly.
It's weird that current_user returns nil while user_signed_in? returns true.
Any thoughts on how to get this resolved?
In the meantime,warden.authenticate(:scope => :user) seems to return the current_user so I'm just going to add that to my application helper.

Resources