From 60aee4ea0e10a35ce5247b7be0e8576765ff9bc9 Mon Sep 17 00:00:00 2001 From: Ben Pickles Date: Tue, 1 May 2012 16:38:35 +0200 Subject: [PATCH 01/20] Lowercase. --- activerecord/lib/active_record/relation/calculations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index f388b75c05..3ce9995031 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -144,7 +144,7 @@ module ActiveRecord # Examples: # # Person.ids # SELECT people.id FROM people - # Person.joins(:companies).ids # SELECT people.id FROM PEOPLE INNER JOIN companies ON companies.person_id = people.id + # Person.joins(:companies).ids # SELECT people.id FROM people INNER JOIN companies ON companies.person_id = people.id def ids pluck primary_key end From 068e8b20b574395e6d38480f5f124fbd3dd5a370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hrvoje=20=C5=A0imi=C4=87?= Date: Tue, 1 May 2012 18:25:37 +0200 Subject: [PATCH 02/20] simpler wording and explanations --- activerecord/lib/active_record/aggregations.rb | 6 +++--- activerecord/lib/active_record/associations.rb | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index c39284539c..bf1c73209e 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -101,8 +101,8 @@ module ActiveRecord # ActiveRecord::Base classes are entity objects. # # It's also important to treat the value objects as immutable. Don't allow the Money object to have - # its amount changed after creation. Create a new Money object with the new value instead. This - # is exemplified by the Money#exchange_to method that returns a new value object instead of changing + # its amount changed after creation. Create a new Money object with the new value instead. The + # Money#exchange_to method is an example of this. It returns a new value object instead of changing # its own values. Active Record won't persist value objects that have been changed through means # other than the writer method. # @@ -119,7 +119,7 @@ module ActiveRecord # option, as arguments. If the value class doesn't support this convention then +composed_of+ allows # a custom constructor to be specified. # - # When a new value is assigned to the value object the default assumption is that the new value + # When a new value is assigned to the value object, the default assumption is that the new value # is an instance of the value class. Specifying a custom converter allows the new value to be automatically # converted to an instance of value class if necessary. # diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index b901f06ca4..c7a24de11d 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1129,7 +1129,7 @@ module ActiveRecord # it would skip the first 4 rows. # [:select] # By default, this is * as in SELECT * FROM, but can be changed if - # you, for example, want to do a join but not include the joined columns. Do not forget + # you want to do a join but not include the joined columns, for example. Do not forget # to include the primary and foreign keys, otherwise it will raise an error. # [:as] # Specifies a polymorphic interface (See belongs_to). @@ -1264,8 +1264,8 @@ module ActiveRecord # [:as] # Specifies a polymorphic interface (See belongs_to). # [:select] - # By default, this is * as in SELECT * FROM, but can be changed if, for example, - # you want to do a join but not include the joined columns. Do not forget to include the + # By default, this is * as in SELECT * FROM, but can be changed if + # you want to do a join but not include the joined columns, for example. Do not forget to include the # primary and foreign keys, otherwise it will raise an error. # [:through] # Specifies a Join Model through which to perform the query. Options for :class_name, @@ -1355,7 +1355,7 @@ module ActiveRecord # SQL fragment, such as authorized = 1. # [:select] # By default, this is * as in SELECT * FROM, but can be changed - # if, for example, you want to do a join but not include the joined columns. Do not + # if you want to do a join but not include the joined columns, for example. Do not # forget to include the primary and foreign keys, otherwise it will raise an error. # [:foreign_key] # Specify the foreign key used for the association. By default this is guessed to be the name @@ -1382,7 +1382,7 @@ module ActiveRecord # and +decrement_counter+. The counter cache is incremented when an object of this # class is created and decremented when it's destroyed. This requires that a column # named #{table_name}_count (such as +comments_count+ for a belonging Comment class) - # is used on the associate class (such as a Post class) - that is the migration for + # is used on the associate class (such as a Post class) - that is the migration for # #{table_name}_count is created on the associate class (such that Post.comments_count will # return the count cached, see note below). You can also specify a custom counter # cache column by providing a column name instead of a +true+/+false+ value to this @@ -1432,7 +1432,7 @@ module ActiveRecord # Specifies a many-to-many relationship with another class. This associates two classes via an # intermediate join table. Unless the join table is explicitly specified as an option, it is # guessed using the lexical order of the class names. So a join between Developer and Project - # will give the default join table name of "developers_projects" because "D" outranks "P". + # will give the default join table name of "developers_projects" because "D" precedes "P" alphabetically. # Note that this precedence is calculated using the < operator for String. This # means that if the strings are of different lengths, and the strings are equal when compared # up to the shortest length, then the longer string is considered of higher @@ -1576,8 +1576,8 @@ module ActiveRecord # An integer determining the offset from where the rows should be fetched. So at 5, # it would skip the first 4 rows. # [:select] - # By default, this is * as in SELECT * FROM, but can be changed if, for example, - # you want to do a join but not include the joined columns. Do not forget to include the primary + # By default, this is * as in SELECT * FROM, but can be changed if + # you want to do a join but exclude the joined columns, for example. Do not forget to include the primary # and foreign keys, otherwise it will raise an error. # [:readonly] # If true, all the associated objects are readonly through the association. From d752eabde35be96f9d8ab913b21c04e7f6aec485 Mon Sep 17 00:00:00 2001 From: Edward Tsech Date: Tue, 1 May 2012 20:52:41 +0200 Subject: [PATCH 03/20] Add few lines to describe how aggregation part caching works. [ci skip] --- activerecord/lib/active_record/aggregations.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index bf1c73209e..25ab826a13 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -86,6 +86,10 @@ module ActiveRecord # customer.address_street = "Hyancintvej" # customer.address_city = "Copenhagen" # customer.address # => Address.new("Hyancintvej", "Copenhagen") + # customer.address_street = "Vesterbrogade" + # customer.address # => Address.new("Hyancintvej", "Copenhagen") + # customer.clear_aggregation_cache + # customer.address # => Address.new("Vesterbrogade", "Copenhagen") # customer.address = Address.new("May Street", "Chicago") # customer.address_street # => "May Street" # customer.address_city # => "Chicago" From 3305256c95d0d2a621ce85461b881a723cc2d0d3 Mon Sep 17 00:00:00 2001 From: Edward Tsech Date: Tue, 1 May 2012 21:19:58 +0200 Subject: [PATCH 04/20] Add empty rows to improve readability. [ci skip] --- activerecord/lib/active_record/aggregations.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index 25ab826a13..a4db627535 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -86,10 +86,12 @@ module ActiveRecord # customer.address_street = "Hyancintvej" # customer.address_city = "Copenhagen" # customer.address # => Address.new("Hyancintvej", "Copenhagen") + # # customer.address_street = "Vesterbrogade" # customer.address # => Address.new("Hyancintvej", "Copenhagen") # customer.clear_aggregation_cache # customer.address # => Address.new("Vesterbrogade", "Copenhagen") + # # customer.address = Address.new("May Street", "Chicago") # customer.address_street # => "May Street" # customer.address_city # => "Chicago" From e1724b553e25339cd09df325523cce2f76f464f0 Mon Sep 17 00:00:00 2001 From: Rodrigo Pavano Date: Tue, 1 May 2012 19:18:53 -0300 Subject: [PATCH 05/20] Documentation fix in options_for_select helper. Fixed display errors caused by mixing Ruby and HTML code inside the same pre tag [ci skip] --- .../helpers/form_options_helper.rb | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index d61c2bbee2..cafcd93f58 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -288,38 +288,55 @@ module ActionView # # Examples (call, result): # options_for_select([["Dollar", "$"], ["Kroner", "DKK"]]) - # \n + # # + # # # # options_for_select([ "VISA", "MasterCard" ], "MasterCard") - # \n + # # + # # # # options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40") - # \n + # # + # # # # options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"]) - # \n\n + # # + # # + # # # # You can optionally provide html attributes as the last element of the array. # # Examples: # options_for_select([ "Denmark", ["USA", {:class => 'bold'}], "Sweden" ], ["USA", "Sweden"]) - # \n\n + # # + # # + # # # # options_for_select([["Dollar", "$", {:class => "bold"}], ["Kroner", "DKK", {:onclick => "alert('HI');"}]]) - # \n + # # + # # # # If you wish to specify disabled option tags, set +selected+ to be a hash, with :disabled being either a value # or array of values to be disabled. In this case, you can use :selected to specify selected option tags. # # Examples: # options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => "Super Platinum") - # \n\n\n + # # + # # + # # + # # # # options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => ["Advanced", "Super Platinum"]) - # \n\n\n + # # + # # + # # + # # # # options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :selected => "Free", :disabled => "Super Platinum") - # \n\n\n + # # + # # + # # + # # # # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. def options_for_select(container, selected = nil) From 7b9faf7b283c55d35124a3c665f170663994124b Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Wed, 2 May 2012 09:20:50 +0400 Subject: [PATCH 06/20] Fix form tag with non GET/POST method example --- actionpack/lib/action_view/helpers/form_tag_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index b5e0970612..ef35a411ad 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -45,7 +45,7 @@ module ActionView # # =>
# # form_tag('/posts/1', :method => :put) - # # => + # # => ... ... # # form_tag('/upload', :multipart => true) # # => From b214ddd1c986a466923fd8a2f3dddff5bfe28637 Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Wed, 2 May 2012 09:28:43 +0400 Subject: [PATCH 07/20] Fix example url in text helper --- actionpack/lib/action_view/helpers/text_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 12bb162da2..fffc37ce9e 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -45,7 +45,7 @@ module ActionView # if logged_in # concat "Logged in!" # else - # concat link_to('login', :action => login) + # concat link_to('login', :action => :login) # end # # will either display "Logged in!" or a login link # %> From 85f71c53296e2f360f723236dee7a3193db35a13 Mon Sep 17 00:00:00 2001 From: Michael Pearson Date: Wed, 2 May 2012 17:42:33 +1000 Subject: [PATCH 08/20] Add note about image_tag('') issue in Asset Pipeline guide (see rails issue #3080) --- guides/source/asset_pipeline.textile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guides/source/asset_pipeline.textile b/guides/source/asset_pipeline.textile index d79eb01ab2..010154f1d1 100644 --- a/guides/source/asset_pipeline.textile +++ b/guides/source/asset_pipeline.textile @@ -204,6 +204,8 @@ Images can also be organized into subdirectories if required, and they can be ac <%= image_tag "icons/rails.png" %> +WARNING: If you're precompiling your assets (see "In Production":#in-production below), linking to an asset that does not exist will raise an exception in the calling page. This includes linking to a blank string. As such, be careful using image_tag and the other helpers with user-supplied data. + h5. CSS and ERB The asset pipeline automatically evaluates ERB. This means that if you add an +erb+ extension to a CSS asset (for example, +application.css.erb+), then helpers like +asset_path+ are available in your CSS rules: From a411e8828a50795139df6ed210271c1a6cbd135d Mon Sep 17 00:00:00 2001 From: Ayrton De Craene Date: Wed, 2 May 2012 11:49:43 +0300 Subject: [PATCH 09/20] Changed code examples to have a consistent code styling [ci skip] --- guides/source/layouts_and_rendering.textile | 66 ++++++++++----------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/guides/source/layouts_and_rendering.textile b/guides/source/layouts_and_rendering.textile index f69afaa281..e4a1fd6951 100644 --- a/guides/source/layouts_and_rendering.textile +++ b/guides/source/layouts_and_rendering.textile @@ -78,16 +78,16 @@ If we want to display the properties of all the books in our view, we can do so <%= book.title %> <%= book.content %> - <%= link_to 'Show', book %> - <%= link_to 'Edit', edit_book_path(book) %> - <%= link_to 'Remove', book, :confirm => 'Are you sure?', :method => :delete %> + <%= link_to "Show", book %> + <%= link_to "Edit", edit_book_path(book) %> + <%= link_to "Remove", book, :confirm => "Are you sure?", :method => :delete %> <% end %>
-<%= link_to 'New book', new_book_path %> +<%= link_to "New book", new_book_path %> NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. Beginning with Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), and +.builder+ for Builder (XML generator). @@ -177,13 +177,13 @@ h5. Rendering an Action's Template from Another Controller What if you want to render a template from an entirely different controller from the one that contains the action code? You can also do that with +render+, which accepts the full path (relative to +app/views+) of the template to render. For example, if you're running code in an +AdminProductsController+ that lives in +app/controllers/admin+, you can render the results of an action to a template in +app/views/products+ this way: -render 'products/show' +render "products/show" Rails knows that this view belongs to a different controller because of the embedded slash character in the string. If you want to be explicit, you can use the +:template+ option (which was required on Rails 2.2 and earlier): -render :template => 'products/show' +render :template => "products/show" h5. Rendering an Arbitrary File @@ -216,18 +216,18 @@ In fact, in the BooksController class, inside of the update action where we want render :edit render :action => :edit -render 'edit' -render 'edit.html.erb' -render :action => 'edit' -render :action => 'edit.html.erb' -render 'books/edit' -render 'books/edit.html.erb' -render :template => 'books/edit' -render :template => 'books/edit.html.erb' -render '/path/to/rails/app/views/books/edit' -render '/path/to/rails/app/views/books/edit.html.erb' -render :file => '/path/to/rails/app/views/books/edit' -render :file => '/path/to/rails/app/views/books/edit.html.erb' +render "edit" +render "edit.html.erb" +render :action => "edit" +render :action => "edit.html.erb" +render "books/edit" +render "books/edit.html.erb" +render :template => "books/edit" +render :template => "books/edit.html.erb" +render "/path/to/rails/app/views/books/edit" +render "/path/to/rails/app/views/books/edit.html.erb" +render :file => "/path/to/rails/app/views/books/edit" +render :file => "/path/to/rails/app/views/books/edit.html.erb" Which one you use is really a matter of style and convention, but the rule of thumb is to use the simplest one that makes sense for the code you are writing. @@ -306,7 +306,7 @@ h6. The +:content_type+ Option By default, Rails will serve the results of a rendering operation with the MIME content-type of +text/html+ (or +application/json+ if you use the +:json+ option, or +application/xml+ for the +:xml+ option.). There are times when you might like to change this, and you can do so by setting the +:content_type+ option: -render :file => filename, :content_type => 'application/rss' +render :file => filename, :content_type => "application/rss" h6. The +:layout+ Option @@ -316,7 +316,7 @@ With most of the options to +render+, the rendered content is displayed as part You can use the +:layout+ option to tell Rails to use a specific file as the layout for the current action: -render :layout => 'special_layout' +render :layout => "special_layout" You can also tell Rails to render with no layout at all: @@ -378,7 +378,7 @@ You can use a symbol to defer the choice of layout until a request is processed: class ProductsController < ApplicationController - layout :products_layout + layout "products_layout" def show @product = Product.find(params[:id]) @@ -398,7 +398,7 @@ You can even use an inline method, such as a Proc, to determine the layout. For class ProductsController < ApplicationController - layout Proc.new { |controller| controller.request.xhr? ? 'popup' : 'application' } + layout Proc.new { |controller| controller.request.xhr? ? "popup" : "application" } end @@ -445,7 +445,7 @@ end class OldPostsController < SpecialPostsController - layout nil + layout false def show @post = Post.find(params[:id]) @@ -583,7 +583,7 @@ def show @book = Book.find_by_id(params[:id]) if @book.nil? @books = Book.all - render "index", :alert => 'Your book was not found!' + render "index", :alert => "Your book was not found!" end end @@ -770,7 +770,7 @@ By default, the combined file will be delivered as +javascripts/all.js+. You can <%= javascript_include_tag "main", "columns", - :cache => 'cache/main/display' %> + :cache => "cache/main/display" %> You can even use dynamic paths such as +cache/#{current_site}/main/display+. @@ -833,7 +833,7 @@ By default, the combined file will be delivered as +stylesheets/all.css+. You ca <%= stylesheet_link_tag "main", "columns", - :cache => 'cache/main/display' %> + :cache => "cache/main/display" %> You can even use dynamic paths such as +cache/#{current_site}/main/display+. @@ -884,7 +884,7 @@ In addition to the above special tags, you can supply a final hash of standard H <%= image_tag "home.gif", :alt => "Go Home", :id => "HomeImage", - :class => 'nav_bar' %> + :class => "nav_bar" %> h5. Linking to Videos with the +video_tag+ @@ -905,7 +905,7 @@ Like an +image_tag+ you can supply a path, either absolute, or relative to the + The video tag also supports all of the +<video>+ HTML options through the HTML options hash, including: -* +:poster => 'image_name.png'+, provides an image to put in place of the video before it starts playing. +* +:poster => "image_name.png"+, provides an image to put in place of the video before it starts playing. * +:autoplay => true+, starts playing the video on page load. * +:loop => true+, loops the video once it gets to the end. * +:controls => true+, provides browser supplied controls for the user to interact with the video. @@ -1159,7 +1159,7 @@ In the event that the collection is empty, +render+ will return nil, so it shoul

