Model.notFound is a little strange

17 views
Skip to first unread message

Jarrod Carlson

unread,
Apr 13, 2014, 8:52:36 PM4/13/14
to spi...@googlegroups.com
I find the new Model.notFound fallback strategy to be a little awkward; let me explain why.

Suppose I have a Foo model, and I decide to override the .notFound method in order to kickoff some Ajax call to try and fetch records from the server when they don't exist locally. Should I be returning a new Foo instance from my custom .notFound implementation? Isn't it a little awkward that the .notFound method would synchronously return an empty Foo instance that may or may not be "filled in" by an Ajax call at some point in the future? How was this feature intended to be used with Models that are backed by Ajax persistence?

Suppose I don't return anything from my custom .notFound method (except maybe null). I still kickoff the ajax, but I keep the "return null" contract. At that point, why have .find() return the value returned by .notFound()?

Worse still, my .notFound implementation could return something completely different, like a Promise resulting from the ajax request I kicked off. Now every time I call Foo.find() I have to inspect the type of the return value to see if it's a Foo or a Promise. 

Wouldn't it be safer to enforce consistency by making Model.find() look something like this?

@find: (id, notFound) ->
    record = @irecords[id]?.clone()
    notFound?(id) unless record
    return record || null

In general, I think Spine could benefit greatly from embracing asynchronous behavior more readily, especially when it comes to saving or retrieving model instances to a storage mechanism. I often find it problematic to write code that works against both the synchronous LocalStorage implementation and the asynchronous Ajax implementation without my code needing knowledge of how the data is persisted.

Somewhat related, I've been maintaining a set of "monkey patches" to Spine in my current project to add functionality that I need but Spine does not have. I think I'm going to start putting together some pull requests to get those "patches" moved upstream into Spine properly. This idea here might be my first.

Aaron Eischeid

unread,
Apr 14, 2014, 5:11:55 PM4/14/14
to spi...@googlegroups.com
In general I think these are good thoughts on the notFound strategy. It's pretty much up to you to enforce a convention for customizing it, and I can see how it could be troublesome. The usage I had in mind was promise objects, but then I haven't gotten around to using it much myself yet in that way.

I think what you mentioned about Spine embracing asynchronous behavior more readily is spot on. I have been thinking pretty hard about how to go about that, but haven't arrived at any conclusions yet or even got any relevant code pushed yet. That is to say I am very open to ideas on how to solve this, but very much agree that it needs to be solved. I lean towards doing it in a way that all APIs that have to do with persistent records at any layer other than in memory are promises.

I look forward to some good discussion on your pull requests! 

Jarrod Carlson

unread,
Apr 14, 2014, 7:09:18 PM4/14/14
to spi...@googlegroups.com
Great to hear! For a while now I've been monkey-patching in various support for more asynchronous support. Time to start bundling it up into pull requests that I can send upstream! I'm actually just wrapping up a change that will make the Model.fetch() method return a promise and is supported by both the Local storage and the Ajax mechanism. I'll submit that shortly.

I'll also file a change to make the Model.notFound mechanism more consistent, as mentioned in this thread.
Reply all
Reply to author
Forward
0 new messages