solnic / virtus

[DISCONTINUED ] Attributes on Steroids for Plain Old Ruby Objects
MIT License
3.77k stars 228 forks source link

Recursively call attributes #290

Open jaimerson opened 9 years ago

jaimerson commented 9 years ago

Suppose I have a class Foo, which has an array of Bar objects, as follows:

class Foo
  include Virtus.model
  attribute :bars, Array[Bar]
end

class Bar
  include Virtus.model
  attribute :baz
  attributes :bamboo
end

Is there a way to retrieve a attributes hash for each Bar ({ bars: [ {baz:1, bamboo: 2}] }) when I call Foo#attributes? Calling attributes gives me this:

Foo.new(bars: [{baz: 1, bamboo: 2}]).attributes
# => { bars: [#<Bar:0xfd54ad3, @baz=1, @bamboo=2>] }

AlfonsoUceda commented 9 years ago

I look for something like that.

solnic commented 9 years ago

This will be addressed in virtus 2.0 refactoring. #attributes (and effectively #to_h and #to_hash) will be removed from virtus' core and moved to some external gem

AlfonsoUceda commented 9 years ago

thanks @solnic ;)

bradrobertson commented 9 years ago

This would be useful to me as well. IMO to_h and to_hash should not alias attributes but instead return a pure hash. Would a PR in the interim modifying to_h and to_hash to return pure hashes be useful?

Unless 2.0 is right around the corner, but it doesn't look like that's the case.

solnic commented 8 years ago

@bradrobertson we can add that with a limitation that when there are cross-references it will blow up with a stack too deep. You could use a recursion guard too but that will slow it down. I think it's fine to clearly document it and call it a day.

derekclee commented 8 years ago

It seems like to_json works as expected by converting all nested models. So a workaround might be JSON.parse(model.to_json).

ilnurnasyrov2 commented 7 years ago

It seems like to_json works as expected by converting all nested models. So a workaround might be JSON.parse(model.to_json).

looks like this workaround doesn't work anymore


require 'virtus'

class User
  include Virtus.model
end

User.new.to_json #=> NoMethodError: undefined method `to_json' for #<User:0x007fed648427c8>
filipesperandio commented 7 years ago

Is there a recommended way to accomplish this?