Skip to content
This repository
Browse code

Merge branch 'master' of github.com:lifo/docrails

  • Loading branch information...
commit 43af34c0f6c81d4d93be1bc1e743c202e8244485 2 parents 50b1399 + fc3d15d
Vijay Dev authored April 28, 2012
4  actionmailer/lib/action_mailer/base.rb
@@ -486,7 +486,7 @@ def mailer_name
486 486
       self.class.mailer_name
487 487
     end
488 488
 
489  
-    # Allows you to pass random and unusual headers to the new +Mail::Message+ object
  489
+    # Allows you to pass random and unusual headers to the new <tt>Mail::Message</tt> object
490 490
     # which will add them to itself.
491 491
     #
492 492
     #   headers['X-Special-Domain-Specific-Header'] = "SecretValue"
@@ -497,7 +497,7 @@ def mailer_name
497 497
     #   headers 'X-Special-Domain-Specific-Header' => "SecretValue",
498 498
     #           'In-Reply-To' => incoming.message_id
499 499
     #
500  
-    # The resulting Mail::Message will have the following in it's header:
  500
+    # The resulting Mail::Message will have the following in its header:
501 501
     #
502 502
     #   X-Special-Domain-Specific-Header: SecretValue
503 503
     def headers(args=nil)
2  actionpack/lib/action_controller/metal/params_wrapper.rb
@@ -66,7 +66,7 @@ module ActionController
66 66
   #     class Admin::UsersController < ApplicationController
67 67
   #     end
68 68
   #
69  
-  # will try to check if +Admin::User+ or +User+ model exists, and use it to
  69
+  # will try to check if <tt>Admin::User</tt> or +User+ model exists, and use it to
70 70
   # determine the wrapper key respectively. If both models don't exist,
71 71
   # it will then fallback to use +user+ as the key.
72 72
   module ParamsWrapper
6  actionpack/lib/action_controller/metal/streaming.rb
@@ -139,17 +139,17 @@ module ActionController #:nodoc:
139 139
   # session or flash after the template starts rendering will not propagate
140 140
   # to the client.
141 141
   #
142  
-  # If you try to modify cookies, session or flash, an +ActionDispatch::ClosedError+
  142
+  # If you try to modify cookies, session or flash, an <tt>ActionDispatch::ClosedError</tt>
143 143
   # will be raised, showing those objects are closed for modification.
144 144
   #
145 145
   # == Middlewares
146 146
   #
147 147
   # Middlewares that need to manipulate the body won't work with streaming.
148 148
   # You should disable those middlewares whenever streaming in development
149  
-  # or production. For instance, +Rack::Bug+ won't work when streaming as it
  149
+  # or production. For instance, <tt>Rack::Bug</tt> won't work when streaming as it
150 150
   # needs to inject contents in the HTML body.
151 151
   #
152  
-  # Also +Rack::Cache+ won't work with streaming as it does not support
  152
+  # Also <tt>Rack::Cache</tt> won't work with streaming as it does not support
153 153
   # streaming bodies yet. Whenever streaming Cache-Control is automatically
154 154
   # set to "no-cache".
155 155
   #
2  activemodel/lib/active_model/serialization.rb
@@ -34,7 +34,7 @@ module ActiveModel
34 34
   #
35 35
   # Most of the time though, you will want to include the JSON or XML
36 36
   # serializations. Both of these modules automatically include the
37  
-  # +ActiveModel::Serialization+ module, so there is no need to explicitly
  37
+  # <tt>ActiveModel::Serialization</tt> module, so there is no need to explicitly
38 38
   # include it.
39 39
   #
40 40
   # A minimal implementation including XML and JSON would be:
17  activemodel/lib/active_model/validations.rb
@@ -65,7 +65,7 @@ module ClassMethods
65 65
       #
66 66
       #     attr_accessor :first_name, :last_name
67 67
       #
68  
-      #     validates_each :first_name, :last_name do |record, attr, value|
  68
+      #     validates_each :first_name, :last_name, :allow_blank => true do |record, attr, value|
69 69
       #       record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
70 70
       #     end
71 71
       #   end
@@ -128,6 +128,19 @@ def validates_each(*attr_names, &block)
128 128
       #     end
129 129
       #   end
130 130
       #
  131
+      # Options:
  132
+      # * <tt>:on</tt> - Specifies the context where this validation is active
  133
+      #   (e.g. <tt>:on => :create</tt> or <tt>:on => :custom_validation_context</tt>)
  134
