gpt4 book ai didi

ruby - 如何将字符串标识符存储到模型属性

转载 作者:数据小太阳 更新时间:2023-10-29 06:50:05 25 4
gpt4 key购买 nike

我正在使用 Virtus创建代表 Salesforce 对象的模型。

我正在尝试创建具有友好名称的属性,这些名称用于访问我可以用来检索该变量的标识符“String”的值和方法。

Object.attribute #=> "BOB"
Object.get_identifier(:attribute_name) #=> "KEY"
# OR something like this
Object.attribute.identifier #=> "KEY"

友好名称用作 getter/setter 和标识符,我可以存储与 API 名称对应的每个属性。

这是一个例子:

class Case
include Virtus.model

attribute :case_number, String, identifier: 'Case_Number__c'

end

c = Case.new(case_number: 'XXX')
c.case_number #=> 'XXX'
c.case_number.identifier #=> 'Case_Number__c'

或者,不是在属性本身上有一个方法,而是为每个标识符集创建一个辅助方法:

c.case_number #=> 'XXX'
c.case_number_identifier #=> 'Case_Number__c'

我可以延长Virtus::Attribute吗?并添加这个?如果是这样,我不确定该怎么做。

最佳答案

Monkey 修补 Virtus 的 Attribute 类当然是一个选项。
但是,深入到库的内部会使您容易受到该库源代码私有(private)部分重构的影响。

相反,您可以使用封装此功能的辅助模块。这是一个建议:

require 'virtus'

# Put this helper module somewhere on your load path (e.g. your project's lib directory)
module ApiThing

def self.included(base)
base.include Virtus.model
base.extend ApiThing::ClassMethods
end

module ClassMethods
@@identifiers = {}

def api_attribute(attr_name, *virtus_args, identifier:, **virtus_options)
attribute attr_name, *virtus_args, **virtus_options
@@identifiers[attr_name.to_sym] = identifier
end

def identifier_for(attr_name)
@@identifiers.fetch(attr_name.to_sym){ raise ArgumentError, "unknown API attribute #{attr_name.inspect}" }
end
end

def identifier_for(attr_name)
self.class.identifier_for(attr_name)
end

end

# And include it in your API classes
class Balls
include ApiThing

api_attribute :color, String, identifier: 'SOME__fancy_identifier'
api_attribute :number, Integer, identifier: 'SOME__other_identifier'
api_attribute :size, BigDecimal, identifier: 'THAT__third_identifier'
end

# The attributes will be registered with Virtus – as usual
puts Balls.attribute_set[:color].type #=> Axiom::Types::String
puts Balls.attribute_set[:number].type #=> Axiom::Types::Integer
puts Balls.attribute_set[:size].type #=> Axiom::Types::Decimal

# You can use the handy Virtus constructor that takes a hash – as usual
b = Balls.new(color: 'red', number: 2, size: 42)

# You can access the attribute values – as usual
puts b.color #=> "red"
puts b.number #=> 2
puts b.size #=> 0.42e2
puts b.durability #=> undefined method `durability' [...]

# You can ask the instance about identifiers
puts b.identifier_for :color #=> "SOME__fancy_identifier"
puts b.identifier_for :durability #=> unknown API attribute :durability (ArgumentError)

# And you can ask the class about identifiers
puts Balls.identifier_for :color #=> "SOME__fancy_identifier"
puts Balls.identifier_for :durability #=> unknown API attribute :durability (ArgumentError)

您不需要 Virtus 来实现您的 API 标识符。类似的辅助模块可以只注册 attr_accessor 而不是 Virtus 属性。
然而,Virtus 具有其他方便的功能,如哈希构造函数和属性强制转换。如果您不介意没有这些功能或寻找替代品,那么放弃 Virtus 应该不是问题。

喂! :)

关于ruby - 如何将字符串标识符存储到模型属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42544653/

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