Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Adding recursive #to_hash implementation and spec. #83

Closed
wants to merge 1 commit into from

3 participants

@ifesdjeen

Makes API more consistent. Now, if record was created from
some hash, it will get serialized back to same hash.

Closes #82.

@ifesdjeen ifesdjeen Adding recursive #to_hash implementation and spec.
Makes API more consistent. Now, if record was created from
some hash, it will get serialized back to same hash.

Closes #82.
3bfc894
@ifesdjeen

Sorry, that one was silly.
I'll try again tomorrow.

@ifesdjeen ifesdjeen closed this
@dkubb
Collaborator

Don't worry about it. The solution you made is exactly how I would've approached it at first. The fact that structures can be recursive wouldn't be obvious unless you've done it and released it into the wild.

If you need a hand or need some ideas on how to prevent infinite recursion, let me know. Here's a few pointers to get you started:

http://www.codebenders.com/code/preventing-recursion-in-ruby/
https://github.com/dkubb/ice_nine/blob/master/lib/ice_nine/support/recursion_guard.rb

@solnic
Owner

@ifesdjeen there's no such thing as a silly pull request, just like there are no stupid questions :) thanks for your work! Either @dkubb or me can help you with getting this feature done. Looking forward for the next PR.

@ifesdjeen

thank you @solnic. I've kick-started a project that heavily relies on virtus, codebase is strong and well-tested, and there are many features I thought of. I'm currently combining at least 3 databases into a single data repository for some things we use in production, after trying to approach it in a active-record manner.

Maybe that work could also help out in future to make veritas to work with mongodb. Although I'm not yet ready to start writing a complete veritas-mongo-generator yet, but I think it may be an option a bit later, when some more general things are settled.

@dkubb
Collaborator

@ifesdjeen if you ever have any questions or need a hand with an veritas-mongo-adapter (or other related gems) please let me know. I think there are a few other people who may be interested, so it's not something you'd have to attempt solo. Plus of course, I'd give you whatever help I could too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 16, 2012
  1. @ifesdjeen

    Adding recursive #to_hash implementation and spec.

    ifesdjeen authored
    Makes API more consistent. Now, if record was created from
    some hash, it will get serialized back to same hash.
    
    Closes #82.
This page is out of date. Refresh to see the latest.
View
11 lib/virtus/instance_methods.rb
@@ -112,7 +112,8 @@ def attributes=(attributes)
set_attributes(attributes)
end
- # Returns a hash of all publicly accessible attributes
+ # Returns a hash of all publicly accessible attributes by
+ # recursively calling #to_hash on the objects that respond to it.
#
# @example
# class User
@@ -129,7 +130,13 @@ def attributes=(attributes)
#
# @api public
def to_hash
- attributes
+ attrs = attributes.dup
+ attrs.each do |key, value|
+ if value.respond_to?(:to_hash)
+ hash[key] = value.to_hash
+ end
+ end
+ attrs
end
private
View
26 spec/unit/virtus/instance_methods/to_hash_spec.rb
@@ -3,17 +3,29 @@
describe Virtus::InstanceMethods, '#to_hash' do
subject { object.to_hash }
- class Model
+ class Address
include Virtus
- attribute :name, String
- attribute :age, Integer
- attribute :email, String, :accessor => :private
+ attribute :street, String
+ attribute :city, String
end
- let(:model) { Model }
- let(:object) { model.new(attributes) }
- let(:attributes) { { :name => 'john', :age => 28 } }
+ class Person
+ include Virtus
+
+ attribute :name, String
+ attribute :age, Integer
+ attribute :email, String, :accessor => :private
+ attribute :address, Address
+ end
+
+ let(:model) { Person }
+ let(:child_record) { Address }
+
+ let(:address) { { :street => "Sunshinestr.", :city => "Berlin" } }
+ let(:object) { model.new(attributes) }
+
+ let(:attributes) { { :name => 'john', :age => 28, :address => child_record } }
it { should be_instance_of(Hash) }
Something went wrong with that request. Please try again.