railties 3.1.12 → 3.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. data/CHANGELOG.md +2292 -41
  2. data/README.rdoc +14 -5
  3. data/bin/rails +7 -0
  4. data/guides/code/getting_started/Gemfile +27 -0
  5. data/guides/code/getting_started/README.rdoc +261 -0
  6. data/guides/code/getting_started/Rakefile +7 -0
  7. data/guides/code/getting_started/app/assets/images/rails.png +0 -0
  8. data/guides/code/getting_started/app/assets/javascripts/application.js +9 -0
  9. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +3 -0
  10. data/guides/code/getting_started/app/assets/javascripts/home.js.coffee +3 -0
  11. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +3 -0
  12. data/guides/code/getting_started/app/assets/stylesheets/application.css +7 -0
  13. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +3 -0
  14. data/guides/code/getting_started/app/assets/stylesheets/home.css.scss +3 -0
  15. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +3 -0
  16. data/guides/code/getting_started/app/assets/stylesheets/scaffolds.css.scss +56 -0
  17. data/guides/code/getting_started/app/controllers/application_controller.rb +3 -0
  18. data/guides/code/getting_started/app/controllers/comments_controller.rb +16 -0
  19. data/guides/code/getting_started/app/controllers/home_controller.rb +5 -0
  20. data/guides/code/getting_started/app/controllers/posts_controller.rb +84 -0
  21. data/guides/code/getting_started/app/helpers/application_helper.rb +2 -0
  22. data/guides/code/getting_started/app/helpers/comments_helper.rb +2 -0
  23. data/guides/code/getting_started/app/helpers/home_helper.rb +2 -0
  24. data/guides/code/getting_started/app/helpers/posts_helper.rb +5 -0
  25. data/guides/code/getting_started/app/models/comment.rb +3 -0
  26. data/guides/code/getting_started/app/models/post.rb +11 -0
  27. data/guides/code/getting_started/app/models/tag.rb +3 -0
  28. data/guides/code/getting_started/app/views/comments/_comment.html.erb +15 -0
  29. data/guides/code/getting_started/app/views/comments/_form.html.erb +13 -0
  30. data/guides/code/getting_started/app/views/home/index.html.erb +2 -0
  31. data/guides/code/getting_started/app/views/layouts/application.html.erb +14 -0
  32. data/guides/code/getting_started/app/views/posts/_form.html.erb +32 -0
  33. data/guides/code/getting_started/app/views/posts/edit.html.erb +6 -0
  34. data/guides/code/getting_started/app/views/posts/index.html.erb +27 -0
  35. data/guides/code/getting_started/app/views/posts/new.html.erb +5 -0
  36. data/guides/code/getting_started/app/views/posts/show.html.erb +31 -0
  37. data/guides/code/getting_started/app/views/tags/_form.html.erb +12 -0
  38. data/guides/code/getting_started/config.ru +4 -0
  39. data/guides/code/getting_started/config/application.rb +53 -0
  40. data/guides/code/getting_started/config/boot.rb +6 -0
  41. data/guides/code/getting_started/config/database.yml +25 -0
  42. data/guides/code/getting_started/config/environment.rb +5 -0
  43. data/guides/code/getting_started/config/environments/development.rb +37 -0
  44. data/guides/code/getting_started/config/environments/production.rb +67 -0
  45. data/guides/code/getting_started/config/environments/test.rb +37 -0
  46. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +7 -0
  47. data/guides/code/getting_started/config/initializers/inflections.rb +10 -0
  48. data/guides/code/getting_started/config/initializers/mime_types.rb +5 -0
  49. data/guides/code/getting_started/config/initializers/secret_token.rb +7 -0
  50. data/guides/code/getting_started/config/initializers/session_store.rb +8 -0
  51. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +14 -0
  52. data/guides/code/getting_started/config/locales/en.yml +5 -0
  53. data/guides/code/getting_started/config/routes.rb +64 -0
  54. data/guides/code/getting_started/db/migrate/20110901012504_create_posts.rb +11 -0
  55. data/guides/code/getting_started/db/migrate/20110901012815_create_comments.rb +12 -0
  56. data/guides/code/getting_started/db/migrate/20110901013701_create_tags.rb +11 -0
  57. data/guides/code/getting_started/db/schema.rb +43 -0
  58. data/guides/code/getting_started/db/seeds.rb +7 -0
  59. data/guides/code/getting_started/doc/README_FOR_APP +2 -0
  60. data/guides/code/getting_started/public/404.html +26 -0
  61. data/guides/code/getting_started/public/422.html +26 -0
  62. data/guides/code/getting_started/public/500.html +26 -0
  63. data/guides/code/getting_started/public/favicon.ico +0 -0
  64. data/guides/code/getting_started/public/robots.txt +5 -0
  65. data/guides/code/getting_started/script/rails +6 -0
  66. data/guides/code/getting_started/test/fixtures/comments.yml +11 -0
  67. data/guides/code/getting_started/test/fixtures/posts.yml +11 -0
  68. data/guides/code/getting_started/test/fixtures/tags.yml +9 -0
  69. data/guides/code/getting_started/test/functional/comments_controller_test.rb +7 -0
  70. data/guides/code/getting_started/test/functional/home_controller_test.rb +9 -0
  71. data/guides/code/getting_started/test/functional/posts_controller_test.rb +49 -0
  72. data/guides/code/getting_started/test/performance/browsing_test.rb +12 -0
  73. data/guides/code/getting_started/test/test_helper.rb +13 -0
  74. data/guides/code/getting_started/test/unit/comment_test.rb +7 -0
  75. data/guides/code/getting_started/test/unit/helpers/comments_helper_test.rb +4 -0
  76. data/guides/code/getting_started/test/unit/helpers/home_helper_test.rb +4 -0
  77. data/guides/code/getting_started/test/unit/helpers/posts_helper_test.rb +4 -0
  78. data/guides/code/getting_started/test/unit/post_test.rb +7 -0
  79. data/guides/code/getting_started/test/unit/tag_test.rb +7 -0
  80. data/guides/rails_guides/generator.rb +2 -1
  81. data/guides/source/3_0_release_notes.textile +2 -2
  82. data/guides/source/3_1_release_notes.textile +3 -110
  83. data/guides/source/action_controller_overview.textile +11 -13
  84. data/guides/source/action_mailer_basics.textile +7 -18
  85. data/guides/source/action_view_overview.textile +78 -9
  86. data/guides/source/active_model_basics.textile +205 -0
  87. data/guides/source/active_record_basics.textile +31 -31
  88. data/guides/source/active_record_querying.textile +288 -67
  89. data/guides/source/active_record_validations_callbacks.textile +69 -75
  90. data/guides/source/active_resource_basics.textile +48 -2
  91. data/guides/source/active_support_core_extensions.textile +145 -24
  92. data/guides/source/ajax_on_rails.textile +65 -7
  93. data/guides/source/api_documentation_guidelines.textile +0 -6
  94. data/guides/source/asset_pipeline.textile +2 -2
  95. data/guides/source/association_basics.textile +25 -34
  96. data/guides/source/caching_with_rails.textile +12 -17
  97. data/guides/source/command_line.textile +29 -19
  98. data/guides/source/configuring.textile +40 -18
  99. data/guides/source/contributing_to_ruby_on_rails.textile +11 -18
  100. data/guides/source/debugging_rails_applications.textile +10 -21
  101. data/guides/source/engines.textile +618 -0
  102. data/guides/source/form_helpers.textile +1 -12
  103. data/guides/source/generators.textile +9 -11
  104. data/guides/source/getting_started.textile +152 -152
  105. data/guides/source/i18n.textile +4 -5
  106. data/guides/source/index.html.erb +0 -1
  107. data/guides/source/initialization.textile +26 -26
  108. data/guides/source/layouts_and_rendering.textile +97 -61
  109. data/guides/source/migrations.textile +380 -161
  110. data/guides/source/performance_testing.textile +4 -10
  111. data/guides/source/plugins.textile +11 -19
  112. data/guides/source/rails_application_templates.textile +12 -4
  113. data/guides/source/rails_on_rack.textile +25 -19
  114. data/guides/source/routing.textile +6 -13
  115. data/guides/source/ruby_on_rails_guides_guidelines.textile +0 -5
  116. data/guides/source/security.textile +11 -15
  117. data/guides/source/testing.textile +1 -9
  118. data/lib/rails/application.rb +107 -42
  119. data/lib/rails/application/bootstrap.rb +12 -11
  120. data/lib/rails/application/configuration.rb +27 -21
  121. data/lib/rails/application/finisher.rb +40 -17
  122. data/lib/rails/application/route_inspector.rb +75 -0
  123. data/lib/rails/application/routes_reloader.rb +15 -4
  124. data/lib/rails/code_statistics.rb +16 -5
  125. data/lib/rails/commands.rb +6 -5
  126. data/lib/rails/commands/application.rb +8 -1
  127. data/lib/rails/commands/console.rb +2 -0
  128. data/lib/rails/commands/dbconsole.rb +2 -2
  129. data/lib/rails/commands/destroy.rb +0 -2
  130. data/lib/rails/commands/generate.rb +3 -3
  131. data/lib/rails/commands/plugin.rb +161 -159
  132. data/lib/rails/commands/plugin_new.rb +3 -2
  133. data/lib/rails/commands/runner.rb +4 -0
  134. data/lib/rails/console/app.rb +26 -22
  135. data/lib/rails/console/helpers.rb +9 -5
  136. data/lib/rails/engine.rb +70 -34
  137. data/lib/rails/engine/commands.rb +39 -0
  138. data/lib/rails/engine/configuration.rb +1 -1
  139. data/lib/rails/generators.rb +3 -14
  140. data/lib/rails/generators/actions.rb +36 -9
  141. data/lib/rails/generators/app_base.rb +34 -38
  142. data/lib/rails/generators/base.rb +4 -4
  143. data/lib/rails/generators/generated_attribute.rb +1 -1
  144. data/lib/rails/generators/named_base.rb +1 -3
  145. data/lib/rails/generators/rails/app/USAGE +6 -0
  146. data/lib/rails/generators/rails/app/app_generator.rb +6 -2
  147. data/lib/rails/generators/rails/app/templates/Gemfile +4 -3
  148. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +9 -3
  149. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +11 -5
  150. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  151. data/lib/rails/generators/rails/app/templates/app/models/.empty_directory +0 -0
  152. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +1 -1
  153. data/lib/rails/generators/rails/app/templates/config/application.rb +11 -0
  154. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +1 -1
  155. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +1 -1
  156. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +10 -1
  157. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +10 -1
  158. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +6 -6
  159. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +5 -0
  160. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  161. data/lib/rails/generators/rails/app/templates/public/500.html +0 -1
  162. data/lib/rails/generators/rails/app/templates/public/index.html +1 -1
  163. data/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
  164. data/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
  165. data/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +0 -0
  166. data/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +0 -0
  167. data/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +0 -0
  168. data/lib/rails/generators/rails/controller/templates/controller.rb +1 -1
  169. data/lib/rails/generators/rails/generator/templates/templates/.empty_directory +0 -0
  170. data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +17 -5
  171. data/lib/rails/generators/rails/plugin_new/templates/Rakefile +1 -0
  172. data/lib/rails/generators/rails/plugin_new/templates/app/mailers/.empty_directory +0 -0
  173. data/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +0 -0
  174. data/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt +1 -1
  175. data/lib/rails/generators/rails/plugin_new/templates/gitignore +4 -3
  176. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +1 -1
  177. data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +1 -1
  178. data/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +5 -3
  179. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +2 -2
  180. data/lib/rails/generators/rails/task/USAGE +9 -0
  181. data/lib/rails/generators/rails/task/task_generator.rb +12 -0
  182. data/lib/rails/generators/rails/task/templates/task.rb +8 -0
  183. data/lib/rails/generators/resource_helpers.rb +3 -3
  184. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +0 -2
  185. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +4 -4
  186. data/lib/rails/paths.rb +11 -38
  187. data/lib/rails/rack/debugger.rb +3 -4
  188. data/lib/rails/rack/logger.rb +26 -12
  189. data/lib/rails/railtie.rb +6 -1
  190. data/lib/rails/railtie/configuration.rb +12 -5
  191. data/lib/rails/source_annotation_extractor.rb +12 -10
  192. data/lib/rails/tasks/documentation.rake +3 -1
  193. data/lib/rails/tasks/engine.rake +1 -0
  194. data/lib/rails/tasks/misc.rake +1 -1
  195. data/lib/rails/tasks/routes.rake +3 -23
  196. data/lib/rails/test_help.rb +1 -2
  197. data/lib/rails/test_unit/testing.rake +8 -4
  198. data/lib/rails/version.rb +3 -3
  199. metadata +131 -61
  200. checksums.yaml +0 -7
  201. data/lib/rails/generators/rails/plugin/USAGE +0 -13
  202. data/lib/rails/generators/rails/plugin/plugin_generator.rb +0 -54
  203. data/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt +0 -20
  204. data/lib/rails/generators/rails/plugin/templates/README.tt +0 -13
  205. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +0 -23
  206. data/lib/rails/generators/rails/plugin/templates/init.rb +0 -1
  207. data/lib/rails/generators/rails/plugin/templates/install.rb +0 -1
  208. data/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt +0 -1
  209. data/lib/rails/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt +0 -4
  210. data/lib/rails/generators/rails/plugin/templates/uninstall.rb +0 -1