Products

-<%= render(@products) || 'There are no products available.' %> +<%= render(@products) || "There are no products available." %>
h5. Local Variables @@ -1175,7 +1175,7 @@ With this change, you can access an instance of the +@products+ collection as th You can also pass in arbitrary local variables to any partial you are rendering with the +:locals => {}+ option: -<%= render :partial => 'products', :collection => @products, +<%= render :partial => "products", :collection => @products, :as => :item, :locals => {:title => "Products Page"} %> @@ -1214,8 +1214,8 @@ Suppose you have the following +ApplicationController+ layout: - <%= @page_title or 'Page Title' %> - <%= stylesheet_link_tag 'layout' %> + <%= @page_title or "Page Title" %> + <%= stylesheet_link_tag "layout" %> @@ -1239,7 +1239,7 @@ On pages generated by +NewsController+, you want to hide the top menu and add a
Right menu items here
<%= content_for?(:news_content) ? yield(:news_content) : yield %> <% end %> -<%= render :template => 'layouts/application' %> +<%= render :template => "layouts/application" %>
That's it. The News views will use the new layout, hiding the top menu and adding a new right menu inside the "content" div. From 47ec49276d40ed565d805069bb2a746e9a7b3157 Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Wed, 2 May 2012 10:42:59 +0200 Subject: [PATCH 10/20] Rewrite comments action in getting started guide --- .../getting_started/post_with_comments.png | Bin 0 -> 31630 bytes .../app/views/posts/show.html.erb | 12 ++++++ guides/source/getting_started.textile | 35 +++++++----------- 3 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 guides/assets/images/getting_started/post_with_comments.png diff --git a/guides/assets/images/getting_started/post_with_comments.png b/guides/assets/images/getting_started/post_with_comments.png new file mode 100644 index 0000000000000000000000000000000000000000..bd9b2e10f54d6c7cb933735e0323c053055f92f9 GIT binary patch literal 31630 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%0AA-&v+H@5YJ^sZ1x+Q?Y2rz&hb~BMPN=z?1Y3oe* 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 ViloZ{*4O|ky;PGgmwo&Be*yeL)j0qF literal 0 HcmV?d00001 diff --git a/guides/code/getting_started/app/views/posts/show.html.erb b/guides/code/getting_started/app/views/posts/show.html.erb index 0580879c1a..7066c85065 100644 --- a/guides/code/getting_started/app/views/posts/show.html.erb +++ b/guides/code/getting_started/app/views/posts/show.html.erb @@ -8,6 +8,18 @@ <%= @post.text %>

