railties 3.0.20 → 3.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/CHANGELOG +36 -49
  2. data/README.rdoc +2 -1
  3. data/guides/assets/stylesheets/fixes.css +16 -0
  4. data/guides/rails_guides.rb +2 -2
  5. data/guides/rails_guides/generator.rb +8 -3
  6. data/guides/rails_guides/textile_extensions.rb +4 -2
  7. data/guides/source/2_2_release_notes.textile +3 -3
  8. data/guides/source/2_3_release_notes.textile +2 -2
  9. data/guides/source/3_0_release_notes.textile +14 -14
  10. data/guides/source/action_controller_overview.textile +54 -79
  11. data/guides/source/action_mailer_basics.textile +39 -9
  12. data/guides/source/action_view_overview.textile +257 -211
  13. data/guides/source/active_record_basics.textile +1 -1
  14. data/guides/source/active_record_querying.textile +217 -27
  15. data/guides/source/active_record_validations_callbacks.textile +94 -25
  16. data/guides/source/active_support_core_extensions.textile +109 -77
  17. data/guides/source/ajax_on_rails.textile +15 -150
  18. data/guides/source/api_documentation_guidelines.textile +12 -12
  19. data/guides/source/association_basics.textile +74 -60
  20. data/guides/source/caching_with_rails.textile +59 -60
  21. data/guides/source/command_line.textile +46 -47
  22. data/guides/source/configuring.textile +55 -37
  23. data/guides/source/contribute.textile +7 -7
  24. data/guides/source/contributing_to_ruby_on_rails.textile +14 -23
  25. data/guides/source/credits.html.erb +3 -3
  26. data/guides/source/debugging_rails_applications.textile +59 -46
  27. data/guides/source/form_helpers.textile +76 -31
  28. data/guides/source/generators.textile +39 -40
  29. data/guides/source/getting_started.textile +73 -94
  30. data/guides/source/i18n.textile +64 -58
  31. data/guides/source/index.html.erb +3 -3
  32. data/guides/source/initialization.textile +634 -3284
  33. data/guides/source/layout.html.erb +6 -7
  34. data/guides/source/layouts_and_rendering.textile +59 -60
  35. data/guides/source/migrations.textile +63 -59
  36. data/guides/source/nested_model_forms.textile +2 -2
  37. data/guides/source/performance_testing.textile +16 -16
  38. data/guides/source/plugins.textile +236 -1280
  39. data/guides/source/rails_application_templates.textile +37 -29
  40. data/guides/source/rails_on_rack.textile +4 -9
  41. data/guides/source/routing.textile +96 -75
  42. data/guides/source/ruby_on_rails_guides_guidelines.textile +19 -12
  43. data/guides/source/security.textile +57 -30
  44. data/guides/source/testing.textile +26 -24
  45. data/guides/w3c_validator.rb +2 -2
  46. data/lib/rails.rb +1 -7
  47. data/lib/rails/application.rb +46 -76
  48. data/lib/rails/application/bootstrap.rb +6 -11
  49. data/lib/rails/application/configuration.rb +43 -40
  50. data/lib/rails/application/finisher.rb +16 -4
  51. data/lib/rails/application/railties.rb +6 -24
  52. data/lib/rails/application/routes_reloader.rb +45 -0
  53. data/lib/rails/backtrace_cleaner.rb +1 -1
  54. data/lib/rails/cli.rb +7 -5
  55. data/lib/rails/commands.rb +27 -2
  56. data/lib/rails/commands/application.rb +14 -1
  57. data/lib/rails/commands/benchmarker.rb +3 -1
  58. data/lib/rails/commands/dbconsole.rb +2 -2
  59. data/lib/rails/commands/destroy.rb +3 -1
  60. data/lib/rails/commands/generate.rb +3 -1
  61. data/lib/rails/commands/plugin.rb +2 -7
  62. data/lib/rails/commands/plugin_new.rb +10 -0
  63. data/lib/rails/commands/profiler.rb +3 -1
  64. data/lib/rails/commands/server.rb +4 -0
  65. data/lib/rails/configuration.rb +8 -81
  66. data/lib/rails/console/app.rb +2 -2
  67. data/lib/rails/engine.rb +460 -78
  68. data/lib/rails/engine/configuration.rb +46 -49
  69. data/lib/rails/engine/railties.rb +33 -0
  70. data/lib/rails/generators.rb +11 -5
  71. data/lib/rails/generators/actions.rb +2 -27
  72. data/lib/rails/generators/app_base.rb +216 -0
  73. data/lib/rails/generators/base.rb +3 -2
  74. data/lib/rails/generators/erb/scaffold/templates/index.html.erb +1 -1
  75. data/lib/rails/generators/generated_attribute.rb +2 -1
  76. data/lib/rails/generators/migration.rb +6 -2
  77. data/lib/rails/generators/named_base.rb +79 -3
  78. data/lib/rails/generators/rails/app/app_generator.rb +44 -209
  79. data/lib/rails/generators/rails/app/templates/Gemfile +15 -31
  80. data/lib/rails/generators/rails/app/templates/README +2 -2
  81. data/lib/rails/generators/rails/app/templates/Rakefile +1 -1
  82. data/lib/rails/generators/rails/app/templates/{public → app/assets}/images/rails.png +0 -0
  83. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +8 -0
  84. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +5 -0
  85. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  86. data/lib/rails/generators/rails/app/templates/app/models/.empty_directory +0 -0
  87. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +4 -4
  88. data/lib/rails/generators/rails/app/templates/config/application.rb +19 -3
  89. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +4 -4
  90. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +11 -6
  91. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +3 -3
  92. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
  93. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +1 -2
  94. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +14 -11
  95. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -1
  96. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +1 -1
  97. data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +12 -0
  98. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
  99. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  100. data/lib/rails/generators/rails/app/templates/db/{seeds.rb → seeds.rb.tt} +2 -2
  101. data/lib/rails/generators/rails/app/templates/public/index.html +10 -8
  102. data/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
  103. data/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
  104. data/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +0 -0
  105. data/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +0 -0
  106. data/lib/rails/generators/rails/app/templates/test/{test_helper.rb.tt → test_helper.rb} +0 -0
  107. data/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +0 -0
  108. data/lib/rails/generators/rails/assets/USAGE +20 -0
  109. data/lib/rails/generators/rails/assets/assets_generator.rb +39 -0
  110. data/lib/rails/generators/rails/assets/templates/javascript.js +2 -0
  111. data/lib/rails/generators/rails/assets/templates/javascript.js.coffee +3 -0
  112. data/lib/rails/generators/rails/assets/templates/stylesheet.css +4 -0
  113. data/lib/rails/generators/rails/assets/templates/stylesheet.css.scss +5 -0
  114. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  115. data/lib/rails/generators/rails/controller/templates/controller.rb +2 -0
  116. data/lib/rails/generators/rails/generator/generator_generator.rb +2 -2
  117. data/lib/rails/generators/rails/generator/templates/templates/.empty_directory +0 -0
  118. data/lib/rails/generators/rails/helper/templates/helper.rb +2 -0
  119. data/lib/rails/generators/rails/plugin/plugin_generator.rb +7 -0
  120. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +4 -4
  121. data/lib/rails/generators/rails/plugin_new/USAGE +10 -0
  122. data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +303 -0
  123. data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +9 -0
  124. data/lib/rails/generators/rails/plugin_new/templates/Gemfile +11 -0
  125. data/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE +20 -0
  126. data/lib/rails/generators/rails/plugin_new/templates/README.rdoc +3 -0
  127. data/lib/rails/generators/rails/plugin_new/templates/Rakefile +21 -0
  128. data/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt +4 -0
  129. data/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt +4 -0
  130. data/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +0 -0
  131. data/lib/rails/generators/rails/plugin_new/templates/config/routes.rb +6 -0
  132. data/lib/rails/generators/rails/plugin_new/templates/gitignore +6 -0
  133. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb +6 -0
  134. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +7 -0
  135. data/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake +4 -0
  136. data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +16 -0
  137. data/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb +10 -0
  138. data/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb +4 -0
  139. data/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +5 -0
  140. data/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb +7 -0
  141. data/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb +12 -0
  142. data/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb +10 -0
  143. data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
  144. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +20 -1
  145. data/lib/rails/generators/rails/{stylesheets → scaffold}/templates/scaffold.css +0 -0
  146. data/lib/rails/generators/rails/scaffold/templates/scaffold.css.scss +58 -0
  147. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +21 -19
  148. data/lib/rails/generators/resource_helpers.rb +3 -3
  149. data/lib/rails/generators/test_case.rb +2 -20
  150. data/lib/rails/generators/test_unit/controller/templates/functional_test.rb +5 -4
  151. data/lib/rails/generators/test_unit/helper/templates/helper_test.rb +2 -0
  152. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +3 -4
  153. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb +5 -4
  154. data/lib/rails/generators/test_unit/model/templates/fixtures.yml +1 -1
  155. data/lib/rails/generators/test_unit/model/templates/unit_test.rb +5 -4
  156. data/lib/rails/generators/test_unit/observer/templates/unit_test.rb +5 -4
  157. data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +3 -4
  158. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +7 -5
  159. data/lib/rails/info.rb +0 -1
  160. data/lib/rails/paths.rb +119 -65
  161. data/lib/rails/plugin.rb +18 -19
  162. data/lib/rails/rack/log_tailer.rb +1 -1
  163. data/lib/rails/railtie.rb +50 -47
  164. data/lib/rails/railtie/configurable.rb +20 -10
  165. data/lib/rails/railtie/configuration.rb +20 -19
  166. data/lib/rails/source_annotation_extractor.rb +5 -5
  167. data/lib/rails/tasks.rb +1 -0
  168. data/lib/rails/tasks/assets.rake +10 -0
  169. data/lib/rails/tasks/documentation.rake +2 -8
  170. data/lib/rails/tasks/engine.rake +69 -0
  171. data/lib/rails/tasks/framework.rake +4 -21
  172. data/lib/rails/tasks/misc.rake +1 -1
  173. data/lib/rails/tasks/routes.rake +2 -1
  174. data/lib/rails/test_help.rb +17 -1
  175. data/lib/rails/test_unit/railtie.rb +1 -1
  176. data/lib/rails/test_unit/testing.rake +8 -3
  177. data/lib/rails/version.rb +3 -3
  178. metadata +128 -100
  179. checksums.yaml +0 -7
  180. data/lib/rails/application/configurable.rb +0 -19
  181. data/lib/rails/console/sandbox.rb +0 -6
  182. data/lib/rails/deprecation.rb +0 -41
  183. data/lib/rails/engine/configurable.rb +0 -25
  184. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +0 -62
  185. data/lib/rails/generators/rails/app/templates/public/javascripts/application.js +0 -2
  186. data/lib/rails/generators/rails/app/templates/public/javascripts/controls.js +0 -965
  187. data/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js +0 -974
  188. data/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +0 -1123
  189. data/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +0 -6001
  190. data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +0 -202
  191. data/lib/rails/generators/rails/stylesheets/USAGE +0 -5
  192. data/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb +0 -9
  193. data/lib/rails/info_routes.rb +0 -3
