嵌套 JSON 的存储访问器
Store accessor for nested JSON
我有一个模型 "Organization",它存储与组织相关的所有信息。有一个名为 "integrations" 的类型 JSONB 字段,用于存储与组织拥有的所有外部服务集成相关的信息。
如何使用存储访问器访问存储在嵌套 JSON 中的信息,例如:
{
"mailchimp": {"api_key":"vsvsvef", "list_id":"12345"},
"sendgrid" : {"username":"msdvsv", "password":"123456"}
}
我知道我可以像这样使用商店访问器访问 mailchimp:
store_accessor :integrations, :mailchimp
如何轻松访问 mailchimp 的 api_key?
你是对的,不幸的是 store_accessor
不允许你访问嵌套键。原因是 store_accessor
基本上只是定义 getter 和 setter 方法的快捷方式:
# here is a part of store_accessor method code, you can take a look at
# full implementation at
# http://apidock.com/rails/ActiveRecord/Store/ClassMethods/store_accessor
_store_accessors_module.module_eval do
keys.each do |key|
# here we define a setter for each passed key
define_method("#{key}=") do |value|
write_store_attribute(store_attribute, key, value)
end
# and here goes the getter
define_method(key) do
read_store_attribute(store_attribute, key)
end
end
end
那么,您的选择是:
要手动实现您自己的一组 getter 和 setter 方法:
# somewhere in your model
def mailchimp_api_key
self.mailchimp["api_key"]
end
def mailchimp_api_key= value
self.mailchimp["api_key"] = value
end
这解决了一个问题,但是您必须为每个嵌套属性重复编写很多这样的代码。
在 ActiveRecord::Store::ClassMethods
模块中编写您自己的辅助方法,该方法将为您传入的属性集动态定义相同的 setter 和 getter 方法. 您必须采用 Rails store_accessor
的基本实现并向其添加额外的哈希键迭代。不确定这是否会很简单,但看到共享为 gem.
肯定会很有趣
保留 Rails 本身并使用 postgres json
类型支持的强大功能以及一些纯 SQL
代码。例如,您可以使用类似的方式访问 api_key
属性:
SELECT integrations->'mailchimp'->>'api_key' as mailchimp_api_key FROM your_table_name;
有关 postgres json 查询的更多信息,请参见 here。
我也在找同样的东西。正如@twonegatives 所指出的,store_accessor 对我们没有帮助。但我确实发现#dig 方法非常适合获取数据。所以...
#somewhere in Organization model
def api_key
integrations.dig("mailchimp", "api_key")
end
def username
integrations.dig("sendgrid", "username")
end
您可以使用 the Attribute API
store_accessor :integrations, :mailchimp
store_accessor :mailchimp, :api_key, :list_id
attribute :mailchimp, :json # :jsonb also works if you're using a PG column of that type for `integrations`
我有一个模型 "Organization",它存储与组织相关的所有信息。有一个名为 "integrations" 的类型 JSONB 字段,用于存储与组织拥有的所有外部服务集成相关的信息。
如何使用存储访问器访问存储在嵌套 JSON 中的信息,例如:
{
"mailchimp": {"api_key":"vsvsvef", "list_id":"12345"},
"sendgrid" : {"username":"msdvsv", "password":"123456"}
}
我知道我可以像这样使用商店访问器访问 mailchimp:
store_accessor :integrations, :mailchimp
如何轻松访问 mailchimp 的 api_key?
你是对的,不幸的是 store_accessor
不允许你访问嵌套键。原因是 store_accessor
基本上只是定义 getter 和 setter 方法的快捷方式:
# here is a part of store_accessor method code, you can take a look at
# full implementation at
# http://apidock.com/rails/ActiveRecord/Store/ClassMethods/store_accessor
_store_accessors_module.module_eval do
keys.each do |key|
# here we define a setter for each passed key
define_method("#{key}=") do |value|
write_store_attribute(store_attribute, key, value)
end
# and here goes the getter
define_method(key) do
read_store_attribute(store_attribute, key)
end
end
end
那么,您的选择是:
要手动实现您自己的一组 getter 和 setter 方法:
# somewhere in your model def mailchimp_api_key self.mailchimp["api_key"] end def mailchimp_api_key= value self.mailchimp["api_key"] = value end
这解决了一个问题,但是您必须为每个嵌套属性重复编写很多这样的代码。
在
ActiveRecord::Store::ClassMethods
模块中编写您自己的辅助方法,该方法将为您传入的属性集动态定义相同的 setter 和 getter 方法. 您必须采用 Railsstore_accessor
的基本实现并向其添加额外的哈希键迭代。不确定这是否会很简单,但看到共享为 gem. 肯定会很有趣
保留 Rails 本身并使用 postgres
json
类型支持的强大功能以及一些纯SQL
代码。例如,您可以使用类似的方式访问api_key
属性:SELECT integrations->'mailchimp'->>'api_key' as mailchimp_api_key FROM your_table_name;
有关 postgres json 查询的更多信息,请参见 here。
我也在找同样的东西。正如@twonegatives 所指出的,store_accessor 对我们没有帮助。但我确实发现#dig 方法非常适合获取数据。所以...
#somewhere in Organization model
def api_key
integrations.dig("mailchimp", "api_key")
end
def username
integrations.dig("sendgrid", "username")
end
您可以使用 the Attribute API
store_accessor :integrations, :mailchimp
store_accessor :mailchimp, :api_key, :list_id
attribute :mailchimp, :json # :jsonb also works if you're using a PG column of that type for `integrations`