+

Comments

+<% @post.comments.each do |comment| %> +

+ Commenter: + <%= comment.commenter %> +

+ +

+ Comment: + <%= comment.body %> +

+<% end %>

Add a comment:

<%= form_for([@post, @post.comments.build]) do |f| %> diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index 44f3b978db..7ad01ae636 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -1367,60 +1367,53 @@ template. This is where we want the comment to show, so let's add that to the +app/views/posts/show.html.erb+. -

<%= notice %>

-

- Name: - <%= @post.name %> -

- -

- Title: + Title: <%= @post.title %>

- Content: - <%= @post.content %> + Text: + <%= @post.texthttp://beginningruby.org/ %>

Comments

<% @post.comments.each do |comment| %>

- Commenter: + Commenter: <%= comment.commenter %>

- Comment: + Comment: <%= comment.body %>

<% end %>

Add a comment:

<%= form_for([@post, @post.comments.build]) do |f| %> -
+

<%= f.label :commenter %>
<%= f.text_field :commenter %> -

-
+

+

<%= f.label :body %>
<%= f.text_area :body %> -

-
+

+

<%= f.submit %> -

+

<% end %> -
- <%= link_to 'Edit Post', edit_post_path(@post) %> | -<%= link_to 'Back to Posts', posts_path %> | +<%= link_to 'Back to Posts', posts_path %>
Now you can add posts and comments to your blog and have them show up in the right places. +!images/getting_started/post_with_comments.png(Post with Comments)! + h3. Refactoring Now that we have posts and comments working, take a look at the From 323d2c42c3782db9e30b37abb4787fe73d6d7c8d Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Wed, 2 May 2012 11:13:20 +0200 Subject: [PATCH 11/20] Rewrite refactoring section in getting started guide --- .../app/views/comments/_comment.html.erb | 8 +-- .../app/views/comments/_form.html.erb | 12 ++-- .../app/views/posts/show.html.erb | 26 +------- guides/source/getting_started.textile | 65 +++++++------------ 4 files changed, 34 insertions(+), 77 deletions(-) diff --git a/guides/code/getting_started/app/views/comments/_comment.html.erb b/guides/code/getting_started/app/views/comments/_comment.html.erb index 4c3fbf26cd..0cebe0bd96 100644 --- a/guides/code/getting_started/app/views/comments/_comment.html.erb +++ b/guides/code/getting_started/app/views/comments/_comment.html.erb @@ -1,13 +1,13 @@

