pathable / supermodel

Supermodel - Minimal Model Tracking for Backbonejs
http://pathable.github.io/supermodel
MIT License
229 stars 36 forks source link

Bug? #30

Closed krokhale closed 11 years ago

krokhale commented 11 years ago

I am facing a peculiar issue. For instance if i define a require.js module models.js.coffee, that returns App and Apps.

//models.js.coffee define ['supermodel', 'backbone-query'], (Supermodel, query) -> class App extends Supermodel.Model urlRoot: 'apps'

class Apps extends Backbone.QueryCollection model: (attrs, options) -> App.create(attrs, options) url: 'apps' Models = App: App Apps: Apps

Now somewhere else in the app, i load another require.js module that has another set of models. //custom_app_models.js define ['supermodel', 'backbone-query', 'models'], (Supermodel, query, Models) ->

class Form extends Supermodel.Model urlRoot: 'forms'

class Forms extends Backbone.QueryCollection model: (attrs, options) -> Form.create(attrs, options) url: 'forms'

Models.App.has().many "forms", collection: Forms inverse: "app"

What is expected is that,

app_instance = @app.forms() should return the expected forms collection, but that is not the case, since i defined the has_many in a different module, i guess the association wasn't reinitialized. Now if i do a @app.fetch(), i get back the @app object, and it has a _forms function now, not the usual, @app.forms(), so actually i end up doing @app._forms() to get the relevant forms after fetch.

I think it would be great to have associations reinitialize whenever a new association is defined on a model, i haven't really had a chance to look at the code yet, is it possible or am i missing something?

braddunbar commented 11 years ago

Hi @krokhale! I've experienced similar issues in the past, but defining a relationship in a separate module should be fine as long as you have references to both model classes. Would you mind putting some illustrative code in a fiddle/bin so I can take a look?

krokhale commented 11 years ago
define ['supermodel', 'backbone-query'], (Supermodel, query) ->
  class App extends Supermodel.Model
    urlRoot: 'apps'

  class Apps extends Backbone.QueryCollection
    model: (attrs, options) ->
      App.create(attrs, options)
    url: 'apps'
  Models = 
    App: App
    Apps: Apps

define ['supermodel', 'backbone-query', 'models'], (Supermodel, query, Models) ->

  class Form extends Supermodel.Model
    urlRoot: 'forms'

  class Forms extends Backbone.QueryCollection
    model: (attrs, options) ->
     Form.create(attrs, options)
    url: 'forms'

  Models.App.has().many "forms",
   collection: Forms
   inverse: "app"

@app.fetch() // Fetching app model, I dont really want to do a fetch, the forms collections is already present
as an attribute, but the relationship isn't initialized. This is the first issue.    
forms = @app._forms()  // The second issue, is after fetch, i have to do a _forms(), not the usual forms().

Sorry about the earlier post, yeah i guess it was messy! Thanks!

krokhale commented 11 years ago

@braddunbar , just to add to this, i get over the first issue and save myself a fetch by doing @app.initialize() Which gets me the _forms() function without a fetch, i guess its a decent work around for the moment, but the second issue persists.

braddunbar commented 11 years ago

I tried to recreate this here, but it seems to work correctly for me there. Can you tell me what you're doing that I'm not?

krokhale commented 11 years ago

Just added comments to the bin, i believe the way its invoked there, it should run correctly and as expected, the problem occurs when i am defining the App model in a module and a relationship on its reference in another module. Hope my comments make that clear.

Thats when results are not as expected. I guess an easy way to replicate would be in an app that uses require.js.

http://jsbin.com/ezimak/2/edit

braddunbar commented 11 years ago

Defining App in a different module than Forms (and the associated relationships) shouldn't cause any problems. I use requirejs with the same strategy and it seems to work out quite well.

However, if you're creating the App instance (i.e. app = App.create(...)) before defining the relationship, that will cause problems. Make sure that all setup code is run prior to instantiating instances.

Hope that helps. :)