@@ -78,12 +78,14 @@ The following values are considered to be blank in a Rails application:
78
78
 
79
79
  * +nil+ and +false+,
80
80
 
81
- * strings composed only of whitespace, i.e. matching +/\A\s*\z/+,
81
+ * strings composed only of whitespace (see note below),
82
82
 
83
83
  * empty arrays and hashes, and
84
84
 
85
85
  * any other object that responds to +empty?+ and it is empty.
86
86
 
87
+ INFO: In Ruby 1.9 the predicate for strings uses the Unicode-aware character class <tt>[:space:]</tt>, so for example U+2029 (paragraph separator) is considered to be whitespace. In Ruby 1.8 whitespace is considered to be <tt>\s</tt> together with the ideographic space U+3000.
88
+
87
89
  WARNING: Note that numbers are not mentioned, in particular 0 and 0.0 are *not* blank.
88
90
 
89
91
  For example, this method from +ActionDispatch::Session::AbstractStore+ uses +blank?+ for checking whether a session key is present:
@@ -438,14 +440,16 @@ NOTE: Defined in +active_support/core_ext/kernel/reporting.rb+.
438
440
 
439
441
  h4. +in?+
440
442
 
441
- The predicate +in?+ tests if an object is included in another object. An +ArgumentError+ exception will be raised if the argument passed does not respond to +include?+.
443
+ The predicate +in?+ tests if an object is included in another object or a list of objects. An +ArgumentError+ exception will be raised if a single argument is passed and it does not respond to +include?+.
442
444
 
