Reputation: 1128
I'm trying to make a specific link in my application only visible to users who have the attribute :department
equal to "Sales".
In other words, I've got a model Users, in which a user has a password
, username
, and department
. The session saves the :user_id
once the user is logged in.
What I would like to do is when my view is rendered, depending on the :department
of the logged in user, either display, or don't display a specific link.
Here's the code I've got in my view, but I'm struggling with how to take the session info and find the department of the user from it.
<% if Users.where(id: session[:user_id])[:department] == "Sales" %>
<%= link_to 'New Request', new_request_path %>
<% else nil %>
<% end %>
I know it's bad to do a query anywhere other than the controller or model, so if you have any advice on how to better structure this logic as well, I would appreciate it.
Upvotes: 0
Views: 147
Reputation: 13354
I think what you want is:
<% user = User.find_by_id(session[:user_id]) %>
<% if user.present? && user[:department] == "Sales" %>
<%= link_to 'New Request', new_request_path %>
<% end %>
Personally, I'd put this into a helper method to clean it up:
In app/helpers/users_helper.rb:
def user_in_sales?
user = User.find_by_id(session[:user_id])
user.present? && user[:department] == "Sales"
end
Then your view:
<% if user_in_sales? %>
<%= link_to 'New Request', new_request_path %>
<% end %>
Personally, I'd strongly look into using something like cancan to handle this situation. I think you may find that you could use cancan as an effective authorization tool other places in your app, especially if you're doing logic like this elsewhere.
Upvotes: 1
Reputation: 80041
First, you're using an object oriented language. It would help you to quit getting hung up on implementation details (e.g. department == "Sales") and instead consider the intent or meaning you're trying to express and code to meet that. For example:
if current_user.works_in?(:jewelry)
link_to 'Request Receipt', new_request_path
end
Your models should expose a public interface that allows other objects in your code (like your controller) to get the information they need (i.e. whether or not a user has an association with a department) without knowledge of or concern for the underlying data storage schema.
class User
def works_in?(department_name)
departments.pluck(:name).include?(department_name.to_s)
end
end
Upvotes: 1