This project is archived and is in readonly mode.
Has_many :through _ids not passing conditions to SQL
Reported by Chris Your | April 7th, 2011 @ 02:55 AM
Hi everyone,
First off, I love Rails. It's a fantastic framework.
So on to this possible bug...
Say I have a Book model with many authors through an
AuthorAssignment model. The AuthorAssignment model also has an
additional boolean column named featured
.
class Book < ActiveRecord::Base
has_many :author_assignments, :dependent => :destroy
has_many :featured_authors, :through => :author_assignments, :conditions => "`author_assignments`.featured = 1"
end
Here is my problem:
When I call:
@book.featured_author_ids
The expected array of ids is incorrect. I get an array of all
the author ids, not just the featured authors. The SQL query
doesn't include the condition that
'author_assignments'.featured
must be true.
SELECT `author_assignments`.author_id FROM `author_assignments` WHERE (`author_assignments`.book_id = 4)
On the other hand, when I fetch the
@book.featured_authors
records:
@book.featured_authors
The 'author_assignments'.featured
condition is
included in the SQL finder and the expected result for records is
correct.
Thanks,
Chris
Comments and changes to this ticket
-
Chris Your April 8th, 2011 @ 04:21 PM
I took a look at ActiveRecord-3.0.6 in associations.rb
redefine_method("#{reflection.name.to_s.singularize}_ids")
on line 1492. As far as I can see, the _ids method on thehas_many :through
association creates the finder on the through model like this (around line 1500:send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map! { |r| r.send(primary_key) }
I can easily add an if condition that looks for the
:conditions
option on the reflection and add thewhere
conditions like this:if reflection.options[:conditions] send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").where(reflection.options[:conditions]).map! { |r| r.send(primary_key) } else send(through.name).select("DISTINCT #{through.quoted_table_name}.#{primary_key}").map! { |r| r.send(primary_key) } end
But I'm sure there's a Rails way of doing this kind of thing.
Any help to get this patched would be appreciated.
Thanks,
Chris -
Anatoliy Lysenko April 8th, 2011 @ 04:55 PM
I think you should look at master not v3.0.6 if you want to create a pathc.
CollectionAssociation#reader_ids:column = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}" scoped.select(column).except(:includes).map! do |record| record.send(reflection.association_primary_key) end
Maybe scoped already has conditions?
-
Chris Your April 8th, 2011 @ 05:12 PM
Hi Anatoliy,
Thanks for the advice. I haven't contributed to Rails' source before...
Scoped on the
through
object's reflection doesn't have thewhere
conditions - the conditions are on thereflection
object's reflection. If that makes sense.I wish I knew more about reflections and Arel. I'm learning as I dig through this source though. :)
-
Chris Your April 8th, 2011 @ 06:22 PM
I took a look at Rails Master. Looks awesome. Lots of changes.
I'll have to checkout master to see if the CollectionAssociation#reader_ids fixes this little bit of missing functionality in 3.0.6.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>