Skip to content

Instantly share code, notes, and snippets.

@ritikesh
Last active August 10, 2016 16:20
Show Gist options
  • Save ritikesh/d68a45caf82f4bd0c6c476449e0efe00 to your computer and use it in GitHub Desktop.
Save ritikesh/d68a45caf82f4bd0c6c476449e0efe00 to your computer and use it in GitHub Desktop.
Rails 3 - Extra join conditions for ActiveRecord "through" joins - eg.) table1.account_id = table2.account_id
module AccountJoinCondition
def join_with_account(table, constraint)
s_r = reflection.source_reflection
# source reflection can be polymorphic
s_r = reflection if s_r && s_r.options[:polymorphic]
t_r = reflection.through_reflection
if s_r && t_r && has_account?(s_r) && has_account?(t_r)
sr_account_column = account_col(s_r)
tr_account_column = account_col(t_r)
constraint = constraint.and(sr_account_column.eq(tr_account_column)) if direct_through_join?(sr_account_column, tr_account_column, constraint)
end
join_without_account(table, constraint)
end
def self.included(receiver)
receiver.send :include, CustomJoinMethods
receiver.alias_method_chain :join, :account
end
module CustomJoinMethods
private
def has_account?(reflection_obj)
reflection_obj.klass.column_names.include?("account_id")
end
def account_col(reflection_obj)
reflection_obj.klass.arel_table["account_id"]
end
# for joins made directly on a class and a through association using active record query syntax,
# source_reflection's table_name is different in the first join
def direct_through_join?(sr_account_column, tr_account_column, constraint)
sr_account_column.relation.name.eql?(constraint.left.relation.name) && tr_account_column.relation.name.eql?(constraint.right.relation.name)
end
end
end
ActiveRecord::Associations::JoinHelper.send(:include, AccountJoinCondition)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment