Tôi hiện đang sử dụng hai cách khác nhau để làm việc với các kiểu đa hình "đường ray". Tôi đã cập nhật mã bên dưới để hiển thị cả hai cách sử dụng.
Attachment
mô hình: Đây là "đa hình" ở bên Rails nhưng luôn được "nhúng" ở phía Ember. Lý do cho điều này là tôi hiện chỉ cần lưu/cập nhật các tệp đính kèm cùng với mô hình được liên kết của chúng.
Comment
mô hình: Đây là đa hình ở cả bên Rails và bên Ember.
Tôi cũng đã bao gồm mã cho mô hình Post
vì nó có thể có nhiều tệp đính kèm và nhiều nhận xét. đang
Rails: đang
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()
Thật không may đang Rails của tôi đã trở thành một ít bị ô nhiễm với ember dữ liệu oddities cụ thể như nó cố gắng gửi lại tất cả các thuộc tính được xác định trên các mô hình. (Lưu ý : Có một open proposal cho read-only thuộc tính đó sẽ giải quyết vấn đề ô nhiễm params)
Nếu có ai biết một cách tốt hơn để tiếp cận bất kỳ ở trên xin vui lòng cho tôi biết!
NB: Tôi lo ngại rằng việc có mô hình mở rộng từ App.Commentable
sẽ ngăn không cho tôi có nhiều tệp đính kèm đa hình trên mô hình, tôi có thể cần tìm cách xử lý khác.
Cảm ơn bạn đã đăng giải pháp của mình. Tôi đang cố gắng sử dụng mã của bạn làm hướng dẫn để triển khai mỏ của tôi. Tôi muốn làm rõ nếu đó là cách chính xác bạn đã xác định mô hình đính kèm trong dữ liệu ember. Tôi hỏi vì các liên kết đến các ví dụ đa hình dữ liệu ember trong câu hỏi của bạn đã xác định mô hình đính kèm như sau: ** App.Attachment = DS.Model.extend ({attachable: DS.belongsTo ('App.Attachable', {polymorphic: true })}) ** và sau đó ** App.Attachable = DS.Model.extend ({tệp đính kèm: DS.hasMany ('App.Attachment')}) **. Ngoài ra kể từ khi đường ray mong đợi trở lại ** attachable_type ** như là một lĩnh vực như thế nào để bạn nhận được rằng với mã hiện tại. – brg
Ngay bây giờ, có. Tôi nghĩ bởi vì việc sử dụng hiện tại của tôi "tập tin đính kèm" là rất hạn chế nó làm việc nhưng không hoàn toàn thiết lập. Tôi sẽ sử dụng đúng tính đa hình vào cuối tuần và sẽ cập nhật mã ở đây để khớp.Tôi về cơ bản là sidestepping vấn đề 'attachable_type' bằng cách luôn xử lý các tệp đính kèm như được nhúng ở phía máy khách, cho phép phía máy chủ quản lý những gì nó cần. –
Cảm ơn Kevin đã làm rõ. Tôi sẽ kiểm tra lại vào cuối tuần để biết mã cập nhật cho tính đa hình phù hợp. Có một ngày tuyệt vời. – brg