蝙蝠侠多态属于联想

时间:2014-01-25 22:22:19

标签: polymorphic-associations batman.js

我正在尝试为具有多种不同类型子级的父级设置多态关联。我在文档中找到的是关于反问题的:有不同类型父母的孩子。

我尝试了下面的代码,但这总是产生“Store”类型的产品,而我希望它们是“Book”或“DVD”。

class App.Product extends Batman.Model
  @belongsTo 'productable', {polymorphic: true}

class App.Book extends Product
class App.DVD extends Product

class App.Store extends Batman.Model
  @hasMany 'products', {as: 'productable'}

感谢。

1 个答案:

答案 0 :(得分:0)

是的,你是对的。通常,多态性适用于以下情况:

class App.Product extends Batman.Model
  @belongsTo 'productable', polymorphic: true

class App.Store extends Batman.Model
  @hasMany 'products', as: 'productable', polymorphic: true

class App.VendingMachine extends Batman.Model
  @hasMany 'products', as: 'productable', polymorphic: true

现在,Product会同时存储productable_idproductable_typeproductable_type将是StoreVendingMachine

但是......你想从一个访问者那里获得不同类型的孩子吗?我不知道batman.js支持这种开箱即用,但这里有一种方法可以让你完成它:

class App.Store extends Batman.Model
  @hasMany 'products' # setup the relationships individually
  @hasMany 'books'
  @hasMany 'dvds'

  @accessor 'allProducts', -> # then create a custom accessor for all of them
    products = @get('products')
    books = @get('books')
    dvds = @get('dvds')
    products.merge(books, dvds) # returns a new Batman.Set

实际上,the docs say不要在访问者中使用Set::merge,而是使用Batman.SetUnion。如果这种方法看似可行,那么您可能需要研究一下!

然后,如果您需要以JSON格式发送类名,则可以在子模型上使用@encode,例如:

class App.Product extends Batman.Model
  @resourceName: 'product'
  @encode 'product_type', 
    encode: (value, key, builtJSON, record) ->   
      builtJSON.product_type = Batman.helpers.camelize(record.constructor.resourceName)

希望有所帮助!

修改

你可以简写关系和访问者,如果你认为你会有很多这些关系和访问者:

class App.Store extends Batman.Model
  @productTypes: [
    'products'
    'books'
    'dvds'
   ]
  for productType in @productTypes
      @hasMany productType

  @accessor 'allProducts', ->
    allProducts = new Batman.Set
    productSets = (@get(pt) for pt in @constructor.productTypes)
    allProducts.merge(productSets...)

反正可能值得一试!