443
445
  Examples of +in?+:
444
446
 
445
447
  <ruby>
448
+ 1.in?(1,2) # => true
446
449
  1.in?([1,2]) # => true
447
450
  "lo".in?("hello") # => true
448
451
  25.in?(30..50) # => false
452
+ 1.in?(1) # => ArgumentError
449
453
  </ruby>
450
454
 
451
455
  NOTE: Defined in +active_support/core_ext/object/inclusion.rb+.
@@ -569,7 +573,7 @@ NOTE: Defined in +active_support/core_ext/module/attr_accessor_with_default.rb+.
569
573
 
570
574
  h5. Internal Attributes
571
575
 
572
- When you are defining an attribute in a class that is meant to be subclassed name collisions are a risk. That's remarkably important for libraries.
576
+ When you are defining an attribute in a class that is meant to be subclassed, name collisions are a risk. That's remarkably important for libraries.
573
577
 
574
578
  Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby built-in +attr_*+ counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
575
579
 
@@ -717,12 +721,70 @@ X.local_constants # => ["X2", "X1", "Y"], assumes Ruby 1.8
717
721
  X::Y.local_constants # => ["X1", "Y1"], assumes Ruby 1.8
718
722
  </ruby>
719
723
 
720
- The names are returned as strings in Ruby 1.8, and as symbols in Ruby 1.9. The method +local_constant_names+ returns always strings.
724
+ The names are returned as strings in Ruby 1.8, and as symbols in Ruby 1.9. The method +local_constant_names+ always returns strings.
721
725
 
