Methods
Attributes
| [R] | aliased_join_table_name | |
| [R] | aliased_prefix | |
| [R] | aliased_table_name | |
| [R] | parent | |
| [R] | parent_table_name | |
| [R] | reflection |
Public Class methods
[ show source ]
# File lib/active_record/associations.rb, line 1396
1396: def initialize(reflection, join_dependency, parent = nil)
1397: reflection.check_validity!
1398: if reflection.options[:polymorphic]
1399: raise EagerLoadPolymorphicError.new(reflection)
1400: end
1401:
1402: super(reflection.klass)
1403: @parent = parent
1404: @reflection = reflection
1405: @aliased_prefix = "t#{ join_dependency.joins.size }"
1406: @aliased_table_name = table_name # start with the table name
1407: @parent_table_name = parent.active_record.table_name
1408:
1409: if !parent.table_joins.blank? && parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{aliased_table_name.downcase}\son}
1410: join_dependency.table_aliases[aliased_table_name] += 1
1411: end
1412:
1413: unless join_dependency.table_aliases[aliased_table_name].zero?
1414: # if the table name has been used, then use an alias
1415: @aliased_table_name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}"
1416: table_index = join_dependency.table_aliases[aliased_table_name]
1417: @aliased_table_name = @aliased_table_name[0..active_record.connection.table_alias_length-3] + "_#{table_index+1}" if table_index > 0
1418: end
1419: join_dependency.table_aliases[aliased_table_name] += 1
1420:
1421: if reflection.macro == :has_and_belongs_to_many || (reflection.macro == :has_many && reflection.options[:through])
1422: @aliased_join_table_name = reflection.macro == :has_and_belongs_to_many ? reflection.options[:join_table] : reflection.through_reflection.klass.table_name
1423: unless join_dependency.table_aliases[aliased_join_table_name].zero?
1424: @aliased_join_table_name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}_join"
1425: table_index = join_dependency.table_aliases[aliased_join_table_name]
1426: @aliased_join_table_name = @aliased_join_table_name[0..active_record.connection.table_alias_length-3] + "_#{table_index+1}" if table_index > 0
1427: end
1428: join_dependency.table_aliases[aliased_join_table_name] += 1
1429: end
1430: end
Public Instance methods
[ show source ]
# File lib/active_record/associations.rb, line 1432
1432: def association_join
1433: join = case reflection.macro
1434: when :has_and_belongs_to_many
1435: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1436: table_alias_for(options[:join_table], aliased_join_table_name),
1437: aliased_join_table_name,
1438: options[:foreign_key] || reflection.active_record.to_s.classify.foreign_key,
1439: reflection.active_record.table_name, reflection.active_record.primary_key] +
1440: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1441: table_name_and_alias, aliased_table_name, klass.primary_key,
1442: aliased_join_table_name, options[:association_foreign_key] || klass.table_name.classify.foreign_key
1443: ]
1444: when :has_many, :has_one
1445: case
1446: when reflection.macro == :has_many && reflection.options[:through]
1447: through_conditions = through_reflection.options[:conditions] ? "AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}" : ''
1448: if through_reflection.options[:as] # has_many :through against a polymorphic join
1449: polymorphic_foreign_key = through_reflection.options[:as].to_s + '_id'
1450: polymorphic_foreign_type = through_reflection.options[:as].to_s + '_type'
1451:
1452: " LEFT OUTER JOIN %s ON (%s.%s = %s.%s AND %s.%s = %s) " % [
1453: table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
1454: aliased_join_table_name, polymorphic_foreign_key,
1455: parent.aliased_table_name, parent.primary_key,
1456: aliased_join_table_name, polymorphic_foreign_type, klass.quote(parent.active_record.base_class.name)] +
1457: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [table_name_and_alias,
1458: aliased_table_name, primary_key, aliased_join_table_name, options[:foreign_key] || reflection.klass.to_s.classify.foreign_key
1459: ]
1460: else
1461: if source_reflection.macro == :has_many && source_reflection.options[:as]
1462: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1463: table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), aliased_join_table_name,
1464: through_reflection.primary_key_name,
1465: parent.aliased_table_name, parent.primary_key] +
1466: " LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s " % [
1467: table_name_and_alias,
1468: aliased_table_name, "#{source_reflection.options[:as]}_id",
1469: aliased_join_table_name, options[:foreign_key] || primary_key,
1470: aliased_table_name, "#{source_reflection.options[:as]}_type",
1471: klass.quote(source_reflection.active_record.base_class.name)
1472: ]
1473: else
1474: case source_reflection.macro
1475: when :belongs_to
1476: first_key = primary_key
1477: second_key = options[:foreign_key] || klass.to_s.classify.foreign_key
1478: when :has_many
1479: first_key = through_reflection.klass.to_s.classify.foreign_key
1480: second_key = options[:foreign_key] || primary_key
1481: end
1482:
1483: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1484: table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), aliased_join_table_name,
1485: through_reflection.primary_key_name,
1486: parent.aliased_table_name, parent.primary_key] +
1487: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1488: table_name_and_alias,
1489: aliased_table_name, first_key,
1490: aliased_join_table_name, second_key
1491: ]
1492: end
1493: end
1494:
1495: when reflection.macro == :has_many && reflection.options[:as]
1496: " LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s" % [
1497: table_name_and_alias,
1498: aliased_table_name, "#{reflection.options[:as]}_id",
1499: parent.aliased_table_name, parent.primary_key,
1500: aliased_table_name, "#{reflection.options[:as]}_type",
1501: klass.quote(parent.active_record.base_class.name)
1502: ]
1503: when reflection.macro == :has_one && reflection.options[:as]
1504: " LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s " % [
1505: table_name_and_alias,
1506: aliased_table_name, "#{reflection.options[:as]}_id",
1507: parent.aliased_table_name, parent.primary_key,
1508: aliased_table_name, "#{reflection.options[:as]}_type",
1509: klass.quote(reflection.active_record.base_class.name)
1510: ]
1511: else
1512: foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
1513: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1514: table_name_and_alias,
1515: aliased_table_name, foreign_key,
1516: parent.aliased_table_name, parent.primary_key
1517: ]
1518: end
1519: when :belongs_to
1520: " LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [
1521: table_name_and_alias, aliased_table_name, reflection.klass.primary_key,
1522: parent.aliased_table_name, options[:foreign_key] || klass.to_s.foreign_key
1523: ]
1524: else
1525: ""
1526: end || ''
1527: join << %(AND %s.%s = %s ) % [
1528: aliased_table_name,
1529: reflection.active_record.connection.quote_column_name(reflection.active_record.inheritance_column),
1530: klass.quote(klass.name)] unless klass.descends_from_active_record?
1531: join << "AND #{interpolate_sql(sanitize_sql(reflection.options[:conditions]))} " if reflection.options[:conditions]
1532: join
1533: end
Protected Instance methods
[ show source ]
# File lib/active_record/associations.rb, line 1548
1548: def interpolate_sql(sql)
1549: instance_eval("%@#{sql.gsub('@', '\@')}@")
1550: end
[ show source ]
# File lib/active_record/associations.rb, line 1536
1536: def pluralize(table_name)
1537: ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
1538: end
[ show source ]
# File lib/active_record/associations.rb, line 1540
1540: def table_alias_for(table_name, table_alias)
1541: "#{table_name} #{table_alias if table_name != table_alias}".strip
1542: end
[ show source ]
# File lib/active_record/associations.rb, line 1544
1544: def table_name_and_alias
1545: table_alias_for table_name, @aliased_table_name
1546: end