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
@@ -16,7 +16,7 @@ Action View and Action Controller are the two major components of Action Pack. I
16
16
 
17
17
  Action View templates are written using embedded Ruby in tags mingled with HTML. To avoid cluttering the templates with boilerplate code, a number of helper classes provide common behavior for forms, dates, and strings. It's also easy to add new helpers to your application as it evolves.
18
18
 
19
- Note: Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend.
19
+ NOTE. Some features of Action View are tied to Active Record, but that doesn't mean that Action View depends on Active Record. Action View is an independent package that can be used with any sort of backend.
20
20
 
21
21
  h3. Using Action View with Rails
22
22
 
@@ -454,6 +454,83 @@ input("post", "title") # =>
454
454
  <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
455
455
  </ruby>
456
456
 
457
+ h4. RecordTagHelper
458
+
459
+ This module provides methods for generating a container tag, such as a +<div>+, for your record. This is the recommended way of creating a container for render your Active Record object, as it adds an appropriate class and id attributes to that container. You can then refer to those containers easily by following the convention, instead of having to think about which class or id attribute you should use.
460
+
461
+ h5. content_tag_for
462
+
463
+ Renders a container tag that relates to your Active Record Object.
464
+
465
+ For example, given +@post+ is the object of +Post+ class, you can do:
466
+
467
+ <ruby>
468
+ <%= content_tag_for(:tr, @post) do %>
469
+ <td><%= @post.title %></td>
470
+ <% end %>
471
+ </ruby>
472
+
473
+ This will generate this HTML output:
474
+
475
+ <html>
476
+ <tr id="post_1234" class="post">
477
+ <td>Hello World!</td>
478
+ </tr>
479
+ </html>
480
+
481
+ You can also supply HTML attributes as an additional option hash. For example:
482
+
483
+ <ruby>
484
+ <%= content_tag_for(:tr, @post, :class => "frontpage") do %>
485
+ <td><%= @post.title %></td>
486
+ <% end %>
487
+ </ruby>
488
+
489
+ Will generate this HTML output:
490
+
491
+ <html>
492
+ <tr id="post_1234" class="post frontpage">
493
+ <td>Hello World!</td>
494
+ </tr>
495
+ </html>
496
+
497
+ You can pass a collection of Active Record objects. This method will loop through your objects and create a container for each of them. For example, given +@posts+ is an array of two +Post+ objects:
498
+
499
+ <ruby>
500
+ <%= content_tag_for(:tr, @posts) do |post| %>
501
+ <td><%= post.title %></td>
502
+ <% end %>
503
+ </ruby>
504
+
505
+ Will generate this HTML output:
506
+
507
+ <html>
508
+ <tr id="post_1234" class="post">
509
+ <td>Hello World!</td>
510
+ </tr>
511
+ <tr id="post_1235" class="post">
512
+ <td>Ruby on Rails Rocks!</td>
513
+ </tr>
514
+ </html>
515
+
516
+ h5. div_for
517
+
518
+ This is actually a convenient method which calls +content_tag_for+ internally with +:div+ as the tag name. You can pass either an Active Record object or a collection of objects. For example:
519
+
520
+ <ruby>
521
+ <%= div_for(@post, :class => "frontpage") do %>
522
+ <td><%= @post.title %></td>
523
+ <% end %>
524
+ </ruby>
525
+
526
+ Will generate this HTML output:
527
+
528
+ <html>
529
+ <div id="post_1234" class="post frontpage">
530
+ <td>Hello World!</td>
531
+ </div>
532
+ </html>
533
+
457
534
  h4. AssetTagHelper
458
535
 
459
536
  This module provides methods for generating HTML that links views to assets such as images, JavaScript files, stylesheets, and feeds.
@@ -478,7 +555,6 @@ javascript_include_tag :monkey # =>
478
555
  <script type="text/javascript" src="/javascripts/tail.js"></script>
479
556
  </ruby>
480
557
 
481
-
482
558
  h5. register_stylesheet_expansion
483
559
 
484
560
  Register one or more stylesheet files to be included when symbol is passed to +stylesheet_link_tag+. This method is typically intended to be called from plugin initialization to register stylesheet files that the plugin installed in +public/stylesheets+.