+      # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
  135
+      # * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
  136
+      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
  137
+      #   if the validation should occur (e.g. <tt>:if => :allow_validation</tt>,
  138
+      #   or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The method,
  139
+      #   proc or string should return or evaluate to a true or false value.
  140
+      # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
  141
+      #   not occur (e.g. <tt>:unless => :skip_validation</tt>, or
  142
+      #   <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
  143
+      #   method, proc or string should return or evaluate to a true or false value.
131 144
       def validate(*args, &block)
132 145
         options = args.extract_options!
133 146
         if options.key?(:on)
@@ -145,7 +158,7 @@ def validators
145 158
         _validators.values.flatten.uniq
146 159
       end
147 160
 
148  
-      # List all validators that being used to validate a specific attribute.
  161
+      # List all validators that are being used to validate a specific attribute.
149 162
       def validators_on(*attributes)
150 163
         attributes.map do |attribute|
151 164
           _validators[attribute.to_sym]
6  activemodel/lib/active_model/validations/with.rb
@@ -126,12 +126,12 @@ def validates_with(*args, &block)
126 126
     #   end
127 127
     #
128 128
     # Standard configuration options (:on, :if and :unless), which are
129  
-    # available on the class version of validates_with, should instead be
130  
-    # placed on the <tt>validates</tt> method as these are applied and tested
  129
+    # available on the class version of +validates_with+, should instead be
  130
+    # placed on the +validates+ method as these are applied and tested
131 131
     # in the callback
132 132
     #
133 133
     # If you pass any additional configuration options, they will be passed
134  
-    # to the class and available as <tt>options</tt>, please refer to the
  134
+    # to the class and available as +options+, please refer to the
135 135
     # class version of this method for more information
136 136
     #
137 137
     def validates_with(*args, &block)
BIN  guides/assets/images/getting_started/confirm_dialog.png
BIN  guides/assets/images/getting_started/undefined_method_post_path.png
7  guides/code/getting_started/app/controllers/posts_controller.rb
@@ -35,4 +35,11 @@ def update
35 35
       render 'edit'
36 36
     end
37 37
   end
  38
+
  39
+  def destroy
  40
+    @post = Post.find(params[:id])
  41
+    @post.destroy
  42
+
  43
+    redirect_to :action => :index
  44
+  end
38 45
 end
2  guides/code/getting_started/app/views/posts/_form.html.erb
... ...
@@ -1,4 +1,4 @@
1  
-<%= form_for :post, :url => { :action => :update, :id => @post.id }, :method => :put do |f| %>
  1
+<%= form_for @post do |f| %>
2 2
   <% if @post.errors.any? %>
3 3
     <div id="errorExplanation">
4 4
       <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
2  guides/code/getting_started/app/views/posts/index.html.erb
@@ -8,6 +8,7 @@
8 8
     <th>Text</th>
9 9
     <th></th>
10 10
     <th></th>
  11
+    <th></th>
11 12
   </tr>
12 13
 
13 14
 <% @posts.each do |post| %>
@@ -16,6 +17,7 @@
16 17
     <td><%= post.text %></td>
17 18
     <td><%= link_to 'Show', :action => :show, :id => post.id %>
18 19
     <td><%= link_to 'Edit', :action => :edit, :id => post.id %>
  20
+    <td><%= link_to 'Destroy', { :action => :destroy, :id => post.id }, :method => :delete, :confirm => 'Are you sure?' %>
19 21
   </tr>
20 22
 <% end %>
21 23
 </table>
5  guides/code/getting_started/config/routes.rb
@@ -6,9 +6,10 @@
6 6
   get "posts" => "posts#index"
7 7
   get "posts/new"
8 8
   post "posts/create"
9  
-  get "posts/:id" => "posts#show"
  9
+  get "posts/:id" => "posts#show", :as => :post
10 10
   get "posts/:id/edit" => "posts#edit"
11  
-  put "posts/:id/update" => "posts#update"
  11
+  put "posts/:id" => "posts#update"
  12
+  delete "posts/:id" => "posts#destroy"
12 13
 
13 14
   # The priority is based upon order of creation:
14 15
   # first created -> highest priority.
2  guides/source/active_record_validations_callbacks.textile
Source Rendered
@@ -1064,6 +1064,7 @@ Additionally, the +after_find+ callback is triggered by the following finder met
1064 1064
 * +find_all_by_<em>attribute</em>+
