Changeset 8126
- Timestamp:
- 11/10/07 21:33:13 (1 year ago)
- Files:
-
- trunk/activerecord/CHANGELOG (modified) (1 diff)
- trunk/activerecord/lib/active_record/associations.rb (modified) (14 diffs)
- trunk/activerecord/test/associations/inner_join_association_test.rb (modified) (2 diffs)
- trunk/activerecord/test/reserved_word_test_mysql.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activerecord/CHANGELOG
r8120 r8126 1 1 *SVN* 2 3 * Ensure that column names are quoted. Closes #10134 [wesley.moxam] 2 4 3 5 * Smattering of grammatical fixes to documentation. Closes #10083 [BobSilva] trunk/activerecord/lib/active_record/associations.rb
r8119 r8126 1248 1248 def construct_finder_sql_with_included_associations(options, join_dependency) 1249 1249 scope = scope(:find) 1250 sql = "SELECT #{column_aliases(join_dependency)} FROM #{ (scope && scope[:from]) || options[:from] || table_name} "1250 sql = "SELECT #{column_aliases(join_dependency)} FROM #{connection.quote_table_name((scope && scope[:from]) || options[:from] || table_name)} " 1251 1251 sql << join_dependency.join_associations.collect{|join| join.association_join }.join 1252 1252 … … 1265 1265 def add_limited_ids_condition!(sql, options, join_dependency) 1266 1266 unless (id_list = select_limited_ids_list(options, join_dependency)).empty? 1267 sql << "#{condition_word(sql)} #{ table_name}.#{primary_key} IN (#{id_list}) "1267 sql << "#{condition_word(sql)} #{connection.quote_table_name table_name}.#{primary_key} IN (#{id_list}) " 1268 1268 else 1269 1269 throw :invalid_query … … 1285 1285 sql = "SELECT " 1286 1286 if is_distinct 1287 sql << connection.distinct("#{ table_name}.#{primary_key}", options[:order])1287 sql << connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", options[:order]) 1288 1288 else 1289 1289 sql << primary_key 1290 1290 end 1291 sql << " FROM #{ table_name} "1291 sql << " FROM #{connection.quote_table_name table_name} " 1292 1292 1293 1293 if is_distinct … … 1341 1341 def column_aliases(join_dependency) 1342 1342 join_dependency.joins.collect{|join| join.column_names_with_alias.collect{|column_name, aliased_name| 1343 "#{ join.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}"}}.flatten.join(", ")1343 "#{connection.quote_table_name join.aliased_table_name}.#{connection.quote_column_name column_name} AS #{aliased_name}"}}.flatten.join(", ") 1344 1344 end 1345 1345 … … 1594 1594 1595 1595 def association_join 1596 connection = reflection.active_record.connection 1596 1597 join = case reflection.macro 1597 1598 when :has_and_belongs_to_many 1598 1599 " #{join_type} %s ON %s.%s = %s.%s " % [ 1599 1600 table_alias_for(options[:join_table], aliased_join_table_name), 1600 aliased_join_table_name,1601 connection.quote_table_name(aliased_join_table_name), 1601 1602 options[:foreign_key] || reflection.active_record.to_s.foreign_key, 1602 parent.aliased_table_name, reflection.active_record.primary_key] + 1603 connection.quote_table_name(parent.aliased_table_name), 1604 reflection.active_record.primary_key] + 1603 1605 " #{join_type} %s ON %s.%s = %s.%s " % [ 1604 table_name_and_alias, aliased_table_name, klass.primary_key, 1605 aliased_join_table_name, options[:association_foreign_key] || klass.to_s.foreign_key 1606 table_name_and_alias, 1607 connection.quote_table_name(aliased_table_name), 1608 klass.primary_key, 1609 connection.quote_table_name(aliased_join_table_name), 1610 options[:association_foreign_key] || klass.to_s.foreign_key 1606 1611 ] 1607 1612 when :has_many, :has_one … … 1616 1621 jt_foreign_key = through_reflection.options[:as].to_s + '_id' 1617 1622 jt_as_extra = " AND %s.%s = %s" % [ 1618 aliased_join_table_name,1619 reflection.active_record.connection.quote_column_name(through_reflection.options[:as].to_s + '_type'),1623 connection.quote_table_name(aliased_join_table_name), 1624 connection.quote_column_name(through_reflection.options[:as].to_s + '_type'), 1620 1625 klass.quote_value(parent.active_record.base_class.name) 1621 1626 ] … … 1630 1635 second_key = options[:foreign_key] || primary_key 1631 1636 as_extra = " AND %s.%s = %s" % [ 1632 aliased_table_name,1633 reflection.active_record.connection.quote_column_name("#{source_reflection.options[:as]}_type"),1637 connection.quote_table_name(aliased_table_name), 1638 connection.quote_column_name("#{source_reflection.options[:as]}_type"), 1634 1639 klass.quote_value(source_reflection.active_record.base_class.name) 1635 1640 ] … … 1641 1646 unless through_reflection.klass.descends_from_active_record? 1642 1647 jt_sti_extra = " AND %s.%s = %s" % [ 1643 aliased_join_table_name,1644 reflection.active_record.connection.quote_column_name(through_reflection.active_record.inheritance_column),1648 connection.quote_table_name(aliased_join_table_name), 1649 connection.quote_column_name(through_reflection.active_record.inheritance_column), 1645 1650 through_reflection.klass.quote_value(through_reflection.klass.name.demodulize)] 1646 1651 end … … 1650 1655 second_key = source_reflection.association_foreign_key 1651 1656 jt_source_extra = " AND %s.%s = %s" % [ 1652 aliased_join_table_name,1653 reflection.active_record.connection.quote_column_name(reflection.source_reflection.options[:foreign_type]),1657 connection.quote_table_name(aliased_join_table_name), 1658 connection.quote_column_name(reflection.source_reflection.options[:foreign_type]), 1654 1659 klass.quote_value(reflection.options[:source_type]) 1655 1660 ] … … 1661 1666 " #{join_type} %s ON (%s.%s = %s.%s%s%s%s) " % [ 1662 1667 table_alias_for(through_reflection.klass.table_name, aliased_join_table_name), 1663 parent.aliased_table_name, reflection.active_record.connection.quote_column_name(parent.primary_key), 1664 aliased_join_table_name, reflection.active_record.connection.quote_column_name(jt_foreign_key), 1668 connection.quote_table_name(parent.aliased_table_name), 1669 connection.quote_column_name(parent.primary_key), 1670 connection.quote_table_name(aliased_join_table_name), 1671 connection.quote_column_name(jt_foreign_key), 1665 1672 jt_as_extra, jt_source_extra, jt_sti_extra 1666 1673 ] + 1667 1674 " #{join_type} %s ON (%s.%s = %s.%s%s) " % [ 1668 1675 table_name_and_alias, 1669 aliased_table_name, reflection.active_record.connection.quote_column_name(first_key), 1670 aliased_join_table_name, reflection.active_record.connection.quote_column_name(second_key), 1676 connection.quote_table_name(aliased_table_name), 1677 connection.quote_column_name(first_key), 1678 connection.quote_table_name(aliased_join_table_name), 1679 connection.quote_column_name(second_key), 1671 1680 as_extra 1672 1681 ] … … 1675 1684 " #{join_type} %s ON %s.%s = %s.%s AND %s.%s = %s" % [ 1676 1685 table_name_and_alias, 1677 aliased_table_name, "#{reflection.options[:as]}_id", 1678 parent.aliased_table_name, parent.primary_key, 1679 aliased_table_name, "#{reflection.options[:as]}_type", 1686 connection.quote_table_name(aliased_table_name), 1687 "#{reflection.options[:as]}_id", 1688 connection.quote_table_name(parent.aliased_table_name), 1689 parent.primary_key, 1690 connection.quote_table_name(aliased_table_name), 1691 "#{reflection.options[:as]}_type", 1680 1692 klass.quote_value(parent.active_record.base_class.name) 1681 1693 ] … … 1684 1696 " #{join_type} %s ON %s.%s = %s.%s " % [ 1685 1697 table_name_and_alias, 1686 aliased_table_name, foreign_key, 1687 parent.aliased_table_name, parent.primary_key 1698 aliased_table_name, 1699 foreign_key, 1700 parent.aliased_table_name, 1701 parent.primary_key 1688 1702 ] 1689 1703 end 1690 1704 when :belongs_to 1691 1705 " #{join_type} %s ON %s.%s = %s.%s " % [ 1692 table_name_and_alias, aliased_table_name, reflection.klass.primary_key, 1693 parent.aliased_table_name, options[:foreign_key] || klass.to_s.foreign_key 1706 table_name_and_alias, 1707 connection.quote_table_name(aliased_table_name), 1708 reflection.klass.primary_key, 1709 connection.quote_table_name(parent.aliased_table_name), 1710 options[:foreign_key] || klass.to_s.foreign_key 1694 1711 ] 1695 1712 else … … 1697 1714 end || '' 1698 1715 join << %(AND %s.%s = %s ) % [ 1699 aliased_table_name,1700 reflection.active_record.connection.quote_column_name(klass.inheritance_column),1716 connection.quote_table_name(aliased_table_name), 1717 connection.quote_column_name(klass.inheritance_column), 1701 1718 klass.quote_value(klass.name.demodulize)] unless klass.descends_from_active_record? 1702 1719 … … 1715 1732 1716 1733 def table_alias_for(table_name, table_alias) 1717 "#{table_name} #{table_alias if table_name != table_alias}".strip1734 "#{reflection.active_record.connection.quote_table_name(table_name)} #{table_alias if table_name != table_alias}".strip 1718 1735 end 1719 1736 trunk/activerecord/test/associations/inner_join_association_test.rb
r8109 r8126 11 11 def test_construct_finder_sql_creates_inner_joins 12 12 sql = Author.send(:construct_finder_sql, :joins => :posts) 13 assert_match /INNER JOIN posts ON posts.author_id = authors.id/, sql13 assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql 14 14 end 15 15 16 16 def test_construct_finder_sql_cascades_inner_joins 17 17 sql = Author.send(:construct_finder_sql, :joins => {:posts => :comments}) 18 assert_match /INNER JOIN posts ON posts.author_id = authors.id/, sql19 assert_match /INNER JOIN comments ON comments.post_id = posts.id/, sql18 assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql 19 assert_match /INNER JOIN `?comments`? ON `?comments`?.post_id = posts.id/, sql 20 20 end 21 21 22 22 def test_construct_finder_sql_inner_joins_through_associations 23 23 sql = Author.send(:construct_finder_sql, :joins => :categorized_posts) 24 assert_match /INNER JOIN categorizations.*INNER JOIN posts/, sql24 assert_match /INNER JOIN `?categorizations`?.*INNER JOIN `?posts`?/, sql 25 25 end 26 26 27 27 def test_construct_finder_sql_applies_association_conditions 28 28 sql = Author.send(:construct_finder_sql, :joins => :categories_like_general, :conditions => "TERMINATING_MARKER") 29 assert_match /INNER JOIN categories ON.*AND.*'General'.*TERMINATING_MARKER/, sql29 assert_match /INNER JOIN `?categories`? ON.*AND.*`?General`?.*TERMINATING_MARKER/, sql 30 30 end 31 31 … … 33 33 sql = Author.send(:construct_finder_sql, :joins => {:posts => [[:comments]]}) 34 34 assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present" 35 assert_match /INNER JOIN posts ON posts.author_id = authors.id/, sql36 assert_match /INNER JOIN comments ON comments.post_id = posts.id/, sql35 assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql 36 assert_match /INNER JOIN `?comments`? ON `?comments`?.post_id = `?posts`?.id/, sql 37 37 end 38 38 trunk/activerecord/test/reserved_word_test_mysql.rb
r8061 r8126 148 148 end 149 149 150 def test_associations_work_with_reserved_words 151 assert_nothing_raised { Select.find(:all, :include => [:groups]) } 152 end 153 150 154 #the following functions were added to DRY test cases 151 155