722
- WARNING: This method is exact if running under Ruby 1.9. In previous versions it may miss some constants if their value in some ancestor stores the exact same object than in the receiver.
726
+ WARNING: This method returns precise results in Ruby 1.9. In older versions of Ruby, however, it may miss some constants in case the same constant exists in the receiver module as well as in any of its ancestors and both constants point to the same object (objects are compared using +Object#object_id+).
723
727
 
724
728
  NOTE: Defined in +active_support/core_ext/module/introspection.rb+.
725
729
 
730
+ h5. Qualified Constant Names
731
+
732
+ The standard methods +const_defined?+, +const_get+ , and +const_set+ accept
733
+ bare constant names. Active Support extends this API to be able to pass
734
+ relative qualified constant names.
735
+
736
+ The new methods are +qualified_const_defined?+, +qualified_const_get+, and
737
+ +qualified_const_set+. Their arguments are assumed to be qualified constant
738
+ names relative to their receiver:
739
+
740
+ <ruby>
741
+ Object.qualified_const_defined?("Math::PI") # => true
742
+ Object.qualified_const_get("Math::PI") # => 3.141592653589793
743
+ Object.qualified_const_set("Math::Phi", 1.618034) # => 1.618034
744
+ </ruby>
745
+
746
+ Arguments may be bare constant names:
747
+
748
+ <ruby>
749
+ Math.qualified_const_get("E") # => 2.718281828459045
750
+ </ruby>
751
+
752
+ These methods are analogous to their builtin counterparts. In particular,
753
+ +qualified_constant_defined?+ accepts an optional second argument in 1.9
754
+ to be able to say whether you want the predicate to look in the ancestors.
755
+ This flag is taken into account for each constant in the expression while
756
+ walking down the path.
757
+
758
+ For example, given
759
+
760
+ <ruby>
761
+ module M
762
+ X = 1
763
+ end
764
+
765
+ module N
766
+ class C
767
+ include M
768
+ end
769
+ end
770
+ </ruby>
771
+
772
+ +qualified_const_defined?+ behaves this way:
773
+
774
+ <ruby>
775
+ N.qualified_const_defined?("C::X", false) # => false (1.9 only)
776
+ N.qualified_const_defined?("C::X", true) # => true (1.9 only)
777
+ N.qualified_const_defined?("C::X") # => false in 1.8, true in 1.9
778
+ </ruby>
779
+
780
+ As the last example implies, in 1.9 the second argument defaults to true,
781
+ as in +const_defined?+.
782
+
783
+ For coherence with the builtin methods only relative paths are accepted.
784
+ Absolute qualified constant names like +::Math::PI+ raise +NameError+.
785
+
786
+ NOTE: Defined in +active_support/core_ext/module/qualified_const.rb+.
787
+
726
788
  h4. Synchronization
727
789
 
728
790
  The +synchronize+ macro declares a method to be synchronized:
@@ -862,7 +924,9 @@ end
862
924
 
863
925
  It is shorter, and the intention more obvious.
864
926
 
865
- The macro accepts several methods:
927
+ The method must be public in the target.
928
+
929
+ The +delegate+ macro accepts several methods:
866
930
 
867
931
  <ruby>
868
932
  delegate :name, :age, :address, :twitter, :to => :profile
@@ -1237,7 +1301,7 @@ NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
1237
1301
 
1238
1302
  h5. Transformation
1239
1303
 
1240
- As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +donwcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
1304
+ As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +downcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
1241
1305
 
1242
1306
  In the case of in-place transformations like +gsub!+ the receiver itself becomes unsafe.
1243
1307
 
@@ -1422,6 +1486,14 @@ The method +pluralize+ returns the plural of its receiver:
1422
1486
 
1423
1487
  As the previous example shows, Active Support knows some irregular plurals and uncountable nouns. Built-in rules can be extended in +config/initializers/inflections.rb+. That file is generated by the +rails+ command and has instructions in comments.
1424
1488
 
1489
+ +pluralize+ can also take an optional +count+ parameter. If <tt>count == 1</tt> the singular form will be returned. For any other value of +count+ the plural form will be returned:
1490
+
1491
+ <ruby>
1492
+ "dude".pluralize(0) # => "dudes"
1493
+ "dude".pluralize(1) # => "dude"
1494
+ "dude".pluralize(2) # => "dudes"
1495
+ </ruby>
1496
+
1425
1497
  Active Record uses this method to compute the default table name that corresponds to a model:
1426
1498
 
1427
1499
  <ruby>
@@ -1585,7 +1657,7 @@ NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
1585
1657
 
1586
1658
  h5. +demodulize+
1587
1659
 
1588
- Given a string with a qualified constant reference expression, +demodulize+ returns the very constant name, that is, the rightmost part of it:
1660
+ Given a string with a qualified constant name, +demodulize+ returns the very constant name, that is, the rightmost part of it:
1589
1661
 
1590
1662
  <ruby>
1591
1663
  "Product".demodulize # => "Product"
@@ -1608,6 +1680,31 @@ end
1608
1680
 
1609
1681
  NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
1610
1682
 
1683
+ h5. +deconstantize+
1684
+
1685
+ Given a string with a qualified constant reference expression, +deconstantize+ removes the rightmost segment, generally leaving the name of the constant's container:
1686
+
1687
+ <ruby>
1688
+ "Product".deconstantize # => ""
1689
+ "Backoffice::UsersController".deconstantize # => "Backoffice"
1690
+ "Admin::Hotel::ReservationUtils".deconstantize # => "Admin::Hotel"
1691
+ </ruby>
1692
+
1693
+ Active Support for example uses this method in +Module#qualified_const_set+:
1694
+
1695
+ <ruby>
1696
+ def qualified_const_set(path, value)
1697
+ QualifiedConstUtils.raise_if_absolute(path)
1698
+
1699
+ const_name = path.demodulize
1700
+ mod_name = path.deconstantize
1701
+ mod = mod_name.empty? ? self : qualified_const_get(mod_name)
1702
+ mod.const_set(const_name, value)
1703
+ end
1704
+ </ruby>
1705
+
1706
+ NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
1707
+
1611
1708
  h5. +parameterize+
1612
1709
 
1613
1710
  The method +parameterize+ normalizes its receiver in a way that can be used in pretty URLs.
@@ -1956,6 +2053,16 @@ end
1956
2053
 
1957
2054
  NOTE: Defined in +active_support/core_ext/enumerable.rb+.
1958
2055
 
2056
+ h4. +pluck+
2057
+
2058
+ The +pluck+ method collects the value of the passed method for each element and returns the result as an array.
2059
+
2060
+ <ruby>
2061
+ people.pluck(:name) # => [ "David Heinemeier Hansson", "Jamie Heinemeier Hansson" ]
2062
+ </ruby>
2063
+
2064
+ NOTE: Defined in +active_support/core_ext/enumerable.rb+.
2065
+
1959
2066
  h4. +each_with_object+
1960
2067
 
1961
2068
  The +inject+ method offers iteration with an accumulator:
@@ -2944,15 +3051,30 @@ Active Support defines these methods as well for Ruby 1.8.
2944
3051
 
2945
3052
  h6. +beginning_of_week+, +end_of_week+
2946
3053
 
2947
- The methods +beginning_of_week+ and +end_of_week+ return the dates for the beginning and end of week, assuming weeks start on Monday:
3054
+ The methods +beginning_of_week+ and +end_of_week+ return the dates for the
3055
+ beginning and end of the week, respectively. Weeks are assumed to start on
3056
+ Monday, but that can be changed passing an argument.
2948
3057
 
2949
3058
  <ruby>
2950
- d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
2951
- d.beginning_of_week # => Mon, 03 May 2010
2952
- d.end_of_week # => Sun, 09 May 2010
3059
+ d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
3060
+ d.beginning_of_week # => Mon, 03 May 2010
3061
+ d.beginning_of_week(:sunday) # => Sun, 02 May 2010
3062
+ d.end_of_week # => Sun, 09 May 2010
3063
+ d.end_of_week(:sunday) # => Sat, 08 May 2010
2953
3064
  </ruby>
2954
3065
 
2955
- +beginning_of_week+ is aliased to +monday+ and +at_beginning_of_week+. +end_of_week+ is aliased to +sunday+ and +at_end_of_week+.
3066
+ +beginning_of_week+ is aliased to +at_beginning_of_week+ and +end_of_week+ is aliased to +at_end_of_week+.
3067
+
3068
+ h6. +monday+, +sunday+
3069
+
3070
+ The methods +monday+ and +sunday+ return the dates for the beginning and
3071
+ end of the week, respectively. Weeks are assumed to start on Monday.
3072
+
3073
+ <ruby>
3074
+ d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
3075
+ d.monday # => Mon, 03 May 2010
3076
+ d.sunday # => Sun, 09 May 2010
3077
+ </ruby>
2956
3078
 
2957
3079
  h6. +prev_week+, +next_week+
2958
3080
 
@@ -3177,8 +3299,10 @@ The class +DateTime+ is a subclass of +Date+ so by loading +active_support/core_
3177
3299
  <ruby>
3178
3300
  yesterday
3179
3301
  tomorrow
3180
- beginning_of_week (monday, at_beginning_of_week)
3181
- end_on_week (at_end_of_week)
3302
+ beginning_of_week (at_beginning_of_week)
3303
+ end_of_week (at_end_of_week)
3304
+ monday
3305
+ sunday
3182
3306
  weeks_ago
3183
3307
  prev_week
3184
3308
  next_week
@@ -3351,8 +3475,10 @@ ago
3351
3475
  since (in)
3352
3476
  beginning_of_day (midnight, at_midnight, at_beginning_of_day)
3353
3477
  end_of_day
3354
- beginning_of_week (monday, at_beginning_of_week)
3355
- end_on_week (at_end_of_week)
3478
+ beginning_of_week (at_beginning_of_week)
3479
+ end_of_week (at_end_of_week)
3480
+ monday
3481
+ sunday
3356
3482
  weeks_ago
3357
3483
  prev_week
3358
3484
  next_week
@@ -3514,8 +3640,8 @@ h4. +around_[level]+
3514
3640
  Takes two arguments, a +before_message+ and +after_message+ and calls the current level method on the +Logger+ instance, passing in the +before_message+, then the specified message, then the +after_message+:
3515
3641
 
3516
3642
  <ruby>
3517
- logger = Logger.new("log/development.log")
3518
- logger.around_info("before", "after") { |logger| logger.info("during") }
3643
+ logger = Logger.new("log/development.log")
3644
+ logger.around_info("before", "after") { |logger| logger.info("during") }
3519
3645
  </ruby>
3520
3646
 
3521
3647
  h4. +silence+
@@ -3595,8 +3721,3 @@ end
3595
3721
  </ruby>
3596
3722
 
3597
3723
  NOTE: Defined in +active_support/core_ext/load_error.rb+.
3598
-
3599
- h3. Changelog
3600
-
3601
- * August 10, 2010: Starts to take shape, added to the index.
3602
- * April 18, 2009: Initial version by "Xavier Noria":credits.html#fxn
@@ -3,7 +3,7 @@ h2. AJAX on Rails
3
3
  This guide covers the built-in Ajax/JavaScript functionality of Rails (and more); it will enable you to create rich and dynamic AJAX applications with ease! We will cover the following topics:
4
4
 
5
5
  * Quick introduction to AJAX and related technologies
6
- * Handling JavaScript the Rails way: Rails helpers, Prototype and script.aculo.us
6
+ * Unobtrusive JavaScript helpers with drivers for Prototype, jQuery etc
7
7
  * Testing JavaScript functionality
8
8
 
9
9
  endprologue.
@@ -24,20 +24,80 @@ h4. Standard HTML communication vs AJAX
24
24
 
25
25
  How do 'standard' and AJAX requests differ, why does this matter for understanding AJAX on Rails (tie in for *_remote helpers, the next section)
26
26
 
27
+ h3. Built-in Rails Helpers
27
28
 
29
+ Rails 3.1 ships with "jQuery":http://jquery.com as the default JavaScript library. The Gemfile contains <tt>gem 'jquery-rails'</tt> which makes the jQuery files available to the application automatically. This can be accessed as:
28
30
 
31
+ <ruby>
32
+ javascript_include_tag :defaults
33
+ </ruby>
29
34
 
35
+ h4. Examples
30
36
 
37
+ All the remote_method helpers has been removed. To make them working with AJAX, simply pass the <tt>:remote => true</tt> option to the original non-remote method.
31
38
 
32
- h3. Built-in Rails Helpers
39
+ <ruby>
40
+ button_to "New", :action => "new", :form_class => "new-thing"
41
+ </ruby>
42
+
43
+ will produce
44
+
45
+ <html>
46
+ <form method="post" action="/controller/new" class="new-thing">
47
+ <div><input value="New" type="submit" /></div>
48
+ </form>
49
+ </html>
50
+
51
+ <ruby>
52
+ button_to "Create", :action => "create", :remote => true, :form => { "data-type" => "json" }
53
+ </ruby>
54
+
55
+ will produce
33
56
 
34
- Rails' JavaScript framework of choice is "Prototype":http://www.prototypejs.org. Prototype is a generic-purpose JavaScript framework that aims to ease the development of dynamic web applications by offering DOM manipulation, AJAX and other JavaScript functionality ranging from utility functions to object oriented constructs. It is not specifically written for any language, so Rails provides a set of helpers to enable seamless integration of Prototype with your Rails views.
57
+ <html>
58
+ <form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
59
+ <div><input value="Create" type="submit" /></div>
60
+ </form>
61
+ </html>
35
62
 
36
- To get access to these helpers, all you have to do is to include the prototype framework in your pages - typically in your master layout, application.html.erb - like so:
37
63
  <ruby>
38
- javascript_include_tag 'prototype'
64
+ button_to "Delete Image", { :action => "delete", :id => @image.id },
65
+ :confirm => "Are you sure?", :method => :delete
39
66
  </ruby>
40
67
 
68
+ will produce
69
+
70
+ <html>
71
+ <form method="post" action="/images/delete/1" class="button_to">
72
+ <div>
73
+ <input type="hidden" name="_method" value="delete" />
74
+ <input data-confirm='Are you sure?' value="Delete" type="submit" />
75
+ </div>
76
+ </form>
77
+ </html>
78
+
79
+ <ruby>
80
+ button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
81
+ :method => "delete", :remote => true, :disable_with => 'loading...')
82
+ </ruby>
83
+
84
+ will produce
85
+
86
+ <html>
87
+ <form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
88
+ <div>
89
+ <input name='_method' value='delete' type='hidden' />
90
+ <input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' />
91
+ </div>
92
+ </form>
93
+ </html>
94
+
95
+ You can also choose to use Prototype instead of jQuery and specify the option using +-j+ switch while generating the application.
96
+
97
+ <shell>
98
+ rails new app_name -j prototype
99
+ </shell>
100
+
41
101
  You are ready to add some AJAX love to your Rails app!