- Commenter: + Commenter: <%= comment.commenter %>

- +

- Comment: + Comment: <%= comment.body %>

- +

<%= link_to 'Destroy Comment', [comment.post, comment], :confirm => 'Are you sure?', diff --git a/guides/code/getting_started/app/views/comments/_form.html.erb b/guides/code/getting_started/app/views/comments/_form.html.erb index d15bdd6b59..00cb3a08f0 100644 --- a/guides/code/getting_started/app/views/comments/_form.html.erb +++ b/guides/code/getting_started/app/views/comments/_form.html.erb @@ -1,13 +1,13 @@ <%= form_for([@post, @post.comments.build]) do |f| %> -

+

<%= f.label :commenter %>
<%= f.text_field :commenter %> -

-
+

+

<%= f.label :body %>
<%= f.text_area :body %> -

-
+

+

<%= f.submit %> -

+

<% end %> diff --git a/guides/code/getting_started/app/views/posts/show.html.erb b/guides/code/getting_started/app/views/posts/show.html.erb index 7066c85065..65809033ed 100644 --- a/guides/code/getting_started/app/views/posts/show.html.erb +++ b/guides/code/getting_started/app/views/posts/show.html.erb @@ -9,32 +9,10 @@

Comments

-<% @post.comments.each do |comment| %> -