@@ -1419,10 +1495,3 @@ end
1419
1495
  Then you could create special views like +app/views/posts/show.expert.html.erb+ that would only be displayed to expert users.
1420
1496
 
1421
1497
  You can read more about the Rails Internationalization (I18n) API "here":i18n.html.
1422
-
1423
- h3. Changelog
1424
-
1425
- * May 29, 2011: Removed references to remote_* helpers - Vijay Dev
1426
- * April 16, 2011: Added 'Using Action View with Rails', 'Templates' and 'Partials' sections. "Sebastian Martinez":http://wyeworks.com
1427
- * September 3, 2009: Continuing work by Trevor Turk, leveraging the Action Pack docs and "What's new in Edge Rails":http://ryandaigle.com/articles/2007/8/3/what-s-new-in-edge-rails-partials-get-layouts
1428
- * April 5, 2009: Starting work by Trevor Turk, leveraging Mike Gunderloy's docs
@@ -0,0 +1,205 @@
1
+ h2. Active Model Basics
2
+
3
+ This guide should provide you with all you need to get started using model classes. Active Model allow for Action Pack helpers to interact with non-ActiveRecord models. Active Model also helps building custom ORMs for use outside of the Rails framework.
4
+
5
+ endprologue.
6
+
7
+ WARNING. This Guide is based on Rails 3.0. Some of the code shown here will not work in earlier versions of Rails.
8
+
9
+ h3. Introduction
10
+
11
+ Active Model is a library containing various modules used in developing frameworks that need to interact with the Rails Action Pack library. Active Model provides a known set of interfaces for usage in classes. Some of modules are explained below -
12
+
13
+ h4. AttributeMethods
14
+
15
+ AttributeMethods module can add custom prefixes and suffixes on methods of a class. It is used by defining the prefixes and suffixes, which methods on the object will use them.
16
+
17
+ <ruby>
18
+ class Person
19
+ include ActiveModel::AttributeMethods
20
+
21
+ attribute_method_prefix 'reset_'
22
+ attribute_method_suffix '_highest?'
23
+ define_attribute_methods ['age']
24
+
25
+ attr_accessor :age
26
+
27
+ private
28
+ def reset_attribute(attribute)
29
+ send("#{attribute}=", 0)
30
+ end
31
+
32
+ def attribute_highest?(attribute)
33
+ send(attribute) > 100 ? true : false
34
+ end
35
+
36
+ end
37
+
38
+ person = Person.new
39
+ person.age = 110
40
+ person.age_highest? # true
41
+ person.reset_age # 0
42
+ person.age_highest? # false
43
+
44
+ </ruby>
45
+
46
+ h4. Callbacks
47
+
48
+ Callbacks gives Active Record style callbacks. This provides the ability to define the callbacks and those will run at appropriate time. After defining a callbacks you can wrap with before, after and around custom methods.
49
+
50
+ <ruby>
51
+ class Person
52
+ extend ActiveModel::Callbacks
53
+
54
+ define_model_callbacks :update
55
+
56
+ before_update :reset_me
57
+
58
+ def update
59
+ _run_update_callbacks do
60
+ # This will call when we are trying to call update on object.
61
+ end
62
+ end
63
+
64
+ def reset_me
65
+ # This method will call when you are calling update on object as a before_update callback as defined.
66
+ end
67
+ end
68
+ </ruby>
69
+
70
+ h4. Conversion
71
+
72
+ If a class defines persisted? and id methods then you can include Conversion module in that class and you can able to call Rails conversion methods to objects of that class.
73
+
74
+ <ruby>
75
+ class Person
76
+ include ActiveModel::Conversion
77
+
78
+ def persisted?
79
+ false
80
+ end
81
+
82
+ def id
83
+ nil
84
+ end
85
+ end
86
+
87
+ person = Person.new
88
+ person.to_model == person #=> true
89
+ person.to_key #=> nil
90
+ person.to_param #=> nil
91
+ </ruby>
92
+
93
+ h4. Dirty
94
+
95
+ An object becomes dirty when an object is gone through one or more changes to its attributes and not yet saved. This gives the ability to check whether an object has been changed or not. It also has attribute based accessor methods. Lets consider a Person class with attributes first_name and last_name
96
+
97
+ <ruby>
98
+ require 'rubygems'
99
+ require 'active_model'
100
+
101
+ class Person
102
+ include ActiveModel::Dirty
103
+ define_attribute_methods [:first_name, :last_name]
104
+
105
+ def first_name
106
+ @first_name
107
+ end
108
+
109
+ def first_name=(value)
110
+ first_name_will_change!
111
+ @first_name = value
112
+ end
113
+
114
+ def last_name
115
+ @last_name
116
+ end
117
+
118
+ def last_name=(value)
119
+ last_name_will_change!
120
+ @last_name = value
121
+ end
122
+
123
+ def save
124
+ @previously_changed = changes
125
+ end
126
+
127
+ end
128
+ </ruby>
129
+
130
+ h5. Querying object directly for its list of all changed attributes.
131
+
132
+ <ruby>
133
+ person = Person.new
134
+ person.first_name = "First Name"
135
+
136
+ person.first_name #=> "First Name"
137
+ person.first_name = "First Name Changed"
138
+
139
+ person.changed? #=> true
140
+
141
+ #returns an list of fields arry which all has been changed before saved.
142
+ person.changed #=> ["first_name"]
143
+
144
+ #returns a hash of the fields that have changed with their original values.
145
+ person.changed_attributes #=> {"first_name" => "First Name Changed"}
146
+
147
+ #returns a hash of changes, with the attribute names as the keys, and the values will be an array of the old and new value for that field.
148
+ person.changes #=> {"first_name" => ["First Name","First Name Changed"]}
149
+ </ruby>
150
+
151
+ h5. Attribute based accessor methods
152
+
153
+ Track whether the particular attribute has been changed or not.
154
+
155
+ <ruby>
156
+ #attr_name_changed?
157
+ person.first_name #=> "First Name"
158
+
159
+ #assign some other value to first_name attribute
160
+ person.first_name = "First Name 1"
161
+
162
+ person.first_name_changed? #=> true
163
+ </ruby>
164
+
165
+ Track what was the previous value of the attribute.
166
+
167
+ <ruby>
168
+ #attr_name_was accessor
169
+ person.first_name_was #=> "First Name"
170
+ </ruby>
171
+
172
+ Track both previous and current value of the changed attribute. Returns an array if changed else returns nil
173
+
174
+ <ruby>
175
+ #attr_name_change
176
+ person.first_name_change #=> ["First Name", "First Name 1"]
177
+ person.last_name_change #=> nil
178
+ </ruby>
179
+
180
+ h4. Validations
181
+
182
+ Validations module adds the ability to class objects to validate them in Active Record style.
183
+
184
+ <ruby>
185
+ class Person
186
+ include ActiveModel::Validations
187
+
188
+ attr_accessor :name, :email, :token
189
+
190
+ validates :name, :presence => true
191
+ validates_format_of :email, :with => /^([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})$/i
192
+ validates! :token, :presence => true
193
+
194
+ end
195
+
196
+ person = Person.new(:token => "2b1f325")
197
+ person.valid? #=> false
198
+ person.name = 'vishnu'
199
+ person.email = 'me'
200
+ person.valid? #=> false
201
+ person.email = 'me@vishnuatrai.com'
202
+ person.valid? #=> true
203
+ person.token = nil
204
+ person.valid? #=> raises ActiveModel::StrictValidationFailed
205
+ </ruby>
@@ -38,47 +38,48 @@ When writing applications using other programming languages or frameworks, it ma
38
38
 
