-1

I have three roles in my app: admin, dev, and client. In my header, dev can access the same tabs as admin.

I tried this:

li = link_to 'Mon compte', client_edit_infos_path unless current_client.role == 'admin' || 'dev'

It worked for admin and dev roles, but not for client role.

Can someone tell me another way to authorize two roles and restrict one?

sawa
  • 165,429
  • 45
  • 277
  • 381
Enner31
  • 193
  • 1
  • 13
  • It should be either `current_client.role == 'admin'` or `current_client.role == 'dev'` so `current_client.role == 'admin' || current_client.role == 'dev'` – Sebastián Palma Apr 23 '18 at 13:08
  • Better, create respective methods to your model: `admin?`, `admin_or_dev?` etc.. – yzalavin Apr 23 '18 at 13:10

3 Answers3

1
%w(admin dev).include?(current_client.role)
andriy-baran
  • 620
  • 4
  • 16
1

Please use an authorization gem, such as: https://github.com/CanCanCommunity/cancancan

Doing it manually is error prone and not easy to maintain.

You'll just need to define your ability:

and then in your code:

<% if can? :update, @client_info %>
  <%= link_to "Mon compte", client_edit_infos_path %>
<% end %>

Also, don't forget to set the same restriction in your controller actions! otherwise a user can bypass your view and trigger your action manually and have access to something they shouldn't.

Jonathan Duarte
  • 753
  • 5
  • 9
0

For an actual solution I recommend one of the other answers, but here's how it could work the way you originally intended (aka. what went wrong).

The problem is the condition at the end of the line: unless current_client.role == 'admin' || 'dev'

What ruby does here is not what you think; 'admin' || 'dev' is evaluated as 'admin', so the entire condition is equivalent to unless current_client.role == 'admin'.

The way the || operator works is:

  • If the first operand is truthy, it is the result of the operation.
  • If the first operand is falsey, the second operand is the result of the operation.

For example, true || false evaluates to true, 'hello' || 'world' is 'hello' and nil || 'world' evaluates to 'world'.

The correct condition would be unless current_client.role == 'admin' or current_client.role == 'dev'

or does the same as ||, but with higher precedence.

DarkWiiPlayer
  • 6,871
  • 3
  • 23
  • 38