diff options
Diffstat (limited to 'actionpack/README')
-rw-r--r-- | actionpack/README | 382 |
1 files changed, 0 insertions, 382 deletions
diff --git a/actionpack/README b/actionpack/README deleted file mode 100644 index 272feb63d0..0000000000 --- a/actionpack/README +++ /dev/null @@ -1,382 +0,0 @@ -= Action Pack -- On rails from request to response - -Action Pack splits the response to a web request into a controller part -(performing the logic) and a view part (rendering a template). This two-step -approach is known as an action, which will normally create, read, update, or -delete (CRUD for short) some sort of model part (often backed by a database) -before choosing either to render a template or redirecting to another action. - -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 ContactsController -would be responsible for listing contacts, creating, deleting, and updating -contacts. A WeblogController could be responsible for both posts and comments. - -Action View templates are written using embedded Ruby in tags mingled in with -the HTML. To avoid cluttering the templates with code, a bunch of helper -classes provide common behavior for forms, dates, and strings. And it's easy -to add specific helpers to keep the separation as the application evolves. - -A short rundown of the major features: - -* Actions grouped in controller as methods instead of separate command objects - and can therefore share helper methods - - CustomersController < ActionController::Base - def show - @customer = find_customer - end - - def update - @customer = find_customer - @customer.attributes = params[:customer] - @customer.save ? - redirect_to(:action => "show") : - render(:action => "edit") - end - - private - def find_customer() Customer.find(params[:id]) end - end - - {Learn more}[link:classes/ActionController/Base.html] - - -* Embedded Ruby for templates (no new "easy" template language) - - <% for post in @posts %> - Title: <%= post.title %> - <% end %> - - All post titles: <%= @posts.collect{ |p| p.title }.join ", " %> - - <% unless @person.is_client? %> - Not for clients to see... - <% end %> - - {Learn more}[link:classes/ActionView.html] - - -* Builder-based templates (great for XML content, like RSS) - - xml.rss("version" => "2.0") do - xml.channel do - xml.title(@feed_title) - xml.link(@url) - xml.description "Basecamp: Recent items" - xml.language "en-us" - xml.ttl "40" - - for item in @recent_items - xml.item do - xml.title(item_title(item)) - xml.description(item_description(item)) - xml.pubDate(item_pubDate(item)) - xml.guid(@recent_items.url(item)) - xml.link(@recent_items.url(item)) - end - end - end - end - - {Learn more}[link:classes/ActionView/Base.html] - - -* Filters for pre and post processing of the response (as methods, procs, and classes) - - class WeblogController < ActionController::Base - before_filter :authenticate, :cache, :audit - after_filter { |c| c.response.body = Gzip::compress(c.response.body) } - after_filter LocalizeFilter - - def index - # Before this action is run, the user will be authenticated, the cache - # will be examined to see if a valid copy of the results already - # exists, and the action will be logged for auditing. - - # After this action has run, the output will first be localized then - # compressed to minimize bandwidth usage - end - - private - def authenticate - # Implement the filter with full access to both request and response - end - end - - {Learn more}[link:classes/ActionController/Filters/ClassMethods.html] - - -* Helpers for forms, dates, action links, and text - - <%= text_field "post", "title", "size" => 30 %> - <%= html_date_select(Date.today) %> - <%= link_to "New post", :controller => "post", :action => "new" %> - <%= truncate(post.title, :length => 25) %> - - {Learn more}[link:classes/ActionView/Helpers.html] - - -* Layout sharing for template reuse (think simple version of Struts - Tiles[http://jakarta.apache.org/struts/userGuide/dev_tiles.html]) - - class WeblogController < ActionController::Base - layout "weblog_layout" - - def hello_world - end - end - - Layout file (called weblog_layout): - <html><body><%= yield %></body></html> - - Template for hello_world action: - <h1>Hello world</h1> - - Result of running hello_world action: - <html><body><h1>Hello world</h1></body></html> - - {Learn more}[link:classes/ActionController/Layout/ClassMethods.html] - - -* Routing makes pretty urls incredibly easy - - map.connect 'clients/:client_name/:project_name/:controller/:action' - - Accessing /clients/37signals/basecamp/project/dash calls ProjectController#dash with - { "client_name" => "37signals", "project_name" => "basecamp" } in params[:params] - - From that URL, you can rewrite the redirect in a number of ways: - - redirect_to(:action => "edit") => - /clients/37signals/basecamp/project/dash - - redirect_to(:client_name => "nextangle", :project_name => "rails") => - /clients/nextangle/rails/project/dash - - {Learn more}[link:classes/ActionController/Base.html] - - -* Easy testing of both controller and rendered template through ActionController::TestCase - - class LoginControllerTest < ActionController::TestCase - def test_failing_authenticate - process :authenticate, :user_name => "nop", :password => "" - assert flash.has_key?(:alert) - assert_redirected_to :action => "index" - end - end - - {Learn more}[link:classes/ActionController/TestCase.html] - - -* Automated benchmarking and integrated logging - - Started GET "/weblog" for 127.0.0.1 at Fri May 28 00:41:55 - Processing by WeblogController#index as HTML - Rendered weblog/index.html.erb within layouts/application (25.7ms) - Completed 200 OK in 29.3ms - - If Active Record is used as the model, you'll have the database debugging - as well: - - Started POST "/posts" for 127.0.0.1 at Sat Jun 19 14:04:23 - Processing by PostsController#create as HTML - Parameters: {"post"=>{"title"=>"this is good"}} - SQL (0.6ms) INSERT INTO posts (title) VALUES('this is good') - Redirected to http://example.com/posts/5 - Completed 302 Found in 221ms (Views: 215ms | ActiveRecord: 0.6ms) - - You specify a logger through a class method, such as: - - ActionController::Base.logger = Logger.new("Application Log") - ActionController::Base.logger = Log4r::Logger.new("Application Log") - - -* Caching at three levels of granularity (page, action, fragment) - - class WeblogController < ActionController::Base - caches_page :show - caches_action :account - - def show - # the output of the method will be cached as - # ActionController::Base.page_cache_directory + "/weblog/show/n.html" - # and the web server will pick it up without even hitting Rails - end - - def account - # the output of the method will be cached in the fragment store - # but Rails is hit to retrieve it, so filters are run - end - - def update - List.update(params[:list][:id], params[:list]) - expire_page :action => "show", :id => params[:list][:id] - expire_action :action => "account" - redirect_to :action => "show", :id => params[:list][:id] - end - end - - {Learn more}[link:classes/ActionController/Caching.html] - - -* Powerful debugging mechanism for local requests - - All exceptions raised on actions performed on the request of a local user - will be presented with a tailored debugging screen that includes exception - message, stack trace, request parameters, session contents, and the - half-finished response. - - {Learn more}[link:classes/ActionController/Rescue.html] - - -* Scaffolding for Active Record model objects - - class AccountController < ActionController::Base - scaffold :account - end - - The AccountController now has the full CRUD range of actions and default - templates: list, show, destroy, new, create, edit, update - - {Learn more}[link:classes/ActionController/Scaffolding/ClassMethods.html] - - -* Form building for Active Record model objects - - The post object has a title (varchar), content (text), and - written_on (date) - - <%= form "post" %> - - ...will generate something like (the selects will have more options, of - course): - - <form action="create" method="POST"> - <p> - <b>Title:</b><br/> - <input type="text" name="post[title]" value="<%= @post.title %>" /> - </p> - <p> - <b>Content:</b><br/> - <textarea name="post[content]"><%= @post.title %></textarea> - </p> - <p> - <b>Written on:</b><br/> - <select name='post[written_on(3i)]'><option>18</option></select> - <select name='post[written_on(2i)]'><option value='7'>July</option></select> - <select name='post[written_on(1i)]'><option>2004</option></select> - </p> - - <input type="submit" value="Create"> - </form> - - This form generates a params[:post] array that can be used directly in a save action: - - class WeblogController < ActionController::Base - def create - post = Post.create(params[:post]) - redirect_to :action => "show", :id => post.id - end - end - - {Learn more}[link:classes/ActionView/Helpers/ActiveRecordHelper.html] - - -* Runs on top of WEBrick, Mongrel, CGI, FCGI, and mod_ruby - - -== Simple example (from outside of Rails) - -This example will implement a simple weblog system using inline templates and -an Active Record model. So let's build that WeblogController with just a few -methods: - - require 'action_controller' - require 'post' - - class WeblogController < ActionController::Base - layout "weblog/layout" - - def index - @posts = Post.find(:all) - end - - def show - @post = Post.find(params[:id]) - end - - def new - @post = Post.new - end - - def create - @post = Post.create(params[:post]) - redirect_to :action => "show", :id => @post.id - end - end - - WeblogController::Base.view_paths = [ File.dirname(__FILE__) ] - WeblogController.process_cgi if $0 == __FILE__ - -The last two lines are responsible for telling ActionController where the -template files are located and actually running the controller on a new -request from the web-server (like to be Apache). - -And the templates look like this: - - weblog/layout.html.erb: - <html><body> - <%= yield %> - </body></html> - - weblog/index.html.erb: - <% for post in @posts %> - <p><%= link_to(post.title, :action => "show", :id => post.id) %></p> - <% end %> - - weblog/show.html.erb: - <p> - <b><%= @post.title %></b><br/> - <b><%= @post.content %></b> - </p> - - 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 show page using -an URL such as /weblog/5 (where 5 is the id of the post). - - -== Download - -The latest version of Action Pack can be installed with Rubygems: - -* gem install actionpack - -Documentation can be found at - -* http://api.rubyonrails.org - - -== License - -Action Pack is released under the MIT license. - - -== Support - -The Action Pack homepage is http://www.rubyonrails.org. You can find -the Action Pack RubyForge page at http://rubyforge.org/projects/actionpack. -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. |