39
39
  h4. Naming Conventions
40
40
 
41
- By default, Active Record uses some naming conventions to find out how the mapping between models and database tables should be created. Rails will pluralize your class names to find the respective database table. So, for a class +Book+, you should have a database table called *books*. The Rails pluralization mechanisms are very powerful, being capable to pluralize (and singularize) both regular and irregular words. When using class names composed of two or more words, the model class name should follow the Ruby conventions, using the camelCase form, while the table name must contain the words separated by underscores. Examples:
41
+ By default, Active Record uses some naming conventions to find out how the mapping between models and database tables should be created. Rails will pluralize your class names to find the respective database table. So, for a class +Book+, you should have a database table called *books*. The Rails pluralization mechanisms are very powerful, being capable to pluralize (and singularize) both regular and irregular words. When using class names composed of two or more words, the model class name should follow the Ruby conventions, using the CamelCase form, while the table name must contain the words separated by underscores. Examples:
42
42
 
43
- * Database Table - Plural with underscores separating words (e.g., book_clubs)
44
- * Model Class - Singular with the first letter of each word capitalized (e.g., BookClub)
43
+ * Database Table - Plural with underscores separating words (e.g., +book_clubs+)
44
+ * Model Class - Singular with the first letter of each word capitalized (e.g., +BookClub+)
45
45
 
