mirror of
https://github.com/github/rails.git
synced 2026-01-10 07:07:54 -05:00
Added has_one and has_many
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user