在Rails

时间:2017-11-22 20:48:13

标签: authorization ruby-on-rails-5 before-filter

我有一个Rails应用程序,其中包含属于类别的文章

class Article < ApplicationRecord
  belongs_to :category


class Category < ApplicationRecord
  has_many :articles, dependent: :destroy

它有一个基本的用户模型,其中一些滚动您自己的身份验证和授权但是我遇到了一个路障,试图将某些用户限制在特定类别下的文章

有&#34; admin&#34;用户和&#34;内部&#34;用户。

还有一个名为Internal的类别

我希望将对类别设置为“内部”的任何文章的访问权限限制为仅限管理员和内部用户。

如果普通用户或未登录用户尝试访问内部类别下的文章,他们将被重定向到主页,并且会有一条Flash消息让他们知道访问被拒绝。

我不希望他们看到的特定页面是其类别设置为内部的任何文章的显示页面以及内部类别的显示页面。

内部类别的显示页面遍历所有文章,其类别设置为内部。

我已将其设置为使用before_action限制对新页面,编辑和销毁页面的未授权访问。

before_action :admin_user,       only: [:new, :edit, :destroy]

def admin_user
      redirect_to(root_url) && flash[:danger] = "You are not authorized!" unless current_user.admin?
    end

我的主要问题是是否有更细粒度的方法来限制从模型中访问单个记录而不仅仅是整个控制器操作?

我挖掘了一些像cancancan这样的宝石,但它们似乎都专注于限制对整个控制器操作的访问,而不是单个记录。

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:0)

我最终找到了完成这项工作的方法,但是我确信我的代码很难看,并愿意接受清理并使其更优雅的建议。我想我会发布我的答案,以防将来帮助任何人。

我最终在文章控制器上添加了一个before_action,用于检查用户正在尝试查看的文章,以及是否将其类别设置为&#34;内部&#34;它只允许他们查看它是否是内部用户。它还限制他们编辑它,除非它们是内部的。

用户模型有一个布尔值,用于将用户设置为内部。

before_action :internal_article,  only: [:show, :edit]

def internal_article
  @article = Article.find(params[:id])
  if @article.category.name == "Internal"
    redirect_to(root_url) && flash[:danger] = "You are not authorized to view that article!" unless logged_in? && current_user.internal?
  end
end 

答案 1 :(得分:0)

您可以将此类方法放入文章模型中

def self.non_internal
  where(category: Category.where.not(name: 'internal'))
end
控制器中的

以这种方式使用

@article = Article.non_internal.find(params[:id])
if @article.nil?
  redirect_to(root_url) && flash[:danger] = "You are not authorized to view that article!" unless logged_in? && current_user.internal?
end