How to use CanCanCan with enum field?

我与影子孤独终老i 提交于 2019-12-21 20:26:32

问题


I got Article model with enum field enum status: [:pending, :done].

Here's my ability file

class Ability
  include CanCan::Ability

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

    if user.member?
      can :read, Article.done
    end
  end
end

In view I am trying to render Article.done collection for member but nothings renders.

<% if can? :read, Article.done %> 
  <%= render partial: 'article', collection: Article.done, as: :article %>
<% end %>

Therefore I have a question: is there any possible way to work with enum in CanCanCan?


回答1:


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


来源:https://stackoverflow.com/questions/34963775/how-to-use-cancancan-with-enum-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!