I have a user model with a column superuser:boolean. I also using a navigationbar where I want to to have three different views according to those conditions:
When someone is not signed in
When someone is signed in as a user
When someone is signed is as a user and the boolean value for superuser is true
<% if (user_signed_in? && user.super_user?) %>
<% elsif (user_signed_in?) %>
<% else %>
I am getting the error: "undefined local variable or method `user'"
How can I check if the column super_user of an user is true or false?
1) It looks like you're using Devise gem (because of user_signed_in?). In this case it is a current_user helper you're looking for, not user.
2) You do not need ? in here current_user.super_user - column is called super_user, not super_user?.
<% if (user_signed_in? && current_user.super_user) %>
<% elsif (user_signed_in?) %>
<% else %>
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!
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.
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 .
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)
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 ;)
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
I want to display the page if the page is public. If the user of the page is trying to view the page if it's private and if it's the admin trying to view the page.
I have written
<% if #user.is_public == true || session[:user_id] == #user.id %>
<%= render "public_page" %>
<% else %>
Private Page
<%end%>
I don't know how to add something like below to the mix. Any ideas?
<% unless session[:site_admin] %>
The purpose is to allow the site admin to view all private pages.
Just add the check to the if:
<% if #user.is_public == true || session[:user_id] == #user.id || session[:site_admin] %>
<%= render "public_page" %>
<% else %>
Private Page
<%end%>
Btw, the more ruby way of naming is_public method would be public?
Btw btw, if your project is big and you want solid permission management it's a good practice to use Devise gem combined with CanCanCan. You then define all permissions in a single place, models/ability.rb and check permissions with can? :read, #post.
I want to show the user a part of the page if he has an attribute with a certain value.
something like this
<% if user.st == "Completed" %>
<p>just for him</p>
<% end %>
I get undefined method for nil class, how can I select the class in my views directly so I can access the attribute. I cannot use any params
edit: If I do this it works, but I want to check the attribute not if he is signed in
<% if user_signed_in? %>
<% end %>
thanks
In place of user use current_user, I'm assuming that it is for signed in user only
<% if current_user.st == "Completed" %>
<p>just for him</p>
<% end %>
You can do something like this:
In your controller:
#user = User.find(params[:id]) #or whatever user you want
In your view:
<% if #user.st == "Completed" %>
<p>just for him</p>
<% end %>
I'm just starting out with Ruby and Rails, trying out Devise with Rails 3. I've got a loop around a list of Posts, each of which has an associated user. I only want to display editing controls for those posts which are associated with the current user.
<% #posts.each do |post| %>
<%= link_to "show" %>
<% if current_user = post.user %>
<%= link_to "edit" %>
<% end %>
<% end %>
(The above is simplified, and from memory, so I'm sure the syntax isn't entirely right - but you get the gist.)
If no user is logged in, the posts show as intended - there's a Show link, but no Edit link. However, if I am logged in at all, all of the Edit links show up, even fir posts created by a different user.
I've verified in the console that User.find(1) != User.find(2), but for some reason the current_user = post.user evaluates to true no matter who is currently logged in. Is this to do with current_user being a helper as opposed to a "real" user object? How can I use current_user to get at the ACTUAL current user to make my comparison?
Thanks,
Dan
You're assigning rather than testing - use == - i.e.
<% if current_user == post.user %>