Giter Site home page Giter Site logo

Comments (8)

vjpr avatar vjpr commented on April 28, 2024

At the moment I'm using this hack:

  initialize: =>
    @on 'fetched', @onFetched

  onFetched: (model, resp, options) =>
    unless _.isEmpty resp
      @fetched = true

  isNew: =>
    not @fetched

I'm sure I will encounter lots of issues.

from bookshelf.

studds avatar studds commented on April 28, 2024

I took a slightly different approach. Because the id is created client side, it will never be null. So I overrode the default isNew to check 'serverCreatedAt' instead and added timestamps to all my tables.

Originally I thought about hacking in some sort of 'upsert', but that seemed messy and inefficient (with postgres... other databases this might be a good option). Checking the serverCreatedAt column is a better match to the original design, but is still exposed to race conditions, though, so I'll need to add in some sort of intelligent retry - perhaps it's enough to revert to 'update' if 'insert' fails?

    // A model is new if it has never been saved to the server, and lacks an 'serverCreatedAt' date
    Bookshelf.Model.prototype.hasTimestamps = ['serverCreatedAt', 'serverUpdatedAt'];
    Bookshelf.Model.prototype.isNew = function () {
        console.log('serverCreatedAt', this.get('serverCreatedAt'));
        return !this.get('serverCreatedAt');
    };

from bookshelf.

tgriesser avatar tgriesser commented on April 28, 2024

Yeah, @studds that sounds like a good solution - for now, I think this feature is best implemented as a custom method that handles the fetch to check for existence and then handles the save. But this might be something I take a look at once more of the core functionality is squared away.

from bookshelf.

jukkatupamaki avatar jukkatupamaki commented on April 28, 2024

I'm using generated UUIDs and because of existing conventions in Backbone and Bookshelf, the column name for the UUID is 'id'. I noticed that when setting the 'id' field manually in a model's initialize() method, the underlying updated only the 'updated_at' field.

I fixed this using the following override for isNew() and provided a boolean flagging whether the model is still new:

idSetButNew: false,

initialize: function(params) {
    if(this.isNew()) {
        this.set('id', uuid.v4());
        this.idSetButNew = true;
    }
    // more initialization stuff
},

isNew: function() {
    return !this.get('id') || this.idSetButNew;
}

I think it could be useful if Bookshelf provided some practices for using custom ID generators to avoid this kind of overrides.

from bookshelf.

johanneslumpe avatar johanneslumpe commented on April 28, 2024

I quickly want to chime in on this. I'm also using UUIDs, but it seems that it is not necessary to overwrite the isNew() function to achieve the desired behavior. By hooking into the saving event on the model we can generate an id after the insert/update method has been determined, like so:

initialize: function(params) {
    this.on('saving', this._generateId);
},

_generateId: function (model, attrs, options) {
    if (model.isNew()) {
      model.set(model.idAttribute, uuid.v4());
    }
}

This way there is no override involved and to me this does not feel messy or hackish. @tgriesser would you agree?

from bookshelf.

jukkatupamaki avatar jukkatupamaki commented on April 28, 2024

@johanneslumpe: I think that's a good workaround. Way better than what I had.

from bookshelf.

tgriesser avatar tgriesser commented on April 28, 2024

Yeah @johanneslumpe - that looks like a good approach!

from bookshelf.

sidazhang avatar sidazhang commented on April 28, 2024

@johanneslumpe the issue with your approach seems to be that the point of client-side generated id is so that you know the id before the insert event. Now, we won't know it. Which renders it the same as a server SERIAL.

from bookshelf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.