Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helper to get single result from a M2M relation #30

Closed
vjpr opened this issue Jun 20, 2013 · 9 comments
Closed

Helper to get single result from a M2M relation #30

vjpr opened this issue Jun 20, 2013 · 9 comments

Comments

@vjpr
Copy link

vjpr commented Jun 20, 2013

A common query would be to get a single result from a M2M.

It becomes something like:

@belongsToMany(db.Models.Collection).query().where(id: id).limit(1).select().then (models) ->
  models[0] if models.length

In Sequelize I could write `User.getCollection(where: {id: id}).done ...) which would return a single result.

Having a single method which returns on object or null rather than an array. Maybe more for the Knex lib?

@belongsToMany(db.Models.Collection).query().where(id: id).single()

You could go even shorter too.

Also, a get raw json as the result when what I would like is a Collection of Models.

On a side note, I'm finding a lot of common queries are quite verbose in Bookshelf. I think finder method would help with this.

At present I've got a BaseModel class with lots of finder methods. I love the extensibility and clean Backbone-style codebase + documentation compared with Sequelize, but simple common operations are still a little verbose. I'm very conscious though of the desire to keep the lib quite small without the kitchen-sink, like Backbone.

@tgriesser
Copy link
Member

So this is probably what you want:

class MyModel extends Bookshelf.Model
  items: (id) ->
    @belongsToMany(Item)

new MyModel(id: 1).items().query('where', 'id', id).fetch().then (c) ->
  c.at(0)

The reason I didn't want to put finder methods in is because there's a million permutations of them, and once you start adding direct support for them the API can quickly become a bit of a mess.

By using query the way described above you can add them wherever you need... and by not doing query() but instead query('method', args*) you stay on the context of the current model/collection you're accessing rather than dropping down into the Knex builder.

Though I agree some way to fetch/return a single model from a collection could a good addition in this case (hadn't considered relations), I'll take a look into supporting it...

And yeah, a BaseModel is exactly what I'm thinking would be a good way to go... so you can build out the API you'd find most intuitive... it's a little more verbose the first time but it makes the library easier to wrap your head around.

Also, a get raw json as the result when what I would like is a Collection of Models.

Sorry... I'm not sure I follow... you do or do not want that?

@vjpr
Copy link
Author

vjpr commented Jun 20, 2013

Sorry... I'm not sure I follow... you do or do not want that?

query().where() produces the json from the db. When I wanted a Model or a Collection of Models.

But you have covered this above:

you stay on the context of the current model/collection you're accessing rather than dropping down into the Knex builder.

@tgriesser
Copy link
Member

Yeah, query('where', ... will do it.

@vjpr
Copy link
Author

vjpr commented Jun 20, 2013

And yeah, a BaseModel is exactly what I'm thinking would be a good way to go... so you can build out the API you'd find most intuitive... it's a little more verbose the first time but it makes the library easier to wrap your head around.

I agree. The thing that drew me to Bookshelf was the fact that it was layered really nicely. In Sequelize and most ORMs if you find something you can't do you have to drop straight down to SQL, and extensibility is difficult.

@vjpr
Copy link
Author

vjpr commented Jun 20, 2013

Yeah, query('where', ... will do it.

Would be nice if you could pass in a hash.

@tgriesser
Copy link
Member

Would be nice if you could pass in a hash.

Interesting, so like query({where: {id: 1}, orWhere: {id: 2})

@vjpr
Copy link
Author

vjpr commented Jun 20, 2013

Yep. That would be great.

Also, if a query is called on a collection I think it should always return the models as a collection of models.

If the user wants to run a raw query they should use Bookshelf.Knex.

@tgriesser
Copy link
Member

Yeah... that's the idea, unless you call query() with no arguments which returns the underlying Knex builder, which I think I'll keep in there.

Take a look at the last commit for the object support.

tgriesser added a commit that referenced this issue Jun 25, 2013
* master:
  0.2.0
  some docs cleanups
  minor docs tweaks
  Pivot column typo, fixes #31
  Fix for #33, empty EagerRelation attachment, with tests.
  #30, allowing objects to be passed to query builder
  docs tweaks, blank target for some external links
  returning null for empty model fetch - #21
  better docs for attach, fixes #28
  fixing issue with exec plugin
@tgriesser
Copy link
Member

So I think that I'm going to revisit the idea of fetching a single object from a collection at some point down the road... for now I'm going to have the object support for the query chain be the solution for this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants