Rails 6,设计和主动存储

问题描述

我在Rails 6应用程序中使用Devise和Active Storage。当前使用before_action: authenticate_user!会为非用户禁用所有图像,这很不错,除了我希望允许record_type中带有active_storage_attachments'News'的图像可供用户和非用户查看。

下面的代码是我到目前为止的内容,查看了record_type是新闻的ActiveStorage :: Attachment。此代码显示用户和非用户的所有图像,这是不理想的。

class ActiveStorage::BaseController < ActionController::Base
  before_action :allow_certain_assets
  include ActiveStorage::SetCurrent

  protect_from_forgery with: :exception
  
  private
  
  def allow_certain_assets
    if (ActiveStorage::Attachment.where(record_type: 'News')).present?
    else
      authenticate_user!
    end
  end
  
end

解决方法

您的代码存在的问题是您正在执行以下操作:

(ActiveStorage::Attachment.where(record_type: 'News')).present?

它将检查整个数据库,如果有attachment为“新闻”的record_type。但是相反,您需要检查用户尝试访问的特定图像是否为“新闻”类型,然后允许他使用,否则不允许他使用。一种方法是在可以检查的表演动作上:

def show
  # this code might be incorrect and I am not sure how you would be getting 
  # the attachment object but this would explain a way you can authenticate it
  @attachment = ActiveStorage::Attachment.find params[:id]
  authenticate_user! unless @attachment.record_type == 'News'
end

因此,这将检查用户尝试访问的特定对象。

添加:

可以使用某些授权库自动完成这种类型的授权,例如:

  1. CanCanCan
  2. Pundit

您还可以在其中允许访客用户使用某些类型的图像,而仅允许注册用户使用其他类型的图像。

,

这将与Pundit gem(@Deep here提到的选项之一)一起使用

# controller
class ImagesController < ApplicationController
  def index
    authorize :image,:index?
    @images = policy_scope(ActiveRecord::Attachment)
  end

  def show
    @image = policy_scope(ActiveRecord::Attachment).find(params[:id])
    authorize @image,policy_class: ImagePolicy
  end
end
# policy
class ImagePolicy < ApplicationPolicy
  def index?
    true # must be true so that every can see the list
  end

  def show?
    true # optional: add more logic here
  end

  class Scope
    def initialize(user,scope)
      @user  = user
      @scope = scope
    end

    def resolve
      if user
        scope
      else        
        scope.where(record_type: 'News') # we limit the records here
      end
    end
  end
end

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...