title: Doing an update_all with joins in Rails
body: <p>It's times like this that Rails' abstraction from raw SQL drives me batty. In MySQL I could do this:</p>
  
  <pre><code>UPDATE FROM tasks AS t 
  LEFT JOIN projects as p 
  ON t.project_id = p.id 
  SET t.invoice_id = 7
  WHERE p.organization_id == 42
  AND t.invoice_id IS NULL
  </code></pre>
  
  <p>How can I do this in Rails 3.0.1 with eager loading? I've tried all of the following:</p>
  
  <pre><code>Tasks.joins(:project).where('projects.organization_id' =&gt; 42, :invoice_id =&gt; nil).update_all( :invoice_id =&gt; 7 )
  </code></pre>
  
  <p>And all of the variations of the above. All either gave errors or didn't find anything.</p>
  
  <p>Then I tried to use <code>scope</code>:</p>
  
  <pre><code>Task.scope :find =&gt; {:joins =&gt; :project, :conditions =&gt; ["projects.organization_id == ? AND invoice_id IS NULL", @organization.id] } do
    Task.update_all :invoice_id =&gt; @invoice.id
  end
  </code></pre>
  
  <p>This one gave me the error <code>undefined method 'to_sym' for #&lt;Hash:0x1065c6438&gt;</code>.</p>
  
  <p>I've spent way too many hours on this, just to replicate a simple SQL query. Please help!</p>
  
  <hr>
  
  <p><strong>EDIT: Temporary bad solution to get around n+1:</strong></p>
  
  <pre><code>task_ids = Task.select('tasks.id').joins(:project).where('projects.organization_id' =&gt; @organization.id, :invoice_id =&gt; nil).collect{|t| t.id}
  Task.update_all ['invoice_id = ?', @invoice.id], ["id in (#{task_ids.join(',')})"]
  </code></pre>
  
  <hr>