问题
I have two ActiveRecord
models which have a HABTM association.
I want to write a scope
to get the orphan records using Arel.
My problem is that I couldn't find a method to retrieve the arel_table
of the association. Since the relation is HABTM, there is no model to call arel_table
on.
I have the following now (which works), but I make a new arel table with the name of the join table (retrieved by using the reflect_on_association
method).
scope :orphans, lambda {
teachers = arel_table
join_table = Arel::Table.new(reflect_on_association(:groups).options[:join_table])
join_table_condition = join_table.project(join_table[:teacher_id])
where(teachers[:id].not_in(join_table_condition))
}
This produces the following SQL:
SELECT `teachers`.*
FROM `teachers`
WHERE (`teachers`.`id` NOT IN (SELECT `groups_teachers`.`teacher_id`
FROM `groups_teachers` ))
So is there any better way to retrieve the arel_table
instead of making a new one?
回答1:
Unfortunately, I believe your solution is pretty much the cleanest there is right now and is, in fact, what the association itself does internally when instantiated:
https://github.com/rails/rails/blob/46492949b8c09f99db78b9f7a02d039e7bc6a702/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb#L7
I believe the reflection.join_table they use vs reflection.options[:join_table] is only in master right now though.
回答2:
If you know the name of the association and therefore the join table, which in this case it looks like you do, you should be able to call:
Arel::Table.new(:groups_teachers)
In my testing that returns Arel table of a habtm association. Thanks to this answer for pointing this out to me.
来源:https://stackoverflow.com/questions/8747284/how-to-get-the-arel-table-of-a-habtm-association