Get UserID for Current User using Devise/Rails

26,642

Solution 1

I see a few problems here

def index
  @currentUser = current_user.id
end

Other than what @HolyMoly already commented, you should use underscore and not camelcase, if current_user is nil here, .id will fail on it, resulting in an exception.

Second, you are checking "ability" by comparing values of ids, I would change your code to do this

<% if allow_product_delete?(@product) %>

In a helper

def allow_product_delete?(product)
  return false unless current_user
  @product.user_id == current_user.id
end

if you are using devise current_user exists in controller and views, you don't need to define it as an instance variable, it's already defined as a controller method on all actions (by default). so by calling current_user in your views you are done.

If a user is not logged in, current_user will be nil, you always have to prepare for this and protect against it.

Last, I would look into ability gems (cancan or cancancan), those provide a very nice DSL for dealing with what you were trying here.

Solution 2

Have you set it up to actually be able to user current_user ? in your code you have :

@currentUser = current_user.id

But where was current_user defined? I haven't used Devise but with sessions you could define the value of current_user with a helper method (you may be able to also do it right there in the sessions_controller #create method), like this:

 def current_user
     @current_user ||= User.find_by(id: session[:user_id])
  end

then throughout your app you could use current_user.id or current_user.name or whatever you needed.

So while sessions is not Devise, I hope this helps .

Solution 3

First of all, ruby like undescored_rather_than camelCased style.

Secondly, you need two equal signs instead of three. @currentUser == @product.user_id should work

At third, you don't need to compare integer ids, you can compare models, something like that:

<% if current_user == @product.user %>
  <%= link_to "Back", products_path %>
  <%= link_to "Edit", edit_product_path(@product) %>
  <%= link_to "Delete", product_path(@product), method: :delete, data: { confirm: "Are you sure?"} %>
<% end %>

Please note that I omitted the @ in current_user method, because current_user is helper for devise, else I removed unnecessary <% else %> (in my opinion)

Solution 4

You should use current_user for this. You can do it everywhere in project. No needs to define variable @currentUser or etc.

You can compare like models

if current_user == @product.user

that is the equivalent to

if current_user.id == @product.user.id

In some cases you can use

if current_user.id == @product.user_id

This prevent extra sql query to load user model

If you are using Devise for authorization and you need control access for actions you should see (maybe use) gem https://github.com/CanCanCommunity/cancancan

https://github.com/airbnb/ruby will help you to stay in tune ;)

Share:
26,642
aishaq11
Author by

aishaq11

Updated on July 21, 2022

Comments

  • aishaq11
    aishaq11 almost 2 years

    So I, a rails newbie, am currently trying to get the User ID from the current Devise session, and I am having a bit of trouble.

    I have this in my controller now:

    def index
      @currentUser = current_user.id
    end
    

    And I want to make a simple if statement to show/hide fields in my form.

    <% if @currentUser === @product.user_id %>
              <%= link_to "Back", products_path %>
              <%= link_to "Edit", edit_product_path(@product) %>
              <%= link_to "Delete", product_path(@product), method: :delete, data: { confirm: "Are you sure?"} %>
          <% else %>
              <span></span>
    <% end %>
    

    I have a feeling my syntax in defining my currentUser variable is bad, but I have no idea how to fix this. There were a few similar questions on Stack, but none of them really applied to me or helped me.

    Thanks in advance!

  • aishaq11
    aishaq11 over 8 years
    Thank you for the fast reply. I tried this out, but it didn't work out, so I wanted to see exactly what is being compared, and printed out <%= current_user %>, and got #<User:0x00000006e5e2e0>. Does this have to do with what you said about comparing models instead of integer id's?
  • asiniy
    asiniy over 8 years
    @aishaq11 it's normal situation - this is representing of Object class with it's unique id. Try out something like <%= current_user.id %> and <%= product.user_id %> at the same rendering. Does id values same?