Skip to content

Commit

Permalink
Merge with docrails
Browse files Browse the repository at this point in the history
  • Loading branch information
lifo committed Dec 7, 2008
1 parent 9eca588 commit dbbae5e
Show file tree
Hide file tree
Showing 78 changed files with 5,289 additions and 1,429 deletions.
96 changes: 21 additions & 75 deletions actionpack/README
Expand Up @@ -10,7 +10,7 @@ Action Pack implements these actions as public methods on Action Controllers
and uses Action Views to implement the template rendering. Action Controllers
are then responsible for handling all the actions relating to a certain part
of an application. This grouping usually consists of actions for lists and for
CRUDs revolving around a single (or a few) model objects. So ContactController
CRUDs revolving around a single (or a few) model objects. So ContactsController
would be responsible for listing contacts, creating, deleting, and updating
contacts. A WeblogController could be responsible for both posts and comments.

Expand All @@ -33,7 +33,7 @@ A short rundown of the major features:
* Actions grouped in controller as methods instead of separate command objects
and can therefore share helper methods

BlogController < ActionController::Base
CustomersController < ActionController::Base
def show
@customer = find_customer
end
Expand All @@ -42,7 +42,7 @@ A short rundown of the major features:
@customer = find_customer
@customer.attributes = params[:customer]
@customer.save ?
redirect_to(:action => "display") :
redirect_to(:action => "show") :
render(:action => "edit")
end

Expand All @@ -59,7 +59,7 @@ A short rundown of the major features:
Title: <%= post.title %>
<% end %>

All post titles: <%= @post.collect{ |p| p.title }.join ", " %>
All post titles: <%= @posts.collect{ |p| p.title }.join ", " %>

<% unless @person.is_client? %>
Not for clients to see...
Expand Down Expand Up @@ -123,7 +123,7 @@ A short rundown of the major features:
<%= text_field "post", "title", "size" => 30 %>
<%= html_date_select(Date.today) %>
<%= link_to "New post", :controller => "post", :action => "new" %>
<%= truncate(post.title, 25) %>
<%= truncate(post.title, :length => 25) %>

{Learn more}[link:classes/ActionView/Helpers.html]

Expand Down Expand Up @@ -177,21 +177,6 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionView/Helpers/JavaScriptHelper.html]


* Pagination for navigating lists of results

# controller
def list
@pages, @people =
paginate :people, :order => 'last_name, first_name'
end

# view
<%= link_to "Previous page", { :page => @pages.current.previous } if @pages.current.previous %>
<%= link_to "Next page", { :page => @pages.current.next } if @pages.current.next %>

{Learn more}[link:classes/ActionController/Pagination.html]


* Easy testing of both controller and rendered template through ActionController::TestCase

class LoginControllerTest < ActionController::TestCase
Expand All @@ -215,11 +200,11 @@ A short rundown of the major features:
If Active Record is used as the model, you'll have the database debugging
as well:

