首页 > 解决方案 > 基于 current_user 序列化 Rails 6 模型

问题描述

在 API 控制器中,我想根据谁登录来限制可以看到模型的哪些字段。ActiveModel 序列化程序似乎允许这样做,但我对以下情况没有运气:

class MyModelSerializer < ActiveModel::Serializer
  attributes :name, :custom_field, :secret_field

  has_many :linked_records

  def custom_field
    object.do_something
  end

  def filter(keys)
    unless scope.is_admin?
      keys.delete :secret_field
      keys.delete :linked_records
    end
    keys
  end
end

但是,过滤永远不会执行,因此即使没有用户登录,我的输出也始终包含 :secret_field 和 :linked_records 。

也许这是因为我使用的是 Rails 6,而且似乎 ActiveModel Serializers 可能不再是最好的工具(例如https://stevenyue.com/blogs/migrating-active-model-serializers-to-jserializer)。

如果您能想到更好的方法,请提供您对执行此操作的方法的建议。

编辑:

除了下面的所有评论,这里有一些不同的代码:

  attributes :name, :id, :admin_only_field, :is_admin

  $admin_only = %i[:id, :admin_only_field]

  def attributes(*args)
    hash = super
    $admin_only.each do |key|
      unless scope.is_admin?
        hash.delete(key)
      end
    end
    hash
  end

  def is_admin
    if scope.is_admin?
      'admin!'
    else
      'not an admin!'
    end
  end

如果我然后以管理员身份访问模型的索引页面,我会看到 admin_only_field 和 id 都存在,而 is_admin 说我不存在。奇怪。

标签: ruby-on-rails

解决方案


class MyModelSerializer < ActiveModel::Serializer
  attributes :name, :custom_field, :secret_field

  has_many :linked_records

  def custom_field
    object.do_something
  end

 private

  def attributes
    hash = super
    unless scope.is_admin?
      hash.delete :secret_field
      hash.delete :linked_records
    end
    hash
  end

end

推荐阅读