@@ -20,7 +20,7 @@ Thus, after a simple require like:
20
20
  require 'active_support'
21
21
  </ruby>
22
22
 
23
- objects do not even respond to +blank?+, let's see how to load its definition.
23
+ objects do not even respond to +blank?+. Let's see how to load its definition.
24
24
 
25
25
  h5. Cherry-picking a Definition
26
26
 
@@ -42,7 +42,7 @@ h5. Loading Grouped Core Extensions
42
42
 
43
43
  The next level is to simply load all extensions to +Object+. As a rule of thumb, extensions to +SomeClass+ are available in one shot by loading +active_support/core_ext/some_class+.
44
44
 
45
- Thus, if that would do, to have +blank?+ available we could just load all extensions to +Object+:
45
+ Thus, to load all extensions to +Object+ (including +blank?+):
46
46
 
47
47
  <ruby>
48
48
  require 'active_support/core_ext/object'
@@ -167,6 +167,12 @@ def log_info(sql, name, ms)
167
167
  end
168
168
  </ruby>
169
169
 
170
+ +try+ can also be called without arguments but a block, which will only be executed if the object is not nil:
171
+
172
+ <ruby>
173
+ @person.try { |p| "#{p.first_name} #{p.last_name}" }
174
+ </ruby>
175
+
170
176
  NOTE: Defined in +active_support/core_ext/object/try.rb+.