1065 1065
 * +find_by_<em>attribute</em>+
1066 1066
 * +find_by_<em>attribute</em>!+
  1067
+* +find_by_sql+
1067 1068
 * +last+
1068 1069
 
1069 1070
 The +after_initialize+ callback is triggered every time a new object of the class is initialized.
@@ -1076,7 +1077,6 @@ Just as with validations, it is also possible to skip callbacks. These methods s
1076 1077
 * +decrement_counter+
1077 1078
 * +delete+
1078 1079
 * +delete_all+
1079  
-* +find_by_sql+
1080 1080
 * +increment+
1081 1081
 * +increment_counter+
1082 1082
 * +toggle+
2  guides/source/active_support_core_extensions.textile
Source Rendered
@@ -1131,7 +1131,7 @@ h4. Output Safety
1131 1131
 
1132 1132
 h5. Motivation
1133 1133
 
1134  
-Inserting data into HTML templates needs extra care. For example you can't just interpolate +@review.title+ verbatim into an HTML page. On one hand if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;amp;". On the other hand, depending on the application that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the "section about cross-site scripting in the Security guide":security.html#cross-site-scripting-xss for further information about the risks.
  1134
+Inserting data into HTML templates needs extra care. For example, you can't just interpolate +@review.title+ verbatim into an HTML page. For one thing, if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;amp;". What's more, depending on the application, that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the "section about cross-site scripting in the Security guide":security.html#cross-site-scripting-xss for further information about the risks.
1135 1135
 
1136 1136
 h5. Safe Strings
1137 1137
 
2  guides/source/engines.textile
Source Rendered
@@ -695,7 +695,7 @@ If a template is rendered from within an engine and it's attempting to use one o
695 695
 
696 696
 h4. Assets
697 697
 
698  
-Assets within an engine work in an identical way to a full application. Because the engine class inherits from +Rails::Engine+, the application will know to look up in the engine's +app/assets+ directory for potential assets.
  698
+Assets within an engine work in an identical way to a full application. Because the engine class inherits from +Rails::Engine+, the application will know to look up in the engine's +app/assets+ and +lib/assets+ directories for potential assets.
699 699
 
700 700
 Much like all the other components of an engine, the assets should also be namespaced. This means if you have an asset called +style.css+, it should be placed at +app/assets/stylesheets/[engine name]/style.css+, rather than +app/assets/stylesheets/style.css+. If this asset wasn't namespaced, then there is a possibility that the host application could have an asset named identically, in which case the application's asset would take precedence and the engine's one would be all but ignored.
701 701
 
2  guides/source/generators.textile
Source Rendered
@@ -468,7 +468,7 @@ Replaces text inside a file.
468 468
 
469 469
 <ruby>
470 470
 gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code'
471  
-</ruby
  471
+</ruby>
472 472
 
473 473
 Regular Expressions can be used to make this method more precise. You can also use append_file and prepend_file in the same way to place code at the beginning and end of a file respectively.
474 474
 
173  guides/source/getting_started.textile
Source Rendered
@@ -465,7 +465,7 @@ invoking the command: <tt>rake db:migrate RAILS_ENV=production</tt>.
465 465
 
466 466
 h4. Saving data in the controller
467 467
 
468  
-Back into +posts_controller+, we need to change the +create+ action
  468
+Back in +posts_controller+, we need to change the +create+ action
469 469
 to use the new +Post+ model to save data in the database. Open that file
470 470
 and change the +create+ action to look like the following:
471 471
 
@@ -835,7 +835,7 @@ Moving on, we need to add the +update+ action. The file
835 835
 +config/routes.rb+ will need just one more line:
836 836
 
837 837
 <ruby>
838  
-put "posts/:id/update"
  838
+put "posts/:id" => "posts#update"
839 839
 </ruby>
840 840
 
841 841
 And the +update+ action in +posts_controller+ itself should not look too complicated by now:
@@ -930,6 +930,175 @@ Our +edit+ action looks very similar to the +new+ action, in fact they
930 930
 both share the same code for displaying the form. Lets clean them up by
931 931
 using a +_form+ partial.
932 932
 
  933
+Create a new file +app/views/posts/_form.html.erb+ with the following
  934
+content:
  935
+
  936
+<erb>
  937
+<%= form_for @post do |f| %>
  938
+  <% if @post.errors.any? %>
  939
+  <div id="errorExplanation">
  940
+    <h2><%= pluralize(@post.errors.count, "error") %> prohibited
  941
