Added has_one and has_many

This commit is contained in:
Jose and Yehuda
2011-10-15 16:20:45 +02:00
parent 598fc578fb
commit 2a4aaae72a
2 changed files with 125 additions and 16 deletions

View File

@@ -7,20 +7,41 @@ module ActiveModel
class_attribute :_attributes
self._attributes = Set.new
def self.attributes(*attrs)
self._attributes += attrs
class_attribute :_associations
self._associations = {}
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 inherited(klass)
name = klass.name.demodulize.underscore.sub(/_serializer$/, '')
klass.class_eval do
alias_method name.to_sym, :object
end
end
end
attr_reader :object, :scope
def self.inherited(klass)
name = klass.name.demodulize.underscore.sub(/_serializer$/, '')
klass.class_eval do
alias_method name.to_sym, :object
end
end
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

View File

@@ -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