- Commenter: - <%= comment.commenter %> -

- -

- Comment: - <%= comment.body %> -

-<% end %> +<%= render @post.comments %>

Add a comment:

-<%= form_for([@post, @post.comments.build]) do |f| %> -

- <%= f.label :commenter %>
- <%= f.text_field :commenter %> -

-

- <%= f.label :body %>
- <%= f.text_area :body %> -

-

- <%= f.submit %> -

-<% end %> +<%= render "comments/form" %> <%= link_to 'Edit Post', edit_post_path(@post) %> | <%= link_to 'Back to Posts', posts_path %> diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index 7ad01ae636..8ea7c5ab6e 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -1428,12 +1428,12 @@ following into it:

- Commenter: + Commenter: <%= comment.commenter %>

- Comment: + Comment: <%= comment.body %>

@@ -1442,21 +1442,14 @@ Then you can change +app/views/posts/show.html.erb+ to look like the following: -

<%= notice %>

-

- Name: - <%= @post.name %> -

- -

- Title: + Title: <%= @post.title %>

- Content: - <%= @post.content %> + Text: + <%= @post.texthttp://beginningruby.org/ %>

Comments

@@ -1464,23 +1457,21 @@ following:

Add a comment:

<%= form_for([@post, @post.comments.build]) do |f| %> -
+

<%= f.label :commenter %>
<%= f.text_field :commenter %> -

-
+

+

<%= f.label :body %>
<%= f.text_area :body %> -

-
+

+

<%= f.submit %> -

+

<% end %> -
- <%= link_to 'Edit Post', edit_post_path(@post) %> | -<%= link_to 'Back to Posts', posts_path %> | +<%= link_to 'Back to Posts', posts_path %>
This will now render the partial in +app/views/comments/_comment.html.erb+ once @@ -1496,50 +1487,38 @@ create a file +app/views/comments/_form.html.erb+ containing: <%= form_for([@post, @post.comments.build]) do |f| %> -
+

<%= f.label :commenter %>
<%= f.text_field :commenter %> -

-
+

+

<%= f.label :body %>
<%= f.text_area :body %> -

-
+

+

<%= f.submit %> -

+

<% end %>
Then you make the +app/views/posts/show.html.erb+ look like the following: -

<%= notice %>

-

- Name: - <%= @post.name %> -

- -

- Title: + Title: <%= @post.title %>

- Content: - <%= @post.content %> + Text: + <%= @post.texthttp://beginningruby.org/ %>

-

Comments

-<%= render @post.comments %> -

