check if user has attribute with certain value in views - ruby-on-rails

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 %>

Related

Can I query against the DEVISE current_user helper in my application menu?

The problem is, In the menu of my app I want to check if the current user has a book. If they do I will show a link to the edit book path, if not, I will show a link to the create book path.
<% if current_user.book? %>
<% else %>
<% end %>
Yes, you should be able to access current_user from any controller. But always make sure you handle if current_user returns nil.
You can use a try or safe navigation.
<% if current_user.try(:book?) %>
<% else %>
<% end %>
Or
<% if current_user&.book? %>
<% else %>
<% end %>

How to hide an element if it's being viewed from a certain route?

I've got a partial with a form in it. I would like to have control over which routes admin users are able to view this form in.
There are two routes, advertisements/show, and advertisements/admin-edit. The partial is displayed in both views.
I tried doing
<%= unless current_user.admin %>
# display section of partial
<% end %>
but this isn't optimal because it stop admins from being able to test the application from the advertisements/show route.
Is there a way to hide the form if the current path is admin_edit_path?
try this one:
<% unless params[:action] == 'edit' && params[:controller] == 'admin' %>
# display partial
<% end %>```
<% unless current_page?(controller: 'advertisements', action: 'admin_edit') %>
#display partial
<% end %>

Check if user voted acts as votable

I want to make some styling changes if user has voted for a photo, and I used this code (acts_as_votable docs):
<% if current_user.voted_for? #photo %>
<%= link_to like_photo_path(#photo), method: :put do %>
<button>
¡Liked!
</button>
<% end %>
<% else %>
You dont like it yet
<% end %>
But this wont work because it will show "Liked" all the time, even if I didn't click the Like button.
photos controller
def upvote
#photo = Photo.friendly.find(params[:id])
#photo.liked_by current_user
redirect_to user_photo_path(#photo.user,#photo)
end
What can it be wrong?
Add an additional condition in your if statement
<% if current_user.voted_for? #photo && #photo.liked_by current_user %>
# different text
<% elsif current_user.voted_for? #photo %>
<%= link_to like_photo_path(#photo), method: :put do %>
<button>
¡Liked!
</button>
<% end %>
<% else %>
You dont like it yet
<% end %>
This is a pretty common design pattern of basically falling through to the next logical default.
Note that if you find yourself nesting "if" statements, like so
if condition_one
if condition_two
if condition_three
# do something
else
# do something else
end
This is the same as
if condition_one && condition_two && condition_three
# do something
else
# do something else
end
If you find yourself falling into the nested ifs pattern then rethink what you're doing. You may need to decompose the code into a helper method, etc.

<% if current_user.id == #status.user_id %> when user not signed in

Currently, I have in my 'show' view for a question model
<% if current_user.id == #question.user_id %>
<%= link_to 'Edit', edit_question_path(#question) %>
<% else %>
<% end %>
To allow the user that created the question to edit it. This works fine when a user is logged in.
However, if a guest is not logged in. I get this error:
NoMethodError in Questions#show
undefined method `id' for nil:NilClass
It doesn't seem to like this line
<% if current_user.id == #question.user_id %>
Can anyone advise a rewrite to get this to work with guest users too?
Thanks
Why not do something like <% if current_user == #question.user %>? Take out the IDs.
Or if you really want the IDs. something like <% if current_user.present? && current_user.id == #question.user_id %>
In a helper
def current_user?(user)
current_user && current_user == user
end
Then in the view
<% if current_user?(#question.user) %>
You can't have an user.id if the user is not in the database. There is a good screencast about this: http://railscasts.com/episodes/393-guest-user-record?view=asciicast
#BillyChan - for that requirement, i would allow upvoting if someone isn't signed in. No need to create an unsaved user record. I'd probably want to use cookies to stop people multiple-upvoting, but to be honest i'd probably argue with the client that we shouldn't let people upvote without being logged in.
Use this
<% if current_user.present? && current_user.id == #question.user_id %>

Test ownership in a helper

I have this block in my views:
<% video.members.each do |p| %>
<% if p.id == current_user.id %>
<%= "paid" %>
<% end %>
<% end %>
Basically I'm trying to work out if a member has paid for a video based on whether the id's match.
Maybe this a really bad way of doing it, which case I'd be happy to try and different method.
Assuming it is an ok way of checking this, how could I write a similar statement but as a helper method? I've tried, but it seems you can't write the same logic in helpers as the block just spits out the full array and not the id, meaning it doesn't work.
You should do this instead:
<% if video.members.exists?(id: current_user.id) %>
<%= 'Paid' %>
<% end %>
This will generate a single query to test if the video has been paid by the current_user ;-)
In a helper:
# application_helper.rb
def display_paid_or_not(video)
return '' if video.blank? # similar to .nil?
video.members.exists?(id: current_user.id) ? 'Paid' : ''
end
# in view
<%= display_paid_or_not(video) %>
Hope this helps!

Resources