title: How do I properly update models with Bookshelf.js?
body: <p>I'm sure I am missing something but I find the Bookshelf API to be relentlessly confusing for me. Here's what I am trying to do:</p>
  
  <ul>
  <li>I have a model called <code>Radio</code> with an application-assigned string primary key named <code>serial</code> and, for the purpose of this example, two fields named <code>example1</code> and <code>example2</code>. I have specified the custom ID with <code>idAttribute: 'serial'</code> in the model definition.</li>
  <li>I'm trying to perform an upsert with Bookshelf (not with Knex directly, in my actual application that query becomes rather complex).</li>
  <li>I've got the <em>insert</em> case working but can't seem to get the <em>update</em> case working.</li>
  <li>For simplicity I'm not caring about transactions or atomicity right now. I am satisfied to get a simple <em>select &rarr; insert/update</em> to work.</li>
  </ul>
  
  <p>And specifically in this example:</p>
  
  <ul>
  <li>On insert set <code>example1</code> and <code>example2</code>.</li>
  <li>On update set <code>example1</code> and leave <code>example2</code> unchanged.</li>
  </ul>
  
  <p>So I've got something like this in the Bookshelf model, as a class (i.e. "static") method ("info" has fields "serial", "example1", and "example2"):</p>
  
  <pre><code>insertOrUpdate: function (info) {
      return new Radio({'serial':info.serial}).fetch().then(function (model) {
          if (model) {
              model.set('example1', info.example1);
              return model.save({}, {
                  method: 'update',
                  patch: true
              })
          } else {
              return new Radio({
                  serial: info.serial,
                  example1: info.example1,
                  example2: info.example2
              }).save({}, {
                  method: 'insert'
              })
          }
      }).then(function (model) {
          console.log("SUCCESS");
      }).catch(function (err) {
          console.log("ERROR", err);
      });
  }
  </code></pre>
  
  <p>Example call:</p>
  
  <pre><code>Radio.insertOrUpdate({
      serial: ...,
      example1: ...,
      example2: ...
  })
  </code></pre>
  
  <p>The problem I'm running into here is that while the "insert" case works, the "update" case fails with:</p>
  
  <pre><code>ERROR { Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where `serial` = '123223'' at line 1
  </code></pre>
  
  <p>Which is obvious with Knex debugging turned on, where the generated query is missing the <code>set</code> clause:</p>
  
  <pre><code>update `radios` set  where `serial` = ?
  </code></pre>
  
  <p>Now, I'm focused on the Bookshelf docs for <a href="http://bookshelfjs.org/#Model-instance-fetch"><code>fetch</code></a> and <a href="http://bookshelfjs.org/#Model-instance-save"><code>save</code></a>, and I'm wondering if I'm headed in the wrong direction.</p>
  
  <p>I know I'm using the API wrong but I can't figure it out. A couple of weird things I noticed / had to do just to get it into its semi-working state:</p>
  
  <ul>
  <li><p>I don't understand the first parameter of <code>save</code>. It <em>would</em> make sense to me if save was a <em>static</em> method of <code>Model</code>, but it isn't. It's an instance method and you can already pass attributes to the <code>Model</code> constructor (e.g. what would <code>new X(a:1).save({a:2})</code> mean...?), and you can already set attributes with <code>set</code> prior to the save. So I can't make sense of this. I had to pass <code>{}</code> as a placeholder to let me specify the options.</p></li>
  <li><p>There is this <a href="http://bookshelfjs.org/#Model-static-forge"><code>forge</code></a> thing but I'm not sure what its purpose is since you can already pass attributes to the <code>Model</code> constructor (unless the authors found some benefit to <code>X.forge({a:1})</code> vs. <code>new X({a:1})</code>...?).</p></li>
  <li><p>I found that I had to explicitly specify the method to save because of an apparent Bookshelf quirk: Bookshelf bases its choice of method on <code>isNew()</code>, but <code>isNew()</code> is always <code>true</code> when you pass the id to the model constructor, which you have to do in the application-assigned ID case. Therefore for application-assigned IDs Bookshelf will <em>always</em> do an "insert" since it <em>always</em> thinks the model "is new". So you have to force the method to "update"... this just adds to my Bookshelf confusion.</p></li>
  </ul>
  
  <p>Anyways, how do I do this properly? How do I make this insert and update work?</p>
  
  <p>More importantly, where is this documented? In good faith I assume that it <em>is</em> documented clearly somewhere and I just can't see the forest for the trees right now, so I'd actually appreciate some direction to follow in the docs even more than a direct answer, because I do need to figure this out. I've been spending a <em>lot</em> of time on Bookshelf instead of actual development, so much that I almost wish I would have just stuck to direct SQL queries from the start.</p>