171
177
 
172
178
  h4. +singleton_class+
@@ -395,39 +401,6 @@ C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
395
401
 
396
402
  NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
397
403
 
398
- h5. +copy_instance_variables_from(object, exclude = [])+
399
-
400
- Copies the instance variables of +object+ into +self+.
401
-
402
- Instance variable names in the +exclude+ array are ignored. If +object+
403
- responds to +protected_instance_variables+ the ones returned are
404
- also ignored. For example, Rails controllers implement that method.
405
-
406
- In both arrays strings and symbols are understood, and they have to include
407
- the at sign.
408
-
409
- <ruby>
410
- class C
411
- def initialize(x, y, z)
412
- @x, @y, @z = x, y, z
413
- end
414
-
415
- def protected_instance_variables
416
- %w(@z)
417
- end
418
- end
419
-
420
- a = C.new(0, 1, 2)
421
- b = C.new(3, 4, 5)
422
-
423
- a.copy_instance_variables_from(b, [:@y])
424
- # a is now: @x = 3, @y = 1, @z = 2
425
- </ruby>
426
-
427
- In the example +object+ and +self+ are of the same type, but they don't need to.
428
-
429
- NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
430
-
431
404
  h4. Silencing Warnings, Streams, and Exceptions
432
405
 
433
406
  The methods +silence_warnings+ and +enable_warnings+ change the value of +$VERBOSE+ accordingly for the duration of their block, and reset it afterwards:
@@ -459,7 +432,7 @@ h4. +require_library_or_gem+
459
432
 
460
433
  The convenience method +require_library_or_gem+ tries to load its argument with a regular +require+ first. If it fails loads +rubygems+ and tries again.
461
434
 
462
- If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. On the other hand, if +rubygems+ is available but the argument is not loadable as a gem, the method gives up and +LoadError+ is also raised.
435
+ If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. A +LoadError+ is also raised if +rubygems+ is available but the argument is not loadable as a gem.
463
436
 
464
437
  For example, that's the way the MySQL adapter loads the MySQL library:
465
438
 
@@ -469,6 +442,20 @@ require_library_or_gem('mysql')
469
442
 
470
443
  NOTE: Defined in +active_support/core_ext/kernel/requires.rb+.
471
444
 
445
+ h4. +in?+
446
+
447
+ 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?+.
448
+
449
+ Examples of +in?+:
450
+
451
+ <ruby>
452
+ 1.in?([1,2]) # => true
453
+ "lo".in?("hello") # => true
454
+ 25.in?(30..50) # => false
455
+ </ruby>
456
+
457
+ NOTE: Defined in +active_support/core_ext/object/inclusion.rb+.
458
+
472
459
  h3. Extensions to +Module+
473
460
 
474
461
  h4. +alias_method_chain+
@@ -525,12 +512,12 @@ h4. Attributes
525
512
 
526
513
  h5. +alias_attribute+
527
514
 
528
- Model attributes have a reader, a writer, and a predicate. You can aliase a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (my mnemonic is they go in the same order as if you did an assignment):
515
+ Model attributes have a reader, a writer, and a predicate. You can alias a model attribute having the corresponding three methods defined for you in one shot. As in other aliasing methods, the new name is the first argument, and the old name is the second (my mnemonic is they go in the same order as if you did an assignment):
529
516
 
530
517
  <ruby>
531
518
  class User < ActiveRecord::Base
532
519
  # let me refer to the email column as "login",
533
- # much meaningful for authentication code
520
+ # possibly meaningful for authentication code
534
521
  alias_attribute :login, :email
535
522
  end
536
523
  </ruby>
@@ -554,9 +541,9 @@ The default value can be also specified with a block, which is called in the con
554
541
  <ruby>
555
542
  class User
556
543
  attr_accessor :name, :surname
557
- attr_accessor_with_default(:full_name) {
558
- [name, surname].compact.join(" ")
559
- }
544
+ attr_accessor_with_default(:full_name) do
545
+ [name, surname].compact.join(" ")
546
+ end
560
547
  end
561
548
 
562
549
  u = User.new
@@ -590,7 +577,7 @@ h5. Internal Attributes
590
577
 
591
578
  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.
592
579
 
593
- Active Support defines the macros +attr_internal_reader+, +attr_internal_writer+, and +attr_internal_accessor+. They behave like their Ruby builtin +attr_*+ counterparts, except they name the underlying instance variable in a way that makes collisions less likely.
580
+ 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.
594
581
 
595
582
  The macro +attr_internal+ is a synonym for +attr_internal_accessor+:
596
583
 
@@ -1018,7 +1005,7 @@ a2.x # => 2, overridden in a2
1018
1005
  The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to false, as in
1019
1006
 
1020
1007
  <ruby>
