I have an ActiveRecord called Name which contains names in various Languages.
class Name < ActiveRecord::Base
belongs_to :language
class Language < ActiveRecord::Base
has_many :names
Finding names in one language is easy enough:
Language.find(1).names.find(whatever)
But I need to find matching pairs where both language 1 and language 2 have the same name. In SQL, this calls for a simple self-join:
SELECT n1.id,n2.id FROM names AS n1, names AS n2
WHERE n1.language_id=1 AND n2.language_id=2
AND n1.normalized=n2.normalized AND n1.id != n2.id;
How can I do a query like this with ActiveRecord? Note that I need to find pairs of names (= both sides of the match), not just a list of names in language 1 that happens to match with something.
For bonus points, replace n1.normalized=n2.normalized with n1.normalized LIKE n2.normalized, since the field may contain SQL wildcards.
I'm also open to ideas about modeling the data differently, but I'd prefer to avoid having separate tables for each language if I can.
Try this:
ids = [1,2]
Name.all(:select => "names.id, n2.id AS id2",
:joins => "JOIN names AS n2
ON n2.normalized = names.normalized AND
n2.language_id != names.language_id AND
n2.language_id IN (%s)" % ids.join(','),
:conditions => ["names.language_id IN (?)", ids]
).each do |name|
p "id1 : #{name.id}"
p "id2 : #{name.id2}"
end
PS: Make sure you sanitize the parameters passed to the join condition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With