46
46
  |_.Model / Class |_.Table / Schema |
47
- |Post |posts|
48
- |LineItem |line_items|
49
- |Deer |deer|
50
- |Mouse |mice|
51
- |Person |people|
47
+ |+Post+ |+posts+|
48
+ |+LineItem+ |+line_items+|
49
+ |+Deer+ |+deer+|
50
+ |+Mouse+ |+mice+|
51
+ |+Person+ |+people+|
52
52
 
53
53
 
54
54
  h4. Schema Conventions
55
55
 
56
56
  Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns.
57
57
 
58
- * *Foreign keys* - These fields should be named following the pattern table_id (e.g., item_id, order_id). These are the fields that Active Record will look for when you create associations between your models.
59
- * *Primary keys* - By default, Active Record will use an integer column named "id" as the table's primary key. When using "Rails Migrations":migrations.html to create your tables, this column will be automatically created.
58
+ * *Foreign keys* - These fields should be named following the pattern +singularized_table_name_id+ (e.g., +item_id+, +order_id+). These are the fields that Active Record will look for when you create associations between your models.
59
+ * *Primary keys* - By default, Active Record will use an integer column named +id+ as the table's primary key. When using "Rails Migrations":migrations.html to create your tables, this column will be automatically created.
60
60
 
61
61
  There are also some optional column names that will create additional features to Active Record instances:
62
62
 
63
- * *created_at* - Automatically gets set to the current date and time when the record is first created.
64
- * *created_on* - Automatically gets set to the current date when the record is first created.
65
- * *updated_at* - Automatically gets set to the current date and time whenever the record is updated.
66
- * *updated_on* - Automatically gets set to the current date whenever the record is updated.
67
- * *lock_version* - Adds "optimistic locking":http://api.rubyonrails.org/classes/ActiveRecord/Locking.html to a model.
68
- * *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.org/classes/ActiveRecord/Base.html
69
- * *(table_name)_count* - Used to cache the number of belonging objects on associations. For example, a +comments_count+ column in a +Post+ class that has many instances of +Comment+ will cache the number of existent comments for each post.
63
+ * +created_at+ - Automatically gets set to the current date and time when the record is first created.
64
+ * +created_on+ - Automatically gets set to the current date when the record is first created.
65
+ * +updated_at+ - Automatically gets set to the current date and time whenever the record is updated.
66
+ * +updated_on+ - Automatically gets set to the current date whenever the record is updated.
67
+ * +lock_version+ - Adds "optimistic locking":http://api.rubyonrails.org/classes/ActiveRecord/Locking.html to a model.
68
+ * +type+ - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.org/classes/ActiveRecord/Base.html
69
+ * +(table_name)_count+ - Used to cache the number of belonging objects on associations. For example, a +comments_count+ column in a +Post+ class that has many instances of +Comment+ will cache the number of existent comments for each post.
70
70
 
71
- NOTE: While these column names are optional they are in fact reserved by Active Record. Steer clear of reserved keywords unless you want the extra functionality. For example, "type" is a reserved keyword used to designate a table using Single Table Inheritance. If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
71
+ NOTE: While these column names are optional, they are in fact reserved by Active Record. Steer clear of reserved keywords unless you want the extra functionality. For example, +type+ is a reserved keyword used to designate a table using Single Table Inheritance (STI). If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
72
72
 
73
73
  h3. Creating Active Record Models
74
74
 
75
- It's very easy to create Active Record models. All you have to do is to subclass the +ActiveRecord::Base+ class and you're good to go:
75
+ It is very easy to create Active Record models. All you have to do is to subclass the +ActiveRecord::Base+ class and you're good to go:
76
76
 
77
77
  <ruby>
