2017-03-28 5 views
1

내가 키에 (질문을 여기에, 다른 사람 또는 무언가) 객체, 상징 소요 방법 "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 메서드를 호출합니다.
문제는 모델에 중첩 된 특성이있어서 기호를 사용하는 것과 동일한 방법으로 모델에 액세스해야한다는 것입니다 ...

도움을 주셔서 감사합니다!

답변

1

여기가 시작되었습니다. 방법은 :d 키에 관련된 모든 가치를 돌연변이 것

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"}]} 

참고 :이 곳에서 데이터를 변경 재귀 방법입니다. 귀하의 예제에서와 같이 :b[:d]을 지정하지 마십시오.

+1

답장을 보내 주셔서 감사합니다. 매력처럼 작동합니다. 내 필요에 맞게 switch 문에 사례를 추가했습니다. MyModel object.attributes.each_value do | value | deep_transform (값, 키 및 블록) 끝 끝 – Francois