ember.js – ember-data中的Rails风格多态模型

前端之家收集整理的这篇文章主要介绍了ember.js – ember-data中的Rails风格多态模型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我在Rails中有以下模型,我将如何在Ember / Ember数据中表示这个?
class Attachment < ActiveRecord::Base
  belongs_to :user
  belongs_to :attachable,polymorphic: true
end

class Profile < ActiveRecord::Base
  belongs_to :user
  has_one :photo,class_name: 'Attachment',as: :attachable
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :attachments,as: :attachable
end

我发现的参考文献是the relevant ember-data pull request,the ember-data tests for polymorphic relationshipsthis related question,但很难从它们中找出一个典型的例子.

解决方法

我现在使用两种不同的方式使用rails风格的“多态”模型.我已更新下面的代码显示两种用途.

附件模型:这是Rails端的“多态”,但总是“嵌入”在Ember端.原因是我目前只需要保存/更新附件及其相关模型.

评论模型:这在Rails方面和Ember方面都是多态的.

我还为Post模型添加代码,因为它可以有多个附件和多个注释.

Rails代码

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,: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

灰烬代码

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()

不幸的是,我的Rails代码变得有点污染了特定于ember数据的怪异,因为它试图发送回模型上定义的所有属性. (注意:有一个open proposal的只读属性可以解决params污染问题)

如果有人知道更好的方法来接近上述任何一种,请告诉我!

注意:我有点担心从App.Commentable扩展模型会阻止我在模型上有多个多态附件,我可能需要寻找一种不同的处理方式.

猜你在找的JavaScript相关文章