42
102
 
43
103
  h4. The Quintessential AJAX Rails Helper: link_to_remote
@@ -59,7 +119,6 @@ link_to_remote "Add to cart",
59
119
  </ruby>
60
120
 
61
121
  * The very first parameter, a string, is the text of the link which appears on the page.
62
-
63
122
  * The second parameter, the +options+ hash is the most interesting part as it has the AJAX specific stuff:
64
123
  ** *:url* This is the only parameter that is always required to generate the simplest remote link (technically speaking, it is not required, you can pass an empty +options+ hash to +link_to_remote+ - but in this case the URL used for the POST request will be equal to your current URL which is probably not your intention). This URL points to your AJAX action handler. The URL is typically specified by Rails REST view helpers, but you can use the +url_for+ format too.
65
124
  ** *:update* Specifying a DOM id of the element we would like to update. The above example demonstrates the simplest way of accomplishing this - however, we are in trouble if the server responds with an error message because that will be injected into the page too! However, Rails has a solution for this situation:
@@ -195,7 +254,6 @@ end
195
254
 
196
255
  What happens here is that by specifying the Content-Type header variable, we instruct the browser to evaluate the text we are sending over (rather than displaying it as plain text, which is the default behavior).
197
256
 
198
-
199
257
  h3. Testing JavaScript