Processing WeblogController#create (for 127.0.0.1 at Sat Jun 19 14:04:23)
Params: {"controller"=>"weblog", "action"=>"create",
Processing PostsController#create (for 127.0.0.1 at Sat Jun 19 14:04:23)
Params: {"controller"=>"posts", "action"=>"create",
"post"=>{"title"=>"this is good"} }
SQL (0.000627) INSERT INTO posts (title) VALUES('this is good')
Redirected to http://test/weblog/display/5
Redirected to http://example.com/posts/5
Completed in 0.221764 (4 reqs/sec) | DB: 0.059920 (27%)

You specify a logger through a class method, such as:
Expand Down Expand Up @@ -256,30 +241,6 @@ A short rundown of the major features:
{Learn more}[link:classes/ActionController/Caching.html]


* Component requests from one controller to another

class WeblogController < ActionController::Base
# Performs a method and then lets hello_world output its render
def delegate_action
do_other_stuff_before_hello_world
render_component :controller => "greeter", :action => "hello_world"
end
end

class GreeterController < ActionController::Base
def hello_world
render_text "Hello World!"
end
end

The same can be done in a view to do a partial rendering:

Let's see a greeting:
<%= render_component :controller => "greeter", :action => "hello_world" %>

{Learn more}[link:classes/ActionController/Components.html]


* Powerful debugging mechanism for local requests

All exceptions raised on actions performed on the request of a local user
Expand Down Expand Up @@ -336,7 +297,7 @@ A short rundown of the major features:
class WeblogController < ActionController::Base
def create
post = Post.create(params[:post])
redirect_to :action => "display", :id => post.id
redirect_to :action => "show", :id => post.id
end
end

Expand All @@ -362,7 +323,7 @@ methods:
@posts = Post.find(:all)
end

def display
def show
@post = Post.find(params[:id])
end

Expand All @@ -372,7 +333,7 @@ methods:

def create
@post = Post.create(params[:post])
redirect_to :action => "display", :id => @post.id
redirect_to :action => "show", :id => @post.id
end
end

Expand All @@ -385,47 +346,32 @@ request from the web-server (like to be Apache).

And the templates look like this:

weblog/layout.erb:
weblog/layout.html.erb:
<html><body>
<%= yield %>
</body></html>

weblog/index.erb:
weblog/index.html.erb:
<% for post in @posts %>
<p><%= link_to(post.title, :action => "display", :id => post.id %></p>
<p><%= link_to(post.title, :action => "show", :id => post.id) %></p>
<% end %>

weblog/display.erb:
weblog/show.html.erb:
<p>
<b><%= post.title %></b><br/>
<b><%= post.content %></b>
<b><%= @post.title %></b><br/>
<b><%= @post.content %></b>
</p>

weblog/new.erb:
weblog/new.html.erb:
<%= form "post" %>

This simple setup will list all the posts in the system on the index page,
which is called by accessing /weblog/. It uses the form builder for the Active
Record model to make the new screen, which in turn hands everything over to
the create action (that's the default target for the form builder when given a
new model). After creating the post, it'll redirect to the display page using
an URL such as /weblog/display/5 (where 5 is the id of the post).


== Examples

Action Pack ships with three examples that all demonstrate an increasingly
detailed view of the possibilities. First is blog_controller that is just a
single file for the whole MVC (but still split into separate parts). Second is
the debate_controller that uses separate template files and multiple screens.
Third is the address_book_controller that uses the layout feature to separate
template casing from content.

Please note that you might need to change the "shebang" line to
#!/usr/local/env ruby, if your Ruby is not placed in /usr/local/bin/ruby
new model). After creating the post, it'll redirect to the show page using
an URL such as /weblog/5 (where 5 is the id of the post).

Also note that these examples are all for demonstrating using Action Pack on
its own. Not for when it's used inside of Rails.

== Download

Expand Down Expand Up @@ -460,4 +406,4 @@ And as Jim from Rake says:

Feel free to submit commits or feature requests. If you send a patch,
remember to update the corresponding unit tests. If fact, I prefer
new feature to be submitted in the form of new unit tests.
new feature to be submitted in the form of new unit tests.
26 changes: 17 additions & 9 deletions actionpack/lib/action_controller/caching/fragments.rb
Expand Up @@ -83,15 +83,23 @@ def fragment_exist?(key, options = nil)
end
end

# Name can take one of three forms:
# * String: This would normally take the form of a path like "pages/45/notes"
# * Hash: Is treated as an implicit call to url_for, like { :controller => "pages", :action => "notes", :id => 45 }
# * Regexp: Will destroy all the matched fragments, example:
# %r{pages/\d*/notes}
# Ensure you do not specify start and finish in the regex (^$) because
# the actual filename matched looks like ./cache/filename/path.cache
# Regexp expiration is only supported on caches that can iterate over
# all keys (unlike memcached).
# Removes fragments from the cache.
#
# +key+ can take one of three forms:
# * String - This would normally take the form of a path, like
# <tt>"pages/45/notes"</tt>.
# * Hash - Treated as an implicit call to +url_for+, like
# <tt>{:controller => "pages", :action => "notes", :id => 45}</tt>
# * Regexp - Will remove any fragment that matches, so
# <tt>%r{pages/\d*/notes}</tt> might remove all notes. Make sure you
# don't use anchors in the regex (<tt>^</tt> or <tt>$</tt>) because
# the actual filename matched looks like
# <tt>./cache/filename/path.cache</tt>. Note: Regexp expiration is
# only supported on caches that can iterate over all keys (unlike
# memcached).
#
# +options+ is passed through to the cache store's <tt>delete</tt>
# method (or <tt>delete_matched</tt>, for Regexp keys.)
def expire_fragment(key, options = nil)
return unless cache_configured?

Expand Down
26 changes: 12 additions & 14 deletions actionpack/lib/action_controller/caching/pages.rb
Expand Up @@ -33,28 +33,26 @@ module Caching
#
# Additionally, you can expire caches using Sweepers that act on changes in the model to determine when a cache is supposed to be
# expired.
#
# == Setting the cache directory
#
# The cache directory should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>.
# For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>RAILS_ROOT + "/public"</tt>). Changing
# this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your
# web server to look in the new location for cached files.
#
# == Setting the cache extension
#
# Most Rails requests do not have an extension, such as <tt>/weblog/new</tt>. In these cases, the page caching mechanism will add one in
# order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is <tt>.html</tt>.
# If you want something else, like <tt>.php</tt> or <tt>.shtml</tt>, just set Base.page_cache_extension. In cases where a request already has an
# extension, such as <tt>.xml</tt> or <tt>.rss</tt>, page caching will not add an extension. This allows it to work well with RESTful apps.
module Pages
def self.included(base) #:nodoc:
base.extend(ClassMethods)
base.class_eval do
@@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : ""
##
# :singleton-method:
# The cache directory should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>.
# For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>RAILS_ROOT + "/public"</tt>). Changing
# this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your
# web server to look in the new location for cached files.
cattr_accessor :page_cache_directory

@@page_cache_extension = '.html'
##
# :singleton-method:
# Most Rails requests do not have an extension, such as <tt>/weblog/new</tt>. In these cases, the page caching mechanism will add one in
# order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is <tt>.html</tt>.
# If you want something else, like <tt>.php</tt> or <tt>.shtml</tt>, just set Base.page_cache_extension. In cases where a request already has an
# extension, such as <tt>.xml</tt> or <tt>.rss</tt>, page caching will not add an extension. This allows it to work well with RESTful apps.
cattr_accessor :page_cache_extension
end
end
Expand Down
7 changes: 6 additions & 1 deletion actionpack/lib/action_controller/resources.rb
Expand Up @@ -283,7 +283,12 @@ def initialize(entity, options)
# * <tt>:new</tt> - Same as <tt>:collection</tt>, but for actions that operate on the new \resource action.
# * <tt>:controller</tt> - Specify the controller name for the routes.
# * <tt>:singular</tt> - Specify the singular name used in the member routes.
# * <tt>:requirements</tt> - Set custom routing parameter requirements.
# * <tt>:requirements</tt> - Set custom routing parameter requirements; this is a hash of either
# regular expressions (which must match for the route to match) or extra parameters. For example:
#
# map.resource :profile, :path_prefix => ':name', :requirements => { :name => /[a-zA-Z]+/, :extra => 'value' }
#
# will only match if the first part is alphabetic, and will pass the parameter :extra to the controller.
# * <tt>:conditions</tt> - Specify custom routing recognition conditions. \Resources sets the <tt>:method</tt> value for the method-specific routes.
# * <tt>:as</tt> - Specify a different \resource name to use in the URL path. For example:
# # products_path == '/productos'
Expand Down
6 changes: 4 additions & 2 deletions actionpack/lib/action_controller/routing.rb
Expand Up @@ -83,9 +83,11 @@ module ActionController
# This sets up +blog+ as the default controller if no other is specified.
# This means visiting '/' would invoke the blog controller.
#
# More formally, you can define defaults in a route with the <tt>:defaults</tt> key.
# More formally, you can include arbitrary parameters in the route, thus:
#
# map.connect ':controller/:action/:id', :action => 'show', :defaults => { :page => 'Dashboard' }
# map.connect ':controller/:action/:id', :action => 'show', :page => 'Dashboard'
#
# This will pass the :page parameter to all incoming requests that match this route.
#
# Note: The default routes, as provided by the Rails generator, make all actions in every
# controller accessible via GET requests. You should consider removing them or commenting
Expand Down
10 changes: 10 additions & 0 deletions actionpack/lib/action_controller/session/active_record_store.rb
Expand Up @@ -56,6 +56,8 @@ def model
class ActiveRecordStore
# The default Active Record class.
class Session < ActiveRecord::Base
##
# :singleton-method:
# Customizable data column name. Defaults to 'data'.
cattr_accessor :data_column_name
self.data_column_name = 'data'
Expand Down Expand Up @@ -166,17 +168,25 @@ def raise_on_session_data_overflow!
# binary session data in a +text+ column. For higher performance,
# store in a +blob+ column instead and forgo the Base64 encoding.
class SqlBypass
##
# :singleton-method:
# Use the ActiveRecord::Base.connection by default.
cattr_accessor :connection

##
# :singleton-method:
# The table name defaults to 'sessions'.
cattr_accessor :table_name
@@table_name = 'sessions'

##
# :singleton-method:
# The session id field defaults to 'session_id'.
cattr_accessor :session_id_column
@@session_id_column = 'session_id'

##
# :singleton-method:
# The data field defaults to 'data'.
cattr_accessor :data_column
@@data_column = 'data'
Expand Down
8 changes: 6 additions & 2 deletions actionpack/lib/action_view/base.rb
Expand Up @@ -183,13 +183,17 @@ def self.exempt_from_layout(*extensions)
@@exempt_from_layout.merge(regexps)
end

@@debug_rjs = false
##
# :singleton-method:
# Specify whether RJS responses should be wrapped in a try/catch block
# that alert()s the caught exception (and then re-raises it).
@@debug_rjs = false
cattr_accessor :debug_rjs

# A warning will be displayed whenever an action results in a cache miss on your view paths.
@@warn_cache_misses = false
##
# :singleton-method:
# A warning will be displayed whenever an action results in a cache miss on your view paths.
cattr_accessor :warn_cache_misses

attr_internal :request
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_view/helpers/tag_helper.rb
Expand Up @@ -97,7 +97,7 @@ def cdata_section(content)
# Returns an escaped version of +html+ without affecting existing escaped entities.
#
# ==== Examples
# escape_once("1 > 2 &amp; 3")
# escape_once("1 < 2 &amp; 3")
# # => "1 &lt; 2 &amp; 3"
#
# escape_once("&lt;&lt; Accept & Checkout")
Expand Down
2 changes: 2 additions & 0 deletions actionpack/lib/action_view/template_handlers/erb.rb
Expand Up @@ -3,6 +3,8 @@ module TemplateHandlers
class ERB < TemplateHandler
include Compilable

##
# :singleton-method:
# Specify trim mode for the ERB compiler. Defaults to '-'.
# See ERb documentation for suitable values.
cattr_accessor :erb_trim_mode
Expand Down
2 changes: 2 additions & 0 deletions activemodel/lib/active_model/errors.rb
Expand Up @@ -24,6 +24,8 @@ class Errors < Hash
:even => "must be even"
}

##
# :singleton-method:
# Holds a hash with all the default error messages that can be replaced by your own copy or localizations.
cattr_accessor :default_error_messages

Expand Down

0 comments on commit dbbae5e

Please sign in to comment.