Ruby 使用符号访问嵌套属性
Ruby access nested attributes with symbol
我正在尝试编写一个方法,该方法采用 一个对象、一个符号(或其他东西,这是问题所在)和"upcases" 键处的值(例如)。
简单案例:
foo = { a: 'hi', b: 'there' }
def upc_value(object, key)
object[key].upcase!
end
upc_value(foo, :b)
puts foo #=> { a: 'hi', b: 'THERE' }
但如果我的 foo
对象更复杂,我也希望该方法能够处理嵌套属性。
更复杂案例:
foo = { a: 'hi', b: [{ c: 'foo', d: 'bar' }, { c: 'bob', d: 'lisa' }] }
def upc_value(object, key)
object[key].upcase!
end
# I would like to be able to do something like:
upc_value(foo, :b[:d])
puts foo #=> { a: 'hi', b: [{ c: 'foo', d: 'BAR' }, { c: 'bob', d: 'LISA' }] }
我显然不能这样做,我很好奇是否存在类似 "deep_symbol" 的东西...
真正的问题:
我在这里真正想要实现的是一个模块,它在保存模型之前从包含 URL 的每个字段中删除主机。
它包含在每个需要它的模型中,我调用了一个 fields_containing_url
方法来获取字段的符号。
问题是我在我的一个模型上嵌套了属性,我需要使用采用符号的完全相同的方法来访问它们...
谢谢你的帮助!
这是一个开始。这是一种就地更改数据的递归方法:
def deep_transform(object, key, &block)
case object
when Array
object.each do |element|
deep_transform(element, key, &block)
end
when Hash
object.each_value do |value|
deep_transform(value, key, &block)
end
if value = object[key]
object[key] = yield(value)
end
end
end
foo = { a: 'hi', b: 'there' }
deep_transform(foo, :b){ |str| str.upcase }
p foo
# {:a=>"hi", :b=>"THERE"}
foo = { a: 'hi', b: [{ c: 'foo', d: 'bar' }, { c: 'bob', d: 'lisa' }] }
deep_transform(foo, :d, &:upcase) # Alternative way to call the method
p foo
# {:a=>"hi", :b=>[{:c=>"foo", :d=>"BAR"}, {:c=>"bob", :d=>"LISA"}]}
请注意,该方法将改变与 :d
键相关的每个值。您没有像示例中那样指定 :b[:d]
。
我正在尝试编写一个方法,该方法采用 一个对象、一个符号(或其他东西,这是问题所在)和"upcases" 键处的值(例如)。
简单案例:
foo = { a: 'hi', b: 'there' }
def upc_value(object, key)
object[key].upcase!
end
upc_value(foo, :b)
puts foo #=> { a: 'hi', b: 'THERE' }
但如果我的 foo
对象更复杂,我也希望该方法能够处理嵌套属性。
更复杂案例:
foo = { a: 'hi', b: [{ c: 'foo', d: 'bar' }, { c: 'bob', d: 'lisa' }] }
def upc_value(object, key)
object[key].upcase!
end
# I would like to be able to do something like:
upc_value(foo, :b[:d])
puts foo #=> { a: 'hi', b: [{ c: 'foo', d: 'BAR' }, { c: 'bob', d: 'LISA' }] }
我显然不能这样做,我很好奇是否存在类似 "deep_symbol" 的东西...
真正的问题:
我在这里真正想要实现的是一个模块,它在保存模型之前从包含 URL 的每个字段中删除主机。
它包含在每个需要它的模型中,我调用了一个 fields_containing_url
方法来获取字段的符号。
问题是我在我的一个模型上嵌套了属性,我需要使用采用符号的完全相同的方法来访问它们...
谢谢你的帮助!
这是一个开始。这是一种就地更改数据的递归方法:
def deep_transform(object, key, &block)
case object
when Array
object.each do |element|
deep_transform(element, key, &block)
end
when Hash
object.each_value do |value|
deep_transform(value, key, &block)
end
if value = object[key]
object[key] = yield(value)
end
end
end
foo = { a: 'hi', b: 'there' }
deep_transform(foo, :b){ |str| str.upcase }
p foo
# {:a=>"hi", :b=>"THERE"}
foo = { a: 'hi', b: [{ c: 'foo', d: 'bar' }, { c: 'bob', d: 'lisa' }] }
deep_transform(foo, :d, &:upcase) # Alternative way to call the method
p foo
# {:a=>"hi", :b=>[{:c=>"foo", :d=>"BAR"}, {:c=>"bob", :d=>"LISA"}]}
请注意,该方法将改变与 :d
键相关的每个值。您没有像示例中那样指定 :b[:d]
。