200
258
 
201
259
  JavaScript testing reminds me the definition of the world 'classic' by Mark Twain: "A classic is something that everybody wants to have read and nobody wants to read." It's similar with JavaScript testing: everyone would like to have it, yet it's not done by too much developers as it is tedious, complicated, there is a proliferation of tools and no consensus/accepted best practices, but we will nevertheless take a stab at it:
@@ -106,7 +106,6 @@ routes.rb # NO
106
106
  RAILS_ROOT/config/routes.rb # NO
107
107
  </plain>
108
108
 
109
-
110
109
  h3. Fonts
111
110
 
112
111
  h4. Fixed-width Font
@@ -184,8 +183,3 @@ self.class_eval %{
184
183
  end
185
184
  }
186
185
  </ruby>
187
-
188
- h3. Changelog
189
-
190
- * July 17, 2010: ported from the docrails wiki and revised by "Xavier Noria":credits.html#fxn
191
-
@@ -430,7 +430,7 @@ location ~ ^/assets/ {
430
430
  }
431
431
  </plain>
432
432
 
433
- When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves.
433
+ When files are precompiled, Sprockets also creates a "gzipped":http://en.wikipedia.org/wiki/Gzip (.gz) version of your assets. Web servers are typically configured to use a moderate compression ratio as a compromise, but since precompilation happens once, Sprockets uses the maximum compression ratio, thus reducing the size of the data transfer to the minimum. On the other hand, web servers can be configured to serve compressed content directly from disk, rather than deflating non-compressed files themselves.
434
434
 
435
435
  Nginx is able to do this automatically enabling +gzip_static+:
436
436
 
@@ -481,7 +481,7 @@ h3. Customizing the Pipeline
481
481
 
482
482
  h4. CSS Compression
483
483
 
484
- There is currently one option for compressing CSS, YUI. This Gem extends the CSS syntax and offers minification.
484
+ There is currently one option for compressing CSS, YUI. The "YUI CSS compressor":http://developer.yahoo.com/yui/compressor/css.html provides minification.
485
485
 
486
486
  The following line enables YUI compression, and requires the +yui-compressor+ gem.
487
487
 
@@ -211,7 +211,7 @@ end
211
211
 
212
212
  h4. Choosing Between +belongs_to+ and +has_one+
213
213
 
214
- If you want to set up a 1–1 relationship between two models, you'll need to add +belongs_to+ to one, and +has_one+ to the other. How do you know which is which?
214
+ If you want to set up a one-to-one relationship between two models, you'll need to add +belongs_to+ to one, and +has_one+ to the other. How do you know which is which?
215
215
 
216
216
  The distinction is in where you place the foreign key (it goes on the table for the class declaring the +belongs_to+ association), but you should give some thought to the actual meaning of the data as well. The +has_one+ relationship says that one of something is yours - that is, that something points back to you. For example, it makes more sense to say that a supplier owns an account than that an account owns a supplier. This suggests that the correct relationships are like this:
217
217
 