+	    this post from being saved:</h2>
  942
+    <ul>
  943
+    <% @post.errors.full_messages.each do |msg| %>
  944
+      <li><%= msg %></li>
  945
+    <% end %>
  946
+    </ul>
  947
+  </div>
  948
+  <% end %>
  949
+  <p>
  950
+    <%= f.label :title %><br>
  951
+    <%= f.text_field :title %>
  952
+  </p>
  953
+
  954
+  <p>
  955
+    <%= f.label :text %><br>
  956
+    <%= f.text_area :text %>
  957
+  </p>
  958
+
  959
+  <p>
  960
+    <%= f.submit %>
  961
+  </p>
  962
+<% end %>
  963
+</erb>
  964
+
  965
+Everything except for the +form_for+ declaration remained the same. I'll
  966
+explain later how +form_for+ can figure out the right +action+ and
  967
++method+ attributes when building the form, for now let's update the
  968
++new+ and +edit+ views:
  969
+
  970
+<erb>
  971
+# app/views/posts/new.html.erb
  972
+
  973
+<h1>New post</h1>
  974
+
  975
+<%= render 'form' %>
  976
+
  977
+<%= link_to 'Back', :action => :index %>
  978
+
  979
+
  980
+# app/views/posts/edit.html.erb
  981
+
  982
+<h1>Edit post</h1>
  983
+
  984
+<%= render 'form' %>
  985
+
  986
+<%= link_to 'Back', :action => :index %>
  987
+</erb>
  988
+
  989
+Point your browser to
  990
+"http://localhost:3000/posts/new":http://localhost:3000/posts/new and
  991
+try creating a new post. Everything still works. Now try editing the
  992
+post and you'll receive the following error:
  993
+
  994
+!images/getting_started/undefined_method_post_path.png(Undefined method
  995
+post_path)!
  996
+
  997
+To understand this error, you need to understand how +form_for+ works.
  998
+When you pass an object to +form_for+ and you don't specify a +:url+
  999
+option, Rails will try to guess the +action+ and +method+ options by
  1000
+checking if the passed object is a new record or not. Rails follows the
  1001
+REST convention, so to create a new +Post+ object it will look for a
  1002
+route named +posts_path+, and to update a +Post+ object it will look for
  1003
+a route named +post_path+ and pass the current object. Similarly, rails
  1004
+knows that it should create new objects via POST and update them via
  1005
+PUT.
  1006
+
  1007
+If you run +rake routes+ from the console you'll see that we already
  1008
+have a +posts_path+ route, which was created automatically by Rails.
  1009
+However, we don't have a +post_path+ yet, which is the reason why we
  1010
+received an error before.
  1011
+
  1012
+<shell>
  1013
+# rake routes
  1014
+
  1015
+       posts GET  /posts(.:format)            posts#index
  1016
+   posts_new GET  /posts/new(.:format)        posts#new
  1017
+posts_create POST /posts/create(.:format)     posts#create
  1018
+             GET  /posts/:id(.:format)        posts#show
  1019
+             GET  /posts/:id/edit(.:format)   posts#edit
  1020
+             PUT  /posts/:id(.:format)        posts#update
  1021
+        root      /                           welcome#index
  1022
+</shell>
  1023
+
  1024
+To fix this, open +config/routes.rb+ and modify the +get "posts/:id"+
  1025
+line like this:
  1026
+
  1027
+<ruby>
  1028
+get "posts/:id" => "posts#show", :as => :post
  1029
+</ruby>
  1030
+
  1031
+Now you'll be able to update posts again.
  1032
+
  1033
+h4. Deleting Posts
  1034
+
  1035
+We're now ready to cover the "D" part of CRUD, deleting posts from the
  1036
+database. Following the REST convention, we're going to add a route for
  1037
+deleting posts:
  1038
+
  1039
+<ruby>
  1040
+# config/routes.rb
  1041
+
  1042
+delete "posts/:id" => "posts#destroy"
  1043
+</ruby>
  1044
+
  1045
+We use the +delete+ method for destroying resources, which is mapped to
  1046
+the +destroy+ action, which is provided below:
  1047
+
  1048
+<ruby>
  1049
+# app/controllers/posts_controller.rb
  1050
+
  1051
+def destroy
  1052
+  @post = Post.find(params[:id])
  1053
+  @post.destroy
  1054
+
  1055
+  redirect_to :action => :index
  1056
+end
  1057
+</ruby>
  1058
