How to use CanCanCan with enum field?

南笙酒味 提交于 2019-12-04 15:21:32

I may be wrong, but I think that enum only creates instance methods:.

@article = Article.find params[:id]
@article.done?

I was wrong...

Scopes based on the allowed values of the enum field will be provided as well. With the above example:

Conversation.active
Conversation.archived

--

I'll delete this if it doesn't work; I would be evaluating against the hash of conditions, not the class itself:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if user.member?
      can :read, Article, status: Article.statuses[:done]
    end
  end
end

Update

Several important things to consider.

Firstly, when using hash conditions:

Important: If a block or hash of conditions exist they will be ignored when checking on a class, and it will return true.

This means that you cannot call specific conditions on an "ability" whilst passing a class, it has to be called on an instance of an object.

Secondly, it seems CanCanCan has some issues evaluating enum values, which makes the following code necessary:

#app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.member?
      can :read, Article do |article|
        article.done?
      end
    end
  end
end

You then need to pass the article instance to the can? method:

#app/views/articles/index.html.erb
<table>
    <%= render @articles %>
</table>

#app/views/articles/_article.html.erb
<% if can? :read, article %>
    <tr>
      <td>Title:</td>
      <td><%= article.title %></td>
      <td><%= article.status %></td>
    </tr>
<% end %>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!