78
- class Product < ActiveRecord::Base; end
78
+ class Product < ActiveRecord::Base
79
+ end
79
80
  </ruby>
80
81
 
81
- This will create a +Product+ model, mapped to a *products* table at the database. By doing this you'll also have the ability to map the columns of each row in that table with the attributes of the instances of your model. So, suppose that the *products* table was created using an SQL sentence like:
82
+ This will create a +Product+ model, mapped to a +products+ table at the database. By doing this you'll also have the ability to map the columns of each row in that table with the attributes of the instances of your model. Suppose that the +products+ table was created using an SQL sentence like:
82
83
 
83
84
  <sql>
84
85
  CREATE TABLE products (
@@ -100,11 +101,11 @@ h3. Overriding the Naming Conventions
100
101
 
101
102
  What if you need to follow a different naming convention or need to use your Rails application with a legacy database? No problem, you can easily override the default conventions.
102
103
 
103
- You can use the +ActiveRecord::Base.set_table_name+ method to specify the table name that should be used:
104
+ You can use the +ActiveRecord::Base.table_name=+ method to specify the table name that should be used:
104
105
 
105
106
  <ruby>
106
107
  class Product < ActiveRecord::Base
107
- set_table_name "PRODUCT"
108
+ self.table_name = "PRODUCT"
108
109
  end
109
110
  </ruby>
110
111
 
@@ -126,21 +127,21 @@ class Product < ActiveRecord::Base
126
127
  end
127
128
  </ruby>
128
129
 
129
- h3. Reading and Writing Data
130
+ h3. CRUD: Reading and Writing Data
130
131
 
131
132
  CRUD is an acronym for the four verbs we use to operate on data: *C*reate, *R*ead, *U*pdate and *D*elete. Active Record automatically creates methods to allow an application to read and manipulate data stored within its tables.
132
133
 
133
134
  h4. Create
134
135
 
135
- Active Record objects can be created from a hash, a block or have its attributes manually set after creation. The _new_ method will return a new object while _create_ will return the object and save it to the database.
136
+ Active Record objects can be created from a hash, a block or have their attributes manually set after creation. The +new+ method will return a new object while +create+ will return the object and save it to the database.
136
137
 
137
- For example, given a model +User+ with attributes of +name+ and +occupation+, the _create_ method call will create and save a new record into the database:
138
+ For example, given a model +User+ with attributes of +name+ and +occupation+, the +create+ method call will create and save a new record into the database:
138
139
 
139
140
  <ruby>
140
141
  user = User.create(:name => "David", :occupation => "Code Artist")
141
142
  </ruby>
142
143
 
143
- Using the _new_ method, an object can be created without being saved:
144
+ Using the +new+ method, an object can be created without being saved:
144
145
 
145
146
  <ruby>
146
147
  user = User.new
@@ -148,9 +149,9 @@ Using the _new_ method, an object can be created without being saved:
148
149
  user.occupation = "Code Artist"
149
150
  </ruby>
150
151
 
151
- A call to _user.save_ will commit the record to the database.
152
+ A call to +user.save+ will commit the record to the database.
152
153
 
153
- Finally, passing a block to either create or new will return a new User object:
154
+ Finally, if a block is provided, both +create+ and +new+ will yield the new object to that block for initialization:
154
155
 
155
156
  <ruby>
156
157
  user = User.new do |u|
@@ -164,7 +165,7 @@ h4. Read
164
165
  Active Record provides a rich API for accessing data within a database. Below are a few examples of different data access methods provided by Active Record.
165
166
 
166
167
  <ruby>
167
- # return all records
168
+ # return array with all records
168
169
  users = User.all
169
170
  </ruby>
170
171
 
@@ -204,7 +205,6 @@ Likewise, once retrieved an Active Record object can be destroyed which removes
204
205
  user.destroy
205
206
  </ruby>
206
207
 
207
-
208
208
  h3. Validations
209
209
 
210
210
  Active Record allows you to validate the state of a model before it gets written into the database. There are several methods that you can use to check your models and validate that an attribute value is not empty, is unique and not already in the database, follows a specific format and many more. You can learn more about validations in the "Active Record Validations and Callbacks guide":active_record_validations_callbacks.html#validations-overview.