Używam teraz dwóch różnych sposobów pracy z "polimorficznymi" modelami szyn. Zaktualizowałem poniższy kod, aby pokazać oba zastosowania.
Attachment
model: Jest to "polimorficzny" po stronie szyny, ale zawsze jest "osadzony" po stronie Embera. Powodem tego jest to, że obecnie muszę tylko zapisywać/aktualizować załączniki wraz z ich powiązanym modelem.
Comment
model: Jest polimorficzny zarówno po stronie Railsów, jak i po stronie Ember.
Dołączyłem również kod modelu Post
, ponieważ może on zawierać wiele załączników i wiele komentarzy. Kod
szyn: Kod
class Attachment < ActiveRecord::Base
belongs_to :user
belongs_to :attachable, polymorphic: true
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :commentable, polymorphic: true
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :attachments, as: :attachable
has_many :comments, as: :commentable
end
class ApplicationSerializer < ActiveModel::Serializer
embed :ids, include: true
end
class AttachmentSerializer < ApplicationSerializer
attributes :id, :url, :errors
has_many :comments
end
class CommentSerializer < ApplicationSerializer
attributes :id, :body, :created_at, :commentable_id, :commentable_type
has_one :user
end
class PostSerializer < ApplicationSerializer
attributes :id, :title, :body, :posted_at, :errors
has_one :user
has_many :attachments, embed: :objects, include: true
has_many :comments
end
class Api::V1::PostsController < Api::V1::BaseController
before_filter :auth_only!, only: :create
def create
# clean/capture ember-data supplied arguments
params[:post].delete(:user_id)
attachments_params = params[:post].delete(:attachments)
@post = current_user.posts.new(params[:post])
process_attachments(attachments_params)
if @post.save
render json: @post, status: 201
else
warden.custom_failure!
render json: @post, status: 422
end
end
protected
def process_attachments(attachments_params)
return unless attachments_params.present?
attachments_params.each do |attachment_params|
# ignore ember-data's additional keys
attachment_params.delete(:created_at)
attachment_params.delete(:user_id)
attachment = @post.attachments.new(attachment_params)
attachment.user = current_user
end
end
end
Ember:
DS.RESTAdapter.configure 'App.Post',
alias: 'Post'
DS.RESTAdapter.map 'App.Post',
attachments: { embedded: 'always' }
App.Store = DS.Store.extend
adapter: DS.RESTAdapter.create
namespace: 'api/v1'
App.Comment = App.Model.extend
user: DS.belongsTo('App.User')
commentable: DS.belongsTo('App.Commentable', { polymorphic: true })
body: DS.attr('string')
createdAt: DS.attr('date')
App.Commentable = App.Model.extend
comments: DS.hasMany('App.Comment')
App.Attachment = App.Commentable.extend
user: DS.belongsTo('App.User')
url: DS.attr('string')
App.Post = App.Commentable.extend
user: DS.belongsTo('App.User')
attachments: DS.hasMany('App.Attachment')
title: DS.attr('string')
body: DS.attr('string')
postedAt: DS.attr('date')
App.PostFormOverlayController = App.OverlayController.extend
# 'files' attribute is set by a widget that wraps the filepicker.io JS
updateAttachments: (->
attachments = @get('attachments')
attachments.clear()
@get('files').forEach (file) =>
attachment = App.Attachment.createRecord({fpFile: file})
attachments.addObject(attachment)
).observes('files')
App.CommentNewController = App.ObjectController.extend
# this should be instantiated with it's model set to the commentable
# item. eg. `{{render 'comment/new' content}}`
save: ->
transaction = @get('store').transaction()
comment = transaction.createRecord App.Comment,
body: @get('body')
commentable: @get('model')
comment.one 'didCreate', @, ->
@set('body', null)
transaction.commit()
Niestety mój kod Rails stała się mało zanieczyszczone ember transmisji danych specyficznych dziwactw, ponieważ próbuje odeślij wszystkie atrybuty zdefiniowane w modelach. (Uwaga: Jest open proposal na tylko do odczytu atrybutów, które rozwiązałoby problem zanieczyszczenia params)
Jeśli ktoś zna lepszy sposób podejść do żadnej z powyższych proszę dać mi znać!
UWAGA: Jestem trochę zaniepokojony tym, że o modele rozciągają się od App.Commentable
uniemożliwi mi o wielu polimorficznych załączników na modelu, może trzeba szukać innego sposobu obchodzenia tego.
Dziękujemy za opublikowanie rozwiązania. Próbuję użyć twojego kodu jako przewodnika do realizacji mojego. Chcę wyjaśnić, czy jest to dokładny sposób zdefiniowania modelu załącznika w danych embers. Pytam, ponieważ linki do polimorficznych przykładów danych z ember-danych w twoim pytaniu definiowały model przywiązania w następujący sposób: ** App.Attachment = DS.Model.extend ({attachable: DS.belongsTo ('AppAAckachable', {polimorficzny: true })}) **, a następnie ** App.Attachable = DS.Model.extend ({attachments: DS.hasMany ('App.Attachment')}) **. Także od czasu, gdy rails oczekuje z powrotem ** attachable_type ** jako pole, jak to robisz z bieżącym kodem. – brg
Teraz, tak. Myślę, że moje obecne użycie "załączników" jest bardzo ograniczone, działa, ale nie w pełni skonfigurowane. W weekend wykorzystam polimorfizm i zaktualizuję kod, aby się do niego dopasować.Zasadniczo omijam problem 'attachable_type', zawsze traktując załączniki jako osadzone po stronie klienta, pozwalając stronie serwera zarządzać tym, czego potrzebuje. –
Dziękuję Kevinowi za wyjaśnienie. Sprawdzę w ciągu weekendu zaktualizowany kod dla właściwego polimorfizmu. Miłego dnia. – brg