Class ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation
In: vendor/rails/activerecord/lib/active_record/associations.rb
Parent: JoinBase

Methods

Attributes

aliased_join_table_name  [R] 
aliased_prefix  [R] 
aliased_table_name  [R] 
parent  [R] 
parent_table_name  [R] 
reflection  [R] 

Public Class methods

[Source]

      # File vendor/rails/activerecord/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

[Source]

      # File vendor/rails/activerecord/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

[Source]

      # File vendor/rails/activerecord/lib/active_record/associations.rb, line 1548
1548:               def interpolate_sql(sql)
1549:                 instance_eval("%@#{sql.gsub('@', '\@')}@")
1550:               end

[Source]

      # File vendor/rails/activerecord/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

[Source]

      # File vendor/rails/activerecord/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

[Source]

      # File vendor/rails/activerecord/lib/active_record/associations.rb, line 1544
1544:               def table_name_and_alias
1545:                 table_alias_for table_name, @aliased_table_name
1546:               end

[Validate]