1441: def association_join
1442: join = case reflection.macro
1443: when :has_and_belongs_to_many
1444: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1445: table_alias_for(options[:join_table], aliased_join_table_name),
1446: aliased_join_table_name,
1447: options[:foreign_key] || reflection.active_record.to_s.classify.foreign_key,
1448: reflection.active_record.table_name, reflection.active_record.primary_key] +
1449: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1450: table_name_and_alias, aliased_table_name, klass.primary_key,
1451: aliased_join_table_name, options[:association_foreign_key] || klass.table_name.classify.foreign_key
1452: ]
1453: when :has_many, :has_one
1454: case
1455: when reflection.macro == :has_many && reflection.options[:through]
1456: through_conditions = through_reflection.options[:conditions] ? "AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}" : ''
1457: if through_reflection.options[:as]
1458: polymorphic_foreign_key = through_reflection.options[:as].to_s + '_id'
1459: polymorphic_foreign_type = through_reflection.options[:as].to_s + '_type'
1460:
1461: " LEFT OUTER JOIN %s ON (%s.%s = %s.%s AND %s.%s = %s) " % [
1462: table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
1463: aliased_join_table_name, polymorphic_foreign_key,
1464: parent.aliased_table_name, parent.primary_key,
1465: aliased_join_table_name, polymorphic_foreign_type, klass.quote(parent.active_record.base_class.name)] +
1466: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [table_name_and_alias,
1467: aliased_table_name, primary_key, aliased_join_table_name, options[:foreign_key] || reflection.klass.to_s.classify.foreign_key
1468: ]
1469: else
1470: if source_reflection.macro == :has_many && source_reflection.options[:as]
1471: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1472: table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), aliased_join_table_name,
1473: through_reflection.primary_key_name,
1474: parent.aliased_table_name, parent.primary_key] +
1475: " LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s " % [
1476: table_name_and_alias,
1477: aliased_table_name, "#{source_reflection.options[:as]}_id",
1478: aliased_join_table_name, options[:foreign_key] || primary_key,
1479: aliased_table_name, "#{source_reflection.options[:as]}_type",
1480: klass.quote(source_reflection.active_record.base_class.name)
1481: ]
1482: else
1483: case source_reflection.macro
1484: when :belongs_to
1485: first_key = primary_key
1486: second_key = options[:foreign_key] || klass.to_s.classify.foreign_key
1487: when :has_many
1488: first_key = through_reflection.klass.to_s.classify.foreign_key
1489: second_key = options[:foreign_key] || primary_key
1490: end
1491:
1492: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1493: table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), aliased_join_table_name,
1494: through_reflection.primary_key_name,
1495: parent.aliased_table_name, parent.primary_key] +
1496: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1497: table_name_and_alias,
1498: aliased_table_name, first_key,
1499: aliased_join_table_name, second_key
1500: ]
1501: end
1502: end
1503:
1504: when reflection.macro == :has_many && reflection.options[:as]
1505: " LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s" % [
1506: table_name_and_alias,
1507: aliased_table_name, "#{reflection.options[:as]}_id",
1508: parent.aliased_table_name, parent.primary_key,
1509: aliased_table_name, "#{reflection.options[:as]}_type",
1510: klass.quote(parent.active_record.base_class.name)
1511: ]
1512: when reflection.macro == :has_one && reflection.options[:as]
1513: " LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s " % [
1514: table_name_and_alias,
1515: aliased_table_name, "#{reflection.options[:as]}_id",
1516: parent.aliased_table_name, parent.primary_key,
1517: aliased_table_name, "#{reflection.options[:as]}_type",
1518: klass.quote(reflection.active_record.base_class.name)
1519: ]
1520: else
1521: foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
1522: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1523: table_name_and_alias,
1524: aliased_table_name, foreign_key,
1525: parent.aliased_table_name, parent.primary_key
1526: ]
1527: end
1528: when :belongs_to
1529: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1530: table_name_and_alias, aliased_table_name, reflection.klass.primary_key,
1531: parent.aliased_table_name, options[:foreign_key] || klass.to_s.foreign_key
1532: ]
1533: else
1534: ""
1535: end || ''
1536: join << %(AND %s.%s = %s ) % [
1537: aliased_table_name,
1538: reflection.active_record.connection.quote_column_name(reflection.active_record.inheritance_column),
1539: klass.quote(klass.name)] unless klass.descends_from_active_record?
1540: join << "AND #{interpolate_sql(sanitize_sql(reflection.options[:conditions]))} " if reflection.options[:conditions]
1541: join
1542: end