mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
Merge pull request #8 from Adman65/association_options
Closes #4 (Associations with :as)
This commit is contained in:
commit
3b38af1b49
@ -351,6 +351,32 @@ for the current user.
|
||||
|
||||
NOTE: The logic for deciding which comments a user should see still belongs in the model layer. In general, you should encapsulate concerns that require making direct Active Record queries in scopes or public methods on your models.
|
||||
|
||||
h4. Modifying Associations
|
||||
|
||||
You can also rename associations if required. Say for example you have an association that
|
||||
makes sense to be named one thing in your code, but another when data is serialized.
|
||||
You can use the <code>:as</code> option to specify a different name for an association.
|
||||
Here is an exmaple:
|
||||
|
||||
<pre lang="ruby">
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
has_many :followed_posts, :as => :posts
|
||||
has_one :owne_account, :as => :account
|
||||
end
|
||||
</pre>
|
||||
|
||||
Using the <code>:as</code> without a <code>:serializer</code> option will use implicit detection
|
||||
to determine a serializer. In this example, you'd have to define two classes: <code>PostSerializer</code>
|
||||
and <code>AccountSerializer</code>. You can also add the <code>:serializer</code> option
|
||||
to set it explicitly:
|
||||
|
||||
<pre lang="ruby">
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
has_many :followed_posts, :as => :posts, :serializer => CustomPostSerializer
|
||||
has_one :owne_account, :as => :account, :serializer => PrivateAccountSerializer
|
||||
end
|
||||
</pre>
|
||||
|
||||
h3. Customizing Associations
|
||||
|
||||
Not all front-ends expect embedded documents in the same form. In these cases, you can override the
|
||||
@ -431,6 +457,7 @@ The +association_ids+ helper will use the overridden version of the association,
|
||||
this case, +association_ids+ will only include the ids of the comments provided by the
|
||||
+comments+ method.
|
||||
|
||||
|
||||
h3. Special Association Serializers
|
||||
|
||||
So far, associations defined in serializers use either the +as_json+ method on the model
|
||||
|
||||
@ -68,6 +68,10 @@ module ActiveModel
|
||||
def serializer
|
||||
options[:serializer]
|
||||
end
|
||||
|
||||
def key
|
||||
options[:as] || name
|
||||
end
|
||||
end
|
||||
|
||||
class HasMany < Config #:nodoc:
|
||||
@ -122,7 +126,14 @@ module ActiveModel
|
||||
class_eval "def #{attr}() object.#{attr} end", __FILE__, __LINE__
|
||||
end
|
||||
|
||||
options[:serializer] ||= const_get("#{attr.to_s.camelize}Serializer")
|
||||
# if :as is specified without :serializer, then use conventions
|
||||
# to determine the serializer
|
||||
if options[:as] && !options[:serializer]
|
||||
options[:serializer] = const_get("#{options[:as].to_s.camelize.singularize}Serializer")
|
||||
else
|
||||
options[:serializer] ||= const_get("#{attr.to_s.camelize}Serializer")
|
||||
end
|
||||
|
||||
klass.new(attr, options)
|
||||
end
|
||||
end
|
||||
@ -212,7 +223,7 @@ module ActiveModel
|
||||
|
||||
_associations.each do |association|
|
||||
associated_object = send(association.name)
|
||||
hash[association.name] = association.serialize(associated_object, scope)
|
||||
hash[association.key] = association.serialize(associated_object, scope)
|
||||
end
|
||||
|
||||
hash
|
||||
@ -225,7 +236,7 @@ module ActiveModel
|
||||
|
||||
_associations.each do |association|
|
||||
associated_object = send(association.name)
|
||||
hash[association.name] = association.serialize_ids(associated_object, scope)
|
||||
hash[association.key] = association.serialize_ids(associated_object, scope)
|
||||
end
|
||||
|
||||
hash
|
||||
@ -250,4 +261,4 @@ class Array
|
||||
def active_model_serializer
|
||||
ActiveModel::ArraySerializer
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -34,6 +34,11 @@ class SerializerTest < ActiveModel::TestCase
|
||||
end
|
||||
|
||||
class Post < Model
|
||||
def initialize(attributes)
|
||||
super(attributes)
|
||||
self.comments ||= []
|
||||
end
|
||||
|
||||
attr_accessor :comments
|
||||
def active_model_serializer; PostSerializer; end
|
||||
end
|
||||
@ -429,4 +434,78 @@ class SerializerTest < ActiveModel::TestCase
|
||||
{ :comment => { :title => "Comment1" } }
|
||||
], serializer.as_json)
|
||||
end
|
||||
end
|
||||
|
||||
class CustomBlog < Blog
|
||||
attr_accessor :public_posts, :public_user
|
||||
end
|
||||
|
||||
class CustomBlogSerializer < ActiveModel::Serializer
|
||||
has_many :public_posts, :as => :posts, :serializer => PostSerializer
|
||||
has_one :public_user, :as => :user, :serializer => UserSerializer
|
||||
end
|
||||
|
||||
def test_associations_with_as
|
||||
posts = [
|
||||
Post.new(:title => 'First Post', :body => 'text'),
|
||||
Post.new(:title => 'Second Post', :body => 'text')
|
||||
]
|
||||
user = User.new
|
||||
|
||||
custom_blog = CustomBlog.new
|
||||
custom_blog.public_posts = posts
|
||||
custom_blog.public_user = user
|
||||
|
||||
serializer = CustomBlogSerializer.new(custom_blog, :scope => true)
|
||||
|
||||
assert_equal({
|
||||
:custom_blog => {
|
||||
:posts => [
|
||||
{:title => 'First Post', :body => 'text', :comments => []},
|
||||
{:title => 'Second Post', :body => 'text', :comments => []}
|
||||
],
|
||||
:user => {
|
||||
:first_name => "Jose",
|
||||
:last_name => "Valim", :ok => true,
|
||||
:scope => true
|
||||
}
|
||||
}
|
||||
}, serializer.as_json)
|
||||
end
|
||||
|
||||
def test_implicity_detection_for_association_serializers
|
||||
implicit_serializer = Class.new(ActiveModel::Serializer) do
|
||||
root :custom_blog
|
||||
const_set(:UserSerializer, UserSerializer)
|
||||
const_set(:PostSerializer, PostSerializer)
|
||||
|
||||
has_many :public_posts, :as => :posts
|
||||
has_one :public_user, :as => :user
|
||||
end
|
||||
|
||||
posts = [
|
||||
Post.new(:title => 'First Post', :body => 'text', :comments => []),
|
||||
Post.new(:title => 'Second Post', :body => 'text', :comments => [])
|
||||
]
|
||||
user = User.new
|
||||
|
||||
custom_blog = CustomBlog.new
|
||||
custom_blog.public_posts = posts
|
||||
custom_blog.public_user = user
|
||||
|
||||
serializer = implicit_serializer.new(custom_blog, :scope => true)
|
||||
|
||||
assert_equal({
|
||||
:custom_blog => {
|
||||
:posts => [
|
||||
{:title => 'First Post', :body => 'text', :comments => []},
|
||||
{:title => 'Second Post', :body => 'text', :comments => []}
|
||||
],
|
||||
:user => {
|
||||
:first_name => "Jose",
|
||||
:last_name => "Valim", :ok => true,
|
||||
:scope => true
|
||||
}
|
||||
}
|
||||
}, serializer.as_json)
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user