Reputation: 1538
Stripping out the irrelevant parts, I have the following models:
class Member < ActiveRecord::Base
attr_accessible :custom_fields_attributes
has_many :custom_fields, :as => :custom_fieldable
end
class CustomField < ActiveRecord::Base
attr_accessible :key_id, :value
belongs_to :key
belongs_to :custom_fieldable, :polymorphic => true
end
class Key < ActiveRecord::Base
attr_accessible :key
end
Suppose I have two entries in my keys
table:
---------------
id | key
---+-----------
1 | Hair color
2 | Height
how do I run a query that would let me retrieve all members with "Brown" hair color and "5ft" in height?
I tried doing it as two successive commands:
ms = Member.joins(:custom_fields).where("custom_fields.key_id = 1 AND custom_fields.value = 'Brown'")
ms.joins(:custom_fields).where("custom_fields.key_id = 2 AND custom_fields.value = '5ft'")
However, this doesn't work because ActiveRecord runs the second query like this:
SELECT `members`.* FROM `members` INNER JOIN `custom_fields` ON
`custom_fields`.`custom_fieldable_id` = `members`.`id` AND
`custom_fields`.`custom_fieldable_type` = 'Member' WHERE
(custom_fields.key_id = 1 AND custom_fields.value = 'Brown') AND
(custom_fields.key_id = 2 AND custom_fields.value = '5ft')
The query above returns an empty record because no custom field can be simultaneously two things at once.
What I would like to do is to have Rails evaluate the first result, and then run the second query on it. How would I do that?
The version I'm using is Rails 3.2.14.
Upvotes: 0
Views: 144
Reputation: 25029
I suspect you will have to alias one (or both) of the times you're joining the custom_fields
table if you want to do it in one query.
Something like:
Member
.joins('custom_fields as custom_fields_1').where("custom_fields_1.key_id = 1 AND custom_fields_1.value = 'Brown'")
.joins('custom_fields as custom_fields_2').where("custom_fields_2.key_id = 2 AND custom_fields_2.value = '5ft'")
Alternatively, run the two queries separately, and merge the results. eg.
brown_members = Member.joins(:custom_fields).where("custom_fields.key_id = 1 AND custom_fields.value = 'Brown'")
height_members = Member.joins(:custom_fields).where("custom_fields.key_id = 2 AND custom_fields.value = '5ft'")
ms = brown_members.merge(height_members)
Upvotes: 1