1021
- module AcitveRecord
1008
+ module ActiveRecord
1022
1009
  class Base
1023
1010
  class_attribute :table_name_prefix, :instance_writer => false
1024
1011
  self.table_name_prefix = ""
@@ -1028,7 +1015,7 @@ end
1028
1015
 
1029
1016
  A model may find that option useful as a way to prevent mass-assignment from setting the attribute.
1030
1017
 
1031
- For convenience +class_attribute+ defines also an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+.
1018
+ For convenience +class_attribute+ also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+.
1032
1019
 
1033
1020
  NOTE: Defined in +active_support/core_ext/class/attribute.rb+
1034
1021
 
@@ -1072,6 +1059,8 @@ NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
1072
1059
 
1073
1060
  h4. Class Inheritable Attributes
1074
1061
 
1062
+ WARNING: Class Inheritable Attributes are deprecated. It's recommended that you use +Class#class_attribute+ instead.
1063
+
1075
1064
  Class variables are shared down the inheritance tree. Class instance variables are not shared, but they are not inherited either. The macros +class_inheritable_reader+, +class_inheritable_writer+, and +class_inheritable_accessor+ provide accessors for class-level data which is inherited but not shared with children:
1076
1065
 
1077
1066
  <ruby>
@@ -1234,7 +1223,7 @@ NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
1234
1223
 
1235
1224
  h4. +squish+
1236
1225
 
1237
- The method +String#squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
1226
+ The method +squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
1238
1227
 
1239
1228
  <ruby>
1240
1229
  " \n foo\n\r \t bar \n".squish # => "foo bar"
@@ -1277,6 +1266,15 @@ WARNING: The option +:separator+ can't be a regexp.
1277
1266
 
1278
1267
  NOTE: Defined in +active_support/core_ext/string/filters.rb+.
1279
1268
 
1269
+ h4. +inquiry+
1270
+
1271
+ The <tt>inquiry</tt> method converts a string into a +StringInquirer+ object making equality checks prettier.
1272
+
1273
+ <ruby>
1274
+ "production".inquiry.production? # => true
1275
+ "active".inquiry.inactive? # => false
1276
+ </ruby>
1277
+
1280
1278
  h4. Key-based Interpolation
1281
1279
 
1282
1280
  In Ruby 1.9 the <tt>%</tt> string operator supports key-based interpolation, both formatted and unformatted:
@@ -1291,7 +1289,7 @@ Active Support adds that functionality to <tt>%</tt> in previous versions of Rub
1291
1289
 
1292
1290
  NOTE: Defined in +active_support/core_ext/string/interpolation.rb+.
1293
1291
 
1294
- h4. +starts_with?+ and +ends_width?+
1292
+ h4. +starts_with?+ and +ends_with?+
1295
1293
 
1296
1294
  Active Support defines 3rd person aliases of +String#start_with?+ and +String#end_with?+:
1297
1295
 
@@ -1595,7 +1593,7 @@ The method +tableize+ is +underscore+ followed by +pluralize+.
1595
1593
  "InvoiceLine".tableize # => "invoice_lines"
1596
1594
  </ruby>
1597
1595
 
1598
- As a rule of thumb, +tableize+ returns the table name that corresponds to a given model for simple cases. The actual implementation in Active Record is not straight +tableize+ indeed, because it also demodulizes de class name and checks a few options that may affect the returned string.
1596
+ As a rule of thumb, +tableize+ returns the table name that corresponds to a given model for simple cases. The actual implementation in Active Record is not straight +tableize+ indeed, because it also demodulizes the class name and checks a few options that may affect the returned string.
1599
1597
 
1600
1598
  NOTE: Defined in +active_support/core_ext/string/inflections.rb+.
1601
1599
 
@@ -1843,7 +1841,7 @@ h3. Extensions to +Float+
1843
1841
 
1844
1842
  h4. +round+
1845
1843
 
1846
- The built-in method +Float#round+ rounds a float to the nearest integer. Active Support adds an optional parameter to let you specify a precision:
1844
+ The built-in method +Float#round+ rounds a float to the nearest integer. In Ruby 1.9 this method takes an optional argument to let you specify a precision. Active Support adds that functionality to +round+ in previous versions of Ruby:
1847
1845
 
1848
1846
  <ruby>
1849
1847
  Math::E.round(4) # => 2.7183
@@ -1895,7 +1893,7 @@ The sum of an empty collection is zero by default, but this is customizable:
1895
1893
  [].sum(1) # => 1
1896
1894
  </ruby>
1897
1895
 
1898
- If a block is given +sum+ becomes an iterator that yields the elements of the collection and sums the returned values:
1896
+ If a block is given, +sum+ becomes an iterator that yields the elements of the collection and sums the returned values:
1899
1897
 
1900
1898
  <ruby>
1901
1899
  (1..5).sum {|n| n * 2 } # => 30
@@ -1923,7 +1921,7 @@ h4. +each_with_object+
1923
1921
  The +inject+ method offers iteration with an accumulator:
1924
1922
 
1925
1923
  <ruby>
1926
- [2, 3, 4].inject(1) {|acc, i| product*i } # => 24
1924
+ [2, 3, 4].inject(1) {|product, i| product*i } # => 24
1927
1925
  </ruby>
1928
1926
 
1929
1927
  The block is expected to return the value for the accumulator in the next iteration, and this makes building mutable objects a bit cumbersome:
@@ -1969,7 +1967,7 @@ The method +many?+ is shorthand for +collection.size > 1+:
1969
1967
  <% end %>
1970
1968
  </erb>
1971
1969
 
1972
- If an optional block is given +many?+ only takes into account those elements that return true:
1970
+ If an optional block is given, +many?+ only takes into account those elements that return true:
1973
1971
 
1974
1972
  <ruby>
1975
1973
  @see_more = videos.many? {|video| video.category == params[:category]}
