Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Serialization Separation #6

Merged
merged 3 commits into from

1 participant

@jnunemaker
Owner

Separated serialization of object stuff and assocation stuff.

@jnunemaker jnunemaker merged commit d943155 into master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 19, 2012
  1. Remove Gemfile.lock.

    authored
  2. Separated object and association serialization.

    authored
    Moved object serialization into Toy::Object and included association
    serialization in Toy::Store.
This page is out of date. Refresh to see the latest.
View
3  .gitignore
@@ -4,4 +4,5 @@ testing/
log
tmp
pkg
-.bundle
+.bundle
+Gemfile.lock
View
14 Gemfile
@@ -1,15 +1,15 @@
source :rubygems
gemspec
-gem 'rake'
-gem 'oj'
-gem 'multi_json'
+gem 'rake', '~> 0.9.0'
+gem 'oj', '~> 1.0.0'
+gem 'multi_json', '~> 1.3.2'
group(:guard) do
- gem 'guard'
- gem 'guard-rspec'
- gem 'guard-bundler'
- gem 'growl'
+ gem 'guard', '~> 1.0.0'
+ gem 'guard-rspec', '~> 0.6.0'
+ gem 'guard-bundler', '~> 0.1.0'
+ gem 'growl', '~> 1.0.0'
end
group(:test) do
View
67 Gemfile.lock
@@ -1,67 +0,0 @@
-PATH
- remote: .
- specs:
- toystore (0.9.0)
- activemodel (~> 3.0, < 3.2)
- activesupport (~> 3.0, < 3.2)
- adapter (~> 0.5.1)
- simple_uuid (~> 0.1.1)
-
-GEM
- remote: http://rubygems.org/
- specs:
- activemodel (3.1.4)
- activesupport (= 3.1.4)
- builder (~> 3.0.0)
- i18n (~> 0.6)
- activesupport (3.1.4)
- multi_json (~> 1.0)
- adapter (0.5.2)
- builder (3.0.0)
- diff-lcs (1.1.3)
- ffi (1.0.11)
- growl (1.0.3)
- guard (1.0.0)
- ffi (>= 0.5.0)
- thor (~> 0.14.6)
- guard-bundler (0.1.3)
- bundler (>= 1.0.0)
- guard (>= 0.2.2)
- guard-rspec (0.6.0)
- guard (>= 0.10.0)
- i18n (0.6.0)
- multi_json (1.3.2)
- oj (1.0.6)
- rack (1.4.0)
- rack-test (0.6.1)
- rack (>= 1.0)
- rake (0.9.2.2)
- rspec (2.8.0)
- rspec-core (~> 2.8.0)
- rspec-expectations (~> 2.8.0)
- rspec-mocks (~> 2.8.0)
- rspec-core (2.8.0)
- rspec-expectations (2.8.0)
- diff-lcs (~> 1.1.2)
- rspec-mocks (2.8.0)
- simple_uuid (0.1.2)
- thor (0.14.6)
- timecop (0.3.5)
- tzinfo (0.3.31)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- growl
- guard
- guard-bundler
- guard-rspec
- multi_json
- oj
- rack-test (~> 0.6.0)
- rake
- rspec (~> 2.8.0)
- timecop (~> 0.3.0)
- toystore!
- tzinfo (~> 0.3.0)
View
3  lib/toy.rb
@@ -79,6 +79,7 @@ module Middleware
autoload 'Querying', 'toy/querying'
autoload 'Reloadable', 'toy/reloadable'
autoload 'Serialization', 'toy/serialization'
+ autoload 'AssociationSerialization','toy/association_serialization'
autoload 'Timestamps', 'toy/timestamps'
autoload 'Validations', 'toy/validations'
@@ -101,4 +102,4 @@ module Identity
require 'toy/object'
require 'toy/store'
-Toy::IdentityMap.enabled = false
+Toy::IdentityMap.enabled = false
View
50 lib/toy/association_serialization.rb
@@ -0,0 +1,50 @@
+module Toy
+ module AssociationSerialization
+ extend ActiveSupport::Concern
+ include Serialization
+
+ def serializable_hash(options = nil)
+ options ||= {}
+ super.tap { |hash|
+ serializable_add_includes(options) do |association, records, opts|
+ hash[association] = records.is_a?(Enumerable) ?
+ records.map { |r| r.serializable_hash(opts) } :
+ records.serializable_hash(opts)
+ end
+ }
+ end
+
+ private
+
+ # Add associations specified via the <tt>:includes</tt> option.
+ # Expects a block that takes as arguments:
+ # +association+ - name of the association
+ # +records+ - the association record(s) to be serialized
+ # +opts+ - options for the association records
+ def serializable_add_includes(options = {})
+ return unless include_associations = options.delete(:include)
+
+ base_only_or_except = { :except => options[:except],
+ :only => options[:only] }
+
+ include_has_options = include_associations.is_a?(Hash)
+ associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
+
+ for association in associations
+ records = if self.class.list?(association)
+ send(association).to_a
+ elsif self.class.reference?(association) || self.class.parent_reference?(association)
+ send(association)
+ end
+
+ unless records.nil?
+ association_options = include_has_options ? include_associations[association] : base_only_or_except
+ opts = options.merge(association_options)
+ yield(association, records, opts)
+ end
+ end
+
+ options[:include] = include_associations
+ end
+ end
+end
View
1  lib/toy/object.rb
@@ -12,6 +12,7 @@ module Object
include Inspect
include Logger
include Inheritance
+ include Serialization
end
def persisted?
View
41 lib/toy/serialization.rb
@@ -37,46 +37,7 @@ def serializable_hash(options = nil)
end
end
- serializable_add_includes(options) do |association, records, opts|
- hash[association] = records.is_a?(Enumerable) ?
- records.map { |r| r.serializable_hash(opts) } :
- records.serializable_hash(opts)
- end
-
hash
end
-
- private
-
- # Add associations specified via the <tt>:includes</tt> option.
- # Expects a block that takes as arguments:
- # +association+ - name of the association
- # +records+ - the association record(s) to be serialized
- # +opts+ - options for the association records
- def serializable_add_includes(options = {})
- return unless include_associations = options.delete(:include)
-
- base_only_or_except = { :except => options[:except],
- :only => options[:only] }
-
- include_has_options = include_associations.is_a?(Hash)
- associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
-
- for association in associations
- records = if self.class.list?(association)
- send(association).to_a
- elsif self.class.reference?(association) || self.class.parent_reference?(association)
- send(association)
- end
-
- unless records.nil?
- association_options = include_has_options ? include_associations[association] : base_only_or_except
- opts = options.merge(association_options)
- yield(association, records, opts)
- end
- end
-
- options[:include] = include_associations
- end
end
-end
+end
View
4 lib/toy/store.rb
@@ -13,14 +13,14 @@ module Store
include Callbacks
include Validations
- include Serialization
include Timestamps
include Lists
include References
+ include AssociationSerialization
include IdentityMap
include Caching
end
end
-end
+end
View
4 lib/toy/timestamps.rb
@@ -1,6 +1,8 @@
module Toy
module Timestamps
extend ActiveSupport::Concern
+ include Attributes
+ include Callbacks
module ClassMethods
def timestamps
@@ -19,4 +21,4 @@ def timestamps
end
end
end
-end
+end
View
103 spec/toy/association_serialization_spec.rb
@@ -0,0 +1,103 @@
+require 'helper'
+
+describe Toy::AssociationSerialization do
+ uses_constants('User', 'Game', 'Move')
+
+ before do
+ User.attribute :name, String
+ User.attribute :age, Integer
+ end
+
+ describe "serializing relationships" do
+ before do
+ User.list :games, :inverse_of => :user
+ Game.reference :user
+ end
+
+ it "should include references" do
+ user = User.create(:name => 'John', :age => 28)
+ game = user.games.create
+
+ MultiJson.load(game.to_json(:include => [:user])).should == {
+ 'game' => {
+ 'id' => game.id,
+ 'user_id' => user.id,
+ 'user' => {
+ 'name' => 'John',
+ 'game_ids' => [game.id],
+ 'id' => user.id,
+ 'age' => 28,
+ }
+ }
+ }
+ end
+
+ it "should include lists" do
+ user = User.create(:name => 'John', :age => 28)
+ game = user.games.create
+ MultiJson.load(user.to_json(:include => [:games])).should == {
+ 'user' => {
+ 'name' => 'John',
+ 'game_ids' => [game.id],
+ 'id' => user.id,
+ 'age' => 28,
+ 'games' => [{'id' => game.id, 'user_id' => user.id}],
+ }
+ }
+ end
+
+ it "should not cause circular reference JSON errors for references" do
+ user = User.create(:name => 'John', :age => 28)
+ game = user.games.create
+
+ MultiJson.load(ActiveSupport::JSON.encode(game.user)).should == {
+ 'user' => {
+ 'name' => 'John',
+ 'game_ids' => [game.id],
+ 'id' => user.id,
+ 'age' => 28
+ }
+ }
+ end
+
+ it "should not cause circular reference JSON errors for references when called indirectly" do
+ user = User.create(:name => 'John', :age => 28)
+ game = user.games.create
+
+ MultiJson.load(ActiveSupport::JSON.encode([game.user])).should == [
+ 'user' => {
+ 'name' => 'John',
+ 'game_ids' => [game.id],
+ 'id' => user.id,
+ 'age' => 28
+ }
+ ]
+ end
+
+ it "should not cause circular reference JSON errors for lists" do
+ user = User.create(:name => 'John', :age => 28)
+ game = user.games.create
+
+ MultiJson.load(ActiveSupport::JSON.encode(user.games)).should == [{
+ 'game' => {
+ 'id' => game.id,
+ 'user_id' => user.id
+ }
+ }]
+ end
+
+ it "should not cause circular reference JSON errors for lists when called indirectly" do
+ user = User.create(:name => 'John', :age => 28)
+ game = user.games.create
+
+ MultiJson.load(ActiveSupport::JSON.encode({:games => user.games})).should == {
+ 'games' => [{
+ 'game' => {
+ 'id' => game.id,
+ 'user_id' => user.id
+ }
+ }]
+ }
+ end
+ end
+end
View
109 spec/toy/serialization_spec.rb
@@ -1,7 +1,7 @@
require 'helper'
describe Toy::Serialization do
- uses_constants('User', 'Game', 'Move')
+ uses_objects('User', 'Move')
before do
User.attribute :name, String
@@ -28,7 +28,6 @@
'age' => 28
}
}
-
end
it "correctly serializes methods" do
@@ -65,99 +64,6 @@ def foo
MultiJson.load(json)['user'].should_not have_key('id')
end
- describe "serializing relationships" do
- before do
- User.list :games, :inverse_of => :user
- Game.reference :user
- end
-
- it "should include references" do
- user = User.create(:name => 'John', :age => 28)
- game = user.games.create
-
- MultiJson.load(game.to_json(:include => [:user])).should == {
- 'game' => {
- 'id' => game.id,
- 'user_id' => user.id,
- 'user' => {
- 'name' => 'John',
- 'game_ids' => [game.id],
- 'id' => user.id,
- 'age' => 28,
- }
- }
- }
- end
-
- it "should include lists" do
- user = User.create(:name => 'John', :age => 28)
- game = user.games.create
- MultiJson.load(user.to_json(:include => [:games])).should == {
- 'user' => {
- 'name' => 'John',
- 'game_ids' => [game.id],
- 'id' => user.id,
- 'age' => 28,
- 'games' => [{'id' => game.id, 'user_id' => user.id}],
- }
- }
- end
-
- it "should not cause circular reference JSON errors for references" do
- user = User.create(:name => 'John', :age => 28)
- game = user.games.create
-
- MultiJson.load(ActiveSupport::JSON.encode(game.user)).should == {
- 'user' => {
- 'name' => 'John',
- 'game_ids' => [game.id],
- 'id' => user.id,
- 'age' => 28
- }
- }
- end
-
- it "should not cause circular reference JSON errors for references when called indirectly" do
- user = User.create(:name => 'John', :age => 28)
- game = user.games.create
-
- MultiJson.load(ActiveSupport::JSON.encode([game.user])).should == [
- 'user' => {
- 'name' => 'John',
- 'game_ids' => [game.id],
- 'id' => user.id,
- 'age' => 28
- }
- ]
- end
-
- it "should not cause circular reference JSON errors for lists" do
- user = User.create(:name => 'John', :age => 28)
- game = user.games.create
-
- MultiJson.load(ActiveSupport::JSON.encode(user.games)).should == [{
- 'game' => {
- 'id' => game.id,
- 'user_id' => user.id
- }
- }]
- end
-
- it "should not cause circular reference JSON errors for lists when called indirectly" do
- user = User.create(:name => 'John', :age => 28)
- game = user.games.create
-
- MultiJson.load(ActiveSupport::JSON.encode({:games => user.games})).should == {
- 'games' => [{
- 'game' => {
- 'id' => game.id,
- 'user_id' => user.id
- }
- }]
- }
- end
- end
-
describe "serializing specific attributes" do
before do
Move.attribute(:index, Integer)
@@ -228,16 +134,15 @@ def calculated_attribute
describe "#serializable_hash" do
context "with method that is another toystore object" do
before do
- Game.reference(:creator, User)
- @game = Game.create(:creator => User.create)
+ Move.class_eval { attr_accessor :creator }
end
- let(:game) { @game }
+
+ let(:move) { Move.new(:creator => User.new) }
it "returns serializable hash of object" do
- game.serializable_hash(:methods => [:creator]).should == {
- 'id' => game.id,
- 'creator_id' => game.creator_id,
- 'creator' => {'id' => game.creator.id}
+ move.serializable_hash(:methods => [:creator]).should == {
+ 'id' => move.id,
+ 'creator' => {'id' => move.creator.id}
}
end
end
Something went wrong with that request. Please try again.