diff options
author | Timothy N. Tsvetkov <timothy.tsvetkov@gmail.com> | 2011-02-05 18:37:53 +0300 |
---|---|---|
committer | Santiago Pastorino <santiago@wyeworks.com> | 2011-02-05 18:58:32 -0200 |
commit | b9309b47cda12db34ac3427fbafff2dca0314ed7 (patch) | |
tree | 3a45755fa1f3430c9ea4152e7f58cba8e8df70b6 | |
parent | 5af31f37fb28e2e78b96d1ccf624871c883cc622 (diff) | |
download | rails-b9309b47cda12db34ac3427fbafff2dca0314ed7.tar.gz rails-b9309b47cda12db34ac3427fbafff2dca0314ed7.tar.bz2 rails-b9309b47cda12db34ac3427fbafff2dca0314ed7.zip |
Added tests for form_for and an authenticity_token option. Added docs for for_for and authenticity_token option. Added section to form helpers guide about forms for external resources and new authenticity_token option for form_tag and form_for helpers.
[#6228 state:committed]
Signed-off-by: Santiago Pastorino <santiago@wyeworks.com>
-rw-r--r-- | actionpack/lib/action_view/helpers/form_helper.rb | 18 | ||||
-rw-r--r-- | actionpack/test/controller/request_forgery_protection_test.rb | 18 | ||||
-rw-r--r-- | railties/guides/source/form_helpers.textile | 36 |
3 files changed, 72 insertions, 0 deletions
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index d6edef0d34..408a3b6721 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -298,6 +298,24 @@ module ActionView # # If you don't need to attach a form to a model instance, then check out # FormTagHelper#form_tag. + # + # === Form to external resources + # + # When you build forms to external resources sometimes you need to set an authenticity token or just render a form + # without it, for example when you submit data to a payment gateway number and types of fields could be limited. + # + # To set an authenticity token you need to pass an <tt>:authenticity_token</tt> parameter in the <tt>:html</tt> + # options section: + # + # <%= form_for @invoice, :url => external_url, :html => { :authenticity_token => 'external_token' } do |f| + # ... + # <% end %> + # + # If you don't want to an authenticity token field be rendered at all just pass <tt>false</tt>: + # + # <%= form_for @invoice, :url => external_url, :html => { :authenticity_token => false } do |f| + # ... + # <% end %> def form_for(record, options = {}, &proc) raise ArgumentError, "Missing block" unless block_given? diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb index 405af2a650..4f4de0cbee 100644 --- a/actionpack/test/controller/request_forgery_protection_test.rb +++ b/actionpack/test/controller/request_forgery_protection_test.rb @@ -28,6 +28,14 @@ module RequestForgeryProtectionActions render :inline => "<%= csrf_meta_tags %>" end + def external_form_for + render :inline => "<%= form_for(:some_resource, :html => { :authenticity_token => 'external_token' }) {} %>" + end + + def form_for_without_protection + render :inline => "<%= form_for(:some_resource, :html => { :authenticity_token => false }) {} %>" + end + def rescue_action(e) raise e end end @@ -68,6 +76,16 @@ module RequestForgeryProtectionTests assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token end + def test_should_render_external_form_for_with_external_token + get :external_form_for + assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', 'external_token' + end + + def test_should_render_form_for_without_token_tag + get :form_for_without_protection + assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token, false + end + def test_should_render_button_to_with_token_tag get :show_button assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', @token diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile index 7b4426b335..cdb311c726 100644 --- a/railties/guides/source/form_helpers.textile +++ b/railties/guides/source/form_helpers.textile @@ -9,6 +9,7 @@ In this guide you will: * Generate select boxes from multiple types of data * Understand the date and time helpers Rails provides * Learn what makes a file upload form different +* Learn some cases of building forms to external resources * Find out where to look for complex forms endprologue. @@ -763,6 +764,40 @@ As a shortcut you can append [] to the name and omit the +:index+ option. This i produces exactly the same output as the previous example. +h3. Forms to external resources + +If you need to post some data to an external resource it is still great to build your from using rails form helpers. But sometimes you need to set an +authenticity_token+ for this resource. You can do it by passing an +:authenticity_token => 'your_external_token'+ parameter to the +form_tag+ options: + +<erb> +<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %> + Form contents +<% end %> +</erb> + +Sometimes when you submit data to an external resource, like payment gateway, fields you can use in your form are limited by an external API. So you may want not to generate an +authenticity_token+ hidden field at all. For doing this just pass +false+ to the +:authenticity_token+ option: + +<erb> +<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %> + Form contents +<% end %> +</erb> + +The same technique is available for the +form_for+ too. You need just to set an +authenticity_token+ through +html+ options: + +<erb> +<%= form_for @invoice, :url => external_url, :html => { :authenticity_token => 'external_token' } do |f| + Form contents +<% end %> +</erb> + +Or if you don't want to render an +authenticity_token+ field: + +<erb> +<%= form_for @invoice, :url => external_url, :html => { :authenticity_token => false } do |f| + Form contents +<% end %> +</erb> + h3. Building Complex Forms Many apps grow beyond simple forms editing a single object. For example when creating a Person you might want to allow the user to (on the same form) create multiple address records (home, work, etc.). When later editing that person the user should be able to add, remove or amend addresses as necessary. While this guide has shown you all the pieces necessary to handle this, Rails does not yet have a standard end-to-end way of accomplishing this, but many have come up with viable approaches. These include: @@ -776,6 +811,7 @@ Many apps grow beyond simple forms editing a single object. For example when cre h3. Changelog +* February 5, 2011: Added 'Forms to external resources' section. Timothy N. Tsvetkov <timothy.tsvetkov@gmail.com> * April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com h3. Authors |