@@ -1979,7 +1977,7 @@ NOTE: Defined in +active_support/core_ext/enumerable.rb+.
1979
1977
 
1980
1978
  h4. +exclude?+
1981
1979
 
1982
- The predicate +exclude?+ tests whether a given object does *not* belong to the collection. It is the negation of the builtin +include?+:
1980
+ The predicate +exclude?+ tests whether a given object does *not* belong to the collection. It is the negation of the built-in +include?+:
1983
1981
 
1984
1982
  <ruby>
1985
1983
  to_visit << node if visited.exclude?(node)
@@ -1998,16 +1996,21 @@ Active Support augments the API of arrays to ease certain ways of accessing them
1998
1996
  [].to(7) # => []
1999
1997
  </ruby>
2000
1998
 
2001
- Similarly, +from+ returns the tail from the element at the passed index on:
1999
+ Similarly, +from+ returns the tail from the element at the passed index to the end. If the index is greater than the length of the array, it returns an empty array.
2002
2000
 
2003
2001
  <ruby>
2004
2002
  %w(a b c d).from(2) # => %w(c d)
2005
- %w(a b c d).from(10) # => nil
2003
+ %w(a b c d).from(10) # => []
2006
2004
  [].from(0) # => []
2007
2005
  </ruby>
2008
2006
 
2009
2007
  The methods +second+, +third+, +fourth+, and +fifth+ return the corresponding element (+first+ is built-in). Thanks to social wisdom and positive constructiveness all around, +forty_two+ is also available.
2010
2008
 
2009
+ <ruby>
2010
+ %w(a b c d).third # => c
2011
+ %w(a b c d).fifth # => nil
2012
+ </ruby>
2013
+
2011
2014
  NOTE: Defined in +active_support/core_ext/array/access.rb+.
2012
2015
 
2013
2016
  h4. Random Access
@@ -2034,9 +2037,9 @@ User.exists?(:email => params[:email])
2034
2037
 
2035
2038
  That syntactic sugar is used a lot in Rails to avoid positional arguments where there would be too many, offering instead interfaces that emulate named parameters. In particular it is very idiomatic to use a trailing hash for options.
2036
2039
 
2037
- If a method expects a variable number of arguments and uses <tt>*</tt> in its declaration, however, such an options hash ends up being an item of the array of arguments, where kind of loses its role.
2040
+ If a method expects a variable number of arguments and uses <tt>*</tt> in its declaration, however, such an options hash ends up being an item of the array of arguments, where it loses its role.
2038
2041
 
2039
- In those cases, you may give an options hash a distinguished treatment with +extract_options!+. That method checks the type of the last item of an array. If it is a hash it pops it and returns it, otherwise returns an empty hash.
2042
+ In those cases, you may give an options hash a distinguished treatment with +extract_options!+. This method checks the type of the last item of an array. If it is a hash it pops it and returns it, otherwise it returns an empty hash.
2040
2043
 
2041
2044
  Let's see for example the definition of the +caches_action+ controller macro:
2042
2045
 
@@ -2103,7 +2106,7 @@ h5. +to_xml+
2103
2106
  The method +to_xml+ returns a string containing an XML representation of its receiver:
2104
2107
 
2105
2108
  <ruby>
2106
- Contributor.all(:limit => 2, :order => 'rank ASC').to_xml
2109
+ Contributor.limit(2).order(:rank).to_xml
2107
2110
  # =>
2108
2111
  # <?xml version="1.0" encoding="UTF-8"?>
2109
2112
  # <contributors type="array">
@@ -2178,7 +2181,7 @@ The name of children nodes is by default the name of the root node singularized.
2178
2181
  The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You can configure your own builder via the <tt>:builder</tt> option. The method also accepts options like <tt>:dasherize</tt> and friends, they are forwarded to the builder:
2179
2182
 
2180
2183
  <ruby>
2181
- Contributor.all(:limit => 2, :order => 'rank ASC').to_xml(:skip_types => true)
2184
+ Contributor.limit(2).order(:rank).to_xml(:skip_types => true)
2182
2185
  # =>
2183
2186
  # <?xml version="1.0" encoding="UTF-8"?>
2184
2187
  # <contributors>
@@ -2217,7 +2220,7 @@ Array.wrap(0) # => [0]
2217
2220
 
2218
2221
  This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
2219
2222
 
2220
- * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt> moves on to try +to_a+ if the returned value is +nil+, but <tt>Arraw.wrap</tt> returns such a +nil+ right away.
2223
+ * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt> moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns +nil+ right away.
2221
2224
  * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt> raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
2222
2225
  * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
2223
2226
 
@@ -2740,6 +2743,14 @@ WARNING: The original +Range#include?+ is still the one aliased to +Range#===+.
2740
2743
 
2741
2744
  NOTE: Defined in +active_support/core_ext/range/include_range.rb+.
2742
2745
 
2746
+ h4. +cover?+
2747
+
2748
+ Ruby 1.9 provides +cover?+, and Active Support defines it for previous versions as an alias for +include?+.
2749
+
2750
+ The method +include?+ in Ruby 1.9 is different from the one in 1.8 for non-numeric ranges: instead of being based on comparisons between the value and the range's endpoints, it walks the range with +succ+ looking for value. This works better for ranges with holes, but it has different complexity and may not finish in some other cases.
2751
+
2752
+ In Ruby 1.9 the old behavior is still available in the new +cover?+, which Active Support backports for forward compatibility. For example, Rails uses +cover?+ for ranges in +validates_inclusion_of+.
2753
+
2743
2754
  h4. +overlaps?+
2744
2755
 
2745
2756
  The method +Range#overlaps?+ says whether any two given ranges have non-void intersection:
@@ -2867,9 +2878,9 @@ d.end_of_week # => Sun, 09 May 2010
2867
2878
 