+
  1059
+You can call +destroy+ on Active Record objects when you want to delete
  1060
+them from the dabase. Note that we don't need to add a view for this
  1061
+action since we're redirecting to the +index+ action.
  1062
+
  1063
+Finally, add a 'destroy' link to your +index+ action to wrap everything
  1064
+together.
  1065
+
  1066
+<erb>
  1067
+<table>
  1068
+  <tr>
  1069
+    <th>Title</th>
  1070
+    <th>Text</th>
  1071
+    <th></th>
  1072
+    <th></th>
  1073
+    <th></th>
  1074
+  </tr>
  1075
+
  1076
+<% @posts.each do |post| %>
  1077
+  <tr>
  1078
+    <td><%= post.title %></td>
  1079
+    <td><%= post.text %></td>
  1080
+    <td><%= link_to 'Show', :action => :show, :id => post.id %></td>
  1081
+    <td><%= link_to 'Edit', :action => :edit, :id => post.id %></td>
  1082
+    <td><%= link_to 'Destroy', { :action => :destroy, :id => post.id }, :method => :delete, :confirm => 'Are you sure?' %></td>
  1083
+  </tr>
  1084
+<% end %>
  1085
+</table>
  1086
+</erb>
  1087
+
  1088
+Here we're using +link_to+ in a different way. We wrap the
  1089
++:action+ and +:id+ attributes in a hash so that we can pass other
  1090
+arguments to +link_to+. The +:method+ and +:confirm+
  1091
+options are used as html5 attributes so that when the click is linked,
  1092
+Rails will first show a confirm dialog to the user, and then submit the
  1093
+link with method +delete+. This is done via javascript automatically.
  1094
+
  1095
+!images/getting_started/confirm_dialog.png(Confirm Dialog)!
  1096
+
  1097
+Congratulations, you can now create, show, list, update and destroy
  1098
+posts. In the next section will see how Rails can aid us when creating
  1099
+REST applications, and how we can refactor our Blog app to take
  1100
+advantage of it.
  1101
+
933 1102
 h4. Using the Console
934 1103
 
935 1104
 To see your validations in action, you can use the console. The console is a
2  railties/lib/rails/configuration.rb
@@ -16,7 +16,7 @@ module Configuration
16 16
     #
17 17
     #     config.middleware.use Magical::Unicorns
18 18
     #
19  
-    # This will put the +Magical::Unicorns+ middleware on the end of the stack.
  19
+    # This will put the <tt>Magical::Unicorns</tt> middleware on the end of the stack.
20 20
     # You can use +insert_before+ if you wish to add a middleware before another:
21 21
     #
22 22
     #     config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
8  railties/lib/rails/generators/test_case.rb
@@ -79,8 +79,8 @@ def self.destination(path)
79 79
       #
80 80
       # Finally, when a block is given, it yields the file content:
81 81
       #
82  
-      #   assert_file "app/controller/products_controller.rb" do |controller|
83  
-      #     assert_instance_method :index, content do |index|
  82
+      #   assert_file "app/controllers/products_controller.rb" do |controller|
  83
+      #     assert_instance_method :index, controller do |index|
84 84
       #       assert_match(/Product\.all/, index)
85 85
       #     end
86 86
       #   end
@@ -159,8 +159,8 @@ def assert_class_method(method, content, &block)
159 159
       # Asserts the given method exists in the given content. When a block is given,
160 160
       # it yields the content of the method.
161 161
       #
162  
-      #   assert_file "app/controller/products_controller.rb" do |controller|
163  
-      #     assert_instance_method :index, content do |index|
  162
+      #   assert_file "app/controllers/products_controller.rb" do |controller|
  163
+      #     assert_instance_method :index, controller do |index|
164 164
       #       assert_match(/Product\.all/, index)
165 165
       #     end
166 166
       #   end
2  railties/lib/rails/paths.rb
@@ -10,7 +10,7 @@ module Paths
10 10
     #   root.add "app/controllers", :eager_load => true
11 11
     #
12 12
     # The command above creates a new root object and add "app/controllers" as a path.
13  
-    # This means we can get a +Rails::Paths::Path+ object back like below:
  13
+    # This means we can get a <tt>Rails::Paths::Path</tt> object back like below:
14 14
     #
15 15
     #   path = root["app/controllers"]
16 16
     #   path.eager_load?               # => true

0 notes on commit 43af34c

Please sign in to comment.
Something went wrong with that request. Please try again.