Ember Data introduziu suporte para associações polimórficas há muito tempo . Ainda assim, é muito difícil de usar, mesmo com a gem ActiveSerializers.
Aqui está como deve funcionar, pois o usuário pode ter mensagens de Post / Comment.
App.User = DS.Model.extend({
messages: DS.hasMany(App.Message, {polymorphic: true})
});
App.Message = DS.Model.extend({
created_at: DS.attr('date'),
user: DS.belongsTo(App.User)
});
App.Post = App.Message.extend({
title: DS.attr('string')
});
App.Comment = App.Message.extend({
body: DS.attr('string'),
message: DS.belongsTo(App.Message, {polymorphic: true})
});
O único problema que tive foi declarar estas linhas:
DS.RESTAdapter.configure('App.Post' {
alias: 'post'
});
DS.RESTAdapter.configure('App.Comment' {
alias: 'comment'
});
Quando postagens e comentários são solicitados por outro modelo que tenha associação polimórfica, ocorre um conflito de nomenclatura e recebo a afirmação com falha “postagem já declarada”.
Por outro lado, realmente precisamos de algo como polimorfismo no lado do cliente?
Decidi tentar os dados da maneira tradicional, mesmo minha associação do lado do servidor foi declarada como polimórfica:
App.User = DS.Model.extend({
posts: DS.hasMany(App.Post),
comments: DS.hasMany(App.Comment)
});
A coisa mais difícil aqui é fazer com que os ActiveSerializers criem carregamento lateral para associação polimórfica em um modelo. Decidi inserir comentários / postagens manualmente se o modelo do proprietário os tiver.
Aqui está um snippet para usar na minha classe UserSerializer do ActiveModelSerialzers :
Digamos que temos em aula.belongs_to :message, polymorphic: true
User
# what kind is polymorph?
def message?(model)
object.message.class.name == model
end
# dynamically creating side loaded associations
['Post', 'Comment'].each do |model|
downcased = model.downcase
has_one downcased.to_sym, embed: :ids, include: true
define_method downcased do
object.message if message?(model)
end
define_method "include_#{downcased}?" do
message?(model)
end
define_method "#{downcased}_id" do
object.message_id
end
define_method "include_#{downcased}_id?" do
message?(model)
end
end
Se o associado do modelo for um comentário, acrescentamos o comentário ao json.
Se for uma postagem, acrescentamos uma postagem.
Pessoalmente, acho isso ainda mais fácil de usar no lado do cliente.
Espero que essa ideia possa ajudar alguém