gpt4 book ai didi

ruby-on-rails - 从 ActiveRecord/ActiveModel JSON 输出中过滤字段(神奇!)

转载 作者:数据小太阳 更新时间:2023-10-29 07:56:20 26 4
gpt4 key购买 nike

我想在输出 JSON 时从 ActiveRecord/ActiveModel 类中过滤掉特定字段。

最直接的方法就是覆盖 as_json,可能像这样:

def as_json (options = nil)
options ||= {}
super(options.deep_merge({:except => filter_attributes}))
end

def filter_attributes
[:password_digest, :some_attribute]
end

这行得通,但它有点冗长,并且不会很快变干。我认为只用神奇的类方法声明过滤属性会很好。例如:

class User < ActiveRecord::Base
include FilterJson

has_secure_password
filter_json :password_digest
#...
end

module FilterJson
extend ActiveSupport::Concern

module ClassMethods
def filter_json (*attributes)
(@filter_attributes ||= Set.new).merge(attributes.map(&:to_s))
end

def filter_attributes
@filter_attributes
end
end

def as_json (options = nil)
options ||= {}
super(options.deep_merge({:except => self.class.filter_attributes.to_a}))
end
end

问题是让它正确处理继承。假设我将用户子类化:

class SecretiveUser < User
filter_json :some_attribute, :another_attribute
#...
end

从逻辑上讲,过滤掉 :some_attribute:another_attribute:password_digest 是有意义的。

但是,这只会过滤在类上声明的属性。为了达到预期目的,我尝试在 filter_attributes 中调用 super,但失败了。我想到了这个,这是一个 hack。

def filter_attributes
if superclass.respond_to?(:filter_attributes)
superclass.filter_attributes + @filter_attributes
else
@filter_attributes
end
end

这显然很脆弱而且不符合习惯,但这是我要完成的“内容”。任何人都可以想出一种更正确(并希望更优雅)的方法吗?谢谢!

最佳答案

我认为将白名单属性列入黑名单是一种更安全的解决方案。这将防止添加到 UserSomeUser 的不需要的 future 属性进入您的 JSON 响应,因为您忘记将所述属性添加到 filter_json

您似乎正在寻找解决特定继承问题的方法。我还是要指出 active_model_serializers ,因为我觉得这是管理序列化的更明智的方法。

class UserSerializer < ActiveModel::Serializer
attributes :id, :first_name, :last_name
end

class SecretUserSerializer < UserSerializer
attributes :secret_attribute, :another_attribute
end

给定一些 SecretUser s 你可以做

SecretUserSerializer.new(s).as_json

你会得到 :id:first_name:last_name:secret_attribute:另一个属性。继承按预期工作。

关于ruby-on-rails - 从 ActiveRecord/ActiveModel JSON 输出中过滤字段(神奇!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18603699/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com