Показать ссылку, если пользователь сеанса соответствует определенным критериям

Я пытаюсь сделать конкретную ссылку в своем приложении видимой только для пользователей, у которых атрибут :department равен «Продажи».

Другими словами, у меня есть модель Пользователи, в которой у пользователя есть password, username и department. Сеанс сохраняет :user_id после входа пользователя в систему.

Что я хотел бы сделать, так это то, что когда мое представление отображается, в зависимости от :department вошедшего в систему пользователя, либо отображать, либо не отображать конкретную ссылку.

Вот код, который у меня есть, на мой взгляд, но я борюсь с тем, как получить информацию о сеансе и найти в нем отдел пользователя.

<% if Users.where(id: session[:user_id])[:department] == "Sales" %>
  <%= link_to 'New Request', new_request_path %>
  <% else nil %>
<% end %>

Я знаю, что делать запрос где-либо, кроме контроллера или модели, плохо, поэтому, если у вас есть какие-либо советы о том, как лучше структурировать эту логику, я был бы признателен.


person sabrams    schedule 18.11.2013    source источник


Ответы (2)


Я думаю, что вы хотите:

<% user = User.find_by_id(session[:user_id]) %>
<% if user.present? && user[:department] == "Sales" %>
  <%= link_to 'New Request', new_request_path %>
<% end %>

Лично я бы поместил это во вспомогательный метод, чтобы очистить его:

В приложении/помощники/users_helper.rb:

def user_in_sales?
  user = User.find_by_id(session[:user_id])

  user.present? && user[:department] == "Sales"
end

Тогда ваш взгляд:

<% if user_in_sales? %>
  <%= link_to 'New Request', new_request_path %>
<% end %>

Лично я бы настоятельно рекомендовал использовать что-то вроде cancan, чтобы справиться с этой ситуацией. Я думаю, вы можете обнаружить, что можете использовать канкан в качестве эффективного инструмента авторизации в других местах вашего приложения, особенно если вы выполняете подобную логику в другом месте.

person CDub    schedule 18.11.2013

Во-первых, вы используете объектно-ориентированный язык. Это поможет вам перестать зацикливаться на деталях реализации (например, отдел == «Продажи») и вместо этого рассмотреть намерение или значение, которое вы пытаетесь выразить, и код, чтобы удовлетворить это. Например:

if current_user.works_in?(:jewelry)
  link_to 'Request Receipt', new_request_path
end

Ваши модели должны предоставлять общедоступный интерфейс, который позволяет другим объектам в вашем коде (например, вашему контроллеру) получать необходимую им информацию (т. е. имеет ли пользователь связь с отделом) без знания или беспокойства о базовой схеме хранения данных. .

class User
  def works_in?(department_name)
    departments.pluck(:name).include?(department_name.to_s)
  end
end
person coreyward    schedule 18.11.2013