2868
2879
  +beginning_of_week+ is aliased to +monday+ and +at_beginning_of_week+. +end_of_week+ is aliased to +sunday+ and +at_end_of_week+.
2869
2880
 
2870
- h6. +next_week+
2881
+ h6. +prev_week+, +next_week+
2871
2882
 
2872
- +next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day in the next week:
2883
+ The method +next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day:
2873
2884
 
2874
2885
  <ruby>
2875
2886
  d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
@@ -2877,6 +2888,14 @@ d.next_week # => Mon, 10 May 2010
2877
2888
  d.next_week(:saturday) # => Sat, 15 May 2010
2878
2889
  </ruby>
2879
2890
 
2891
+ The method +prev_week+ is analogous:
2892
+
2893
+ <ruby>
2894
+ d.prev_week # => Mon, 26 Apr 2010
2895
+ d.prev_week(:saturday) # => Sat, 01 May 2010
2896
+ d.prev_week(:friday) # => Fri, 30 Apr 2010
2897
+ </ruby>
2898
+
2880
2899
  h6. +beginning_of_month+, +end_of_month+
2881
2900
 
2882
2901
  The methods +beginning_of_month+ and +end_of_month+ return the dates for the beginning and end of the month:
@@ -2954,6 +2973,15 @@ Date.new(2010, 4, 30).months_ago(2) # => Sun, 28 Feb 2010
2954
2973
  Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
2955
2974
  </ruby>
2956
2975
 
2976
+ h6. +weeks_ago+
2977
+
2978
+ The method +weeks_ago+ works analogously for weeks:
2979
+
2980
+ <ruby>
2981
+ Date.new(2010, 5, 24).weeks_ago(1) # => Mon, 17 May 2010
2982
+ Date.new(2010, 5, 24).weeks_ago(2) # => Mon, 10 May 2010
2983
+ </ruby>
2984
+
2957
2985
  h6. +advance+
2958
2986
 
2959
2987
  The most generic way to jump to other days is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, and returns a date advanced as much as the present keys indicate:
@@ -3075,6 +3103,8 @@ yesterday
3075
3103
  tomorrow
3076
3104
  beginning_of_week (monday, at_beginning_of_week)
3077
3105
  end_on_week (at_end_of_week)
3106
+ weeks_ago
3107
+ prev_week
3078
3108
  next_week
3079
3109
  months_ago
3080
3110
  months_since
@@ -3228,7 +3258,7 @@ h3. Extensions to +Time+
3228
3258
 