Add a comment:

<%= render "comments/form" %> -
- <%= link_to 'Edit Post', edit_post_path(@post) %> | -<%= link_to 'Back to Posts', posts_path %> | +<%= link_to 'Back to Posts', posts_path %>
The second render just defines the partial template we want to render, From c55ee776232f77a9bd45684a3e6f3f3b13380e4c Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Wed, 2 May 2012 11:39:36 +0200 Subject: [PATCH 12/20] Remove tags from getting started guide and adapt some of the content to the new guide --- .../app/controllers/comments_controller.rb | 5 +- .../app/controllers/posts_controller.rb | 2 + guides/source/getting_started.textile | 216 +----------------- 3 files changed, 7 insertions(+), 216 deletions(-) diff --git a/guides/code/getting_started/app/controllers/comments_controller.rb b/guides/code/getting_started/app/controllers/comments_controller.rb index 7447fd078b..cf3d1be42e 100644 --- a/guides/code/getting_started/app/controllers/comments_controller.rb +++ b/guides/code/getting_started/app/controllers/comments_controller.rb @@ -1,16 +1,17 @@ class CommentsController < ApplicationController http_basic_authenticate_with :name => "dhh", :password => "secret", :only => :destroy + def create @post = Post.find(params[:post_id]) @comment = @post.comments.create(params[:comment]) redirect_to post_path(@post) end - + def destroy @post = Post.find(params[:post_id]) @comment = @post.comments.find(params[:id]) @comment.destroy redirect_to post_path(@post) end - + end diff --git a/guides/code/getting_started/app/controllers/posts_controller.rb b/guides/code/getting_started/app/controllers/posts_controller.rb index 85d2c1de47..a8ac9aba5a 100644 --- a/guides/code/getting_started/app/controllers/posts_controller.rb +++ b/guides/code/getting_started/app/controllers/posts_controller.rb @@ -1,5 +1,7 @@ class PostsController < ApplicationController + http_basic_authenticate_with :name => "dhh", :password => "secret", :except => [:index, :show] + def index @posts = Post.all end diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index 8ea7c5ab6e..1fbbd8af67 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -1540,12 +1540,12 @@ So first, let's add the delete link in the

- Commenter: + Commenter: <%= comment.commenter %>

- Comment: + Comment: <%= comment.body %>

@@ -1594,7 +1594,6 @@ model, +app/models/post.rb+, as follows: class Post < ActiveRecord::Base - validates :name, :presence => true validates :title, :presence => true, :length => { :minimum => 5 } has_many :comments, :dependent => :destroy @@ -1623,11 +1622,8 @@ class PostsController < ApplicationController http_basic_authenticate_with :name => "dhh", :password => "secret", :except => [:index, :show] - # GET /posts - # GET /posts.json def index @posts = Post.all - respond_to do |format| # snipped for brevity @@ -1649,214 +1645,6 @@ Authentication challenge !images/challenge.png(Basic HTTP Authentication Challenge)! -h3. Building a Multi-Model Form - -Another feature of your average blog is the ability to tag posts. To implement -this feature your application needs to interact with more than one model on a -single form. Rails offers support for nested forms. - -To demonstrate this, we will add support for giving each post multiple tags, -right in the form where you create the post. First, create a new model to hold -the tags: - - -$ rails generate model Tag name:string post:references - - -Again, run the migration to create the database table: - - -$ rake db:migrate - - -Next, edit the +post.rb+ file to create the other side of the association, and -to tell Rails (via the +accepts_nested_attributes_for+ macro) that you intend to -edit tags via posts: - - -class Post < ActiveRecord::Base - validates :name, :presence => true - validates :title, :presence => true, - :length => { :minimum => 5 } - - has_many :comments, :dependent => :destroy - has_many :tags - attr_protected :tags - - accepts_nested_attributes_for :tags, :allow_destroy => :true, - :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } -end - - -The +:allow_destroy+ option tells Rails to enable destroying tags through the -nested attributes (you'll handle that by displaying a "remove" checkbox on the -view that you'll build shortly). The +:reject_if+ option prevents saving new -tags that do not have any attributes filled in. - -We will modify +views/posts/_form.html.erb+ to render a partial to make a tag: - - -<% @post.tags.build %> -<%= form_for(@post) do |post_form| %> - <% if @post.errors.any? %> -
-

<%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:

-
    - <% @post.errors.full_messages.each do |msg| %> -
  • <%= msg %>
  • - <% end %> -
-
- <% end %> - -
- <%= post_form.label :name %>
- <%= post_form.text_field :name %> -
-
- <%= post_form.label :title %>
- <%= post_form.text_field :title %> -
-
- <%= post_form.label :content %>
- <%= post_form.text_area :content %> -
-

Tags

- <%= render :partial => 'tags/form', - :locals => {:form => post_form} %> -
- <%= post_form.submit %> -
-<% end %> -
- -Note that we have changed the +f+ in +form_for(@post) do |f|+ to +post_form+ to -make it easier to understand what is going on. - -This example shows another option of the render helper, being able to pass in -local variables, in this case, we want the local variable +form+ in the partial -to refer to the +post_form+ object. - -We also add a @post.tags.build at the top of this form. This is to make -sure there is a new tag ready to have its name filled in by the user. If you do -not build the new tag, then the form will not appear as there is no new Tag -object ready to create. - -Now create the folder app/views/tags and make a file in there called -_form.html.erb which contains the form for the tag: - - -<%= form.fields_for :tags do |tag_form| %> -
- <%= tag_form.label :name, 'Tag:' %> - <%= tag_form.text_field :name %> -
- <% unless tag_form.object.nil? || tag_form.object.new_record? %> -
- <%= tag_form.label :_destroy, 'Remove:' %> - <%= tag_form.check_box :_destroy %> -
- <% end %> -<% end %> -
- -Finally, we will edit the app/views/posts/show.html.erb template to -show our tags. - - -

<%= notice %>

- -

- Name: - <%= @post.name %> -

- -

- Title: - <%= @post.title %> -

- -

- Content: - <%= @post.content %> -

- -

- Tags: - <%= @post.tags.map { |t| t.name }.join(", ") %> -

- -

Comments

-<%= render @post.comments %> - -

Add a comment:

-<%= render "comments/form" %> - - -<%= link_to 'Edit Post', edit_post_path(@post) %> | -<%= link_to 'Back to Posts', posts_path %> | -
- -With these changes in place, you'll find that you can edit a post and its tags -directly on the same view. - -However, that method call @post.tags.map { |t| t.name }.join(", ") is -awkward, we could handle this by making a helper method. - -h3. View Helpers - -View Helpers live in app/helpers and provide small snippets of reusable -code for views. In our case, we want a method that strings a bunch of objects -together using their name attribute and joining them with a comma. As this is -for the Post show template, we put it in the PostsHelper. - -Open up app/helpers/posts_helper.rb and add the following: - - -module PostsHelper - def join_tags(post) - post.tags.map { |t| t.name }.join(", ") - end -end - - -Now you can edit the view in app/views/posts/show.html.erb to look like -this: - - -

<%= notice %>

- -

- Name: - <%= @post.name %> -

- -

- Title: - <%= @post.title %> -

- -

- Content: - <%= @post.content %> -

- -

- Tags: - <%= join_tags(@post) %> -

- -

Comments

-<%= render @post.comments %> - -

Add a comment:

-<%= render "comments/form" %> - - -<%= link_to 'Edit Post', edit_post_path(@post) %> | -<%= link_to 'Back to Posts', posts_path %> | -
- h3. What's Next? Now that you've seen your first Rails application, you should feel free to From b7394646af80cd632b1b4c48feb57f5f48ed160a Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Wed, 2 May 2012 12:34:35 +0200 Subject: [PATCH 13/20] Mention mac os x installation tools on getting started guide --- guides/source/getting_started.textile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index 1fbbd8af67..59c7a167fb 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -87,7 +87,10 @@ To install Rails, use the +gem install+ command provided by RubyGems: # gem install rails -TIP. If you're working on Windows, you can quickly install Ruby and Rails with "Rails Installer":http://railsinstaller.org. +TIP. A number of tools exist to help you quickly install Ruby and Ruby +on Rails on your system. Windows users can use "Rails +Installer":http://railsinstaller.org, while Mac Os X users can use +"Rails One Click":http://railsoneclick.com. To verify that you have everything installed correctly, you should be able to run the following: From 31500f7284515604891a74d9853f691e67c76261 Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Wed, 2 May 2012 13:44:08 +0300 Subject: [PATCH 14/20] Typo --- guides/source/getting_started.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index 59c7a167fb..31eb332c89 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -89,7 +89,7 @@ To install Rails, use the +gem install+ command provided by RubyGems: TIP. A number of tools exist to help you quickly install Ruby and Ruby on Rails on your system. Windows users can use "Rails -Installer":http://railsinstaller.org, while Mac Os X users can use +Installer":http://railsinstaller.org, while Mac OS X users can use "Rails One Click":http://railsoneclick.com. To verify that you have everything installed correctly, you should be able to run the following: From ce9e2534bfe68a1e14b686632cf848909558c098 Mon Sep 17 00:00:00 2001 From: Anuj Dutta Date: Thu, 3 May 2012 00:56:28 +0000 Subject: [PATCH 15/20] Corrected the name of the module that should be included to get the url helpers. --- actionpack/lib/action_dispatch/routing/url_for.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index d75bb1c2de..ee02f4b531 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -68,7 +68,7 @@ module ActionDispatch # This generates, among other things, the method users_path. By default, # this method is accessible from your controllers, views and mailers. If you need # to access this auto-generated method from other places (such as a model), then - # you can do that by including ActionController::UrlFor in your class: + # you can do that by including Rails.application.routes.url_helpers in your class: # # class User < ActiveRecord::Base # include Rails.application.routes.url_helpers From c9e809c8e49ed9af43044554ad1698aa07748851 Mon Sep 17 00:00:00 2001 From: Paul McMahon Date: Thu, 3 May 2012 17:20:59 +0900 Subject: [PATCH 16/20] I found it strange that this guide is redirecting questions to a specific person. Heiko Webers' (@hawe) last blog post is a year and a half old, so it's not obvious that he's still active with Rails security. If he is, feel free to revert. --- guides/source/security.textile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/guides/source/security.textile b/guides/source/security.textile index c065529cac..ac64b82bf6 100644 --- a/guides/source/security.textile +++ b/guides/source/security.textile @@ -1,7 +1,6 @@ h2. Ruby On Rails Security Guide -This manual describes common security problems in web applications and how to avoid them with Rails. If you have any questions or suggestions, please -mail me, Heiko Webers, at 42 {_et_} rorsecurity.info. After reading it, you should be familiar with: +This manual describes common security problems in web applications and how to avoid them with Rails. After reading it, you should be familiar with: * All countermeasures _(highlight)that are highlighted_ * The concept of sessions in Rails, what to put in there and popular attack methods From e608588d3a8dce80d62d78d88d6dea4008bf0d37 Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Thu, 3 May 2012 13:58:19 +0200 Subject: [PATCH 17/20] Update command line guide --- guides/source/command_line.textile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/guides/source/command_line.textile b/guides/source/command_line.textile index 95a01710b5..71386f427a 100644 --- a/guides/source/command_line.textile +++ b/guides/source/command_line.textile @@ -12,7 +12,7 @@ endprologue. NOTE: This tutorial assumes you have basic Rails knowledge from reading the "Getting Started with Rails Guide":getting_started.html. -WARNING. This Guide is based on Rails 3.0. Some of the code shown here will not work in earlier versions of Rails. +WARNING. This Guide is based on Rails 3.2. Some of the code shown here will not work in earlier versions of Rails. h3. Command Line Basics @@ -31,7 +31,7 @@ h4. +rails new+ The first thing we'll want to do is create a new Rails application by running the +rails new+ command after installing Rails. -WARNING: You can install the rails gem by typing +gem install rails+, if you don't have it already. Follow the instructions in the "Rails 3 Release Notes":/3_0_release_notes.html +TIP: You can install the rails gem by typing +gem install rails+, if you don't have it already. $ rails new commandsapp @@ -185,8 +185,6 @@ $ rails server => Booting WEBrick... -WARNING: Make sure that you do not have any "tilde backup" files in +app/views/(controller)+, or else WEBrick will _not_ show the expected output. This seems to be a *bug* in Rails 2.3.0. - The URL will be "http://localhost:3000/greetings/hello":http://localhost:3000/greetings/hello. INFO: With a normal, plain-old Rails application, your URLs will generally follow the pattern of http://(host)/(controller)/(action), and a URL like http://(host)/(controller) will hit the *index* action of that controller. From 026e0d1c4df68c3471a93b0f9d90a581d1511bd1 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Thu, 3 May 2012 22:16:04 -0300 Subject: [PATCH 18/20] Remove vestiges of the http_only! config from configuring guide --- guides/source/configuring.textile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/guides/source/configuring.textile b/guides/source/configuring.textile index 68426221bf..f17912e63c 100644 --- a/guides/source/configuring.textile +++ b/guides/source/configuring.textile @@ -248,14 +248,6 @@ They can also be removed from the stack completely: config.middleware.delete ActionDispatch::BestStandardsSupport
-In addition to these methods to handle the stack, if your application is going to be used as an API endpoint only, the middleware stack can be configured like this: - - -config.middleware.http_only! - - -By doing this, Rails will create a smaller middleware stack, by not adding some middlewares that are usually useful for browser access only, such as Cookies, Session and Flash, BestStandardsSupport, and MethodOverride. You can always add any of them later manually if you want. Refer to the "API App docs":api_app.html for more info on how to setup your application for API only apps. - h4. Configuring i18n * +config.i18n.default_locale+ sets the default locale of an application used for i18n. Defaults to +:en+. From c058a773b89b1bf4103f9bd4910743f60f238792 Mon Sep 17 00:00:00 2001 From: Oscar Del Ben Date: Fri, 4 May 2012 08:36:30 +0200 Subject: [PATCH 19/20] mention database mapping in getting started guide --- guides/source/getting_started.textile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/guides/source/getting_started.textile b/guides/source/getting_started.textile index 31eb332c89..947abd7ba0 100644 --- a/guides/source/getting_started.textile +++ b/guides/source/getting_started.textile @@ -404,7 +404,10 @@ $ rails generate model Post title:string text:text With that command we told Rails that we want a +Post+ model, which in turn should have a title attribute of type string, and a text attribute -of type text. Rails in turn responded by creating a bunch of files. For +of type text. Those attributes are automatically added to the +posts+ +table in the database and mapped to the +Post+ model. + +Rails in turn responded by creating a bunch of files. For now, we're only interested in +app/models/post.rb+ and +db/migrate/20120419084633_create_posts.rb+. The latter is responsible for creating the database structure, which is what we'll look at next. From 616de66c55b58479e7da4271a0c990529395440e Mon Sep 17 00:00:00 2001 From: Alexey Vakhov Date: Fri, 4 May 2012 12:32:35 +0400 Subject: [PATCH 20/20] Fix ActiveModel README example --- activemodel/README.rdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index 9b05384792..1fd75141f8 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -25,7 +25,7 @@ to integrate with Action Pack out of the box: ActiveModel::Model. person = Person.new(:name => 'bob', :age => '18') person.name # => 'bob' - person.age # => 18 + person.age # => '18' person.valid? # => true It includes model name introspections, conversions, translations and