aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose and Yehuda <wycats@gmail.com>2011-10-15 16:20:45 +0200
committerJose and Yehuda <wycats@gmail.com>2011-10-15 18:40:37 +0200
commit2a4aaae72af037715db81fda332190df62f3ec44 (patch)
treea3d3d34eb59176c2b19385adc9dc2ea5bc709069
parent598fc578fbd38907288e14053bfc6eb8d4da1e3b (diff)
downloadrails-2a4aaae72af037715db81fda332190df62f3ec44.tar.gz
rails-2a4aaae72af037715db81fda332190df62f3ec44.tar.bz2
rails-2a4aaae72af037715db81fda332190df62f3ec44.zip
Added has_one and has_many
-rw-r--r--activemodel/lib/active_model/serializer.rb56
-rw-r--r--activemodel/test/cases/serializer_test.rb81
2 files changed, 123 insertions, 14 deletions
diff --git a/activemodel/lib/active_model/serializer.rb b/activemodel/lib/active_model/serializer.rb
index a2035ae2cb..dc5e2aadb3 100644
--- a/activemodel/lib/active_model/serializer.rb
+++ b/activemodel/lib/active_model/serializer.rb
@@ -7,20 +7,41 @@ module ActiveModel
class_attribute :_attributes
self._attributes = Set.new
- def self.attributes(*attrs)
- self._attributes += attrs
- end
+ class_attribute :_associations
+ self._associations = {}
- attr_reader :object, :scope
+ class << self
+ def attributes(*attrs)
+ self._attributes += attrs
+ end
+
+ def has_many(*attrs)
+ options = attrs.extract_options!
+ options[:has_many] = true
+ hash = {}
+ attrs.each { |attr| hash[attr] = options }
+ self._associations = _associations.merge(hash)
+ end
+
+ def has_one(*attrs)
+ options = attrs.extract_options!
+ options[:has_one] = true
+ hash = {}
+ attrs.each { |attr| hash[attr] = options }
+ self._associations = _associations.merge(hash)
+ end
- def self.inherited(klass)
- name = klass.name.demodulize.underscore.sub(/_serializer$/, '')
+ def inherited(klass)
+ name = klass.name.demodulize.underscore.sub(/_serializer$/, '')
- klass.class_eval do
- alias_method name.to_sym, :object
+ klass.class_eval do
+ alias_method name.to_sym, :object
+ end
end
end
+ attr_reader :object, :scope
+
def initialize(object, scope)
@object, @scope = object, scope
end
@@ -30,7 +51,24 @@ module ActiveModel
end
def serializable_hash
- attributes
+ hash = attributes
+
+ _associations.each do |association, options|
+ associated_object = object.send(association)
+ serializer = options[:serializer]
+
+ if options[:has_many]
+ serialized_array = associated_object.map do |item|
+ serializer.new(item, scope).serializable_hash
+ end
+
+ hash[association] = serialized_array
+ elsif options[:has_one]
+ hash[association] = serializer.new(associated_object, scope).serializable_hash
+ end
+ end
+
+ hash
end
def attributes
diff --git a/activemodel/test/cases/serializer_test.rb b/activemodel/test/cases/serializer_test.rb
index 1c1da588f7..24de81d48f 100644
--- a/activemodel/test/cases/serializer_test.rb
+++ b/activemodel/test/cases/serializer_test.rb
@@ -1,17 +1,33 @@
require "cases/helper"
class SerializerTest < ActiveModel::TestCase
- class User
+ class Model
+ def initialize(hash)
+ @attributes = hash
+ end
+
+ def read_attribute_for_serialization(name)
+ @attributes[name]
+ end
+ end
+
+ class User < Model
attr_accessor :superuser
+ def initialize(hash={})
+ super hash.merge(:first_name => "Jose", :last_name => "Valim", :password => "oh noes yugive my password")
+ end
+
def super_user?
@superuser
end
+ end
- def read_attribute_for_serialization(name)
- hash = { :first_name => "Jose", :last_name => "Valim", :password => "oh noes yugive my password" }
- hash[name]
- end
+ class Post < Model
+ attr_accessor :comments
+ end
+
+ class Comment < Model
end
class UserSerializer < ActiveModel::Serializer
@@ -36,6 +52,25 @@ class SerializerTest < ActiveModel::TestCase
end
end
+ class CommentSerializer
+ def initialize(comment, scope)
+ @comment, @scope = comment, scope
+ end
+
+ def serializable_hash
+ { title: @comment.read_attribute_for_serialization(:title) }
+ end
+
+ def as_json
+ { comment: serializable_hash }
+ end
+ end
+
+ class PostSerializer < ActiveModel::Serializer
+ attributes :title, :body
+ has_many :comments, :serializer => CommentSerializer
+ end
+
def test_attributes
user = User.new
user_serializer = UserSerializer.new(user, nil)
@@ -72,4 +107,40 @@ class SerializerTest < ActiveModel::TestCase
assert_equal({ :first_name => "Jose", :last_name => "Valim", :super_user => true }, hash)
end
+
+ def test_has_many
+ user = User.new
+
+ post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com")
+ comments = [Comment.new(:title => "Comment1"), Comment.new(:title => "Comment2")]
+ post.comments = comments
+
+ post_serializer = PostSerializer.new(post, user)
+
+ assert_equal({
+ :title => "New Post",
+ :body => "Body of new post",
+ :comments => [
+ { :title => "Comment1" },
+ { :title => "Comment2" }
+ ]
+ }, post_serializer.as_json)
+ end
+
+ class Blog < Model
+ attr_accessor :author
+ end
+
+ class AuthorSerializer < ActiveModel::Serializer
+ attributes :first_name, :last_name
+ end
+
+ class BlogSerializer < ActiveModel::Serializer
+ has_one :author, :serializer => AuthorSerializer
+ end
+
+ def test_has_one
+ user = User.new
+ blog = Blog.new(:author => user)
+ end
end