3229
3259
  h4(#time-calculations). Calculations
3230
3260
 
3231
- NOTE: All the following methods are defined in +active_support/core_ext/date_time/calculations.rb+.
3261
+ NOTE: All the following methods are defined in +active_support/core_ext/time/calculations.rb+.
3232
3262
 
3233
3263
  Active Support adds to +Time+ many of the methods available for +DateTime+:
3234
3264
 
@@ -3247,6 +3277,8 @@ beginning_of_day (midnight, at_midnight, at_beginning_of_day)
3247
3277
  end_of_day
3248
3278
  beginning_of_week (monday, at_beginning_of_week)
3249
3279
  end_on_week (at_end_of_week)
3280
+ weeks_ago
3281
+ prev_week
3250
3282
  next_week
3251
3283
  months_ago
3252
3284
  months_since
@@ -3389,11 +3421,11 @@ h4. +silence+
3389
3421
  Silences every log level lesser to the specified one for the duration of the given block. Log level orders are: debug, info, error and fatal.
3390
3422
 
3391
3423
  <ruby>
3392
- logger = Logger.new("log/development.log")
3393
- logger.silence(Logger::INFO) do
3394
- logger.debug("In space, no one can hear you scream.")
3395
- logger.info("Scream all you want, small mailman!")
3396
- end
3424
+ logger = Logger.new("log/development.log")
3425
+ logger.silence(Logger::INFO) do
3426
+ logger.debug("In space, no one can hear you scream.")
3427
+ logger.info("Scream all you want, small mailman!")
3428
+ end
3397
3429
  </ruby>
3398
3430
 
3399
3431
  h4. +datetime_format=+
@@ -3401,17 +3433,17 @@ h4. +datetime_format=+
3401
3433
  Modifies the datetime format output by the formatter class associated with this logger. If the formatter class does not have a +datetime_format+ method then this is ignored.
3402
3434
 
3403
3435
  <ruby>
3404
- class Logger::FormatWithTime < Logger::Formatter
3405
- cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" }
3406
-
3407
- def self.call(severity, timestamp, progname, msg)
3408
- "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n"
3409
- end
3436
+ class Logger::FormatWithTime < Logger::Formatter
3437
+ cattr_accessor(:datetime_format) { "%Y%m%d%H%m%S" }
3438
+
3439
+ def self.call(severity, timestamp, progname, msg)
3440
+ "#{timestamp.strftime(datetime_format)} -- #{String === msg ? msg : msg.inspect}\n"
3410
3441
  end
3411
-
3412
- logger = Logger.new("log/development.log")
3413
- logger.formatter = Logger::FormatWithTime
3414
- logger.info("<- is the current time")
3442
+ end
3443
+
3444
+ logger = Logger.new("log/development.log")
3445
+ logger.formatter = Logger::FormatWithTime
3446
+ logger.info("<- is the current time")
3415
3447
  </ruby>
3416
3448
 
3417
3449
  NOTE: Defined in +active_support/core_ext/logger.rb+.
@@ -1,18 +1,18 @@
1
1
  h2. AJAX on Rails
2
2
 
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:
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, RJS, Prototype and script.aculo.us
7
- * Testing Javascript functionality
6
+ * Handling JavaScript the Rails way: Rails helpers, Prototype and script.aculo.us
7
+ * Testing JavaScript functionality
8
8
 
9
9
  endprologue.
10
10
 
11
11
  h3. Hello AJAX - a Quick Intro
12
12
 
13
- If you are a 'show me the code' type of person, you might want to skip this part and jump to the RJS section right away. However, I would really recommend to read it - you'll need the basics of DOM, http requests and other topics discussed here to really understand Ajax on Rails.
13
+ You'll need the basics of DOM, HTTP requests and other topics discussed here to really understand Ajax on Rails.
14
14
 
15
- h4. Asynchronous Javascript + XML
15
+ h4. Asynchronous JavaScript + XML
16
16
 
17
17
  Basic terminology, new style of creating web apps
18
18
 
@@ -31,7 +31,7 @@ How do 'standard' and AJAX requests differ, why does this matter for understandi
31
31
 
32
32
  h3. Built-in Rails Helpers
33
33
 
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.
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.
35
35
 
36
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
37
  <ruby>
@@ -42,7 +42,7 @@ You are ready to add some AJAX love to your Rails app!
42
42
 
43
43
  h4. The Quintessential AJAX Rails Helper: link_to_remote
44
44
 
45
- Let's start with the the probably most often used helper: +link_to_remote+, which has an interesting feature from the documentation point of view: the options supplied to +link_to_remote+ are shared by all other AJAX helpers, so learning the mechanics and options of +link_to_remote+ is a great help when using other helpers.
45
+ Let's start with what is probably the most often used helper: +link_to_remote+. It has an interesting feature from the documentation point of view: the options supplied to +link_to_remote+ are shared by all other AJAX helpers, so learning the mechanics and options of +link_to_remote+ is a great help when using other helpers.
46
46
 
47
47
  The signature of +link_to_remote+ function is the same as that of the standard +link_to+ helper:
48
48
 
@@ -62,7 +62,7 @@ link_to_remote "Add to cart",
62
62
 
63
63
  * The second parameter, the +options+ hash is the most interesting part as it has the AJAX specific stuff:
64
64
  ** *: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
- ** *:update* There are basically two ways of injecting the server response into the page: One is involving RJS and we will discuss it in the next chapter, and the other is 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:
65
+ ** *: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:
66
66
 
67
67
  <ruby>
68
68
  link_to_remote "Add to cart",
@@ -72,7 +72,7 @@ link_to_remote "Add to cart",
72
72
 
73
73
  If the server returns 200, the output of the above example is equivalent to our first, simple one. However, in case of error, the element with the DOM id +error+ is updated rather than the +cart+ element.
74
74
 
75
- ** *position* By default (i.e. when not specifying this option, like in the examples before) the repsonse is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
75
+ ** *position* By default (i.e. when not specifying this option, like in the examples before) the repsonse is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
76
76
  *** +:before+ Inserts the response text just before the target element. More precisely, it creates a text node from the response and inserts it as the left sibling of the target element.
77
77
  *** +:after+ Similar behavior to +:before+, but in this case the response is inserted after the target element.
78
78
  *** +:top+ Inserts the text into the target element, before it's original content. If the target element was empty, this is equivalent with not specifying +:position+ at all.
@@ -136,7 +136,7 @@ link_to_remote "Add new item",
136
136
  :before => "$('progress').show()",
137
137
  :complete => "$('progress').hide()",
138
138
  :success => "display_item_added(request)",
139
- :failure => "display_error(request)",
139
+ :failure => "display_error(request)"
140
140
  </ruby>
141
141
  ** *:type* If you want to fire a synchronous request for some obscure reason (blocking the browser while the request is processed and doesn't return a status code), you can use the +:type+ option with the value of +:synchronous+.
142
142
  * Finally, using the +html_options+ parameter you can add HTML attributes to the generated tag. It works like the same parameter of the +link_to+ helper. There are interesting side effects for the +href+ and +onclick+ parameters though:
@@ -153,7 +153,7 @@ There are three different ways of adding AJAX forms to your view using Rails Pro
153
153
  * +form_remote_tag+ AJAXifies the form by serializing and sending it's data in the background
154
154
  * +submit_to_remote+ and +button_to_remote+ is more rarely used than the previous two. Rather than creating an AJAX form, you add a button/input
155
155
 
156
- Let's se them in action one by one!
156
+ Let's see them in action one by one!
157
157
 
158
158
  h5. +remote_form_for+
159
159
 
@@ -178,12 +178,7 @@ h5. +remote_function+
178
178
 
179
179
  h5. +update_page+
180
180
 
181
-
182
- h3. JavaScript the Rails way: RJS
183
-
184
- In the last section we sent some AJAX requests to the server, and inserted the HTML response into the page (with the +:update+ option). However, sometimes a more complicated interaction with the page is needed, which you can either achieve with JavaScript... or with RJS! You are sending JavaScript instructions to the server in both cases, but while in the former case you have to write vanilla JavaScript, in the second you can code Rails, and sit back while Rails generates the JavaScript for you - so basically RJS is a Ruby DSL to write JavaScript in your Rails code.
185
-
186
- h4. Javascript without RJS
181
+ h4. Serving JavaScript
187
182
 
188
183
  First we'll check out how to send JavaScript to the server manually. You are practically never going to need this, but it's interesting to understand what's going on under the hood.
189
184
 
@@ -198,140 +193,10 @@ end
198
193
 
199
194
  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).
200
195
 
201
- h4. Inline RJS
202
-
203
- As we said, the purpose of RJS is to write Ruby which is then auto-magically turned into JavaScript by Rails. The above example didn't look too Ruby-esque so let's see how to do it the Rails way:
204
-
205
- <ruby>
206
- def javascript_test
207
- render :update do |page|
208
- page.alert "Hello from inline RJS"
209
- end
210
- end
211
- </ruby>
212
-
213
- The above code snippet does exactly the same as the one in the previous section - going about it much more elegantly though. You don't need to worry about headers,write ugly JavaScript code into a string etc. When the first parameter to +render+ is +:update+, Rails expects a block with a single parameter (+page+ in our case, which is the traditional naming convention) which is an instance of the JavaScriptGenerator:"http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper/JavaScriptGenerator/GeneratorMethods.html" object. As it's name suggests, JavaScriptGenerator is responsible for generating JavaScript from your Ruby code. You can execute multiple method calls on the +page+ instance - it's all turned into JavaScript code and sent to the server with the appropriate Content Type, "text/javascript".
214
-
215
- h4. RJS Templates
216
-
217
- If you don't want to clutter your controllers with view code (especially when your inline RJS is more than a few lines), you can move your RJS code to a template file. RJS templates should go to the +/app/views/+ directory, just as +.html.erb+ or any other view files of the appropriate controller, conventionally named +js.rjs+.
218
-
219
- To rewrite the above example, you can leave the body of the action empty, and create a RJS template named +javascript_test.js.rjs+, containing the following line:
220
-
221
- <ruby>
222
- page.alert "Hello from inline RJS"
223
- </ruby>
224
-
225
- h4. RJS Reference
226
-
227
- In this section we'll go through the methods RJS offers.
228
-
229
- h5. JavaScriptGenerator Methods
230
-
231
- h6. DOM Element Manipulation
232
-
233
- It is possible to manipulate multiple elements at once through the +page+ JavaScriptGenerator instance. Let's see this in action:
234
-
235
- <ruby>
236
- page.show :div_one, :div_two
237
- page.hide :div_one
238
- page.remove :div_one, :div_two, :div_three
239
- page.toggle :other_div
240
- </ruby>
241
-
242
- The above methods (+show+, +hide+, +remove+, +toggle+) have the same semantics as the Prototype methods of the same name. You can pass an arbitrary number (but at least one) of DOM ids to these calls.
243
-
244
-
245
- h6. Inserting and Replacing Content
246
-
247
- You can insert content into an element on the page with the +insert_html+ method:
248
-
249
- <ruby>
250
- page.insert_html :top, :result, '42'
251
- </ruby>
252
-
253
- The first parameter is the position of the new content relative to the element specified by the second parameter, a DOM id.
254
-
255
- Position can be one of these four values:
256
-
257
- *** +:before+ Inserts the response text just before the target element.
258
- *** +:after+ The response is inserted after the target element.
259
- *** +:top+ Inserts the text into the target element, before it's original content.
260
- *** +:bottom+ The counterpart of +:top+: the response is inserted after the target element's original content.
261
-
262
- The third parameter can either be a string, or a hash of options to be passed to ActionView::Base#render - for example:
263
-
264
- <ruby>
265
- page.insert_html :top, :result, :partial => "the_answer"
266
- </ruby>
267
-
268
- You can replace the contents (innerHTML) of an element with the +replace_html+ method. The only difference is that since it's clear where should the new content go, there is no need for a position parameter - so +replace_html+ takes only two arguments,
269
- the DOM id of the element you wish to modify and a string or a hash of options to be passed to ActionView::Base#render.
270
-
271
- h6. Delay
272
-
273
- You can delay the execution of a block of code with +delay+:
274
-
275
- <ruby>
276
- page.delay(10) { page.alert('Hey! Just waited 10 seconds') }
277
- </ruby>
278
-
279
- +delay+ takes one parameter (time to wait in seconds) and a block which will be executed after the specified time has passed - whatever else follows a +page.delay+ line is executed immediately, the delay affects only the code in the block.
280
-
281
- h6. Reloading and Redirecting
282
-
283
- You can reload the page with the +reload+ method:
284
-
285
- <ruby>
286
- page.reload
287
- </ruby>
288
-
289
- When using AJAX, you can't rely on the standard +redirect_to+ controller method - you have to use the +page+'s instance method, also called +redirect_to+:
290
-
291
- <ruby>
292
- page.redirect_to some_url
293
- </ruby>
294
-
295
- h6. Generating Arbitrary JavaScript
296
-
297
- Sometimes even the full power of RJS is not enough to accomplish everything, but you still don't want to drop to pure JavaScript. A nice golden mean is offered by the combination of +<<+, +assign+ and +call+ methods:
298
-
299
- <ruby>
300
- page << "alert('1+1 equals 3')"
301
- </ruby>
302
-
303
- So +<<+ is used to execute an arbitrary JavaScript statement, passed as string to the method. The above code is equivalent to:
304
-
305
- <ruby>
306
- page.assign :result, 3
307
- page.call :alert, '1+1 equals ' + result
308
- </ruby>
309
-
310
- +assign+ simply assigns a value to a variable. +call+ is similar to +<<+ with a slightly different syntax: the first parameter is the name of the function to call, followed by the list of parameters passed to the function.
311
-
312
- h6. Class Proxies
313
-
314
- h5. Element Proxies
315
-
316
- h5. Collection Proxies
317
-
318
- h5. RJS Helpers
319
-
320
-
321
-
322
- h3. I Want my Yellow Thingy: Quick overview of Script.aculo.us
323
-
324
- h4. Introduction
325
-
326
- h4. Visual Effects
327
-
328
- h4. Drag and Drop
329
-
330
-
331
196
 
332
- h3. Testing Javascript
197
+ h3. Testing JavaScript
333
198
 
334
- 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:
199
+ 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:
335
200
 
336
201
  * (Fire)Watir
337
202
  * Selenium
@@ -339,4 +204,4 @@ Javascript testing reminds me the definition of the world 'classic' by Mark Twai
339
204
  * Cucumber+Webrat
340
205
  * Mention stuff like screw.unit/jsSpec
341
206
 
342
- Note to self: check out the RailsConf JS testing video
207
+ Note to self: check out the RailsConf JS testing video