davidgtonge / backbone_query

A lightweight query api for Backbone Collections
MIT License
378 stars 29 forks source link

Nested Models not supported ? #1

Closed suvash closed 12 years ago

suvash commented 12 years ago

I have been using nested models quite a lot (using backbone-relational) to replicate the server side models in Backbone. This seems to be a really interesting project.

It would be even awesome if there would be support for nested models. Atm, it seems like i can perform queries only on categories(of Models in the collection), but what if my models had other nested models (

Lets say Comment Model -> belongs to -> Blog Model -> belongs to -> User Model. Given the Comment Collection, I'd like query and list all the comments that belongs to a User.

Any plans for such support ?

davidgtonge commented 12 years ago

It would be difficult to implement this in a generic way, however it could be achieved quite simply by using the $cb operator and a custom function for the comment model. Here is an example in coffeescript:

Comment = Backbone.RelationalModel.extend
  relations:[] #Standard Backbone Relational settings
  getUserID: -> @get("post")?.get("user")?.id

Comments = Backbone.QueryCollection.extend
  model:Comment
  getByUser: (user_id) ->
    @query
      user:
        $cb: -> @getUserID() is user_id

If you have any ideas on a neater way to implement this, please let me know.

suvash commented 12 years ago

Agree with the fact that it would be hard to implement it in a generic way. And this was the approach I was going for.

atm, cannot think of any other way to implement this other than lets say, perhaps adding a separate query method (or a standard argument passed to the query method) for nested objects that could create and use the getUserID behind the scenes. but then I'm just thinking right now.

Either ways, thanks for the help ! Very appreciated.

suvash commented 12 years ago

Once again, what would you recommend if I wanted to check for more conditions ?

In the above case, what if I wanted to list all the comments that belongs to more than one user. That was in fact, the first reason I got started with the library. lets say something like following in your example, but with the callback.

 MyCollection.query({ title: {$in:["About", "Home", "Contact"] } });
 // Returns all models which have a title attribute of either "About", "Home", or "Contact"`
suvash commented 12 years ago

ok, I figured out a solution. do let me know if you see anything funny in this code.

Comments = Backbone.QueryCollection.extend
  model:Comment
  getByUser: (user_id) ->
    @query
      user:
        $cb: -> @getUserID() is user_id
  getByUsers: (users_id) -> # users_id is an array of id of users
    comments = new Comments
    comments.add @getByUser(user_id) for user_id in users_id
    comments
davidgtonge commented 12 years ago

Hi, if I understand what you need to do, I'd do it simply as follows

Comments = Backbone.QueryCollection.extend
  model:Comment
  getByUser: (user_id) ->
    @query
      user:
        $cb: -> @getUserID() is user_id
  getByUsers: (user_ids) ->
    @query
      user:
        $cb: -> @getUserID() in user_ids

But if you aren't checking for multiple conditions or using the paging / caching features of Backbone.Query, then you are probably better off just using a filter like this:

Comments = Backbone.QueryCollection.extend
  model:Comment
  getByUser: (user_id) ->
    @filter  (model) -> model.getUserID() is user_id
  getByUsers: (user_ids) ->
    @filter (model) -> model.getUserID() in user_ids

Note that both of these methods are using CoffeScripts helpful 'in' operator (http://coffeescript.org/#operators)