Reputation: 179
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!
Upvotes: 10
Views: 31422
Reputation: 383
Comparing IDs is not the best practice for Rails. If you have previously set up the associations correctly, then you don't need to make a comparison between IDs. For example:
User
has_many :group_events
GroupEvent
belongs_to :user
In this scenario, instead of comparing IDs, you can directly compare with association:
Bad
@group_event.user_id == current_user.id
Good
@group_event.user == current_user
Upvotes: 0
Reputation: 884
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 ;)
Upvotes: 1
Reputation: 3285
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.
Upvotes: 13
Reputation: 2080
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 .
Upvotes: 3
Reputation: 15216
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)
Upvotes: 2