@@ -566,7 +566,7 @@ The <tt>build_<em>association</em></tt> method returns a new object of the assoc
566
566
 
567
567
  h6(#belongs_to-create_association). <tt>create_<em>association</em>(attributes = {})</tt>
568
568
 
569
- The <tt>create_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through this object's foreign key will be set. In addition, the associated object _will_ be saved (assuming that it passes any validations).
569
+ The <tt>create_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through this object's foreign key will be set, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
570
570
 
571
571
  <ruby>
572
572
  @customer = @order.create_customer(:customer_number => 123,
@@ -576,7 +576,7 @@ The <tt>create_<em>association</em></tt> method returns a new object of the asso
576
576
 
577
577
  h5. Options for +belongs_to+
578
578
 
579
- In many situations, you can use the default behavior of +belongs_to+ without any customization. But despite Rails' emphasis of convention over customization, you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a +belongs_to+ association. For example, an association with several options might look like this:
579
+ While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +belongs_to+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
580
580
 
581
581
  <ruby>
582
582
  class Order < ActiveRecord::Base
@@ -671,7 +671,7 @@ WARNING: You should not specify this option on a +belongs_to+ association that i
671
671
 
672
672
  h6(#belongs_to-foreign_key). +:foreign_key+
673
673
 
674
- By convention, Rails guesses that the column used to hold the foreign key on this model is the name of the association with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
674
+ By convention, Rails assumes that the column used to hold the foreign key on this model is the name of the association with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
675
675
 
676
676
  <ruby>
677
677
  class Order < ActiveRecord::Base
@@ -760,9 +760,9 @@ h6(#belongs_to-validate). +:validate+
760
760
 
761
761
  If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
762
762
 
763
- h5(#belongs_to-how_to_know_whether_theres_an_associated_object). How To Know Whether There's an Associated Object?
763
+ h5(#belongs_to-do_any_associated_objects_exist). Do Any Associated Objects Exist?
764
764
 
765
- To know whether there's and associated object just check <tt><em>association</em>.nil?</tt>:
765
+ You can see if any associated objects exist by using the <tt><em>association</em>.nil?</tt> method:
766
766
 
767
767
  <ruby>
768
768
  if @order.customer.nil?
@@ -834,7 +834,7 @@ The <tt>build_<em>association</em></tt> method returns a new object of the assoc
834
834
 
835
835
  h6(#has_one-create_association). <tt>create_<em>association</em>(attributes = {})</tt>
836
836
 
837
- The <tt>create_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, and the link through its foreign key will be set. In addition, the associated object _will_ be saved (assuming that it passes any validations).
837
+ The <tt>create_<em>association</em></tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be set, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
838
838
 
839
839
  <ruby>
840
840
  @account = @supplier.create_account(:terms => "Net 30")
@@ -842,7 +842,7 @@ The <tt>create_<em>association</em></tt> method returns a new object of the asso
842
842
 
843
843
  h5. Options for +has_one+
844
844
 
845
- In many situations, you can use the default behavior of +has_one+ without any customization. But despite Rails' emphasis of convention over customization, you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a +has_one+ association. For example, an association with several options might look like this:
845
+ While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +has_one+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
846
846
 
847
847
  <ruby>
848
848
  class Supplier < ActiveRecord::Base
@@ -902,7 +902,7 @@ If you set the +:dependent+ option to +:destroy+, then deleting this object will
902
902
 
903
903
  h6(#has_one-foreign_key). +:foreign_key+
904
904
 
905
- By convention, Rails guesses that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
905
+ By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
906
906
 
907
907
  <ruby>
908
908
  class Supplier < ActiveRecord::Base
@@ -954,7 +954,7 @@ The +:order+ option dictates the order in which associated objects will be recei
954
954
 
955
955
  h6(#has_one-primary_key). +:primary_key+
956
956
 
957
- By convention, Rails guesses that the column used to hold the primary key of this model is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
957
+ By convention, Rails assumes that the column used to hold the primary key of this model is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
958
958
 
959
959
  h6(#has_one-readonly). +:readonly+
960
960
 
@@ -980,9 +980,9 @@ h6(#has_one-validate). +:validate+
980
980
 
981
981
  If you set the +:validate+ option to +true+, then associated objects will be validated whenever you save this object. By default, this is +false+: associated objects will not be validated when this object is saved.
982
982
 
983
- h5(#has_one-how_to_know_whether_theres_an_associated_object). How To Know Whether There's an Associated Object?
983
+ h5(#has_one-do_any_associated_objects_exist). Do Any Associated Objects Exist?
984
984
 
985
- To know whether there's and associated object just check <tt><em>association</em>.nil?</tt>:
985
+ You can see if any associated objects exist by using the <tt><em>association</em>.nil?</tt> method:
986
986
 
987
987
  <ruby>
988
988
  if @supplier.account.nil?
@@ -1147,7 +1147,7 @@ The <tt><em>collection</em>.build</tt> method returns one or more new objects of
1147
1147
 
1148
1148
  h6(#has_many-collection-create). <tt><em>collection</em>.create(attributes = {})</tt>
1149
1149
 
1150
- The <tt><em>collection</em>.create</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be created, and the associated object _will_ be saved (assuming that it passes any validations).
1150
+ The <tt><em>collection</em>.create</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be created, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
1151
1151
 
1152
1152
  <ruby>
1153
1153
  @order = @customer.orders.create(:order_date => Time.now,
@@ -1156,7 +1156,7 @@ The <tt><em>collection</em>.create</tt> method returns a new object of the assoc
1156
1156
 
1157
1157
  h5. Options for +has_many+
1158
1158
 
1159
- In many situations, you can use the default behavior for +has_many+ without any customization. But you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a +has_many+ association. For example, an association with several options might look like this:
1159
+ While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +has_many+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
1160
1160
 
1161
1161
  <ruby>
1162
1162
  class Customer < ActiveRecord::Base
@@ -1260,7 +1260,7 @@ Normally Rails automatically generates the proper SQL to fetch the association m
1260
1260
 
1261
1261
  h6(#has_many-foreign_key). +:foreign_key+
1262
1262
 
1263
- By convention, Rails guesses that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
1263
+ By convention, Rails assumes that the column used to hold the foreign key on the other model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
1264
1264
 
1265
1265
  <ruby>
1266
1266
  class Customer < ActiveRecord::Base
@@ -1343,7 +1343,7 @@ end
1343
1343
 
1344
1344
  h6(#has_many-primary_key). +:primary_key+
1345
1345
 
1346
- By convention, Rails guesses that the column used to hold the primary key of the association is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
1346
+ By convention, Rails assumes that the column used to hold the primary key of the association is +id+. You can override this and explicitly specify the primary key with the +:primary_key+ option.
1347
1347
 
1348
1348
  h6(#has_many-readonly). +:readonly+
1349
1349
 
@@ -1549,7 +1549,7 @@ The <tt><em>collection</em>.find</tt> method finds objects within the collection
1549
1549
  :conditions => ["created_at > ?", 2.days.ago])
1550
1550
  </ruby>
1551
1551
 
1552
- NOTE: Starting Rails 3, supplying options to +ActiveRecord::Base.find+ method is discouraged. Use <tt><em>collection</em>.where</tt> instead when you need to pass conditions.
1552
+ NOTE: Beginning with Rails 3, supplying options to the +ActiveRecord::Base.find+ method is discouraged. Use <tt><em>collection</em>.where</tt> instead when you need to pass conditions.
1553
1553
 
1554
1554
  h6(#has_and_belongs_to_many-collection-where). <tt><em>collection</em>.where(...)</tt>
1555
1555
 
@@ -1574,7 +1574,7 @@ The <tt><em>collection</em>.build</tt> method returns a new object of the associ
1574
1574
 
1575
1575
  h6(#has_and_belongs_to_many-create-attributes). <tt><em>collection</em>.create(attributes = {})</tt>
1576
1576
 
1577
- The <tt><em>collection</em>.create</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through the join table will be created, and the associated object _will_ be saved (assuming that it passes any validations).
1577
+ The <tt><em>collection</em>.create</tt> method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through the join table will be created, and, once it passes all of the validations specified on the associated model, the associated object _will_ be saved.
1578
1578
 
1579
1579
  <ruby>
1580
1580
  @assembly = @part.assemblies.create(
@@ -1583,7 +1583,7 @@ The <tt><em>collection</em>.create</tt> method returns a new object of the assoc
1583
1583
 
1584
1584
  h5. Options for +has_and_belongs_to_many+
1585
1585
 
1586
- In many situations, you can use the default behavior for +has_and_belongs_to_many+ without any customization. But you can alter that behavior in a number of ways. This section covers the options that you can pass when you create a +has_and_belongs_to_many+ association. For example, an association with several options might look like this:
1586
+ While Rails uses intelligent defaults that will work well in most situations, there may be times when you want to customize the behavior of the +has_and_belongs_to_many+ association reference. Such customizations can easily be accomplished by passing options when you create the association. For example, this assocation uses two such options:
1587
1587
 
1588
1588
  <ruby>
1589
1589
  class Parts < ActiveRecord::Base
@@ -1617,7 +1617,7 @@ The +has_and_belongs_to_many+ association supports these options:
1617
1617
 
1618
1618
  h6(#has_and_belongs_to_many-association_foreign_key). +:association_foreign_key+
1619
1619
 
1620
- By convention, Rails guesses that the column in the join table used to hold the foreign key pointing to the other model is the name of that model with the suffix +_id+ added. The +:association_foreign_key+ option lets you set the name of the foreign key directly:
1620
+ By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to the other model is the name of that model with the suffix +_id+ added. The +:association_foreign_key+ option lets you set the name of the foreign key directly:
1621
1621
 
1622
1622
  TIP: The +:foreign_key+ and +:association_foreign_key+ options are useful when setting up a many-to-many self-join. For example:
1623
1623
 
@@ -1685,7 +1685,7 @@ Normally Rails automatically generates the proper SQL to fetch the association m
1685
1685
 
1686
1686
  h6(#has_and_belongs_to_many-foreign_key). +:foreign_key+
1687
1687
 
1688
- By convention, Rails guesses that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
1688
+ By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix +_id+ added. The +:foreign_key+ option lets you set the name of the foreign key directly:
1689
1689
 
1690
1690
  <ruby>
1691
1691
  class User < ActiveRecord::Base
@@ -1853,17 +1853,8 @@ class Customer < ActiveRecord::Base
1853
1853
  end
1854
1854
  </ruby>
1855
1855
 
1856
- Extensions can refer to the internals of the association proxy using these three accessors:
1856
+ Extensions can refer to the internals of the association proxy using these three attributes of the +proxy_association+ accessor:
1857
1857
 
1858
- * +proxy_owner+ returns the object that the association is a part of.
1859
- * +proxy_reflection+ returns the reflection object that describes the association.
1860
- * +proxy_target+ returns the associated object for +belongs_to+ or +has_one+, or the collection of associated objects for +has_many+ or +has_and_belongs_to_many+.
1861
-
1862
- h3. Changelog
1863
-
1864
- * April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
1865
- * April 19, 2009: Added +:touch+ option to +belongs_to+ associations by "Mike Gunderloy":credits.html#mgunderloy
1866
- * February 1, 2009: Added +:autosave+ option "Mike Gunderloy":credits.html#mgunderloy
1867
- * September 28, 2008: Corrected +has_many :through+ diagram, added polymorphic diagram, some reorganization by "Mike Gunderloy":credits.html#mgunderloy . First release version.
1868
- * September 22, 2008: Added diagrams, misc. cleanup by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication)
1869
- * September 14, 2008: initial version by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication)
1858
+ * +proxy_association.owner+ returns the object that the association is a part of.
1859
+ * +proxy_association.reflection+ returns the reflection object that describes the association.
1860
+ * +proxy_association.target+ returns the associated object for +belongs_to+ or +has_one+, or the collection of associated objects for +has_many+ or +has_and_belongs_to_many+.