Note that there are some explanatory texts on larger screens.

plurals
  1. PORails 4 .order() gets mangled with JOINS
    primarykey
    data
    text
    <p>I'm working on upgrading an existing Rails 3.2 application to 4.0. I've run into a brick wall, though.</p> <p>I've got three models, Client, Site, and Contact. Sites are physical locations that belong to a client, and a client can have many sites. Contacts are people that belong to one or more sites. Thus, a client can have many contacts through sites.</p> <p><strong>Clients:</strong></p> <pre><code>class Client &lt; ActiveRecord::Base has_many :sites, -&gt; { where(:sites =&gt; {:deleted =&gt; false}).order(:name =&gt; :asc) }, :dependent =&gt; :destroy has_many :contacts, -&gt; { order(:lastname =&gt; :asc) }, :through =&gt; :sites end </code></pre> <p><strong>Sites:</strong></p> <pre><code>class Site &lt; ActiveRecord::Base belongs_to :client has_and_belongs_to_many :contacts end </code></pre> <p><strong>Contacts:</strong></p> <pre><code>class Contact &lt; ActiveRecord::Base has_and_belongs_to_many :sites end </code></pre> <p>The problem is that when I use <code>Client.find(1).contacts</code>, I get a <code>ActiveRecord::StatementInvalid</code> exception:</p> <blockquote> <p>Mysql2::Error: Unknown column 'contacts.name' in 'order clause': SELECT <code>contacts</code>.* FROM <code>contacts</code> INNER JOIN <code>contacts_sites</code> ON <code>contacts</code>.<code>id</code> = <code>contacts_sites</code>.<code>contact_id</code> INNER JOIN <code>sites</code> ON <code>contacts_sites</code>.<code>site_id</code> = <code>sites</code>.<code>id</code> WHERE <code>sites</code>.<code>client_id</code> = 5 AND <code>sites</code>.<code>deleted</code> = 0 ORDER BY <code>contacts</code>.<code>lastname</code> ASC, <code>contacts</code>.<code>name</code> ASC</p> </blockquote> <p>There's the problem: I have no idea where the <code>ORDER BY ... `contacts`.`name` ASC</code> is coming from. The Contacts table does not have a name column, but Rails is trying to sort with it and I don't know where it's coming from or how to remove it. The <code>ORDER BY `contacts`.`lastname` ASC</code> is easy; it comes from the Client model.</p> <p>These relationships have worked flawlessly in 3.2, but now throw this exception in 4.0.</p> <p><strong>UPDATE:</strong> It's been pointed out that the extra <code>ORDER BY ... `contacts`.`name` ASC</code> is coming from the first <code>has_many</code> in the Clients model. However, the intention there was to sort the Sites, not the Contacts. I tried changing it to <code>.order('sites.name' =&gt; :asc)</code> and SQL complained about there being no column named <code>sites.sites.name</code>. So, it appears that when using <code>:through =&gt;</code> with <code>has_many</code>, the order clause gets mangled.</p> <p>I tried removing the <code>.order()</code> and using <code>default_scope -&gt; { order(:name =&gt; :asc) }</code> in the Sites model, but got exactly the same error as originally reported.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload