Permalink
Browse files

Merge with docrails

  • Loading branch information...
1 parent e56b3e4 commit 53cd102b39eb62567298430cbd94e40dd78d46a0 @lifo lifo committed Feb 24, 2009
Showing with 2,223 additions and 1,512 deletions.
  1. +31 −3 actionpack/lib/action_controller/base.rb
  2. +11 −3 actionpack/lib/action_controller/streaming.rb
  3. +4 −2 actionpack/lib/action_view/helpers/form_helper.rb
  4. +29 −36 activerecord/lib/active_record/associations.rb
  5. +2 −1 activerecord/lib/active_record/base.rb
  6. +33 −5 activerecord/lib/active_record/callbacks.rb
  7. +46 −57 activerecord/lib/active_record/fixtures.rb
  8. +1 −1 railties/guides/files/javascripts/code_highlighter.js
  9. +408 −267 railties/guides/files/stylesheets/main.css
  10. +1 −1 railties/guides/files/stylesheets/print.css
  11. +1 −1 railties/guides/files/stylesheets/reset.css
  12. +1 −1 railties/guides/files/stylesheets/syntax.css
  13. +2 −1 railties/guides/rails_guides.rb
  14. +31 −29 railties/guides/rails_guides/generator.rb
  15. +6 −2 railties/guides/rails_guides/indexer.rb
  16. +3 −0 railties/guides/rails_guides/textile_extensions.rb
  17. +4 −4 railties/guides/source/2_2_release_notes.textile
  18. +47 −4 railties/guides/source/2_3_release_notes.textile
  19. +201 −223 railties/guides/source/action_controller_overview.textile
  20. +77 −112 railties/guides/source/action_mailer_basics.textile
  21. +9 −9 railties/guides/source/active_record_basics.textile
  22. +414 −217 railties/guides/source/active_record_querying.textile
  23. +146 −112 railties/guides/source/activerecord_validations_callbacks.textile
  24. +30 −30 railties/guides/source/association_basics.textile
  25. +126 −40 railties/guides/source/caching_with_rails.textile
  26. +85 −10 railties/guides/source/command_line.textile
  27. +5 −5 railties/guides/source/configuring.textile
  28. +77 −0 railties/guides/source/contribute.textile
  29. +15 −14 railties/guides/source/credits.erb.textile
  30. +1 −1 railties/guides/source/debugging_rails_applications.textile
  31. +25 −29 railties/guides/source/form_helpers.textile
  32. +4 −5 railties/guides/source/getting_started.textile
  33. +1 −1 railties/guides/source/i18n.textile
  34. +7 −3 railties/guides/source/index.erb.textile
  35. +4 −3 railties/guides/source/layout.html.erb
  36. +83 −75 railties/guides/source/layouts_and_rendering.textile
  37. +49 −38 railties/guides/source/migrations.textile
  38. +33 −33 railties/guides/source/performance_testing.textile
  39. +9 −3 railties/guides/source/plugins.textile
  40. +83 −53 railties/guides/source/rails_on_rack.textile
  41. +21 −22 railties/guides/source/routing.textile
  42. +46 −46 railties/guides/source/security.textile
  43. +9 −9 railties/guides/source/testing.textile
  44. +2 −1 railties/lib/initializer.rb
@@ -784,9 +784,37 @@ def append_view_path(path)
# # placed in "app/views/layouts/special.r(html|xml)"
# render :text => "Hi there!", :layout => "special"
#
- # The <tt>:text</tt> option can also accept a Proc object, which can be used to manually control the page generation. This should
- # generally be avoided, as it violates the separation between code and content, and because almost everything that can be
- # done with this method can also be done more cleanly using one of the other rendering methods, most notably templates.
+ # === Streaming data and/or controlling the page generation
+ #
+ # The <tt>:text</tt> option can also accept a Proc object, which can be used to:
+ #
+ # 1. stream on-the-fly generated data to the browser. Note that you should
+ # use the methods provided by ActionController::Steaming instead if you
+ # want to stream a buffer or a file.
+ # 2. manually control the page generation. This should generally be avoided,
+ # as it violates the separation between code and content, and because almost
+ # everything that can be done with this method can also be done more cleanly
+ # using one of the other rendering methods, most notably templates.
+ #
+ # Two arguments are passed to the proc, a <tt>response</tt> object and an
+ # <tt>output</tt> object. The response object is equivalent to the return
+ # value of the ActionController::Base#response method, and can be used to
+ # control various things in the HTTP response, such as setting the
+ # Content-Type header. The output object is an writable <tt>IO</tt>-like
+ # object, so one can call <tt>write</tt> and <tt>flush</tt> on it.
+ #
+ # The following example demonstrates how one can stream a large amount of
+ # on-the-fly generated data to the browser:
+ #
+ # # Streams about 180 MB of generated data to the browser.
+ # render :text => proc { |response, output|
+ # 10_000_000.times do |i|
+ # output.write("This is line #{i}\n")
+ # output.flush
+ # end
+ # }
+ #
+ # Another example:
#
# # Renders "Hello from code!"
# render :text => proc { |response, output| output.write("Hello from code!") }
@@ -1,5 +1,6 @@
module ActionController #:nodoc:
- # Methods for sending files and streams to the browser instead of rendering.
+ # Methods for sending arbitrary data and for streaming files to the browser,
+ # instead of rendering.
module Streaming
DEFAULT_SEND_FILE_OPTIONS = {
:type => 'application/octet-stream'.freeze,
@@ -103,8 +104,11 @@ def send_file(path, options = {}) #:doc:
end
end
- # Send binary data to the user as a file download. May set content type, apparent file name,
- # and specify whether to show data inline or download as an attachment.
+ # Sends the given binary data to the browser. This method is similar to
+ # <tt>render :text => data</tt>, but also allows you to specify whether
+ # the browser should display the response as a file attachment (i.e. in a
+ # download dialog) or as inline data. You may also set the content type,
+ # the apparent file name, and other things.
#
# Options:
# * <tt>:filename</tt> - suggests a filename for the browser to use.
@@ -127,6 +131,10 @@ def send_file(path, options = {}) #:doc:
# send_data image.data, :type => image.content_type, :disposition => 'inline'
#
# See +send_file+ for more information on HTTP Content-* headers and caching.
+ #
+ # <b>Tip:</b> if you want to stream large amounts of on-the-fly generated
+ # data to the browser, then use <tt>render :text => proc { ... }</tt>
+ # instead. See ActionController::Base#render for more information.
def send_data(data, options = {}) #:doc:
logger.info "Sending data #{options[:filename]}" if logger
send_file_headers! options.merge(:length => data.size)
@@ -646,8 +646,10 @@ def check_box(object_name, method, options = {}, checked_value = "1", unchecked_
# Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object
# assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the
- # radio button will be checked. Additional options on the input tag can be passed as a
- # hash with +options+.
+ # radio button will be checked.
+ #
+ # To force the radio button to be checked pass <tt>:checked => true</tt> in the
+ # +options+ hash. You may pass HTML options there as well.
#
# ==== Examples
# # Let's say that @post.category returns "rails":
@@ -133,41 +133,40 @@ def association_instance_set(name, association)
# | | belongs_to |
# generated methods | belongs_to | :polymorphic | has_one
# ----------------------------------+------------+--------------+---------
- # #other | X | X | X
- # #other=(other) | X | X | X
- # #build_other(attributes={}) | X | | X
- # #create_other(attributes={}) | X | | X
- # #other.create!(attributes={}) | | | X
- # #other.nil? | X | X |
+ # other | X | X | X
+ # other=(other) | X | X | X
+ # build_other(attributes={}) | X | | X
+ # create_other(attributes={}) | X | | X
+ # other.create!(attributes={}) | | | X
#
# ===Collection associations (one-to-many / many-to-many)
# | | | has_many
# generated methods | habtm | has_many | :through
# ----------------------------------+-------+----------+----------
- # #others | X | X | X
- # #others=(other,other,...) | X | X | X
- # #other_ids | X | X | X
- # #other_ids=(id,id,...) | X | X | X
- # #others<< | X | X | X
- # #others.push | X | X | X
- # #others.concat | X | X | X
- # #others.build(attributes={}) | X | X | X
- # #others.create(attributes={}) | X | X | X
- # #others.create!(attributes={}) | X | X | X
- # #others.size | X | X | X
- # #others.length | X | X | X
- # #others.count | X | X | X
- # #others.sum(args*,&block) | X | X | X
- # #others.empty? | X | X | X
- # #others.clear | X | X | X
- # #others.delete(other,other,...) | X | X | X
- # #others.delete_all | X | X |
- # #others.destroy_all | X | X | X
- # #others.find(*args) | X | X | X
- # #others.find_first | X | |
- # #others.exists? | X | X | X
- # #others.uniq | X | X | X
- # #others.reset | X | X | X
+ # others | X | X | X
+ # others=(other,other,...) | X | X | X
+ # other_ids | X | X | X
+ # other_ids=(id,id,...) | X | X | X
+ # others<< | X | X | X
+ # others.push | X | X | X
+ # others.concat | X | X | X
+ # others.build(attributes={}) | X | X | X
+ # others.create(attributes={}) | X | X | X
+ # others.create!(attributes={}) | X | X | X
+ # others.size | X | X | X
+ # others.length | X | X | X
+ # others.count | X | X | X
+ # others.sum(args*,&block) | X | X | X
+ # others.empty? | X | X | X
+ # others.clear | X | X | X
+ # others.delete(other,other,...) | X | X | X
+ # others.delete_all | X | X |
+ # others.destroy_all | X | X | X
+ # others.find(*args) | X | X | X
+ # others.find_first | X | |
+ # others.exists? | X | X | X
+ # others.uniq | X | X | X
+ # others.reset | X | X | X
#
# == Cardinality and associations
#
@@ -813,8 +812,6 @@ def has_many(association_id, options = {}, &extension)
# [association=(associate)]
# Assigns the associate object, extracts the primary key, sets it as the foreign key,
# and saves the associate object.
- # [association.nil?]
- # Returns +true+ if there is no associated object.
# [build_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+ and linked to this object through a foreign key, but has not
@@ -833,7 +830,6 @@ def has_many(association_id, options = {}, &extension)
# An Account class declares <tt>has_one :beneficiary</tt>, which will add:
# * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.find(:first, :conditions => "account_id = #{id}")</tt>)
# * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>)
- # * <tt>Account#beneficiary.nil?</tt>
# * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>)
# * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>)
#
@@ -934,8 +930,6 @@ def has_one(association_id, options = {})
# Returns the associated object. +nil+ is returned if none is found.
# [association=(associate)]
# Assigns the associate object, extracts the primary key, and sets it as the foreign key.
- # [association.nil?]
- # Returns +true+ if there is no associated object.
# [build_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
@@ -953,7 +947,6 @@ def has_one(association_id, options = {})
# * <tt>Post#author</tt> (similar to <tt>Author.find(author_id)</tt>)
# * <tt>Post#author=(author)</tt> (similar to <tt>post.author_id = author.id</tt>)
# * <tt>Post#author?</tt> (similar to <tt>post.author == some_author</tt>)
- # * <tt>Post#author.nil?</tt>
# * <tt>Post#build_author</tt> (similar to <tt>post.author = Author.new</tt>)
# * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>)
# The declaration can also include an options hash to specialize the behavior of the association.
@@ -886,7 +886,8 @@ def destroy_all(conditions = nil)
# Deletes the records matching +conditions+ without instantiating the records first, and hence not
# calling the +destroy+ method nor invoking callbacks. This is a single SQL DELETE statement that
# goes straight to the database, much more efficient than +destroy_all+. Be careful with relations
- # though, in particular <tt>:dependent</tt> rules defined on associations are not honored.
+ # though, in particular <tt>:dependent</tt> rules defined on associations are not honored. Returns
+ # the number of rows affected.
#
# ==== Parameters
#
@@ -104,6 +104,37 @@ module ActiveRecord
# The callback objects have methods named after the callback called with the record as the only parameter, such as:
#
# class BankAccount < ActiveRecord::Base
+ # before_save EncryptionWrapper.new
+ # after_save EncryptionWrapper.new
+ # after_initialize EncryptionWrapper.new
+ # end
+ #
+ # class EncryptionWrapper
+ # def before_save(record)
+ # record.credit_card_number = encrypt(record.credit_card_number)
+ # end
+ #
+ # def after_save(record)
+ # record.credit_card_number = decrypt(record.credit_card_number)
+ # end
+ #
+ # alias_method :after_find, :after_save
+ #
+ # private
+ # def encrypt(value)
+ # # Secrecy is committed
+ # end
+ #
+ # def decrypt(value)
+ # # Secrecy is unveiled
+ # end
+ # end
+ #
+ # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has
+ # a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other
+ # initialization data such as the name of the attribute to work with:
+ #
+ # class BankAccount < ActiveRecord::Base
# before_save EncryptionWrapper.new("credit_card_number")
# after_save EncryptionWrapper.new("credit_card_number")
# after_initialize EncryptionWrapper.new("credit_card_number")
@@ -115,11 +146,11 @@ module ActiveRecord
# end
#
# def before_save(record)
- # record.credit_card_number = encrypt(record.credit_card_number)
+ # record.send("#{@attribute}=", encrypt(record.send("#{@attribute}")))
# end
#
# def after_save(record)
- # record.credit_card_number = decrypt(record.credit_card_number)
+ # record.send("#{@attribute}=", decrypt(record.send("#{@attribute}")))
# end
#
# alias_method :after_find, :after_save
@@ -134,9 +165,6 @@ module ActiveRecord
# end
# end
#
- # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has
- # a method by the name of the callback messaged.
- #
# The callback macros usually accept a symbol for the method they're supposed to run, but you can also pass a "method string",
# which will then be evaluated within the binding of the callback. Example:
#
Oops, something went wrong.

0 comments on commit 53cd102

Please sign in to comment.