From a4c93da2d07e67d4d4c407350cc5a7eab9ed38e0 Mon Sep 17 00:00:00 2001 From: Rei Date: Sun, 26 Feb 2017 16:49:35 +0800 Subject: [PATCH 01/17] Fisrt commit --- 2_2_release_notes.html | 731 ++++ 2_3_release_notes.html | 878 +++++ 3_0_release_notes.html | 780 ++++ 3_1_release_notes.html | 751 ++++ 3_2_release_notes.html | 808 ++++ 4_0_release_notes.html | 537 +++ 4_1_release_notes.html | 845 +++++ 4_2_release_notes.html | 1029 +++++ 5_0_release_notes.html | 672 ++++ _license.html | 234 ++ _welcome.html | 246 ++ action_cable_overview.html | 232 ++ action_controller_overview.html | 1184 ++++++ action_mailer_basics.html | 872 +++++ action_view_overview.html | 1439 +++++++ active_job_basics.html | 535 +++ active_model_basics.html | 678 ++++ active_record_basics.html | 498 +++ active_record_callbacks.html | 630 ++++ active_record_migrations.html | 912 +++++ active_record_postgresql.html | 747 ++++ active_record_querying.html | 1923 ++++++++++ active_record_validations.html | 1161 ++++++ active_support_core_extensions.html | 3346 +++++++++++++++++ active_support_instrumentation.html | 1237 ++++++ api_app.html | 476 +++ api_documentation_guidelines.html | 482 +++ asset_pipeline.html | 232 ++ association_basics.html | 2155 +++++++++++ autoloading_and_reloading_constants.html | 1000 +++++ caching_with_rails.html | 576 +++ command_line.html | 798 ++++ configuring.html | 1190 ++++++ contributing_to_ruby_on_rails.html | 641 ++++ credits.html | 312 ++ debugging_rails_applications.html | 964 +++++ development_dependencies_install.html | 482 +++ engines.html | 232 ++ form_helpers.html | 1065 ++++++ generators.html | 848 +++++ getting_started.html | 1337 +++++++ i18n.html | 1244 ++++++ images/akshaysurve.jpg | Bin 0 -> 3444 bytes images/belongs_to.png | Bin 0 -> 25803 bytes images/book_icon.gif | Bin 0 -> 329 bytes images/bullet.gif | Bin 0 -> 60 bytes images/chapters_icon.gif | Bin 0 -> 620 bytes images/check_bullet.gif | Bin 0 -> 376 bytes images/credits_pic_blank.gif | Bin 0 -> 597 bytes images/csrf.png | Bin 0 -> 32179 bytes images/edge_badge.png | Bin 0 -> 5695 bytes images/favicon.ico | Bin 0 -> 16958 bytes images/feature_tile.gif | Bin 0 -> 35 bytes images/footer_tile.gif | Bin 0 -> 36 bytes images/fxn.png | Bin 0 -> 15436 bytes .../getting_started/article_with_comments.png | Bin 0 -> 22560 bytes images/getting_started/challenge.png | Bin 0 -> 21690 bytes images/getting_started/confirm_dialog.png | Bin 0 -> 18809 bytes .../forbidden_attributes_for_new_article.png | Bin 0 -> 10783 bytes images/getting_started/form_with_errors.png | Bin 0 -> 12447 bytes .../index_action_with_edit_link.png | Bin 0 -> 10209 bytes images/getting_started/new_article.png | Bin 0 -> 3579 bytes images/getting_started/rails_welcome.png | Bin 0 -> 1053549 bytes .../routing_error_no_controller.png | Bin 0 -> 4186 bytes .../routing_error_no_route_matches.png | Bin 0 -> 5913 bytes .../show_action_for_articles.png | Bin 0 -> 2965 bytes .../template_is_missing_articles_new.png | Bin 0 -> 587962 bytes .../unknown_action_create_for_articles.png | Bin 0 -> 5327 bytes .../unknown_action_new_for_articles.png | Bin 0 -> 5481 bytes images/grey_bullet.gif | Bin 0 -> 37 bytes images/habtm.png | Bin 0 -> 49332 bytes images/has_many.png | Bin 0 -> 28919 bytes images/has_many_through.png | Bin 0 -> 79428 bytes images/has_one.png | Bin 0 -> 29072 bytes images/has_one_through.png | Bin 0 -> 72434 bytes images/header_backdrop.png | Bin 0 -> 224 bytes images/header_tile.gif | Bin 0 -> 36 bytes images/i18n/demo_html_safe.png | Bin 0 -> 10073 bytes images/i18n/demo_localized_pirate.png | Bin 0 -> 11485 bytes images/i18n/demo_translated_en.png | Bin 0 -> 9325 bytes images/i18n/demo_translated_pirate.png | Bin 0 -> 10202 bytes images/i18n/demo_translation_missing.png | Bin 0 -> 10260 bytes images/i18n/demo_untranslated.png | Bin 0 -> 9224 bytes images/icons/README | 5 + images/icons/callouts/1.png | Bin 0 -> 147 bytes images/icons/callouts/10.png | Bin 0 -> 183 bytes images/icons/callouts/11.png | Bin 0 -> 176 bytes images/icons/callouts/12.png | Bin 0 -> 186 bytes images/icons/callouts/13.png | Bin 0 -> 188 bytes images/icons/callouts/14.png | Bin 0 -> 246 bytes images/icons/callouts/15.png | Bin 0 -> 191 bytes images/icons/callouts/2.png | Bin 0 -> 168 bytes images/icons/callouts/3.png | Bin 0 -> 170 bytes images/icons/callouts/4.png | Bin 0 -> 165 bytes images/icons/callouts/5.png | Bin 0 -> 169 bytes images/icons/callouts/6.png | Bin 0 -> 176 bytes images/icons/callouts/7.png | Bin 0 -> 160 bytes images/icons/callouts/8.png | Bin 0 -> 176 bytes images/icons/callouts/9.png | Bin 0 -> 177 bytes images/icons/caution.png | Bin 0 -> 2295 bytes images/icons/example.png | Bin 0 -> 2078 bytes images/icons/home.png | Bin 0 -> 1163 bytes images/icons/important.png | Bin 0 -> 2451 bytes images/icons/next.png | Bin 0 -> 1146 bytes images/icons/note.png | Bin 0 -> 2155 bytes images/icons/prev.png | Bin 0 -> 1126 bytes images/icons/tip.png | Bin 0 -> 2248 bytes images/icons/up.png | Bin 0 -> 1133 bytes images/icons/warning.png | Bin 0 -> 2616 bytes images/nav_arrow.gif | Bin 0 -> 419 bytes images/oscardelben.jpg | Bin 0 -> 6299 bytes images/polymorphic.png | Bin 0 -> 66415 bytes images/radar.png | Bin 0 -> 17095 bytes images/rails4_features.png | Bin 0 -> 67766 bytes images/rails_guides_kindle_cover.jpg | Bin 0 -> 20955 bytes images/rails_guides_logo.gif | Bin 0 -> 3770 bytes images/rails_logo_remix.gif | Bin 0 -> 8533 bytes images/session_fixation.png | Bin 0 -> 38451 bytes images/tab_grey.gif | Bin 0 -> 4684 bytes images/tab_info.gif | Bin 0 -> 4522 bytes images/tab_note.gif | Bin 0 -> 4566 bytes images/tab_red.gif | Bin 0 -> 4507 bytes images/tab_yellow.gif | Bin 0 -> 4519 bytes images/tab_yellow.png | Bin 0 -> 1441 bytes images/vijaydev.jpg | Bin 0 -> 2897 bytes index.html | 383 ++ initialization.html | 232 ++ javascripts/guides.js | 53 + javascripts/jquery.min.js | 4 + javascripts/responsive-tables.js | 43 + javascripts/syntaxhighlighter.js | 20 + layout.html | 464 +++ layouts_and_rendering.html | 1590 ++++++++ maintenance_policy.html | 246 ++ nested_model_forms.html | 421 +++ plugins.html | 680 ++++ profiling.html | 238 ++ rails_application_templates.html | 479 +++ rails_on_rack.html | 448 +++ routing.html | 1671 ++++++++ ruby_on_rails_guides_guidelines.html | 338 ++ security.html | 587 +++ stylesheets/fixes.css | 16 + stylesheets/kindle.css | 11 + stylesheets/main.css | 713 ++++ stylesheets/print.css | 52 + stylesheets/reset.css | 43 + stylesheets/responsive-tables.css | 50 + stylesheets/style.css | 13 + stylesheets/syntaxhighlighter/shCore.css | 226 ++ .../syntaxhighlighter/shThemeRailsGuides.css | 116 + testing.html | 1403 +++++++ upgrading_ruby_on_rails.html | 1120 ++++++ working_with_javascript_in_rails.html | 517 +++ 154 files changed, 49121 insertions(+) create mode 100644 2_2_release_notes.html create mode 100644 2_3_release_notes.html create mode 100644 3_0_release_notes.html create mode 100644 3_1_release_notes.html create mode 100644 3_2_release_notes.html create mode 100644 4_0_release_notes.html create mode 100644 4_1_release_notes.html create mode 100644 4_2_release_notes.html create mode 100644 5_0_release_notes.html create mode 100644 _license.html create mode 100644 _welcome.html create mode 100644 action_cable_overview.html create mode 100644 action_controller_overview.html create mode 100644 action_mailer_basics.html create mode 100644 action_view_overview.html create mode 100644 active_job_basics.html create mode 100644 active_model_basics.html create mode 100644 active_record_basics.html create mode 100644 active_record_callbacks.html create mode 100644 active_record_migrations.html create mode 100644 active_record_postgresql.html create mode 100644 active_record_querying.html create mode 100644 active_record_validations.html create mode 100644 active_support_core_extensions.html create mode 100644 active_support_instrumentation.html create mode 100644 api_app.html create mode 100644 api_documentation_guidelines.html create mode 100644 asset_pipeline.html create mode 100644 association_basics.html create mode 100644 autoloading_and_reloading_constants.html create mode 100644 caching_with_rails.html create mode 100644 command_line.html create mode 100644 configuring.html create mode 100644 contributing_to_ruby_on_rails.html create mode 100644 credits.html create mode 100644 debugging_rails_applications.html create mode 100644 development_dependencies_install.html create mode 100644 engines.html create mode 100644 form_helpers.html create mode 100644 generators.html create mode 100644 getting_started.html create mode 100644 i18n.html create mode 100644 images/akshaysurve.jpg create mode 100644 images/belongs_to.png create mode 100644 images/book_icon.gif create mode 100644 images/bullet.gif create mode 100644 images/chapters_icon.gif create mode 100644 images/check_bullet.gif create mode 100644 images/credits_pic_blank.gif create mode 100644 images/csrf.png create mode 100644 images/edge_badge.png create mode 100644 images/favicon.ico create mode 100644 images/feature_tile.gif create mode 100644 images/footer_tile.gif create mode 100644 images/fxn.png create mode 100644 images/getting_started/article_with_comments.png create mode 100644 images/getting_started/challenge.png create mode 100644 images/getting_started/confirm_dialog.png create mode 100644 images/getting_started/forbidden_attributes_for_new_article.png create mode 100644 images/getting_started/form_with_errors.png create mode 100644 images/getting_started/index_action_with_edit_link.png create mode 100644 images/getting_started/new_article.png create mode 100644 images/getting_started/rails_welcome.png create mode 100644 images/getting_started/routing_error_no_controller.png create mode 100644 images/getting_started/routing_error_no_route_matches.png create mode 100644 images/getting_started/show_action_for_articles.png create mode 100644 images/getting_started/template_is_missing_articles_new.png create mode 100644 images/getting_started/unknown_action_create_for_articles.png create mode 100644 images/getting_started/unknown_action_new_for_articles.png create mode 100644 images/grey_bullet.gif create mode 100644 images/habtm.png create mode 100644 images/has_many.png create mode 100644 images/has_many_through.png create mode 100644 images/has_one.png create mode 100644 images/has_one_through.png create mode 100644 images/header_backdrop.png create mode 100644 images/header_tile.gif create mode 100644 images/i18n/demo_html_safe.png create mode 100644 images/i18n/demo_localized_pirate.png create mode 100644 images/i18n/demo_translated_en.png create mode 100644 images/i18n/demo_translated_pirate.png create mode 100644 images/i18n/demo_translation_missing.png create mode 100644 images/i18n/demo_untranslated.png create mode 100644 images/icons/README create mode 100644 images/icons/callouts/1.png create mode 100644 images/icons/callouts/10.png create mode 100644 images/icons/callouts/11.png create mode 100644 images/icons/callouts/12.png create mode 100644 images/icons/callouts/13.png create mode 100644 images/icons/callouts/14.png create mode 100644 images/icons/callouts/15.png create mode 100644 images/icons/callouts/2.png create mode 100644 images/icons/callouts/3.png create mode 100644 images/icons/callouts/4.png create mode 100644 images/icons/callouts/5.png create mode 100644 images/icons/callouts/6.png create mode 100644 images/icons/callouts/7.png create mode 100644 images/icons/callouts/8.png create mode 100644 images/icons/callouts/9.png create mode 100644 images/icons/caution.png create mode 100644 images/icons/example.png create mode 100644 images/icons/home.png create mode 100644 images/icons/important.png create mode 100644 images/icons/next.png create mode 100644 images/icons/note.png create mode 100644 images/icons/prev.png create mode 100644 images/icons/tip.png create mode 100644 images/icons/up.png create mode 100644 images/icons/warning.png create mode 100644 images/nav_arrow.gif create mode 100644 images/oscardelben.jpg create mode 100644 images/polymorphic.png create mode 100644 images/radar.png create mode 100644 images/rails4_features.png create mode 100644 images/rails_guides_kindle_cover.jpg create mode 100644 images/rails_guides_logo.gif create mode 100644 images/rails_logo_remix.gif create mode 100644 images/session_fixation.png create mode 100644 images/tab_grey.gif create mode 100644 images/tab_info.gif create mode 100644 images/tab_note.gif create mode 100644 images/tab_red.gif create mode 100644 images/tab_yellow.gif create mode 100644 images/tab_yellow.png create mode 100644 images/vijaydev.jpg create mode 100644 index.html create mode 100644 initialization.html create mode 100644 javascripts/guides.js create mode 100644 javascripts/jquery.min.js create mode 100644 javascripts/responsive-tables.js create mode 100644 javascripts/syntaxhighlighter.js create mode 100644 layout.html create mode 100644 layouts_and_rendering.html create mode 100644 maintenance_policy.html create mode 100644 nested_model_forms.html create mode 100644 plugins.html create mode 100644 profiling.html create mode 100644 rails_application_templates.html create mode 100644 rails_on_rack.html create mode 100644 routing.html create mode 100644 ruby_on_rails_guides_guidelines.html create mode 100644 security.html create mode 100644 stylesheets/fixes.css create mode 100644 stylesheets/kindle.css create mode 100644 stylesheets/main.css create mode 100644 stylesheets/print.css create mode 100644 stylesheets/reset.css create mode 100755 stylesheets/responsive-tables.css create mode 100644 stylesheets/style.css create mode 100644 stylesheets/syntaxhighlighter/shCore.css create mode 100644 stylesheets/syntaxhighlighter/shThemeRailsGuides.css create mode 100644 testing.html create mode 100644 upgrading_ruby_on_rails.html create mode 100644 working_with_javascript_in_rails.html diff --git a/2_2_release_notes.html b/2_2_release_notes.html new file mode 100644 index 0000000..c598606 --- /dev/null +++ b/2_2_release_notes.html @@ -0,0 +1,731 @@ + + + + + + + +Ruby on Rails 2.2 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 2.2 Release Notes

Rails 2.2 delivers a number of new and improved features. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the list of commits in the main Rails repository on GitHub.

Along with Rails, 2.2 marks the launch of the Ruby on Rails Guides, the first results of the ongoing Rails Guides hackfest. This site will deliver high-quality documentation of the major features of Rails.

+ + + +
+
+ +
+
+
+

1 Infrastructure

Rails 2.2 is a significant release for the infrastructure that keeps Rails humming along and connected to the rest of the world.

1.1 Internationalization

Rails 2.2 supplies an easy system for internationalization (or i18n, for those of you tired of typing).

+ +

1.2 Compatibility with Ruby 1.9 and JRuby

Along with thread safety, a lot of work has been done to make Rails work well with JRuby and the upcoming Ruby 1.9. With Ruby 1.9 being a moving target, running edge Rails on edge Ruby is still a hit-or-miss proposition, but Rails is ready to make the transition to Ruby 1.9 when the latter is released.

2 Documentation

The internal documentation of Rails, in the form of code comments, has been improved in numerous places. In addition, the Ruby on Rails Guides project is the definitive source for information on major Rails components. In its first official release, the Guides page includes:

+ +

All told, the Guides provide tens of thousands of words of guidance for beginning and intermediate Rails developers.

If you want to generate these guides locally, inside your application:

+
+rake doc:guides
+
+
+
+

This will put the guides inside Rails.root/doc/guides and you may start surfing straight away by opening Rails.root/doc/guides/index.html in your favourite browser.

+ +

3 Better integration with HTTP : Out of the box ETag support

Supporting the etag and last modified timestamp in HTTP headers means that Rails can now send back an empty response if it gets a request for a resource that hasn't been modified lately. This allows you to check whether a response needs to be sent at all.

+
+class ArticlesController < ApplicationController
+  def show_with_respond_to_block
+    @article = Article.find(params[:id])
+
+    # If the request sends headers that differs from the options provided to stale?, then
+    # the request is indeed stale and the respond_to block is triggered (and the options
+    # to the stale? call is set on the response).
+    #
+    # If the request headers match, then the request is fresh and the respond_to block is
+    # not triggered. Instead the default render will occur, which will check the last-modified
+    # and etag headers and conclude that it only needs to send a "304 Not Modified" instead
+    # of rendering the template.
+    if stale?(:last_modified => @article.published_at.utc, :etag => @article)
+      respond_to do |wants|
+        # normal response processing
+      end
+    end
+  end
+
+  def show_with_implied_render
+    @article = Article.find(params[:id])
+
+    # Sets the response headers and checks them against the request, if the request is stale
+    # (i.e. no match of either etag or last-modified), then the default render of the template happens.
+    # If the request is fresh, then the default render will return a "304 Not Modified"
+    # instead of rendering the template.
+    fresh_when(:last_modified => @article.published_at.utc, :etag => @article)
+  end
+end
+
+
+
+

4 Thread Safety

The work done to make Rails thread-safe is rolling out in Rails 2.2. Depending on your web server infrastructure, this means you can handle more requests with fewer copies of Rails in memory, leading to better server performance and higher utilization of multiple cores.

To enable multithreaded dispatching in production mode of your application, add the following line in your config/environments/production.rb:

+
+config.threadsafe!
+
+
+
+ + +

5 Active Record

There are two big additions to talk about here: transactional migrations and pooled database transactions. There's also a new (and cleaner) syntax for join table conditions, as well as a number of smaller improvements.

5.1 Transactional Migrations

Historically, multiple-step Rails migrations have been a source of trouble. If something went wrong during a migration, everything before the error changed the database and everything after the error wasn't applied. Also, the migration version was stored as having been executed, which means that it couldn't be simply rerun by rake db:migrate:redo after you fix the problem. Transactional migrations change this by wrapping migration steps in a DDL transaction, so that if any of them fail, the entire migration is undone. In Rails 2.2, transactional migrations are supported on PostgreSQL out of the box. The code is extensible to other database types in the future - and IBM has already extended it to support the DB2 adapter.

+ +

5.2 Connection Pooling

Connection pooling lets Rails distribute database requests across a pool of database connections that will grow to a maximum size (by default 5, but you can add a pool key to your database.yml to adjust this). This helps remove bottlenecks in applications that support many concurrent users. There's also a wait_timeout that defaults to 5 seconds before giving up. ActiveRecord::Base.connection_pool gives you direct access to the pool if you need it.

+
+development:
+  adapter: mysql
+  username: root
+  database: sample_development
+  pool: 10
+  wait_timeout: 10
+
+
+
+ + +

5.3 Hashes for Join Table Conditions

You can now specify conditions on join tables using a hash. This is a big help if you need to query across complex joins.

+
+class Photo < ActiveRecord::Base
+  belongs_to :product
+end
+
+class Product < ActiveRecord::Base
+  has_many :photos
+end
+
+# Get all products with copyright-free photos:
+Product.all(:joins => :photos, :conditions => { :photos => { :copyright => false }})
+
+
+
+ + +

5.4 New Dynamic Finders

Two new sets of methods have been added to Active Record's dynamic finders family.

5.4.1 find_last_by_attribute +

The find_last_by_attribute method is equivalent to Model.last(:conditions => {:attribute => value})

+
+# Get the last user who signed up from London
+User.find_last_by_city('London')
+
+
+
+ + +
5.4.2 find_by_attribute! +

The new bang! version of find_by_attribute! is equivalent to Model.first(:conditions => {:attribute => value}) || raise ActiveRecord::RecordNotFound Instead of returning nil if it can't find a matching record, this method will raise an exception if it cannot find a match.

+
+# Raise ActiveRecord::RecordNotFound exception if 'Moby' hasn't signed up yet!
+User.find_by_name!('Moby')
+
+
+
+ + +

5.5 Associations Respect Private/Protected Scope

Active Record association proxies now respect the scope of methods on the proxied object. Previously (given User has_one :account) @user.account.private_method would call the private method on the associated Account object. That fails in Rails 2.2; if you need this functionality, you should use @user.account.send(:private_method) (or make the method public instead of private or protected). Please note that if you're overriding method_missing, you should also override respond_to to match the behavior in order for associations to function normally.

+ +

5.6 Other Active Record Changes

+
    +
  • +rake db:migrate:redo now accepts an optional VERSION to target that specific migration to redo
  • +
  • Set config.active_record.timestamped_migrations = false to have migrations with numeric prefix instead of UTC timestamp.
  • +
  • Counter cache columns (for associations declared with :counter_cache => true) do not need to be initialized to zero any longer.
  • +
  • +ActiveRecord::Base.human_name for an internationalization-aware humane translation of model names
  • +
+

6 Action Controller

On the controller side, there are several changes that will help tidy up your routes. There are also some internal changes in the routing engine to lower memory usage on complex applications.

6.1 Shallow Route Nesting

Shallow route nesting provides a solution to the well-known difficulty of using deeply-nested resources. With shallow nesting, you need only supply enough information to uniquely identify the resource that you want to work with.

+
+map.resources :publishers, :shallow => true do |publisher|
+  publisher.resources :magazines do |magazine|
+    magazine.resources :photos
+  end
+end
+
+
+
+

This will enable recognition of (among others) these routes:

+
+/publishers/1           ==> publisher_path(1)
+/publishers/1/magazines ==> publisher_magazines_path(1)
+/magazines/2            ==> magazine_path(2)
+/magazines/2/photos     ==> magazines_photos_path(2)
+/photos/3               ==> photo_path(3)
+
+
+
+ + +

6.2 Method Arrays for Member or Collection Routes

You can now supply an array of methods for new member or collection routes. This removes the annoyance of having to define a route as accepting any verb as soon as you need it to handle more than one. With Rails 2.2, this is a legitimate route declaration:

+
+map.resources :photos, :collection => { :search => [:get, :post] }
+
+
+
+ + +

6.3 Resources With Specific Actions

By default, when you use map.resources to create a route, Rails generates routes for seven default actions (index, show, create, new, edit, update, and destroy). But each of these routes takes up memory in your application, and causes Rails to generate additional routing logic. Now you can use the :only and :except options to fine-tune the routes that Rails will generate for resources. You can supply a single action, an array of actions, or the special :all or :none options. These options are inherited by nested resources.

+
+map.resources :photos, :only => [:index, :show]
+map.resources :products, :except => :destroy
+
+
+
+ + +

6.4 Other Action Controller Changes

+
    +
  • You can now easily show a custom error page for exceptions raised while routing a request.
  • +
  • The HTTP Accept header is disabled by default now. You should prefer the use of formatted URLs (such as /customers/1.xml) to indicate the format that you want. If you need the Accept headers, you can turn them back on with config.action_controller.use_accept_header = true.
  • +
  • Benchmarking numbers are now reported in milliseconds rather than tiny fractions of seconds
  • +
  • Rails now supports HTTP-only cookies (and uses them for sessions), which help mitigate some cross-site scripting risks in newer browsers.
  • +
  • +redirect_to now fully supports URI schemes (so, for example, you can redirect to a svn`ssh: URI).
  • +
  • +render now supports a :js option to render plain vanilla JavaScript with the right mime type.
  • +
  • Request forgery protection has been tightened up to apply to HTML-formatted content requests only.
  • +
  • Polymorphic URLs behave more sensibly if a passed parameter is nil. For example, calling polymorphic_path([@project, @date, @area]) with a nil date will give you project_area_path.
  • +
+

7 Action View

+
    +
  • +javascript_include_tag and stylesheet_link_tag support a new :recursive option to be used along with :all, so that you can load an entire tree of files with a single line of code.
  • +
  • The included Prototype JavaScript library has been upgraded to version 1.6.0.3.
  • +
  • +RJS#page.reload to reload the browser's current location via JavaScript
  • +
  • The atom_feed helper now takes an :instruct option to let you insert XML processing instructions.
  • +
+

8 Action Mailer

Action Mailer now supports mailer layouts. You can make your HTML emails as pretty as your in-browser views by supplying an appropriately-named layout - for example, the CustomerMailer class expects to use layouts/customer_mailer.html.erb.

+ +

Action Mailer now offers built-in support for GMail's SMTP servers, by turning on STARTTLS automatically. This requires Ruby 1.8.7 to be installed.

9 Active Support

Active Support now offers built-in memoization for Rails applications, the each_with_object method, prefix support on delegates, and various other new utility methods.

9.1 Memoization

Memoization is a pattern of initializing a method once and then stashing its value away for repeat use. You've probably used this pattern in your own applications:

+
+def full_name
+  @full_name ||= "#{first_name} #{last_name}"
+end
+
+
+
+

Memoization lets you handle this task in a declarative fashion:

+
+extend ActiveSupport::Memoizable
+
+def full_name
+  "#{first_name} #{last_name}"
+end
+memoize :full_name
+
+
+
+

Other features of memoization include unmemoize, unmemoize_all, and memoize_all to turn memoization on or off.

+ +

9.2 each_with_object

The each_with_object method provides an alternative to inject, using a method backported from Ruby 1.9. It iterates over a collection, passing the current element and the memo into the block.

+
+%w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } # => {'foo' => 'FOO', 'bar' => 'BAR'}
+
+
+
+

Lead Contributor: Adam Keys

9.3 Delegates With Prefixes

If you delegate behavior from one class to another, you can now specify a prefix that will be used to identify the delegated methods. For example:

+
+class Vendor < ActiveRecord::Base
+  has_one :account
+  delegate :email, :password, :to => :account, :prefix => true
+end
+
+
+
+

This will produce delegated methods vendor#account_email and vendor#account_password. You can also specify a custom prefix:

+
+class Vendor < ActiveRecord::Base
+  has_one :account
+  delegate :email, :password, :to => :account, :prefix => :owner
+end
+
+
+
+

This will produce delegated methods vendor#owner_email and vendor#owner_password.

Lead Contributor: Daniel Schierbeck

9.4 Other Active Support Changes

+
    +
  • Extensive updates to ActiveSupport::Multibyte, including Ruby 1.9 compatibility fixes.
  • +
  • The addition of ActiveSupport::Rescuable allows any class to mix in the rescue_from syntax.
  • +
  • +past?, today? and future? for Date and Time classes to facilitate date/time comparisons.
  • +
  • +Array#second through Array#fifth as aliases for Array#[1] through Array#[4] +
  • +
  • +Enumerable#many? to encapsulate collection.size > 1 +
  • +
  • +Inflector#parameterize produces a URL-ready version of its input, for use in to_param.
  • +
  • +Time#advance recognizes fractional days and weeks, so you can do 1.7.weeks.ago, 1.5.hours.since, and so on.
  • +
  • The included TzInfo library has been upgraded to version 0.3.12.
  • +
  • +ActiveSupport::StringInquirer gives you a pretty way to test for equality in strings: ActiveSupport::StringInquirer.new("abc").abc? => true +
  • +
+

10 Railties

In Railties (the core code of Rails itself) the biggest changes are in the config.gems mechanism.

10.1 config.gems

To avoid deployment issues and make Rails applications more self-contained, it's possible to place copies of all of the gems that your Rails application requires in /vendor/gems. This capability first appeared in Rails 2.1, but it's much more flexible and robust in Rails 2.2, handling complicated dependencies between gems. Gem management in Rails includes these commands:

+
    +
  • +config.gem _gem_name_ in your config/environment.rb file
  • +
  • +rake gems to list all configured gems, as well as whether they (and their dependencies) are installed, frozen, or framework (framework gems are those loaded by Rails before the gem dependency code is executed; such gems cannot be frozen)
  • +
  • +rake gems:install to install missing gems to the computer
  • +
  • +rake gems:unpack to place a copy of the required gems into /vendor/gems +
  • +
  • +rake gems:unpack:dependencies to get copies of the required gems and their dependencies into /vendor/gems +
  • +
  • +rake gems:build to build any missing native extensions
  • +
  • +rake gems:refresh_specs to bring vendored gems created with Rails 2.1 into alignment with the Rails 2.2 way of storing them
  • +
+

You can unpack or install a single gem by specifying GEM=_gem_name_ on the command line.

+ +

10.2 Other Railties Changes

+
    +
  • If you're a fan of the Thin web server, you'll be happy to know that script/server now supports Thin directly.
  • +
  • +script/plugin install &lt;plugin&gt; -r &lt;revision&gt; now works with git-based as well as svn-based plugins.
  • +
  • +script/console now supports a --debugger option
  • +
  • Instructions for setting up a continuous integration server to build Rails itself are included in the Rails source
  • +
  • +rake notes:custom ANNOTATION=MYFLAG lets you list out custom annotations.
  • +
  • Wrapped Rails.env in StringInquirer so you can do Rails.env.development? +
  • +
  • To eliminate deprecation warnings and properly handle gem dependencies, Rails now requires rubygems 1.3.1 or higher.
  • +
+

11 Deprecated

A few pieces of older code are deprecated in this release:

+
    +
  • +Rails::SecretKeyGenerator has been replaced by ActiveSupport::SecureRandom +
  • +
  • +render_component is deprecated. There's a render_components plugin available if you need this functionality.
  • +
  • +

    Implicit local assignments when rendering partials has been deprecated.

    +
    +
    +def partial_with_implicit_local_assignment
    +  @customer = Customer.new("Marcel")
    +  render :partial => "customer"
    +end
    +
    +
    +
    +

    Previously the above code made available a local variable called customer inside the partial 'customer'. You should explicitly pass all the variables via :locals hash now.

    +
  • +
  • country_select has been removed. See the deprecation page for more information and a plugin replacement.

  • +
  • ActiveRecord::Base.allow_concurrency no longer has any effect.

  • +
  • ActiveRecord::Errors.default_error_messages has been deprecated in favor of I18n.translate('activerecord.errors.messages')

  • +
  • The %s and %d interpolation syntax for internationalization is deprecated.

  • +
  • String#chars has been deprecated in favor of String#mb_chars.

  • +
  • Durations of fractional months or fractional years are deprecated. Use Ruby's core Date and Time class arithmetic instead.

  • +
  • Request#relative_url_root is deprecated. Use ActionController::Base.relative_url_root instead.

  • +
+

12 Credits

Release notes compiled by Mike Gunderloy

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/2_3_release_notes.html b/2_3_release_notes.html new file mode 100644 index 0000000..39510af --- /dev/null +++ b/2_3_release_notes.html @@ -0,0 +1,878 @@ + + + + + + + +Ruby on Rails 2.3 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 2.3 Release Notes

Rails 2.3 delivers a variety of new and improved features, including pervasive Rack integration, refreshed support for Rails Engines, nested transactions for Active Record, dynamic and default scopes, unified rendering, more efficient routing, application templates, and quiet backtraces. This list covers the major upgrades, but doesn't include every little bug fix and change. If you want to see everything, check out the list of commits in the main Rails repository on GitHub or review the CHANGELOG files for the individual Rails components.

+ + + +
+
+ +
+
+
+

1 Application Architecture

There are two major changes in the architecture of Rails applications: complete integration of the Rack modular web server interface, and renewed support for Rails Engines.

1.1 Rack Integration

Rails has now broken with its CGI past, and uses Rack everywhere. This required and resulted in a tremendous number of internal changes (but if you use CGI, don't worry; Rails now supports CGI through a proxy interface.) Still, this is a major change to Rails internals. After upgrading to 2.3, you should test on your local environment and your production environment. Some things to test:

+
    +
  • Sessions
  • +
  • Cookies
  • +
  • File uploads
  • +
  • JSON/XML APIs
  • +
+

Here's a summary of the rack-related changes:

+
    +
  • +script/server has been switched to use Rack, which means it supports any Rack compatible server. script/server will also pick up a rackup configuration file if one exists. By default, it will look for a config.ru file, but you can override this with the -c switch.
  • +
  • The FCGI handler goes through Rack.
  • +
  • +ActionController::Dispatcher maintains its own default middleware stack. Middlewares can be injected in, reordered, and removed. The stack is compiled into a chain on boot. You can configure the middleware stack in environment.rb.
  • +
  • The rake middleware task has been added to inspect the middleware stack. This is useful for debugging the order of the middleware stack.
  • +
  • The integration test runner has been modified to execute the entire middleware and application stack. This makes integration tests perfect for testing Rack middleware.
  • +
  • +ActionController::CGIHandler is a backwards compatible CGI wrapper around Rack. The CGIHandler is meant to take an old CGI object and convert its environment information into a Rack compatible form.
  • +
  • +CgiRequest and CgiResponse have been removed.
  • +
  • Session stores are now lazy loaded. If you never access the session object during a request, it will never attempt to load the session data (parse the cookie, load the data from memcache, or lookup an Active Record object).
  • +
  • You no longer need to use CGI::Cookie.new in your tests for setting a cookie value. Assigning a String value to request.cookies["foo"] now sets the cookie as expected.
  • +
  • +CGI::Session::CookieStore has been replaced by ActionController::Session::CookieStore.
  • +
  • +CGI::Session::MemCacheStore has been replaced by ActionController::Session::MemCacheStore.
  • +
  • +CGI::Session::ActiveRecordStore has been replaced by ActiveRecord::SessionStore.
  • +
  • You can still change your session store with ActionController::Base.session_store = :active_record_store.
  • +
  • Default sessions options are still set with ActionController::Base.session = { :key => "..." }. However, the :session_domain option has been renamed to :domain.
  • +
  • The mutex that normally wraps your entire request has been moved into middleware, ActionController::Lock.
  • +
  • +ActionController::AbstractRequest and ActionController::Request have been unified. The new ActionController::Request inherits from Rack::Request. This affects access to response.headers['type'] in test requests. Use response.content_type instead.
  • +
  • +ActiveRecord::QueryCache middleware is automatically inserted onto the middleware stack if ActiveRecord has been loaded. This middleware sets up and flushes the per-request Active Record query cache.
  • +
  • The Rails router and controller classes follow the Rack spec. You can call a controller directly with SomeController.call(env). The router stores the routing parameters in rack.routing_args.
  • +
  • +ActionController::Request inherits from Rack::Request.
  • +
  • Instead of config.action_controller.session = { :session_key => 'foo', ... use config.action_controller.session = { :key => 'foo', ....
  • +
  • Using the ParamsParser middleware preprocesses any XML, JSON, or YAML requests so they can be read normally with any Rack::Request object after it.
  • +
+

1.2 Renewed Support for Rails Engines

After some versions without an upgrade, Rails 2.3 offers some new features for Rails Engines (Rails applications that can be embedded within other applications). First, routing files in engines are automatically loaded and reloaded now, just like your routes.rb file (this also applies to routing files in other plugins). Second, if your plugin has an app folder, then app/[models|controllers|helpers] will automatically be added to the Rails load path. Engines also support adding view paths now, and Action Mailer as well as Action View will use views from engines and other plugins.

2 Documentation

The Ruby on Rails guides project has published several additional guides for Rails 2.3. In addition, a separate site maintains updated copies of the Guides for Edge Rails. Other documentation efforts include a relaunch of the Rails wiki and early planning for a Rails Book.

+ +

3 Ruby 1.9.1 Support

Rails 2.3 should pass all of its own tests whether you are running on Ruby 1.8 or the now-released Ruby 1.9.1. You should be aware, though, that moving to 1.9.1 entails checking all of the data adapters, plugins, and other code that you depend on for Ruby 1.9.1 compatibility, as well as Rails core.

4 Active Record

Active Record gets quite a number of new features and bug fixes in Rails 2.3. The highlights include nested attributes, nested transactions, dynamic and default scopes, and batch processing.

4.1 Nested Attributes

Active Record can now update the attributes on nested models directly, provided you tell it to do so:

+
+class Book < ActiveRecord::Base
+  has_one :author
+  has_many :pages
+
+  accepts_nested_attributes_for :author, :pages
+end
+
+
+
+

Turning on nested attributes enables a number of things: automatic (and atomic) saving of a record together with its associated children, child-aware validations, and support for nested forms (discussed later).

You can also specify requirements for any new records that are added via nested attributes using the :reject_if option:

+
+accepts_nested_attributes_for :author,
+  :reject_if => proc { |attributes| attributes['name'].blank? }
+
+
+
+ + +

4.2 Nested Transactions

Active Record now supports nested transactions, a much-requested feature. Now you can write code like this:

+
+User.transaction do
+  User.create(:username => 'Admin')
+  User.transaction(:requires_new => true) do
+    User.create(:username => 'Regular')
+    raise ActiveRecord::Rollback
+  end
+end
+
+User.find(:all)  # => Returns only Admin
+
+
+
+

Nested transactions let you roll back an inner transaction without affecting the state of the outer transaction. If you want a transaction to be nested, you must explicitly add the :requires_new option; otherwise, a nested transaction simply becomes part of the parent transaction (as it does currently on Rails 2.2). Under the covers, nested transactions are using savepoints so they're supported even on databases that don't have true nested transactions. There is also a bit of magic going on to make these transactions play well with transactional fixtures during testing.

+ +

4.3 Dynamic Scopes

You know about dynamic finders in Rails (which allow you to concoct methods like find_by_color_and_flavor on the fly) and named scopes (which allow you to encapsulate reusable query conditions into friendly names like currently_active). Well, now you can have dynamic scope methods. The idea is to put together syntax that allows filtering on the fly and method chaining. For example:

+
+Order.scoped_by_customer_id(12)
+Order.scoped_by_customer_id(12).find(:all,
+  :conditions => "status = 'open'")
+Order.scoped_by_customer_id(12).scoped_by_status("open")
+
+
+
+

There's nothing to define to use dynamic scopes: they just work.

+ +

4.4 Default Scopes

Rails 2.3 will introduce the notion of default scopes similar to named scopes, but applying to all named scopes or find methods within the model. For example, you can write default_scope :order => 'name ASC' and any time you retrieve records from that model they'll come out sorted by name (unless you override the option, of course).

+ +

4.5 Batch Processing

You can now process large numbers of records from an Active Record model with less pressure on memory by using find_in_batches:

+
+Customer.find_in_batches(:conditions => {:active => true}) do |customer_group|
+  customer_group.each { |customer| customer.update_account_balance! }
+end
+
+
+
+

You can pass most of the find options into find_in_batches. However, you cannot specify the order that records will be returned in (they will always be returned in ascending order of primary key, which must be an integer), or use the :limit option. Instead, use the :batch_size option, which defaults to 1000, to set the number of records that will be returned in each batch.

The new find_each method provides a wrapper around find_in_batches that returns individual records, with the find itself being done in batches (of 1000 by default):

+
+Customer.find_each do |customer|
+  customer.update_account_balance!
+end
+
+
+
+

Note that you should only use this method for batch processing: for small numbers of records (less than 1000), you should just use the regular find methods with your own loop.

+ +

4.6 Multiple Conditions for Callbacks

When using Active Record callbacks, you can now combine :if and :unless options on the same callback, and supply multiple conditions as an array:

+
+before_save :update_credit_rating, :if => :active,
+  :unless => [:admin, :cash_only]
+
+
+
+ +
    +
  • Lead Contributor: L. Caviola
  • +
+

4.7 Find with having

Rails now has a :having option on find (as well as on has_many and has_and_belongs_to_many associations) for filtering records in grouped finds. As those with heavy SQL backgrounds know, this allows filtering based on grouped results:

+
+developers = Developer.find(:all, :group => "salary",
+  :having => "sum(salary) > 10000", :select => "salary")
+
+
+
+ + +

4.8 Reconnecting MySQL Connections

MySQL supports a reconnect flag in its connections - if set to true, then the client will try reconnecting to the server before giving up in case of a lost connection. You can now set reconnect = true for your MySQL connections in database.yml to get this behavior from a Rails application. The default is false, so the behavior of existing applications doesn't change.

+ +

4.9 Other Active Record Changes

+
    +
  • An extra AS was removed from the generated SQL for has_and_belongs_to_many preloading, making it work better for some databases.
  • +
  • +ActiveRecord::Base#new_record? now returns false rather than nil when confronted with an existing record.
  • +
  • A bug in quoting table names in some has_many :through associations was fixed.
  • +
  • You can now specify a particular timestamp for updated_at timestamps: cust = Customer.create(:name => "ABC Industries", :updated_at => 1.day.ago) +
  • +
  • Better error messages on failed find_by_attribute! calls.
  • +
  • Active Record's to_xml support gets just a little bit more flexible with the addition of a :camelize option.
  • +
  • A bug in canceling callbacks from before_update or before_create was fixed.
  • +
  • Rake tasks for testing databases via JDBC have been added.
  • +
  • +validates_length_of will use a custom error message with the :in or :within options (if one is supplied).
  • +
  • Counts on scoped selects now work properly, so you can do things like Account.scoped(:select => "DISTINCT credit_limit").count.
  • +
  • +ActiveRecord::Base#invalid? now works as the opposite of ActiveRecord::Base#valid?.
  • +
+

5 Action Controller

Action Controller rolls out some significant changes to rendering, as well as improvements in routing and other areas, in this release.

5.1 Unified Rendering

ActionController::Base#render is a lot smarter about deciding what to render. Now you can just tell it what to render and expect to get the right results. In older versions of Rails, you often need to supply explicit information to render:

+
+render :file => '/tmp/random_file.erb'
+render :template => 'other_controller/action'
+render :action => 'show'
+
+
+
+

Now in Rails 2.3, you can just supply what you want to render:

+
+render '/tmp/random_file.erb'
+render 'other_controller/action'
+render 'show'
+render :show
+
+
+
+

Rails chooses between file, template, and action depending on whether there is a leading slash, an embedded slash, or no slash at all in what's to be rendered. Note that you can also use a symbol instead of a string when rendering an action. Other rendering styles (:inline, :text, :update, :nothing, :json, :xml, :js) still require an explicit option.

5.2 Application Controller Renamed

If you're one of the people who has always been bothered by the special-case naming of application.rb, rejoice! It's been reworked to be application_controller.rb in Rails 2.3. In addition, there's a new rake task, rake rails:update:application_controller to do this automatically for you - and it will be run as part of the normal rake rails:update process.

+ +

5.3 HTTP Digest Authentication Support

Rails now has built-in support for HTTP digest authentication. To use it, you call authenticate_or_request_with_http_digest with a block that returns the user's password (which is then hashed and compared against the transmitted credentials):

+
+class PostsController < ApplicationController
+  Users = {"dhh" => "secret"}
+  before_filter :authenticate
+
+  def secret
+    render :text => "Password Required!"
+  end
+
+  private
+  def authenticate
+    realm = "Application"
+    authenticate_or_request_with_http_digest(realm) do |name|
+      Users[name]
+    end
+  end
+end
+
+
+
+ + +

5.4 More Efficient Routing

There are a couple of significant routing changes in Rails 2.3. The formatted_ route helpers are gone, in favor just passing in :format as an option. This cuts down the route generation process by 50% for any resource - and can save a substantial amount of memory (up to 100MB on large applications). If your code uses the formatted_ helpers, it will still work for the time being - but that behavior is deprecated and your application will be more efficient if you rewrite those routes using the new standard. Another big change is that Rails now supports multiple routing files, not just routes.rb. You can use RouteSet#add_configuration_file to bring in more routes at any time - without clearing the currently-loaded routes. While this change is most useful for Engines, you can use it in any application that needs to load routes in batches.

+ +

5.5 Rack-based Lazy-loaded Sessions

A big change pushed the underpinnings of Action Controller session storage down to the Rack level. This involved a good deal of work in the code, though it should be completely transparent to your Rails applications (as a bonus, some icky patches around the old CGI session handler got removed). It's still significant, though, for one simple reason: non-Rails Rack applications have access to the same session storage handlers (and therefore the same session) as your Rails applications. In addition, sessions are now lazy-loaded (in line with the loading improvements to the rest of the framework). This means that you no longer need to explicitly disable sessions if you don't want them; just don't refer to them and they won't load.

5.6 MIME Type Handling Changes

There are a couple of changes to the code for handling MIME types in Rails. First, MIME::Type now implements the =~ operator, making things much cleaner when you need to check for the presence of a type that has synonyms:

+
+if content_type && Mime::JS =~ content_type
+  # do something cool
+end
+
+Mime::JS =~ "text/javascript"        => true
+Mime::JS =~ "application/javascript" => true
+
+
+
+

The other change is that the framework now uses the Mime::JS when checking for JavaScript in various spots, making it handle those alternatives cleanly.

+ +

5.7 Optimization of respond_to +

In some of the first fruits of the Rails-Merb team merger, Rails 2.3 includes some optimizations for the respond_to method, which is of course heavily used in many Rails applications to allow your controller to format results differently based on the MIME type of the incoming request. After eliminating a call to method_missing and some profiling and tweaking, we're seeing an 8% improvement in the number of requests per second served with a simple respond_to that switches between three formats. The best part? No change at all required to the code of your application to take advantage of this speedup.

5.8 Improved Caching Performance

Rails now keeps a per-request local cache of read from the remote cache stores, cutting down on unnecessary reads and leading to better site performance. While this work was originally limited to MemCacheStore, it is available to any remote store than implements the required methods.

+ +

5.9 Localized Views

Rails can now provide localized views, depending on the locale that you have set. For example, suppose you have a Posts controller with a show action. By default, this will render app/views/posts/show.html.erb. But if you set I18n.locale = :da, it will render app/views/posts/show.da.html.erb. If the localized template isn't present, the undecorated version will be used. Rails also includes I18n#available_locales and I18n::SimpleBackend#available_locales, which return an array of the translations that are available in the current Rails project.

In addition, you can use the same scheme to localize the rescue files in the public directory: public/500.da.html or public/404.en.html work, for example.

5.10 Partial Scoping for Translations

A change to the translation API makes things easier and less repetitive to write key translations within partials. If you call translate(".foo") from the people/index.html.erb template, you'll actually be calling I18n.translate("people.index.foo") If you don't prepend the key with a period, then the API doesn't scope, just as before.

5.11 Other Action Controller Changes

+
    +
  • ETag handling has been cleaned up a bit: Rails will now skip sending an ETag header when there's no body to the response or when sending files with send_file.
  • +
  • The fact that Rails checks for IP spoofing can be a nuisance for sites that do heavy traffic with cell phones, because their proxies don't generally set things up right. If that's you, you can now set ActionController::Base.ip_spoofing_check = false to disable the check entirely.
  • +
  • +ActionController::Dispatcher now implements its own middleware stack, which you can see by running rake middleware.
  • +
  • Cookie sessions now have persistent session identifiers, with API compatibility with the server-side stores.
  • +
  • You can now use symbols for the :type option of send_file and send_data, like this: send_file("fabulous.png", :type => :png).
  • +
  • The :only and :except options for map.resources are no longer inherited by nested resources.
  • +
  • The bundled memcached client has been updated to version 1.6.4.99.
  • +
  • The expires_in, stale?, and fresh_when methods now accept a :public option to make them work well with proxy caching.
  • +
  • The :requirements option now works properly with additional RESTful member routes.
  • +
  • Shallow routes now properly respect namespaces.
  • +
  • +polymorphic_url does a better job of handling objects with irregular plural names.
  • +
+

6 Action View

Action View in Rails 2.3 picks up nested model forms, improvements to render, more flexible prompts for the date select helpers, and a speedup in asset caching, among other things.

6.1 Nested Object Forms

Provided the parent model accepts nested attributes for the child objects (as discussed in the Active Record section), you can create nested forms using form_for and field_for. These forms can be nested arbitrarily deep, allowing you to edit complex object hierarchies on a single view without excessive code. For example, given this model:

+
+class Customer < ActiveRecord::Base
+  has_many :orders
+
+  accepts_nested_attributes_for :orders, :allow_destroy => true
+end
+
+
+
+

You can write this view in Rails 2.3:

+
+<% form_for @customer do |customer_form| %>
+  <div>
+    <%= customer_form.label :name, 'Customer Name:' %>
+    <%= customer_form.text_field :name %>
+  </div>
+
+  <!-- Here we call fields_for on the customer_form builder instance.
+   The block is called for each member of the orders collection. -->
+  <% customer_form.fields_for :orders do |order_form| %>
+    <p>
+      <div>
+        <%= order_form.label :number, 'Order Number:' %>
+        <%= order_form.text_field :number %>
+      </div>
+
+  <!-- The allow_destroy option in the model enables deletion of
+   child records. -->
+      <% unless order_form.object.new_record? %>
+        <div>
+          <%= order_form.label :_delete, 'Remove:' %>
+          <%= order_form.check_box :_delete %>
+        </div>
+      <% end %>
+    </p>
+  <% end %>
+
+  <%= customer_form.submit %>
+<% end %>
+
+
+
+ + +

6.2 Smart Rendering of Partials

The render method has been getting smarter over the years, and it's even smarter now. If you have an object or a collection and an appropriate partial, and the naming matches up, you can now just render the object and things will work. For example, in Rails 2.3, these render calls will work in your view (assuming sensible naming):

+
+# Equivalent of render :partial => 'articles/_article',
+# :object => @article
+render @article
+
+# Equivalent of render :partial => 'articles/_article',
+# :collection => @articles
+render @articles
+
+
+
+ + +

6.3 Prompts for Date Select Helpers

In Rails 2.3, you can supply custom prompts for the various date select helpers (date_select, time_select, and datetime_select), the same way you can with collection select helpers. You can supply a prompt string or a hash of individual prompt strings for the various components. You can also just set :prompt to true to use the custom generic prompt:

+
+select_datetime(DateTime.now, :prompt => true)
+
+select_datetime(DateTime.now, :prompt => "Choose date and time")
+
+select_datetime(DateTime.now, :prompt =>
+  {:day => 'Choose day', :month => 'Choose month',
+   :year => 'Choose year', :hour => 'Choose hour',
+   :minute => 'Choose minute'})
+
+
+
+ + +

6.4 AssetTag Timestamp Caching

You're likely familiar with Rails' practice of adding timestamps to static asset paths as a "cache buster." This helps ensure that stale copies of things like images and stylesheets don't get served out of the user's browser cache when you change them on the server. You can now modify this behavior with the cache_asset_timestamps configuration option for Action View. If you enable the cache, then Rails will calculate the timestamp once when it first serves an asset, and save that value. This means fewer (expensive) file system calls to serve static assets - but it also means that you can't modify any of the assets while the server is running and expect the changes to get picked up by clients.

6.5 Asset Hosts as Objects

Asset hosts get more flexible in edge Rails with the ability to declare an asset host as a specific object that responds to a call. This allows you to implement any complex logic you need in your asset hosting.

+ +

6.6 grouped_options_for_select Helper Method

Action View already had a bunch of helpers to aid in generating select controls, but now there's one more: grouped_options_for_select. This one accepts an array or hash of strings, and converts them into a string of option tags wrapped with optgroup tags. For example:

+
+grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]],
+  "Cowboy Hat", "Choose a product...")
+
+
+
+

returns

+
+<option value="">Choose a product...</option>
+<optgroup label="Hats">
+  <option value="Baseball Cap">Baseball Cap</option>
+  <option selected="selected" value="Cowboy Hat">Cowboy Hat</option>
+</optgroup>
+
+
+
+

6.7 Disabled Option Tags for Form Select Helpers

The form select helpers (such as select and options_for_select) now support a :disabled option, which can take a single value or an array of values to be disabled in the resulting tags:

+
+select(:post, :category, Post::CATEGORIES, :disabled => 'private')
+
+
+
+

returns

+
+<select name="post[category]">
+<option>story</option>
+<option>joke</option>
+<option>poem</option>
+<option disabled="disabled">private</option>
+</select>
+
+
+
+

You can also use an anonymous function to determine at runtime which options from collections will be selected and/or disabled:

+
+options_from_collection_for_select(@product.sizes, :name, :id, :disabled => lambda{|size| size.out_of_stock?})
+
+
+
+ + +

6.8 A Note About Template Loading

Rails 2.3 includes the ability to enable or disable cached templates for any particular environment. Cached templates give you a speed boost because they don't check for a new template file when they're rendered - but they also mean that you can't replace a template "on the fly" without restarting the server.

In most cases, you'll want template caching to be turned on in production, which you can do by making a setting in your production.rb file:

+
+config.action_view.cache_template_loading = true
+
+
+
+

This line will be generated for you by default in a new Rails 2.3 application. If you've upgraded from an older version of Rails, Rails will default to caching templates in production and test but not in development.

6.9 Other Action View Changes

+
    +
  • Token generation for CSRF protection has been simplified; now Rails uses a simple random string generated by ActiveSupport::SecureRandom rather than mucking around with session IDs.
  • +
  • +auto_link now properly applies options (such as :target and :class) to generated e-mail links.
  • +
  • The autolink helper has been refactored to make it a bit less messy and more intuitive.
  • +
  • +current_page? now works properly even when there are multiple query parameters in the URL.
  • +
+

7 Active Support

Active Support has a few interesting changes, including the introduction of Object#try.

7.1 Object#try

A lot of folks have adopted the notion of using try() to attempt operations on objects. It's especially helpful in views where you can avoid nil-checking by writing code like <%= @person.try(:name) %>. Well, now it's baked right into Rails. As implemented in Rails, it raises NoMethodError on private methods and always returns nil if the object is nil.

+
    +
  • More Information: try() +
  • +
+

7.2 Object#tap Backport

Object#tap is an addition to Ruby 1.9 and 1.8.7 that is similar to the returning method that Rails has had for a while: it yields to a block, and then returns the object that was yielded. Rails now includes code to make this available under older versions of Ruby as well.

7.3 Swappable Parsers for XMLmini

The support for XML parsing in Active Support has been made more flexible by allowing you to swap in different parsers. By default, it uses the standard REXML implementation, but you can easily specify the faster LibXML or Nokogiri implementations for your own applications, provided you have the appropriate gems installed:

+
+XmlMini.backend = 'LibXML'
+
+
+
+ + +

7.4 Fractional seconds for TimeWithZone

The Time and TimeWithZone classes include an xmlschema method to return the time in an XML-friendly string. As of Rails 2.3, TimeWithZone supports the same argument for specifying the number of digits in the fractional second part of the returned string that Time does:

+
+>> Time.zone.now.xmlschema(6)
+=> "2009-01-16T13:00:06.13653Z"
+
+
+
+ + +

7.5 JSON Key Quoting

If you look up the spec on the "json.org" site, you'll discover that all keys in a JSON structure must be strings, and they must be quoted with double quotes. Starting with Rails 2.3, we do the right thing here, even with numeric keys.

7.6 Other Active Support Changes

+
    +
  • You can use Enumerable#none? to check that none of the elements match the supplied block.
  • +
  • If you're using Active Support delegates the new :allow_nil option lets you return nil instead of raising an exception when the target object is nil.
  • +
  • +ActiveSupport::OrderedHash: now implements each_key and each_value.
  • +
  • +ActiveSupport::MessageEncryptor provides a simple way to encrypt information for storage in an untrusted location (like cookies).
  • +
  • Active Support's from_xml no longer depends on XmlSimple. Instead, Rails now includes its own XmlMini implementation, with just the functionality that it requires. This lets Rails dispense with the bundled copy of XmlSimple that it's been carting around.
  • +
  • If you memoize a private method, the result will now be private.
  • +
  • +String#parameterize accepts an optional separator: "Quick Brown Fox".parameterize('_') => "quick_brown_fox".
  • +
  • +number_to_phone accepts 7-digit phone numbers now.
  • +
  • +ActiveSupport::Json.decode now handles \u0000 style escape sequences.
  • +
+

8 Railties

In addition to the Rack changes covered above, Railties (the core code of Rails itself) sports a number of significant changes, including Rails Metal, application templates, and quiet backtraces.

8.1 Rails Metal

Rails Metal is a new mechanism that provides superfast endpoints inside of your Rails applications. Metal classes bypass routing and Action Controller to give you raw speed (at the cost of all the things in Action Controller, of course). This builds on all of the recent foundation work to make Rails a Rack application with an exposed middleware stack. Metal endpoints can be loaded from your application or from plugins.

+ +

8.2 Application Templates

Rails 2.3 incorporates Jeremy McAnally's rg application generator. What this means is that we now have template-based application generation built right into Rails; if you have a set of plugins you include in every application (among many other use cases), you can just set up a template once and use it over and over again when you run the rails command. There's also a rake task to apply a template to an existing application:

+
+rake rails:template LOCATION=~/template.rb
+
+
+
+

This will layer the changes from the template on top of whatever code the project already contains.

+ +

8.3 Quieter Backtraces

Building on thoughtbot's Quiet Backtrace plugin, which allows you to selectively remove lines from Test::Unit backtraces, Rails 2.3 implements ActiveSupport::BacktraceCleaner and Rails::BacktraceCleaner in core. This supports both filters (to perform regex-based substitutions on backtrace lines) and silencers (to remove backtrace lines entirely). Rails automatically adds silencers to get rid of the most common noise in a new application, and builds a config/backtrace_silencers.rb file to hold your own additions. This feature also enables prettier printing from any gem in the backtrace.

8.4 Faster Boot Time in Development Mode with Lazy Loading/Autoload

Quite a bit of work was done to make sure that bits of Rails (and its dependencies) are only brought into memory when they're actually needed. The core frameworks - Active Support, Active Record, Action Controller, Action Mailer and Action View - are now using autoload to lazy-load their individual classes. This work should help keep the memory footprint down and improve overall Rails performance.

You can also specify (by using the new preload_frameworks option) whether the core libraries should be autoloaded at startup. This defaults to false so that Rails autoloads itself piece-by-piece, but there are some circumstances where you still need to bring in everything at once - Passenger and JRuby both want to see all of Rails loaded together.

8.5 rake gem Task Rewrite

The internals of the various rake gem tasks have been substantially revised, to make the system work better for a variety of cases. The gem system now knows the difference between development and runtime dependencies, has a more robust unpacking system, gives better information when querying for the status of gems, and is less prone to "chicken and egg" dependency issues when you're bringing things up from scratch. There are also fixes for using gem commands under JRuby and for dependencies that try to bring in external copies of gems that are already vendored.

+ +

8.6 Other Railties Changes

+
    +
  • The instructions for updating a CI server to build Rails have been updated and expanded.
  • +
  • Internal Rails testing has been switched from Test::Unit::TestCase to ActiveSupport::TestCase, and the Rails core requires Mocha to test.
  • +
  • The default environment.rb file has been decluttered.
  • +
  • The dbconsole script now lets you use an all-numeric password without crashing.
  • +
  • +Rails.root now returns a Pathname object, which means you can use it directly with the join method to clean up existing code that uses File.join.
  • +
  • Various files in /public that deal with CGI and FCGI dispatching are no longer generated in every Rails application by default (you can still get them if you need them by adding --with-dispatchers when you run the rails command, or add them later with rake rails:update:generate_dispatchers).
  • +
  • Rails Guides have been converted from AsciiDoc to Textile markup.
  • +
  • Scaffolded views and controllers have been cleaned up a bit.
  • +
  • +script/server now accepts a --path argument to mount a Rails application from a specific path.
  • +
  • If any configured gems are missing, the gem rake tasks will skip loading much of the environment. This should solve many of the "chicken-and-egg" problems where rake gems:install couldn't run because gems were missing.
  • +
  • Gems are now unpacked exactly once. This fixes issues with gems (hoe, for instance) which are packed with read-only permissions on the files.
  • +
+

9 Deprecated

A few pieces of older code are deprecated in this release:

+
    +
  • If you're one of the (fairly rare) Rails developers who deploys in a fashion that depends on the inspector, reaper, and spawner scripts, you'll need to know that those scripts are no longer included in core Rails. If you need them, you'll be able to pick up copies via the irs_process_scripts plugin.
  • +
  • +render_component goes from "deprecated" to "nonexistent" in Rails 2.3. If you still need it, you can install the render_component plugin.
  • +
  • Support for Rails components has been removed.
  • +
  • If you were one of the people who got used to running script/performance/request to look at performance based on integration tests, you need to learn a new trick: that script has been removed from core Rails now. There's a new request_profiler plugin that you can install to get the exact same functionality back.
  • +
  • +ActionController::Base#session_enabled? is deprecated because sessions are lazy-loaded now.
  • +
  • The :digest and :secret options to protect_from_forgery are deprecated and have no effect.
  • +
  • Some integration test helpers have been removed. response.headers["Status"] and headers["Status"] will no longer return anything. Rack does not allow "Status" in its return headers. However you can still use the status and status_message helpers. response.headers["cookie"] and headers["cookie"] will no longer return any CGI cookies. You can inspect headers["Set-Cookie"] to see the raw cookie header or use the cookies helper to get a hash of the cookies sent to the client.
  • +
  • +formatted_polymorphic_url is deprecated. Use polymorphic_url with :format instead.
  • +
  • The :http_only option in ActionController::Response#set_cookie has been renamed to :httponly.
  • +
  • The :connector and :skip_last_comma options of to_sentence have been replaced by :words_connnector, :two_words_connector, and :last_word_connector options.
  • +
  • Posting a multipart form with an empty file_field control used to submit an empty string to the controller. Now it submits a nil, due to differences between Rack's multipart parser and the old Rails one.
  • +
+

10 Credits

Release notes compiled by Mike Gunderloy. This version of the Rails 2.3 release notes was compiled based on RC2 of Rails 2.3.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/3_0_release_notes.html b/3_0_release_notes.html new file mode 100644 index 0000000..ba7c9e7 --- /dev/null +++ b/3_0_release_notes.html @@ -0,0 +1,780 @@ + + + + + + + +Ruby on Rails 3.0 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 3.0 Release Notes

Rails 3.0 is ponies and rainbows! It's going to cook you dinner and fold your laundry. You're going to wonder how life was ever possible before it arrived. It's the Best Version of Rails We've Ever Done!

But seriously now, it's really good stuff. There are all the good ideas brought over from when the Merb team joined the party and brought a focus on framework agnosticism, slimmer and faster internals, and a handful of tasty APIs. If you're coming to Rails 3.0 from Merb 1.x, you should recognize lots. If you're coming from Rails 2.x, you're going to love it too.

Even if you don't give a hoot about any of our internal cleanups, Rails 3.0 is going to delight. We have a bunch of new features and improved APIs. It's never been a better time to be a Rails developer. Some of the highlights are:

+
    +
  • Brand new router with an emphasis on RESTful declarations
  • +
  • New Action Mailer API modeled after Action Controller (now without the agonizing pain of sending multipart messages!)
  • +
  • New Active Record chainable query language built on top of relational algebra
  • +
  • Unobtrusive JavaScript helpers with drivers for Prototype, jQuery, and more coming (end of inline JS)
  • +
  • Explicit dependency management with Bundler
  • +
+

On top of all that, we've tried our best to deprecate the old APIs with nice warnings. That means that you can move your existing application to Rails 3 without immediately rewriting all your old code to the latest best practices.

These release notes cover the major upgrades, but don't include every little bug fix and change. Rails 3.0 consists of almost 4,000 commits by more than 250 authors! If you want to see everything, check out the list of commits in the main Rails repository on GitHub.

+ + + +
+
+ +
+
+
+

To install Rails 3:

+
+# Use sudo if your setup requires it
+$ gem install rails
+
+
+
+

1 Upgrading to Rails 3

If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 2.3.5 and make sure your application still runs as expected before attempting to update to Rails 3. Then take heed of the following changes:

1.1 Rails 3 requires at least Ruby 1.8.7

Rails 3.0 requires Ruby 1.8.7 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible. Rails 3.0 is also compatible with Ruby 1.9.2.

Note that Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails 3.0. Ruby Enterprise Edition have these fixed since release 1.8.7-2010.02 though. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults on Rails 3.0, so if you want to use Rails 3 with 1.9.x jump on 1.9.2 for smooth sailing.

1.2 Rails Application object

As part of the groundwork for supporting running multiple Rails applications in the same process, Rails 3 introduces the concept of an Application object. An application object holds all the application specific configurations and is very similar in nature to config/environment.rb from the previous versions of Rails.

Each Rails application now must have a corresponding application object. The application object is defined in config/application.rb. If you're upgrading an existing application to Rails 3, you must add this file and move the appropriate configurations from config/environment.rb to config/application.rb.

1.3 script/* replaced by script/rails

The new script/rails replaces all the scripts that used to be in the script directory. You do not run script/rails directly though, the rails command detects it is being invoked in the root of a Rails application and runs the script for you. Intended usage is:

+
+$ rails console                      # instead of script/console
+$ rails g scaffold post title:string # instead of script/generate scaffold post title:string
+
+
+
+

Run rails --help for a list of all the options.

1.4 Dependencies and config.gem

The config.gem method is gone and has been replaced by using bundler and a Gemfile, see Vendoring Gems below.

1.5 Upgrade Process

To help with the upgrade process, a plugin named Rails Upgrade has been created to automate part of it.

Simply install the plugin, then run rake rails:upgrade:check to check your app for pieces that need to be updated (with links to information on how to update them). It also offers a task to generate a Gemfile based on your current config.gem calls and a task to generate a new routes file from your current one. To get the plugin, simply run the following:

+
+$ ruby script/plugin install git://github.com/rails/rails_upgrade.git
+
+
+
+

You can see an example of how that works at Rails Upgrade is now an Official Plugin

Aside from Rails Upgrade tool, if you need more help, there are people on IRC and rubyonrails-talk that are probably doing the same thing, possibly hitting the same issues. Be sure to blog your own experiences when upgrading so others can benefit from your knowledge!

2 Creating a Rails 3.0 application

+
+# You should have the 'rails' RubyGem installed
+$ rails new myapp
+$ cd myapp
+
+
+
+

2.1 Vendoring Gems

Rails now uses a Gemfile in the application root to determine the gems you require for your application to start. This Gemfile is processed by the Bundler which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems.

More information: - bundler homepage

2.2 Living on the Edge

Bundler and Gemfile makes freezing your Rails application easy as pie with the new dedicated bundle command, so rake freeze is no longer relevant and has been dropped.

If you want to bundle straight from the Git repository, you can pass the --edge flag:

+
+$ rails new myapp --edge
+
+
+
+

If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the --dev flag:

+
+$ ruby /path/to/rails/bin/rails new myapp --dev
+
+
+
+

3 Rails Architectural Changes

There are six major changes in the architecture of Rails.

3.1 Railties Restrung

Railties was updated to provide a consistent plugin API for the entire Rails framework as well as a total rewrite of generators and the Rails bindings, the result is that developers can now hook into any significant stage of the generators and application framework in a consistent, defined manner.

3.2 All Rails core components are decoupled

With the merge of Merb and Rails, one of the big jobs was to remove the tight coupling between Rails core components. This has now been achieved, and all Rails core components are now using the same API that you can use for developing plugins. This means any plugin you make, or any core component replacement (like DataMapper or Sequel) can access all the functionality that the Rails core components have access to and extend and enhance at will.

More information: - The Great Decoupling

3.3 Active Model Abstraction

Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.

More information: - Make Any Ruby Object Feel Like ActiveRecord

3.4 Controller Abstraction

Another big part of decoupling the core components was creating a base superclass that is separated from the notions of HTTP in order to handle rendering of views etc. This creation of AbstractController allowed ActionController and ActionMailer to be greatly simplified with common code removed from all these libraries and put into Abstract Controller.

More Information: - Rails Edge Architecture

3.5 Arel Integration

Arel (or Active Relation) has been taken on as the underpinnings of Active Record and is now required for Rails. Arel provides an SQL abstraction that simplifies out Active Record and provides the underpinnings for the relation functionality in Active Record.

More information: - Why I wrote Arel

3.6 Mail Extraction

Action Mailer ever since its beginnings has had monkey patches, pre parsers and even delivery and receiver agents, all in addition to having TMail vendored in the source tree. Version 3 changes that with all email message related functionality abstracted out to the Mail gem. This again reduces code duplication and helps create definable boundaries between Action Mailer and the email parser.

More information: - New Action Mailer API in Rails 3

4 Documentation

The documentation in the Rails tree is being updated with all the API changes, additionally, the Rails Edge Guides are being updated one by one to reflect the changes in Rails 3.0. The guides at guides.rubyonrails.org however will continue to contain only the stable version of Rails (at this point, version 2.3.5, until 3.0 is released).

More Information: - Rails Documentation Projects

5 Internationalization

A large amount of work has been done with I18n support in Rails 3, including the latest I18n gem supplying many speed improvements.

+
    +
  • I18n for any object - I18n behavior can be added to any object by including ActiveModel::Translation and ActiveModel::Validations. There is also an errors.messages fallback for translations.
  • +
  • Attributes can have default translations.
  • +
  • Form Submit Tags automatically pull the correct status (Create or Update) depending on the object status, and so pull the correct translation.
  • +
  • Labels with I18n also now work by just passing the attribute name.
  • +
+

More Information: - Rails 3 I18n changes

6 Railties

With the decoupling of the main Rails frameworks, Railties got a huge overhaul so as to make linking up frameworks, engines or plugins as painless and extensible as possible:

+
    +
  • Each application now has its own name space, application is started with YourAppName.boot for example, makes interacting with other applications a lot easier.
  • +
  • Anything under Rails.root/app is now added to the load path, so you can make app/observers/user_observer.rb and Rails will load it without any modifications.
  • +
  • +

    Rails 3.0 now provides a Rails.config object, which provides a central repository of all sorts of Rails wide configuration options.

    +

    Application generation has received extra flags allowing you to skip the installation of test-unit, Active Record, Prototype and Git. Also a new --dev flag has been added which sets the application up with the Gemfile pointing to your Rails checkout (which is determined by the path to the rails binary). See rails --help for more info.

    +
  • +
+

Railties generators got a huge amount of attention in Rails 3.0, basically:

+
    +
  • Generators were completely rewritten and are backwards incompatible.
  • +
  • Rails templates API and generators API were merged (they are the same as the former).
  • +
  • Generators are no longer loaded from special paths anymore, they are just found in the Ruby load path, so calling rails generate foo will look for generators/foo_generator.
  • +
  • New generators provide hooks, so any template engine, ORM, test framework can easily hook in.
  • +
  • New generators allow you to override the templates by placing a copy at Rails.root/lib/templates.
  • +
  • +Rails::Generators::TestCase is also supplied so you can create your own generators and test them.
  • +
+

Also, the views generated by Railties generators had some overhaul:

+
    +
  • Views now use div tags instead of p tags.
  • +
  • Scaffolds generated now make use of _form partials, instead of duplicated code in the edit and new views.
  • +
  • Scaffold forms now use f.submit which returns "Create ModelName" or "Update ModelName" depending on the state of the object passed in.
  • +
+

Finally a couple of enhancements were added to the rake tasks:

+
    +
  • +rake db:forward was added, allowing you to roll forward your migrations individually or in groups.
  • +
  • +rake routes CONTROLLER=x was added allowing you to just view the routes for one controller.
  • +
+

Railties now deprecates:

+
    +
  • +RAILS_ROOT in favor of Rails.root,
  • +
  • +RAILS_ENV in favor of Rails.env, and
  • +
  • +RAILS_DEFAULT_LOGGER in favor of Rails.logger.
  • +
+

PLUGIN/rails/tasks, and PLUGIN/tasks are no longer loaded all tasks now must be in PLUGIN/lib/tasks.

More information:

+ +

7 Action Pack

There have been significant internal and external changes in Action Pack.

7.1 Abstract Controller

Abstract Controller pulls out the generic parts of Action Controller into a reusable module that any library can use to render templates, render partials, helpers, translations, logging, any part of the request response cycle. This abstraction allowed ActionMailer::Base to now just inherit from AbstractController and just wrap the Rails DSL onto the Mail gem.

It also provided an opportunity to clean up Action Controller, abstracting out what could to simplify the code.

Note however that Abstract Controller is not a user facing API, you will not run into it in your day to day use of Rails.

More Information: - Rails Edge Architecture

7.2 Action Controller

+
    +
  • +application_controller.rb now has protect_from_forgery on by default.
  • +
  • The cookie_verifier_secret has been deprecated and now instead it is assigned through Rails.application.config.cookie_secret and moved into its own file: config/initializers/cookie_verification_secret.rb.
  • +
  • The session_store was configured in ActionController::Base.session, and that is now moved to Rails.application.config.session_store. Defaults are set up in config/initializers/session_store.rb.
  • +
  • +cookies.secure allowing you to set encrypted values in cookies with cookie.secure[:key] => value.
  • +
  • +cookies.permanent allowing you to set permanent values in the cookie hash cookie.permanent[:key] => value that raise exceptions on signed values if verification failures.
  • +
  • You can now pass :notice => 'This is a flash message' or :alert => 'Something went wrong' to the format call inside a respond_to block. The flash[] hash still works as previously.
  • +
  • +respond_with method has now been added to your controllers simplifying the venerable format blocks.
  • +
  • +ActionController::Responder added allowing you flexibility in how your responses get generated.
  • +
+

Deprecations:

+
    +
  • +filter_parameter_logging is deprecated in favor of config.filter_parameters << :password.
  • +
+

More Information:

+ +

7.3 Action Dispatch

Action Dispatch is new in Rails 3.0 and provides a new, cleaner implementation for routing.

+
    +
  • Big clean up and re-write of the router, the Rails router is now rack_mount with a Rails DSL on top, it is a stand alone piece of software.
  • +
  • +

    Routes defined by each application are now name spaced within your Application module, that is:

    +
    +
    +# Instead of:
    +
    +ActionController::Routing::Routes.draw do |map|
    +  map.resources :posts
    +end
    +
    +# You do:
    +
    +AppName::Application.routes do
    +  resources :posts
    +end
    +
    +
    +
    +
  • +
  • Added match method to the router, you can also pass any Rack application to the matched route.

  • +
  • Added constraints method to the router, allowing you to guard routers with defined constraints.

  • +
  • +

    Added scope method to the router, allowing you to namespace routes for different languages or different actions, for example:

    +
    +
    +scope 'es' do
    +  resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'proyecto'
    +end
    +
    +# Gives you the edit action with /es/proyecto/1/cambiar
    +
    +
    +
    +
  • +
  • Added root method to the router as a short cut for match '/', :to => path.

  • +
  • You can pass optional segments into the match, for example match "/:controller(/:action(/:id))(.:format)", each parenthesized segment is optional.

  • +
  • Routes can be expressed via blocks, for example you can call controller :home { match '/:action' }.

  • +
+

The old style map commands still work as before with a backwards compatibility layer, however this will be removed in the 3.1 release.

Deprecations

+
    +
  • The catch all route for non-REST applications (/:controller/:action/:id) is now commented out.
  • +
  • Routes :path_prefix no longer exists and :name_prefix now automatically adds "_" at the end of the given value.
  • +
+

More Information: +* The Rails 3 Router: Rack it Up +* Revamped Routes in Rails 3 +* Generic Actions in Rails 3

7.4 Action View

7.4.1 Unobtrusive JavaScript

Major re-write was done in the Action View helpers, implementing Unobtrusive JavaScript (UJS) hooks and removing the old inline AJAX commands. This enables Rails to use any compliant UJS driver to implement the UJS hooks in the helpers.

What this means is that all previous remote_<method> helpers have been removed from Rails core and put into the Prototype Legacy Helper. To get UJS hooks into your HTML, you now pass :remote => true instead. For example:

+
+form_for @post, :remote => true
+
+
+
+

Produces:

+
+<form action="http://host.com/" id="create-post" method="post" data-remote="true">
+
+
+
+
7.4.2 Helpers with Blocks

Helpers like form_for or div_for that insert content from a block use <%= now:

+
+<%= form_for @post do |f| %>
+  ...
+<% end %>
+
+
+
+

Your own helpers of that kind are expected to return a string, rather than appending to the output buffer by hand.

Helpers that do something else, like cache or content_for, are not affected by this change, they need &lt;% as before.

7.4.3 Other Changes
+
    +
  • You no longer need to call h(string) to escape HTML output, it is on by default in all view templates. If you want the unescaped string, call raw(string).
  • +
  • Helpers now output HTML 5 by default.
  • +
  • Form label helper now pulls values from I18n with a single value, so f.label :name will pull the :name translation.
  • +
  • I18n select label on should now be :en.helpers.select instead of :en.support.select.
  • +
  • You no longer need to place a minus sign at the end of a Ruby interpolation inside an ERB template to remove the trailing carriage return in the HTML output.
  • +
  • Added grouped_collection_select helper to Action View.
  • +
  • +content_for? has been added allowing you to check for the existence of content in a view before rendering.
  • +
  • passing :value => nil to form helpers will set the field's value attribute to nil as opposed to using the default value
  • +
  • passing :id => nil to form helpers will cause those fields to be rendered with no id attribute
  • +
  • passing :alt => nil to image_tag will cause the img tag to render with no alt attribute
  • +
+

8 Active Model

Active Model is new in Rails 3.0. It provides an abstraction layer for any ORM libraries to use to interact with Rails by implementing an Active Model interface.

8.1 ORM Abstraction and Action Pack Interface

Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.

More Information: - Make Any Ruby Object Feel Like ActiveRecord

8.2 Validations

Validations have been moved from Active Record into Active Model, providing an interface to validations that works across ORM libraries in Rails 3.

+
    +
  • There is now a validates :attribute, options_hash shortcut method that allows you to pass options for all the validates class methods, you can pass more than one option to a validate method.
  • +
  • The validates method has the following options: + +
      +
    • +:acceptance => Boolean.
    • +
    • +:confirmation => Boolean.
    • +
    • +:exclusion => { :in => Enumerable }.
    • +
    • +:inclusion => { :in => Enumerable }.
    • +
    • +:format => { :with => Regexp, :on => :create }.
    • +
    • +:length => { :maximum => Fixnum }.
    • +
    • +:numericality => Boolean.
    • +
    • +:presence => Boolean.
    • +
    • +:uniqueness => Boolean.
    • +
    +
  • +
+

All the Rails version 2.3 style validation methods are still supported in Rails 3.0, the new validates method is designed as an additional aid in your model validations, not a replacement for the existing API.

You can also pass in a validator object, which you can then reuse between objects that use Active Model:

+
+class TitleValidator < ActiveModel::EachValidator
+  Titles = ['Mr.', 'Mrs.', 'Dr.']
+  def validate_each(record, attribute, value)
+    unless Titles.include?(value)
+      record.errors[attribute] << 'must be a valid title'
+    end
+  end
+end
+
+
+
+
+
+class Person
+  include ActiveModel::Validations
+  attr_accessor :title
+  validates :title, :presence => true, :title => true
+end
+
+# Or for Active Record
+
+class Person < ActiveRecord::Base
+  validates :title, :presence => true, :title => true
+end
+
+
+
+

There's also support for introspection:

+
+User.validators
+User.validators_on(:login)
+
+
+
+

More Information:

+ +

9 Active Record

Active Record received a lot of attention in Rails 3.0, including abstraction into Active Model, a full update to the Query interface using Arel, validation updates and many enhancements and fixes. All of the Rails 2.x API will be usable through a compatibility layer that will be supported until version 3.1.

9.1 Query Interface

Active Record, through the use of Arel, now returns relations on its core methods. The existing API in Rails 2.3.x is still supported and will not be deprecated until Rails 3.1 and not removed until Rails 3.2, however, the new API provides the following new methods that all return relations allowing them to be chained together:

+
    +
  • +where - provides conditions on the relation, what gets returned.
  • +
  • +select - choose what attributes of the models you wish to have returned from the database.
  • +
  • +group - groups the relation on the attribute supplied.
  • +
  • +having - provides an expression limiting group relations (GROUP BY constraint).
  • +
  • +joins - joins the relation to another table.
  • +
  • +clause - provides an expression limiting join relations (JOIN constraint).
  • +
  • +includes - includes other relations pre-loaded.
  • +
  • +order - orders the relation based on the expression supplied.
  • +
  • +limit - limits the relation to the number of records specified.
  • +
  • +lock - locks the records returned from the table.
  • +
  • +readonly - returns an read only copy of the data.
  • +
  • +from - provides a way to select relationships from more than one table.
  • +
  • +scope - (previously named_scope) return relations and can be chained together with the other relation methods.
  • +
  • +with_scope - and with_exclusive_scope now also return relations and so can be chained.
  • +
  • +default_scope - also works with relations.
  • +
+

More Information:

+ +

9.2 Enhancements

+
    +
  • Added :destroyed? to Active Record objects.
  • +
  • Added :inverse_of to Active Record associations allowing you to pull the instance of an already loaded association without hitting the database.
  • +
+

9.3 Patches and Deprecations

Additionally, many fixes in the Active Record branch:

+
    +
  • SQLite 2 support has been dropped in favor of SQLite 3.
  • +
  • MySQL support for column order.
  • +
  • PostgreSQL adapter has had its TIME ZONE support fixed so it no longer inserts incorrect values.
  • +
  • Support multiple schemas in table names for PostgreSQL.
  • +
  • PostgreSQL support for the XML data type column.
  • +
  • +table_name is now cached.
  • +
  • A large amount of work done on the Oracle adapter as well with many bug fixes.
  • +
+

As well as the following deprecations:

+
    +
  • +named_scope in an Active Record class is deprecated and has been renamed to just scope.
  • +
  • In scope methods, you should move to using the relation methods, instead of a :conditions => {} finder method, for example scope :since, lambda {|time| where("created_at > ?", time) }.
  • +
  • +save(false) is deprecated, in favor of save(:validate => false).
  • +
  • I18n error messages for Active Record should be changed from :en.activerecord.errors.template to :en.errors.template.
  • +
  • +model.errors.on is deprecated in favor of model.errors[] +
  • +
  • validates_presence_of => validates... :presence => true
  • +
  • +ActiveRecord::Base.colorize_logging and config.active_record.colorize_logging are deprecated in favor of Rails::LogSubscriber.colorize_logging or config.colorize_logging +
  • +
+

While an implementation of State Machine has been in Active Record edge for some months now, it has been removed from the Rails 3.0 release.

10 Active Resource

Active Resource was also extracted out to Active Model allowing you to use Active Resource objects with Action Pack seamlessly.

+
    +
  • Added validations through Active Model.
  • +
  • Added observing hooks.
  • +
  • HTTP proxy support.
  • +
  • Added support for digest authentication.
  • +
  • Moved model naming into Active Model.
  • +
  • Changed Active Resource attributes to a Hash with indifferent access.
  • +
  • Added first, last and all aliases for equivalent find scopes.
  • +
  • +find_every now does not return a ResourceNotFound error if nothing returned.
  • +
  • Added save! which raises ResourceInvalid unless the object is valid?.
  • +
  • +update_attribute and update_attributes added to Active Resource models.
  • +
  • Added exists?.
  • +
  • Renamed SchemaDefinition to Schema and define_schema to schema.
  • +
  • Use the format of Active Resources rather than the content-type of remote errors to load errors.
  • +
  • Use instance_eval for schema block.
  • +
  • Fix ActiveResource::ConnectionError#to_s when @response does not respond to #code or #message, handles Ruby 1.9 compatibility.
  • +
  • Add support for errors in JSON format.
  • +
  • Ensure load works with numeric arrays.
  • +
  • Recognizes a 410 response from remote resource as the resource has been deleted.
  • +
  • Add ability to set SSL options on Active Resource connections.
  • +
  • Setting connection timeout also affects Net::HTTP open_timeout.
  • +
+

Deprecations:

+
    +
  • +save(false) is deprecated, in favor of save(:validate => false).
  • +
  • Ruby 1.9.2: URI.parse and .decode are deprecated and are no longer used in the library.
  • +
+

11 Active Support

A large effort was made in Active Support to make it cherry pickable, that is, you no longer have to require the entire Active Support library to get pieces of it. This allows the various core components of Rails to run slimmer.

These are the main changes in Active Support:

+
    +
  • Large clean up of the library removing unused methods throughout.
  • +
  • Active Support no longer provides vendored versions of TZInfo, Memcache Client and Builder. These are all included as dependencies and installed via the bundle install command.
  • +
  • Safe buffers are implemented in ActiveSupport::SafeBuffer.
  • +
  • Added Array.uniq_by and Array.uniq_by!.
  • +
  • Removed Array#rand and backported Array#sample from Ruby 1.9.
  • +
  • Fixed bug on TimeZone.seconds_to_utc_offset returning wrong value.
  • +
  • Added ActiveSupport::Notifications middleware.
  • +
  • +ActiveSupport.use_standard_json_time_format now defaults to true.
  • +
  • +ActiveSupport.escape_html_entities_in_json now defaults to false.
  • +
  • +Integer#multiple_of? accepts zero as an argument, returns false unless the receiver is zero.
  • +
  • +string.chars has been renamed to string.mb_chars.
  • +
  • +ActiveSupport::OrderedHash now can de-serialize through YAML.
  • +
  • Added SAX-based parser for XmlMini, using LibXML and Nokogiri.
  • +
  • Added Object#presence that returns the object if it's #present? otherwise returns nil.
  • +
  • Added String#exclude? core extension that returns the inverse of #include?.
  • +
  • Added to_i to DateTime in ActiveSupport so to_yaml works correctly on models with DateTime attributes.
  • +
  • Added Enumerable#exclude? to bring parity to Enumerable#include? and avoid if !x.include?.
  • +
  • Switch to on-by-default XSS escaping for rails.
  • +
  • Support deep-merging in ActiveSupport::HashWithIndifferentAccess.
  • +
  • +Enumerable#sum now works will all enumerables, even if they don't respond to :size.
  • +
  • +inspect on a zero length duration returns '0 seconds' instead of empty string.
  • +
  • Add element and collection to ModelName.
  • +
  • +String#to_time and String#to_datetime handle fractional seconds.
  • +
  • Added support to new callbacks for around filter object that respond to :before and :after used in before and after callbacks.
  • +
  • The ActiveSupport::OrderedHash#to_a method returns an ordered set of arrays. Matches Ruby 1.9's Hash#to_a.
  • +
  • +MissingSourceFile exists as a constant but it is now just equal to LoadError.
  • +
  • Added Class#class_attribute, to be able to declare a class-level attribute whose value is inheritable and overwritable by subclasses.
  • +
  • Finally removed DeprecatedCallbacks in ActiveRecord::Associations.
  • +
  • +Object#metaclass is now Kernel#singleton_class to match Ruby.
  • +
+

The following methods have been removed because they are now available in Ruby 1.8.7 and 1.9.

+
    +
  • +Integer#even? and Integer#odd? +
  • +
  • String#each_char
  • +
  • +String#start_with? and String#end_with? (3rd person aliases still kept)
  • +
  • String#bytesize
  • +
  • Object#tap
  • +
  • Symbol#to_proc
  • +
  • Object#instance_variable_defined?
  • +
  • Enumerable#none?
  • +
+

The security patch for REXML remains in Active Support because early patch-levels of Ruby 1.8.7 still need it. Active Support knows whether it has to apply it or not.

The following methods have been removed because they are no longer used in the framework:

+
    +
  • Kernel#daemonize
  • +
  • +Object#remove_subclasses_of Object#extend_with_included_modules_from, Object#extended_by +
  • +
  • Class#remove_class
  • +
  • +Regexp#number_of_captures, Regexp.unoptionalize, Regexp.optionalize, Regexp#number_of_captures +
  • +
+

12 Action Mailer

Action Mailer has been given a new API with TMail being replaced out with the new Mail as the email library. Action Mailer itself has been given an almost complete re-write with pretty much every line of code touched. The result is that Action Mailer now simply inherits from Abstract Controller and wraps the Mail gem in a Rails DSL. This reduces the amount of code and duplication of other libraries in Action Mailer considerably.

+
    +
  • All mailers are now in app/mailers by default.
  • +
  • Can now send email using new API with three methods: attachments, headers and mail.
  • +
  • Action Mailer now has native support for inline attachments using the attachments.inline method.
  • +
  • Action Mailer emailing methods now return Mail::Message objects, which can then be sent the deliver message to send itself.
  • +
  • All delivery methods are now abstracted out to the Mail gem.
  • +
  • The mail delivery method can accept a hash of all valid mail header fields with their value pair.
  • +
  • The mail delivery method acts in a similar way to Action Controller's respond_to, and you can explicitly or implicitly render templates. Action Mailer will turn the email into a multipart email as needed.
  • +
  • You can pass a proc to the format.mime_type calls within the mail block and explicitly render specific types of text, or add layouts or different templates. The render call inside the proc is from Abstract Controller and supports the same options.
  • +
  • What were mailer unit tests have been moved to functional tests.
  • +
  • Action Mailer now delegates all auto encoding of header fields and bodies to Mail Gem
  • +
  • Action Mailer will auto encode email bodies and headers for you
  • +
+

Deprecations:

+
    +
  • +:charset, :content_type, :mime_version, :implicit_parts_order are all deprecated in favor of ActionMailer.default :key => value style declarations.
  • +
  • Mailer dynamic create_method_name and deliver_method_name are deprecated, just call method_name which now returns a Mail::Message object.
  • +
  • +ActionMailer.deliver(message) is deprecated, just call message.deliver.
  • +
  • +template_root is deprecated, pass options to a render call inside a proc from the format.mime_type method inside the mail generation block
  • +
  • The body method to define instance variables is deprecated (body {:ivar => value}), just declare instance variables in the method directly and they will be available in the view.
  • +
  • Mailers being in app/models is deprecated, use app/mailers instead.
  • +
+

More Information:

+ +

13 Credits

See the full list of contributors to Rails for the many people who spent many hours making Rails 3. Kudos to all of them.

Rails 3.0 Release Notes were compiled by Mikel Lindsaar.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/3_1_release_notes.html b/3_1_release_notes.html new file mode 100644 index 0000000..64d0f02 --- /dev/null +++ b/3_1_release_notes.html @@ -0,0 +1,751 @@ + + + + + + + +Ruby on Rails 3.1 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 3.1 Release Notes

Highlights in Rails 3.1:

+
    +
  • Streaming
  • +
  • Reversible Migrations
  • +
  • Assets Pipeline
  • +
  • jQuery as the default JavaScript library
  • +
+

These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the list of +commits in the main Rails +repository on GitHub.

+ + + +
+
+ +
+
+
+

1 Upgrading to Rails 3.1

If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 3 in case you haven't and make sure your application still runs as expected before attempting to update to Rails 3.1. Then take heed of the following changes:

1.1 Rails 3.1 requires at least Ruby 1.8.7

Rails 3.1 requires Ruby 1.8.7 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible. Rails 3.1 is also compatible with Ruby 1.9.2.

Note that Ruby 1.8.7 p248 and p249 have marshaling bugs that crash Rails. Ruby Enterprise Edition have these fixed since release 1.8.7-2010.02 though. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults, so if you want to use 1.9.x jump on 1.9.2 for smooth sailing.

1.2 What to update in your apps

The following changes are meant for upgrading your application to Rails 3.1.3, the latest 3.1.x version of Rails.

1.2.1 Gemfile

Make the following changes to your Gemfile.

+
+gem 'rails', '= 3.1.3'
+gem 'mysql2'
+
+# Needed for the new asset pipeline
+group :assets do
+  gem 'sass-rails',   "~> 3.1.5"
+  gem 'coffee-rails', "~> 3.1.1"
+  gem 'uglifier',     ">= 1.0.3"
+end
+
+# jQuery is the default JavaScript library in Rails 3.1
+gem 'jquery-rails'
+
+
+
+
1.2.2 config/application.rb
+
    +
  • +

    The asset pipeline requires the following additions:

    +
    +
    +config.assets.enabled = true
    +config.assets.version = '1.0'
    +
    +
    +
    +
  • +
  • +

    If your application is using the "/assets" route for a resource you may want change the prefix used for assets to avoid conflicts:

    +
    +
    +# Defaults to '/assets'
    +config.assets.prefix = '/asset-files'
    +
    +
    +
    +
  • +
+
1.2.3 config/environments/development.rb
+
    +
  • Remove the RJS setting config.action_view.debug_rjs = true.

  • +
  • +

    Add the following, if you enable the asset pipeline.

    +
    +
    +# Do not compress assets
    +config.assets.compress = false
    +
    +# Expands the lines which load the assets
    +config.assets.debug = true
    +
    +
    +
    +
  • +
+
1.2.4 config/environments/production.rb
+
    +
  • +

    Again, most of the changes below are for the asset pipeline. You can read more about these in the Asset Pipeline guide.

    +
    +
    +# Compress JavaScripts and CSS
    +config.assets.compress = true
    +
    +# Don't fallback to assets pipeline if a precompiled asset is missed
    +config.assets.compile = false
    +
    +# Generate digests for assets URLs
    +config.assets.digest = true
    +
    +# Defaults to Rails.root.join("public/assets")
    +# config.assets.manifest = YOUR_PATH
    +
    +# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
    +# config.assets.precompile `= %w( search.js )
    +
    +# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
    +# config.force_ssl = true
    +
    +
    +
    +
  • +
+
1.2.5 config/environments/test.rb
+
+# Configure static asset server for tests with Cache-Control for performance
+config.serve_static_assets = true
+config.static_cache_control = "public, max-age=3600"
+
+
+
+
1.2.6 config/initializers/wrap_parameters.rb
+
    +
  • +

    Add this file with the following contents, if you wish to wrap parameters into a nested hash. This is on by default in new applications.

    +
    +
    +# Be sure to restart your server when you modify this file.
    +# This file contains settings for ActionController::ParamsWrapper which
    +# is enabled by default.
    +
    +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
    +ActiveSupport.on_load(:action_controller) do
    +  wrap_parameters :format => [:json]
    +end
    +
    +# Disable root element in JSON by default.
    +ActiveSupport.on_load(:active_record) do
    +  self.include_root_in_json = false
    +end
    +
    +
    +
    +
  • +
+
1.2.7 Remove :cache and :concat options in asset helpers references in views
+
    +
  • With the Asset Pipeline the :cache and :concat options aren't used anymore, delete these options from your views.
  • +
+

2 Creating a Rails 3.1 application

+
+# You should have the 'rails' RubyGem installed
+$ rails new myapp
+$ cd myapp
+
+
+
+

2.1 Vendoring Gems

Rails now uses a Gemfile in the application root to determine the gems you require for your application to start. This Gemfile is processed by the Bundler gem, which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems.

More information: - bundler homepage

2.2 Living on the Edge

Bundler and Gemfile makes freezing your Rails application easy as pie with the new dedicated bundle command. If you want to bundle straight from the Git repository, you can pass the --edge flag:

+
+$ rails new myapp --edge
+
+
+
+

If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the --dev flag:

+
+$ ruby /path/to/rails/railties/bin/rails new myapp --dev
+
+
+
+

3 Rails Architectural Changes

3.1 Assets Pipeline

The major change in Rails 3.1 is the Assets Pipeline. It makes CSS and JavaScript first-class code citizens and enables proper organization, including use in plugins and engines.

The assets pipeline is powered by Sprockets and is covered in the Asset Pipeline guide.

3.2 HTTP Streaming

HTTP Streaming is another change that is new in Rails 3.1. This lets the browser download your stylesheets and JavaScript files while the server is still generating the response. This requires Ruby 1.9.2, is opt-in and requires support from the web server as well, but the popular combo of NGINX and Unicorn is ready to take advantage of it.

3.3 Default JS library is now jQuery

jQuery is the default JavaScript library that ships with Rails 3.1. But if you use Prototype, it's simple to switch.

+
+$ rails new myapp -j prototype
+
+
+
+

3.4 Identity Map

Active Record has an Identity Map in Rails 3.1. An identity map keeps previously instantiated records and returns the object associated with the record if accessed again. The identity map is created on a per-request basis and is flushed at request completion.

Rails 3.1 comes with the identity map turned off by default.

4 Railties

+
    +
  • jQuery is the new default JavaScript library.

  • +
  • jQuery and Prototype are no longer vendored and is provided from now on by the jquery-rails and prototype-rails gems.

  • +
  • The application generator accepts an option -j which can be an arbitrary string. If passed "foo", the gem "foo-rails" is added to the Gemfile, and the application JavaScript manifest requires "foo" and "foo_ujs". Currently only "prototype-rails" and "jquery-rails" exist and provide those files via the asset pipeline.

  • +
  • Generating an application or a plugin runs bundle install unless --skip-gemfile or --skip-bundle is specified.

  • +
  • The controller and resource generators will now automatically produce asset stubs (this can be turned off with --skip-assets). These stubs will use CoffeeScript and Sass, if those libraries are available.

  • +
  • Scaffold and app generators use the Ruby 1.9 style hash when running on Ruby 1.9. To generate old style hash, --old-style-hash can be passed.

  • +
  • Scaffold controller generator creates format block for JSON instead of XML.

  • +
  • Active Record logging is directed to STDOUT and shown inline in the console.

  • +
  • Added config.force_ssl configuration which loads Rack::SSL middleware and force all requests to be under HTTPS protocol.

  • +
  • Added rails plugin new command which generates a Rails plugin with gemspec, tests and a dummy application for testing.

  • +
  • Added Rack::Etag and Rack::ConditionalGet to the default middleware stack.

  • +
  • Added Rack::Cache to the default middleware stack.

  • +
  • Engines received a major update - You can mount them at any path, enable assets, run generators etc.

  • +
+

5 Action Pack

5.1 Action Controller

+
    +
  • A warning is given out if the CSRF token authenticity cannot be verified.

  • +
  • Specify force_ssl in a controller to force the browser to transfer data via HTTPS protocol on that particular controller. To limit to specific actions, :only or :except can be used.

  • +
  • Sensitive query string parameters specified in config.filter_parameters will now be filtered out from the request paths in the log.

  • +
  • URL parameters which return nil for to_param are now removed from the query string.

  • +
  • Added ActionController::ParamsWrapper to wrap parameters into a nested hash, and will be turned on for JSON request in new applications by default. This can be customized in config/initializers/wrap_parameters.rb.

  • +
  • Added config.action_controller.include_all_helpers. By default helper :all is done in ActionController::Base, which includes all the helpers by default. Setting include_all_helpers to false will result in including only application_helper and the helper corresponding to controller (like foo_helper for foo_controller).

  • +
  • url_for and named url helpers now accept :subdomain and :domain as options.

  • +
  • +

    Added Base.http_basic_authenticate_with to do simple http basic authentication with a single class method call.

    +
    +
    +class PostsController < ApplicationController
    +  USER_NAME, PASSWORD = "dhh", "secret"
    +
    +  before_filter :authenticate, :except => [ :index ]
    +
    +  def index
    +    render :text => "Everyone can see me!"
    +  end
    +
    +  def edit
    +    render :text => "I'm only accessible if you know the password"
    +  end
    +
    +  private
    +    def authenticate
    +      authenticate_or_request_with_http_basic do |user_name, password|
    +        user_name == USER_NAME && password == PASSWORD
    +      end
    +    end
    +end
    +
    +
    +
    +

    ..can now be written as

    +
    +
    +class PostsController < ApplicationController
    +  http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index
    +
    +  def index
    +    render :text => "Everyone can see me!"
    +  end
    +
    +  def edit
    +    render :text => "I'm only accessible if you know the password"
    +  end
    +end
    +
    +
    +
    +
  • +
  • +

    Added streaming support, you can enable it with:

    +
    +
    +class PostsController < ActionController::Base
    +  stream
    +end
    +
    +
    +
    +

    You can restrict it to some actions by using :only or :except. Please read the docs at ActionController::Streaming for more information.

    +
  • +
  • The redirect route method now also accepts a hash of options which will only change the parts of the url in question, or an object which responds to call, allowing for redirects to be reused.

  • +
+

5.2 Action Dispatch

+
    +
  • config.action_dispatch.x_sendfile_header now defaults to nil and config/environments/production.rb doesn't set any particular value for it. This allows servers to set it through X-Sendfile-Type.

  • +
  • ActionDispatch::MiddlewareStack now uses composition over inheritance and is no longer an array.

  • +
  • Added ActionDispatch::Request.ignore_accept_header to ignore accept headers.

  • +
  • Added Rack::Cache to the default stack.

  • +
  • Moved etag responsibility from ActionDispatch::Response to the middleware stack.

  • +
  • Rely on Rack::Session stores API for more compatibility across the Ruby world. This is backwards incompatible since Rack::Session expects #get_session to accept four arguments and requires #destroy_session instead of simply #destroy.

  • +
  • Template lookup now searches further up in the inheritance chain.

  • +
+

5.3 Action View

+
    +
  • Added an :authenticity_token option to form_tag for custom handling or to omit the token by passing :authenticity_token => false.

  • +
  • Created ActionView::Renderer and specified an API for ActionView::Context.

  • +
  • In place SafeBuffer mutation is prohibited in Rails 3.1.

  • +
  • Added HTML5 button_tag helper.

  • +
  • file_field automatically adds :multipart => true to the enclosing form.

  • +
  • +

    Added a convenience idiom to generate HTML5 data-* attributes in tag helpers from a :data hash of options:

    +
    +
    +tag("div", :data => {:name => 'Stephen', :city_state => %w(Chicago IL)})
    +# => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />
    +
    +
    +
    +
  • +
+

Keys are dasherized. Values are JSON-encoded, except for strings and symbols.

+
    +
  • csrf_meta_tag is renamed to csrf_meta_tags and aliases csrf_meta_tag for backwards compatibility.

  • +
  • The old template handler API is deprecated and the new API simply requires a template handler to respond to call.

  • +
  • rhtml and rxml are finally removed as template handlers.

  • +
  • config.action_view.cache_template_loading is brought back which allows to decide whether templates should be cached or not.

  • +
  • The submit form helper does not generate an id "object_name_id" anymore.

  • +
  • Allows FormHelper#form_for to specify the :method as a direct option instead of through the :html hash. form_for(@post, remote: true, method: :delete) instead of form_for(@post, remote: true, html: { method: :delete }).

  • +
  • Provided JavaScriptHelper#j() as an alias for JavaScriptHelper#escape_javascript(). This supersedes the Object#j() method that the JSON gem adds within templates using the JavaScriptHelper.

  • +
  • Allows AM/PM format in datetime selectors.

  • +
  • auto_link has been removed from Rails and extracted into the rails_autolink gem

  • +
+

6 Active Record

+
    +
  • +

    Added a class method pluralize_table_names to singularize/pluralize table names of individual models. Previously this could only be set globally for all models through ActiveRecord::Base.pluralize_table_names.

    +
    +
    +class User < ActiveRecord::Base
    +  self.pluralize_table_names = false
    +end
    +
    +
    +
    +
  • +
  • +

    Added block setting of attributes to singular associations. The block will get called after the instance is initialized.

    +
    +
    +class User < ActiveRecord::Base
    +  has_one :account
    +end
    +
    +user.build_account{ |a| a.credit_limit = 100.0 }
    +
    +
    +
    +
  • +
  • Added ActiveRecord::Base.attribute_names to return a list of attribute names. This will return an empty array if the model is abstract or the table does not exist.

  • +
  • CSV Fixtures are deprecated and support will be removed in Rails 3.2.0.

  • +
  • +

    ActiveRecord#new, ActiveRecord#create and ActiveRecord#update_attributes all accept a second hash as an option that allows you to specify which role to consider when assigning attributes. This is built on top of Active Model's new mass assignment capabilities:

    +
    +
    +class Post < ActiveRecord::Base
    +  attr_accessible :title
    +  attr_accessible :title, :published_at, :as => :admin
    +end
    +
    +Post.new(params[:post], :as => :admin)
    +
    +
    +
    +
  • +
  • default_scope can now take a block, lambda, or any other object which responds to call for lazy evaluation.

  • +
  • Default scopes are now evaluated at the latest possible moment, to avoid problems where scopes would be created which would implicitly contain the default scope, which would then be impossible to get rid of via Model.unscoped.

  • +
  • PostgreSQL adapter only supports PostgreSQL version 8.2 and higher.

  • +
  • ConnectionManagement middleware is changed to clean up the connection pool after the rack body has been flushed.

  • +
  • Added an update_column method on Active Record. This new method updates a given attribute on an object, skipping validations and callbacks. It is recommended to use update_attributes or update_attribute unless you are sure you do not want to execute any callback, including the modification of the updated_at column. It should not be called on new records.

  • +
  • Associations with a :through option can now use any association as the through or source association, including other associations which have a :through option and has_and_belongs_to_many associations.

  • +
  • The configuration for the current database connection is now accessible via ActiveRecord::Base.connection_config.

  • +
  • +

    limits and offsets are removed from COUNT queries unless both are supplied.

    +
    +
    +People.limit(1).count           # => 'SELECT COUNT(*) FROM people'
    +People.offset(1).count          # => 'SELECT COUNT(*) FROM people'
    +People.limit(1).offset(1).count # => 'SELECT COUNT(*) FROM people LIMIT 1 OFFSET 1'
    +
    +
    +
    +
  • +
  • ActiveRecord::Associations::AssociationProxy has been split. There is now an Association class (and subclasses) which are responsible for operating on associations, and then a separate, thin wrapper called CollectionProxy, which proxies collection associations. This prevents namespace pollution, separates concerns, and will allow further refactorings.

  • +
  • Singular associations (has_one, belongs_to) no longer have a proxy and simply returns the associated record or nil. This means that you should not use undocumented methods such as bob.mother.create - use bob.create_mother instead.

  • +
  • Support the :dependent option on has_many :through associations. For historical and practical reasons, :delete_all is the default deletion strategy employed by association.delete(*records), despite the fact that the default strategy is :nullify for regular has_many. Also, this only works at all if the source reflection is a belongs_to. For other situations, you should directly modify the through association.

  • +
  • The behavior of association.destroy for has_and_belongs_to_many and has_many :through is changed. From now on, 'destroy' or 'delete' on an association will be taken to mean 'get rid of the link', not (necessarily) 'get rid of the associated records'.

  • +
  • Previously, has_and_belongs_to_many.destroy(*records) would destroy the records themselves. It would not delete any records in the join table. Now, it deletes the records in the join table.

  • +
  • Previously, has_many_through.destroy(*records) would destroy the records themselves, and the records in the join table. [Note: This has not always been the case; previous version of Rails only deleted the records themselves.] Now, it destroys only the records in the join table.

  • +
  • Note that this change is backwards-incompatible to an extent, but there is unfortunately no way to 'deprecate' it before changing it. The change is being made in order to have consistency as to the meaning of 'destroy' or 'delete' across the different types of associations. If you wish to destroy the records themselves, you can do records.association.each(&:destroy).

  • +
  • +

    Add :bulk => true option to change_table to make all the schema changes defined in a block using a single ALTER statement.

    +
    +
    +change_table(:users, :bulk => true) do |t|
    +  t.string :company_name
    +  t.change :birthdate, :datetime
    +end
    +
    +
    +
    +
  • +
  • Removed support for accessing attributes on a has_and_belongs_to_many join table. has_many :through needs to be used.

  • +
  • Added a create_association! method for has_one and belongs_to associations.

  • +
  • +

    Migrations are now reversible, meaning that Rails will figure out how to reverse your migrations. To use reversible migrations, just define the change method.

    +
    +
    +class MyMigration < ActiveRecord::Migration
    +  def change
    +    create_table(:horses) do |t|
    +      t.column :content, :text
    +      t.column :remind_at, :datetime
    +    end
    +  end
    +end
    +
    +
    +
    +
  • +
  • Some things cannot be automatically reversed for you. If you know how to reverse those things, you should define up and down in your migration. If you define something in change that cannot be reversed, an IrreversibleMigration exception will be raised when going down.

  • +
  • +

    Migrations now use instance methods rather than class methods:

    +
    +
    +class FooMigration < ActiveRecord::Migration
    +  def up # Not self.up
    +    ...
    +  end
    +end
    +
    +
    +
    +
  • +
  • Migration files generated from model and constructive migration generators (for example, add_name_to_users) use the reversible migration's change method instead of the ordinary up and down methods.

  • +
  • +

    Removed support for interpolating string SQL conditions on associations. Instead, a proc should be used.

    +
    +
    +has_many :things, :conditions => 'foo = #{bar}'          # before
    +has_many :things, :conditions => proc { "foo = #{bar}" } # after
    +
    +
    +
    +

    Inside the proc, self is the object which is the owner of the association, unless you are eager loading the association, in which case self is the class which the association is within.

    +

    You can have any "normal" conditions inside the proc, so the following will work too:

    +
    +
    +has_many :things, :conditions => proc { ["foo = ?", bar] }
    +
    +
    +
    +
  • +
  • Previously :insert_sql and :delete_sql on has_and_belongs_to_many association allowed you to call 'record' to get the record being inserted or deleted. This is now passed as an argument to the proc.

  • +
  • +

    Added ActiveRecord::Base#has_secure_password (via ActiveModel::SecurePassword) to encapsulate dead-simple password usage with BCrypt encryption and salting.

    +
    +
    +# Schema: User(name:string, password_digest:string, password_salt:string)
    +class User < ActiveRecord::Base
    +  has_secure_password
    +end
    +
    +
    +
    +
  • +
  • When a model is generated add_index is added by default for belongs_to or references columns.

  • +
  • Setting the id of a belongs_to object will update the reference to the object.

  • +
  • ActiveRecord::Base#dup and ActiveRecord::Base#clone semantics have changed to closer match normal Ruby dup and clone semantics.

  • +
  • Calling ActiveRecord::Base#clone will result in a shallow copy of the record, including copying the frozen state. No callbacks will be called.

  • +
  • Calling ActiveRecord::Base#dup will duplicate the record, including calling after initialize hooks. Frozen state will not be copied, and all associations will be cleared. A duped record will return true for new_record?, have a nil id field, and is saveable.

  • +
  • The query cache now works with prepared statements. No changes in the applications are required.

  • +
+

7 Active Model

+
    +
  • attr_accessible accepts an option :as to specify a role.

  • +
  • InclusionValidator, ExclusionValidator, and FormatValidator now accepts an option which can be a proc, a lambda, or anything that respond to call. This option will be called with the current record as an argument and returns an object which respond to include? for InclusionValidator and ExclusionValidator, and returns a regular expression object for FormatValidator.

  • +
  • Added ActiveModel::SecurePassword to encapsulate dead-simple password usage with BCrypt encryption and salting.

  • +
  • ActiveModel::AttributeMethods allows attributes to be defined on demand.

  • +
  • Added support for selectively enabling and disabling observers.

  • +
  • Alternate I18n namespace lookup is no longer supported.

  • +
+

8 Active Resource

+
    +
  • +

    The default format has been changed to JSON for all requests. If you want to continue to use XML you will need to set self.format = :xml in the class. For example,

    +
    +
    +class User < ActiveResource::Base
    +  self.format = :xml
    +end
    +
    +
    +
    +
  • +
+

9 Active Support

+
    +
  • ActiveSupport::Dependencies now raises NameError if it finds an existing constant in load_missing_constant.

  • +
  • Added a new reporting method Kernel#quietly which silences both STDOUT and STDERR.

  • +
  • Added String#inquiry as a convenience method for turning a String into a StringInquirer object.

  • +
  • Added Object#in? to test if an object is included in another object.

  • +
  • LocalCache strategy is now a real middleware class and no longer an anonymous class.

  • +
  • ActiveSupport::Dependencies::ClassCache class has been introduced for holding references to reloadable classes.

  • +
  • ActiveSupport::Dependencies::Reference has been refactored to take direct advantage of the new ClassCache.

  • +
  • Backports Range#cover? as an alias for Range#include? in Ruby 1.8.

  • +
  • Added weeks_ago and prev_week to Date/DateTime/Time.

  • +
  • Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants!.

  • +
+

Deprecations:

+
    +
  • +ActiveSupport::SecureRandom is deprecated in favor of SecureRandom from the Ruby standard library.
  • +
+

10 Credits

See the full list of contributors to Rails for the many people who spent many hours making Rails, the stable and robust framework it is. Kudos to all of them.

Rails 3.1 Release Notes were compiled by Vijay Dev

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/3_2_release_notes.html b/3_2_release_notes.html new file mode 100644 index 0000000..551dca6 --- /dev/null +++ b/3_2_release_notes.html @@ -0,0 +1,808 @@ + + + + + + + +Ruby on Rails 3.2 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 3.2 Release Notes

Highlights in Rails 3.2:

+
    +
  • Faster Development Mode
  • +
  • New Routing Engine
  • +
  • Automatic Query Explains
  • +
  • Tagged Logging
  • +
+

These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the list of +commits in the main Rails +repository on GitHub.

+ + + +
+
+ +
+
+
+

1 Upgrading to Rails 3.2

If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 3.1 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 3.2. Then take heed of the following changes:

1.1 Rails 3.2 requires at least Ruby 1.8.7

Rails 3.2 requires Ruby 1.8.7 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible. Rails 3.2 is also compatible with Ruby 1.9.2.

Note that Ruby 1.8.7 p248 and p249 have marshalling bugs that crash Rails. Ruby Enterprise Edition has these fixed since the release of 1.8.7-2010.02. On the 1.9 front, Ruby 1.9.1 is not usable because it outright segfaults, so if you want to use 1.9.x, jump on to 1.9.2 or 1.9.3 for smooth sailing.

1.2 What to update in your apps

+
    +
  • +

    Update your Gemfile to depend on

    +
      +
    • rails = 3.2.0
    • +
    • sass-rails ~> 3.2.3
    • +
    • coffee-rails ~> 3.2.1
    • +
    • uglifier >= 1.0.3
    • +
    +
  • +
  • Rails 3.2 deprecates vendor/plugins and Rails 4.0 will remove them completely. You can start replacing these plugins by extracting them as gems and adding them in your Gemfile. If you choose not to make them gems, you can move them into, say, lib/my_plugin/* and add an appropriate initializer in config/initializers/my_plugin.rb.

  • +
  • +

    There are a couple of new configuration changes you'd want to add in config/environments/development.rb:

    +
    +
    +# Raise exception on mass assignment protection for Active Record models
    +config.active_record.mass_assignment_sanitizer = :strict
    +
    +# Log the query plan for queries taking more than this (works
    +# with SQLite, MySQL, and PostgreSQL)
    +config.active_record.auto_explain_threshold_in_seconds = 0.5
    +
    +
    +
    +

    The mass_assignment_sanitizer config also needs to be added in config/environments/test.rb:

    +
    +
    +# Raise exception on mass assignment protection for Active Record models
    +config.active_record.mass_assignment_sanitizer = :strict
    +
    +
    +
    +
  • +
+

1.3 What to update in your engines

Replace the code beneath the comment in script/rails with the following content:

+
+ENGINE_ROOT = File.expand_path('../..', __FILE__)
+ENGINE_PATH = File.expand_path('../../lib/your_engine_name/engine', __FILE__)
+
+require 'rails/all'
+require 'rails/engine/commands'
+
+
+
+

2 Creating a Rails 3.2 application

+
+# You should have the 'rails' RubyGem installed
+$ rails new myapp
+$ cd myapp
+
+
+
+

2.1 Vendoring Gems

Rails now uses a Gemfile in the application root to determine the gems you require for your application to start. This Gemfile is processed by the Bundler gem, which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems.

More information: Bundler homepage

2.2 Living on the Edge

Bundler and Gemfile makes freezing your Rails application easy as pie with the new dedicated bundle command. If you want to bundle straight from the Git repository, you can pass the --edge flag:

+
+$ rails new myapp --edge
+
+
+
+

If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the --dev flag:

+
+$ ruby /path/to/rails/railties/bin/rails new myapp --dev
+
+
+
+

3 Major Features

3.1 Faster Development Mode & Routing

Rails 3.2 comes with a development mode that's noticeably faster. Inspired by Active Reload, Rails reloads classes only when files actually change. The performance gains are dramatic on a larger application. Route recognition also got a bunch faster thanks to the new Journey engine.

3.2 Automatic Query Explains

Rails 3.2 comes with a nice feature that explains queries generated by Arel by defining an explain method in ActiveRecord::Relation. For example, you can run something like puts Person.active.limit(5).explain and the query Arel produces is explained. This allows to check for the proper indexes and further optimizations.

Queries that take more than half a second to run are automatically explained in the development mode. This threshold, of course, can be changed.

3.3 Tagged Logging

When running a multi-user, multi-account application, it's a great help to be able to filter the log by who did what. TaggedLogging in Active Support helps in doing exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such applications.

4 Documentation

From Rails 3.2, the Rails guides are available for the Kindle and free Kindle Reading Apps for the iPad, iPhone, Mac, Android, etc.

5 Railties

+
    +
  • Speed up development by only reloading classes if dependencies files changed. This can be turned off by setting config.reload_classes_only_on_change to false.

  • +
  • New applications get a flag config.active_record.auto_explain_threshold_in_seconds in the environments configuration files. With a value of 0.5 in development.rb and commented out in production.rb. No mention in test.rb.

  • +
  • Added config.exceptions_app to set the exceptions application invoked by the ShowException middleware when an exception happens. Defaults to ActionDispatch::PublicExceptions.new(Rails.public_path).

  • +
  • Added a DebugExceptions middleware which contains features extracted from ShowExceptions middleware.

  • +
  • Display mounted engines' routes in rake routes.

  • +
  • +

    Allow to change the loading order of railties with config.railties_order like:

    +
    +
    +config.railties_order = [Blog::Engine, :main_app, :all]
    +
    +
    +
    +
  • +
  • Scaffold returns 204 No Content for API requests without content. This makes scaffold work with jQuery out of the box.

  • +
  • Update Rails::Rack::Logger middleware to apply any tags set in config.log_tags to ActiveSupport::TaggedLogging. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications.

  • +
  • Default options to rails new can be set in ~/.railsrc. You can specify extra command-line arguments to be used every time rails new runs in the .railsrc configuration file in your home directory.

  • +
  • Add an alias d for destroy. This works for engines too.

  • +
  • Attributes on scaffold and model generators default to string. This allows the following: rails g scaffold Post title body:text author

  • +
  • +

    Allow scaffold/model/migration generators to accept "index" and "uniq" modifiers. For example,

    +
    +
    +rails g scaffold Post title:string:index author:uniq price:decimal{7,2}
    +
    +
    +
    +

    will create indexes for title and author with the latter being a unique index. Some types such as decimal accept custom options. In the example, price will be a decimal column with precision and scale set to 7 and 2 respectively.

    +
  • +
  • Turn gem has been removed from default Gemfile.

  • +
  • Remove old plugin generator rails generate plugin in favor of rails plugin new command.

  • +
  • Remove old config.paths.app.controller API in favor of config.paths["app/controller"].

  • +
+
5.1 Deprecations
+
    +
  • +Rails::Plugin is deprecated and will be removed in Rails 4.0. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies.
  • +
+

6 Action Mailer

+
    +
  • Upgraded mail version to 2.4.0.

  • +
  • Removed the old Action Mailer API which was deprecated since Rails 3.0.

  • +
+

7 Action Pack

7.1 Action Controller

+
    +
  • Make ActiveSupport::Benchmarkable a default module for ActionController::Base, so the #benchmark method is once again available in the controller context like it used to be.

  • +
  • Added :gzip option to caches_page. The default option can be configured globally using page_cache_compression.

  • +
  • +

    Rails will now use your default layout (such as "layouts/application") when you specify a layout with :only and :except condition, and those conditions fail.

    +
    +
    +class CarsController
    +  layout 'single_car', :only => :show
    +end
    +
    +
    +
    +

    Rails will use layouts/single_car when a request comes in :show action, and use layouts/application (or layouts/cars, if exists) when a request comes in for any other actions.

    +
  • +
  • form_for is changed to use #{action}_#{as} as the css class and id if :as option is provided. Earlier versions used #{as}_#{action}.

  • +
  • ActionController::ParamsWrapper on Active Record models now only wrap attr_accessible attributes if they were set. If not, only the attributes returned by the class method attribute_names will be wrapped. This fixes the wrapping of nested attributes by adding them to attr_accessible.

  • +
  • Log "Filter chain halted as CALLBACKNAME rendered or redirected" every time a before callback halts.

  • +
  • ActionDispatch::ShowExceptions is refactored. The controller is responsible for choosing to show exceptions. It's possible to override show_detailed_exceptions? in controllers to specify which requests should provide debugging information on errors.

  • +
  • Responders now return 204 No Content for API requests without a response body (as in the new scaffold).

  • +
  • +

    ActionController::TestCase cookies is refactored. Assigning cookies for test cases should now use cookies[]

    +
    +
    +cookies[:email] = 'user@example.com'
    +get :index
    +assert_equal 'user@example.com', cookies[:email]
    +
    +
    +
    +

    To clear the cookies, use clear.

    +
    +
    +cookies.clear
    +get :index
    +assert_nil cookies[:email]
    +
    +
    +
    +

    We now no longer write out HTTP_COOKIE and the cookie jar is persistent between requests so if you need to manipulate the environment for your test you need to do it before the cookie jar is created.

    +
  • +
  • send_file now guesses the MIME type from the file extension if :type is not provided.

  • +
  • MIME type entries for PDF, ZIP and other formats were added.

  • +
  • Allow fresh_when/stale? to take a record instead of an options hash.

  • +
  • Changed log level of warning for missing CSRF token from :debug to :warn.

  • +
  • Assets should use the request protocol by default or default to relative if no request is available.

  • +
+
7.1.1 Deprecations
+
    +
  • +

    Deprecated implied layout lookup in controllers whose parent had an explicit layout set:

    +
    +
    +class ApplicationController
    +  layout "application"
    +end
    +
    +class PostsController < ApplicationController
    +end
    +
    +
    +
    +

    In the example above, PostsController will no longer automatically look up for a posts layout. If you need this functionality you could either remove layout "application" from ApplicationController or explicitly set it to nil in PostsController.

    +
  • +
  • Deprecated ActionController::UnknownAction in favor of AbstractController::ActionNotFound.

  • +
  • Deprecated ActionController::DoubleRenderError in favor of AbstractController::DoubleRenderError.

  • +
  • Deprecated method_missing in favor of action_missing for missing actions.

  • +
  • Deprecated ActionController#rescue_action, ActionController#initialize_template_class and ActionController#assign_shortcuts.

  • +
+

7.2 Action Dispatch

+
    +
  • Add config.action_dispatch.default_charset to configure default charset for ActionDispatch::Response.

  • +
  • Added ActionDispatch::RequestId middleware that'll make a unique X-Request-Id header available to the response and enables the ActionDispatch::Request#uuid method. This makes it easy to trace requests from end-to-end in the stack and to identify individual requests in mixed logs like Syslog.

  • +
  • The ShowExceptions middleware now accepts an exceptions application that is responsible to render an exception when the application fails. The application is invoked with a copy of the exception in env["action_dispatch.exception"] and with the PATH_INFO rewritten to the status code.

  • +
  • Allow rescue responses to be configured through a railtie as in config.action_dispatch.rescue_responses.

  • +
+
7.2.1 Deprecations
+
    +
  • Deprecated the ability to set a default charset at the controller level, use the new config.action_dispatch.default_charset instead.
  • +
+

7.3 Action View

+
    +
  • +

    Add button_tag support to ActionView::Helpers::FormBuilder. This support mimics the default behavior of submit_tag.

    +
    +
    +<%= form_for @post do |f| %>
    +  <%= f.button %>
    +<% end %>
    +
    +
    +
    +
  • +
  • Date helpers accept a new option :use_two_digit_numbers => true, that renders select boxes for months and days with a leading zero without changing the respective values. For example, this is useful for displaying ISO 8601-style dates such as '2011-08-01'.

  • +
  • +

    You can provide a namespace for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generated HTML id.

    +
    +
    +<%= form_for(@offer, :namespace => 'namespace') do |f| %>
    +  <%= f.label :version, 'Version' %>:
    +  <%= f.text_field :version %>
    +<% end %>
    +
    +
    +
    +
  • +
  • Limit the number of options for select_year to 1000. Pass :max_years_allowed option to set your own limit.

  • +
  • +

    content_tag_for and div_for can now take a collection of records. It will also yield the record as the first argument if you set a receiving argument in your block. So instead of having to do this:

    +
    +
    +@items.each do |item|
    +  content_tag_for(:li, item) do
    +     Title: <%= item.title %>
    +  end
    +end
    +
    +
    +
    +

    You can do this:

    +
    +
    +content_tag_for(:li, @items) do |item|
    +  Title: <%= item.title %>
    +end
    +
    +
    +
    +
  • +
  • Added font_path helper method that computes the path to a font asset in public/fonts.

  • +
+
7.3.1 Deprecations
+
    +
  • Passing formats or handlers to render :template and friends like render :template => "foo.html.erb" is deprecated. Instead, you can provide :handlers and :formats directly as options: render :template => "foo", :formats => [:html, :js], :handlers => :erb.
  • +
+

7.4 Sprockets

+
    +
  • Adds a configuration option config.assets.logger to control Sprockets logging. Set it to false to turn off logging and to nil to default to Rails.logger.
  • +
+

8 Active Record

+
    +
  • Boolean columns with 'on' and 'ON' values are type cast to true.

  • +
  • When the timestamps method creates the created_at and updated_at columns, it makes them non-nullable by default.

  • +
  • Implemented ActiveRecord::Relation#explain.

  • +
  • Implements ActiveRecord::Base.silence_auto_explain which allows the user to selectively disable automatic EXPLAINs within a block.

  • +
  • Implements automatic EXPLAIN logging for slow queries. A new configuration parameter config.active_record.auto_explain_threshold_in_seconds determines what's to be considered a slow query. Setting that to nil disables this feature. Defaults are 0.5 in development mode, and nil in test and production modes. Rails 3.2 supports this feature in SQLite, MySQL (mysql2 adapter), and PostgreSQL.

  • +
  • +

    Added ActiveRecord::Base.store for declaring simple single-column key/value stores.

    +
    +
    +class User < ActiveRecord::Base
    +  store :settings, accessors: [ :color, :homepage ]
    +end
    +
    +u = User.new(color: 'black', homepage: '37signals.com')
    +u.color                          # Accessor stored attribute
    +u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
    +
    +
    +
    +
  • +
  • +

    Added ability to run migrations only for a given scope, which allows to run migrations only from one engine (for example to revert changes from an engine that need to be removed).

    +
    +
    +rake db:migrate SCOPE=blog
    +
    +
    +
    +
  • +
  • Migrations copied from engines are now scoped with engine's name, for example 01_create_posts.blog.rb.

  • +
  • +

    Implemented ActiveRecord::Relation#pluck method that returns an array of column values directly from the underlying table. This also works with serialized attributes.

    +
    +
    +Client.where(:active => true).pluck(:id)
    +# SELECT id from clients where active = 1
    +
    +
    +
    +
  • +
  • Generated association methods are created within a separate module to allow overriding and composition. For a class named MyModel, the module is named MyModel::GeneratedFeatureMethods. It is included into the model class immediately after the generated_attributes_methods module defined in Active Model, so association methods override attribute methods of the same name.

  • +
  • +

    Add ActiveRecord::Relation#uniq for generating unique queries.

    +
    +
    +Client.select('DISTINCT name')
    +
    +
    +
    +

    ..can be written as:

    +
    +
    +Client.select(:name).uniq
    +
    +
    +
    +

    This also allows you to revert the uniqueness in a relation:

    +
    +
    +Client.select(:name).uniq.uniq(false)
    +
    +
    +
    +
  • +
  • Support index sort order in SQLite, MySQL and PostgreSQL adapters.

  • +
  • +

    Allow the :class_name option for associations to take a symbol in addition to a string. This is to avoid confusing newbies, and to be consistent with the fact that other options like :foreign_key already allow a symbol or a string.

    +
    +
    +has_many :clients, :class_name => :Client # Note that the symbol need to be capitalized
    +
    +
    +
    +
  • +
  • In development mode, db:drop also drops the test database in order to be symmetric with db:create.

  • +
  • Case-insensitive uniqueness validation avoids calling LOWER in MySQL when the column already uses a case-insensitive collation.

  • +
  • Transactional fixtures enlist all active database connections. You can test models on different connections without disabling transactional fixtures.

  • +
  • +

    Add first_or_create, first_or_create!, first_or_initialize methods to Active Record. This is a better approach over the old find_or_create_by dynamic methods because it's clearer which arguments are used to find the record and which are used to create it.

    +
    +
    +User.where(:first_name => "Scarlett").first_or_create!(:last_name => "Johansson")
    +
    +
    +
    +
  • +
  • +

    Added a with_lock method to Active Record objects, which starts a transaction, locks the object (pessimistically) and yields to the block. The method takes one (optional) parameter and passes it to lock!.

    +

    This makes it possible to write the following:

    +
    +
    +class Order < ActiveRecord::Base
    +  def cancel!
    +    transaction do
    +      lock!
    +      # ... cancelling logic
    +    end
    +  end
    +end
    +
    +
    +
    +

    as:

    +
    +
    +class Order < ActiveRecord::Base
    +  def cancel!
    +    with_lock do
    +      # ... cancelling logic
    +    end
    +  end
    +end
    +
    +
    +
    +
  • +
+

8.1 Deprecations

+
    +
  • +

    Automatic closure of connections in threads is deprecated. For example the following code is deprecated:

    +
    +
    +Thread.new { Post.find(1) }.join
    +
    +
    +
    +

    It should be changed to close the database connection at the end of the thread:

    +
    +
    +Thread.new {
    +  Post.find(1)
    +  Post.connection.close
    +}.join
    +
    +
    +
    +

    Only people who spawn threads in their application code need to worry about this change.

    +
  • +
  • +

    The set_table_name, set_inheritance_column, set_sequence_name, set_primary_key, set_locking_column methods are deprecated. Use an assignment method instead. For example, instead of set_table_name, use self.table_name=.

    +
    +
    +class Project < ActiveRecord::Base
    +  self.table_name = "project"
    +end
    +
    +
    +
    +

    Or define your own self.table_name method:

    +
    +
    +class Post < ActiveRecord::Base
    +  def self.table_name
    +    "special_" + super
    +  end
    +end
    +
    +Post.table_name # => "special_posts"
    +
    +
    +
    +
    +
  • +
+

9 Active Model

+
    +
  • Add ActiveModel::Errors#added? to check if a specific error has been added.

  • +
  • Add ability to define strict validations with strict => true that always raises exception when fails.

  • +
  • Provide mass_assignment_sanitizer as an easy API to replace the sanitizer behavior. Also support both :logger (default) and :strict sanitizer behavior.

  • +
+

9.1 Deprecations

+
    +
  • Deprecated define_attr_method in ActiveModel::AttributeMethods because this only existed to support methods like set_table_name in Active Record, which are themselves being deprecated.

  • +
  • Deprecated Model.model_name.partial_path in favor of model.to_partial_path.

  • +
+

10 Active Resource

+
    +
  • Redirect responses: 303 See Other and 307 Temporary Redirect now behave like 301 Moved Permanently and 302 Found.
  • +
+

11 Active Support

+
    +
  • +

    Added ActiveSupport:TaggedLogging that can wrap any standard Logger class to provide tagging capabilities.

    +
    +
    +Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
    +
    +Logger.tagged("BCX") { Logger.info "Stuff" }
    +# Logs "[BCX] Stuff"
    +
    +Logger.tagged("BCX", "Jason") { Logger.info "Stuff" }
    +# Logs "[BCX] [Jason] Stuff"
    +
    +Logger.tagged("BCX") { Logger.tagged("Jason") { Logger.info "Stuff" } }
    +# Logs "[BCX] [Jason] Stuff"
    +
    +
    +
    +
  • +
  • The beginning_of_week method in Date, Time and DateTime accepts an optional argument representing the day in which the week is assumed to start.

  • +
  • ActiveSupport::Notifications.subscribed provides subscriptions to events while a block runs.

  • +
  • Defined new methods Module#qualified_const_defined?, Module#qualified_const_get and Module#qualified_const_set that are analogous to the corresponding methods in the standard API, but accept qualified constant names.

  • +
  • Added #deconstantize which complements #demodulize in inflections. This removes the rightmost segment in a qualified constant name.

  • +
  • Added safe_constantize that constantizes a string but returns nil instead of raising an exception if the constant (or part of it) does not exist.

  • +
  • ActiveSupport::OrderedHash is now marked as extractable when using Array#extract_options!.

  • +
  • Added Array#prepend as an alias for Array#unshift and Array#append as an alias for Array#<<.

  • +
  • The definition of a blank string for Ruby 1.9 has been extended to Unicode whitespace. Also, in Ruby 1.8 the ideographic space U`3000 is considered to be whitespace.

  • +
  • The inflector understands acronyms.

  • +
  • +

    Added Time#all_day, Time#all_week, Time#all_quarter and Time#all_year as a way of generating ranges.

    +
    +
    +Event.where(:created_at => Time.now.all_week)
    +Event.where(:created_at => Time.now.all_day)
    +
    +
    +
    +
  • +
  • Added instance_accessor: false as an option to Class#cattr_accessor and friends.

  • +
  • ActiveSupport::OrderedHash now has different behavior for #each and #each_pair when given a block accepting its parameters with a splat.

  • +
  • Added ActiveSupport::Cache::NullStore for use in development and testing.

  • +
  • Removed ActiveSupport::SecureRandom in favor of SecureRandom from the standard library.

  • +
+

11.1 Deprecations

+
    +
  • ActiveSupport::Base64 is deprecated in favor of ::Base64.

  • +
  • Deprecated ActiveSupport::Memoizable in favor of Ruby memoization pattern.

  • +
  • Module#synchronize is deprecated with no replacement. Please use monitor from ruby's standard library.

  • +
  • Deprecated ActiveSupport::MessageEncryptor#encrypt and ActiveSupport::MessageEncryptor#decrypt.

  • +
  • ActiveSupport::BufferedLogger#silence is deprecated. If you want to squelch logs for a certain block, change the log level for that block.

  • +
  • ActiveSupport::BufferedLogger#open_log is deprecated. This method should not have been public in the first place.

  • +
  • ActiveSupport::BufferedLogger's behavior of automatically creating the directory for your log file is deprecated. Please make sure to create the directory for your log file before instantiating.

  • +
  • +

    ActiveSupport::BufferedLogger#auto_flushing is deprecated. Either set the sync level on the underlying file handle like this. Or tune your filesystem. The FS cache is now what controls flushing.

    +
    +
    +f = File.open('foo.log', 'w')
    +f.sync = true
    +ActiveSupport::BufferedLogger.new f
    +
    +
    +
    +
  • +
  • ActiveSupport::BufferedLogger#flush is deprecated. Set sync on your filehandle, or tune your filesystem.

  • +
+

12 Credits

See the full list of contributors to Rails for the many people who spent many hours making Rails, the stable and robust framework it is. Kudos to all of them.

Rails 3.2 Release Notes were compiled by Vijay Dev.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/4_0_release_notes.html b/4_0_release_notes.html new file mode 100644 index 0000000..b3c0c90 --- /dev/null +++ b/4_0_release_notes.html @@ -0,0 +1,537 @@ + + + + + + + +Ruby on Rails 4.0 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 4.0 Release Notes

Highlights in Rails 4.0:

+
    +
  • Ruby 2.0 preferred; 1.9.3+ required
  • +
  • Strong Parameters
  • +
  • Turbolinks
  • +
  • Russian Doll Caching
  • +
+

These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the list of +commits in the main Rails +repository on GitHub.

+ + + +
+
+ +
+
+
+

1 Upgrading to Rails 4.0

If you're upgrading an existing application, it's a great idea to have good test coverage before going in. You should also first upgrade to Rails 3.2 in case you haven't and make sure your application still runs as expected before attempting an update to Rails 4.0. A list of things to watch out for when upgrading is available in the Upgrading Ruby on Rails guide.

2 Creating a Rails 4.0 application

+
+ You should have the 'rails' RubyGem installed
+$ rails new myapp
+$ cd myapp
+
+
+
+

2.1 Vendoring Gems

Rails now uses a Gemfile in the application root to determine the gems you require for your application to start. This Gemfile is processed by the Bundler gem, which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems.

More information: Bundler homepage

2.2 Living on the Edge

Bundler and Gemfile makes freezing your Rails application easy as pie with the new dedicated bundle command. If you want to bundle straight from the Git repository, you can pass the --edge flag:

+
+$ rails new myapp --edge
+
+
+
+

If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the --dev flag:

+
+$ ruby /path/to/rails/railties/bin/rails new myapp --dev
+
+
+
+

3 Major Features

Rails 4.0

3.1 Upgrade

+
    +
  • +Ruby 1.9.3 (commit) - Ruby 2.0 preferred; 1.9.3+ required
  • +
  • +New deprecation policy - Deprecated features are warnings in Rails 4.0 and will be removed in Rails 4.1.
  • +
  • +ActionPack page and action caching (commit) - Page and action caching are extracted to a separate gem. Page and action caching requires too much manual intervention (manually expiring caches when the underlying model objects are updated). Instead, use Russian doll caching.
  • +
  • +ActiveRecord observers (commit) - Observers are extracted to a separate gem. Observers are only needed for page and action caching, and can lead to spaghetti code.
  • +
  • +ActiveRecord session store (commit) - The ActiveRecord session store is extracted to a separate gem. Storing sessions in SQL is costly. Instead, use cookie sessions, memcache sessions, or a custom session store.
  • +
  • +ActiveModel mass assignment protection (commit) - Rails 3 mass assignment protection is deprecated. Instead, use strong parameters.
  • +
  • +ActiveResource (commit) - ActiveResource is extracted to a separate gem. ActiveResource was not widely used.
  • +
  • +vendor/plugins removed (commit) - Use a Gemfile to manage installed gems.
  • +
+

3.2 ActionPack

+
    +
  • +Strong parameters (commit) - Only allow whitelisted parameters to update model objects (params.permit(:title, :text)).
  • +
  • +Routing concerns (commit) - In the routing DSL, factor out common subroutes (comments from /posts/1/comments and /videos/1/comments).
  • +
  • +ActionController::Live (commit) - Stream JSON with response.stream.
  • +
  • +Declarative ETags (commit) - Add controller-level etag additions that will be part of the action etag computation.
  • +
  • +Russian doll caching (commit) - Cache nested fragments of views. Each fragment expires based on a set of dependencies (a cache key). The cache key is usually a template version number and a model object.
  • +
  • +Turbolinks (commit) - Serve only one initial HTML page. When the user navigates to another page, use pushState to update the URL and use AJAX to update the title and body.
  • +
  • +Decouple ActionView from ActionController (commit) - ActionView was decoupled from ActionPack and will be moved to a separated gem in Rails 4.1.
  • +
  • +Do not depend on ActiveModel (commit) - ActionPack no longer depends on ActiveModel.
  • +
+

3.3 General

+
    +
  • +ActiveModel::Model (commit) - ActiveModel::Model, a mixin to make normal Ruby objects to work with ActionPack out of box (ex. for form_for)
  • +
  • +New scope API (commit) - Scopes must always use callables.
  • +
  • +Schema cache dump (commit) - To improve Rails boot time, instead of loading the schema directly from the database, load the schema from a dump file.
  • +
  • +Support for specifying transaction isolation level (commit) - Choose whether repeatable reads or improved performance (less locking) is more important.
  • +
  • +Dalli (commit) - Use Dalli memcache client for the memcache store.
  • +
  • +Notifications start & finish (commit) - Active Support instrumentation reports start and finish notifications to subscribers.
  • +
  • +Thread safe by default (commit) - Rails can run in threaded app servers without additional configuration.
  • +
+

Check that the gems you are using are threadsafe.

+
    +
  • +PATCH verb (commit) - In Rails, PATCH replaces PUT. PATCH is used for partial updates of resources.
  • +
+

3.4 Security

+
    +
  • +match do not catch all (commit) - In the routing DSL, match requires the HTTP verb or verbs to be specified.
  • +
  • +html entities escaped by default (commit) - Strings rendered in erb are escaped unless wrapped with raw or html_safe is called.
  • +
  • +New security headers (commit) - Rails sends the following headers with every HTTP request: X-Frame-Options (prevents clickjacking by forbidding the browser from embedding the page in a frame), X-XSS-Protection (asks the browser to halt script injection) and X-Content-Type-Options (prevents the browser from opening a jpeg as an exe).
  • +
+

4 Extraction of features to gems

In Rails 4.0, several features have been extracted into gems. You can simply add the extracted gems to your Gemfile to bring the functionality back.

+ +

5 Documentation

+
    +
  • Guides are rewritten in GitHub Flavored Markdown.

  • +
  • Guides have a responsive design.

  • +
+

6 Railties

Please refer to the Changelog for detailed changes.

6.1 Notable changes

+
    +
  • New test locations test/models, test/helpers, test/controllers, and test/mailers. Corresponding rake tasks added as well. (Pull Request)

  • +
  • Your app's executables now live in the bin/ directory. Run rake rails:update:bin to get bin/bundle, bin/rails, and bin/rake.

  • +
  • Threadsafe on by default

  • +
  • Ability to use a custom builder by passing --builder (or -b) to +rails new has been removed. Consider using application templates +instead. (Pull Request)

  • +
+

6.2 Deprecations

+
    +
  • config.threadsafe! is deprecated in favor of config.eager_load which provides a more fine grained control on what is eager loaded.

  • +
  • Rails::Plugin has gone. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies.

  • +
+

7 Action Mailer

Please refer to the Changelog for detailed changes.

7.1 Notable changes

7.2 Deprecations

8 Active Model

Please refer to the Changelog for detailed changes.

8.1 Notable changes

+
    +
  • Add ActiveModel::ForbiddenAttributesProtection, a simple module to protect attributes from mass assignment when non-permitted attributes are passed.

  • +
  • Added ActiveModel::Model, a mixin to make Ruby objects work with Action Pack out of box.

  • +
+

8.2 Deprecations

9 Active Support

Please refer to the Changelog for detailed changes.

9.1 Notable changes

+
    +
  • Replace deprecated memcache-client gem with dalli in ActiveSupport::Cache::MemCacheStore.

  • +
  • Optimize ActiveSupport::Cache::Entry to reduce memory and processing overhead.

  • +
  • Inflections can now be defined per locale. singularize and pluralize accept locale as an extra argument.

  • +
  • Object#try will now return nil instead of raise a NoMethodError if the receiving object does not implement the method, but you can still get the old behavior by using the new Object#try!.

  • +
  • String#to_date now raises ArgumentError: invalid date instead of NoMethodError: undefined method 'div' for nil:NilClass +when given an invalid date. It is now the same as Date.parse, and it accepts more invalid dates than 3.x, such as:

  • +
+
+
+  # ActiveSupport 3.x
+  "asdf".to_date # => NoMethodError: undefined method `div' for nil:NilClass
+  "333".to_date # => NoMethodError: undefined method `div' for nil:NilClass
+
+  # ActiveSupport 4
+  "asdf".to_date # => ArgumentError: invalid date
+  "333".to_date # => Fri, 29 Nov 2013
+
+
+
+

9.2 Deprecations

+
    +
  • Deprecate ActiveSupport::TestCase#pending method, use skip from MiniTest instead.

  • +
  • ActiveSupport::Benchmarkable#silence has been deprecated due to its lack of thread safety. It will be removed without replacement in Rails 4.1.

  • +
  • ActiveSupport::JSON::Variable is deprecated. Define your own #as_json and #encode_json methods for custom JSON string literals.

  • +
  • Deprecates the compatibility method Module#local_constant_names, use Module#local_constants instead (which returns symbols).

  • +
  • BufferedLogger is deprecated. Use ActiveSupport::Logger, or the logger from Ruby standard library.

  • +
  • Deprecate assert_present and assert_blank in favor of assert object.blank? and assert object.present?

  • +
+

10 Action Pack

Please refer to the Changelog for detailed changes.

10.1 Notable changes

+
    +
  • Change the stylesheet of exception pages for development mode. Additionally display also the line of code and fragment that raised the exception in all exceptions pages.
  • +
+

10.2 Deprecations

11 Active Record

Please refer to the Changelog for detailed changes.

11.1 Notable changes

+
    +
  • +

    Improve ways to write change migrations, making the old up & down methods no longer necessary.

    +
      +
    • The methods drop_table and remove_column are now reversible, as long as the necessary information is given. +The method remove_column used to accept multiple column names; instead use remove_columns (which is not revertible). +The method change_table is also reversible, as long as its block doesn't call remove, change or change_default +
    • +
    • New method reversible makes it possible to specify code to be run when migrating up or down. +See the Guide on Migration +
    • +
    • New method revert will revert a whole migration or the given block. +If migrating down, the given migration / block is run normally. +See the Guide on Migration +
    • +
    +
  • +
  • Adds PostgreSQL array type support. Any datatype can be used to create an array column, with full migration and schema dumper support.

  • +
  • Add Relation#load to explicitly load the record and return self.

  • +
  • Model.all now returns an ActiveRecord::Relation, rather than an array of records. Use Relation#to_a if you really want an array. In some specific cases, this may cause breakage when upgrading.

  • +
  • Added ActiveRecord::Migration.check_pending! that raises an error if migrations are pending.

  • +
  • +

    Added custom coders support for ActiveRecord::Store. Now you can set your custom coder like this:

    +
    +
    +store :settings, accessors: [ :color, :homepage ], coder: JSON
    +
    +
    +
    +
  • +
  • mysql and mysql2 connections will set SQL_MODE=STRICT_ALL_TABLES by default to avoid silent data loss. This can be disabled by specifying strict: false in your database.yml.

  • +
  • Remove IdentityMap.

  • +
  • Remove automatic execution of EXPLAIN queries. The option active_record.auto_explain_threshold_in_seconds is no longer used and should be removed.

  • +
  • Adds ActiveRecord::NullRelation and ActiveRecord::Relation#none implementing the null object pattern for the Relation class.

  • +
  • Added create_join_table migration helper to create HABTM join tables.

  • +
  • Allows PostgreSQL hstore records to be created.

  • +
+

11.2 Deprecations

+
    +
  • Deprecated the old-style hash based finder API. This means that methods which previously accepted "finder options" no longer do.

  • +
  • +

    All dynamic methods except for find_by_... and find_by_...! are deprecated. Here's +how you can rewrite the code:

    +
      +
    • +find_all_by_... can be rewritten using where(...).
    • +
    • +find_last_by_... can be rewritten using where(...).last.
    • +
    • +scoped_by_... can be rewritten using where(...).
    • +
    • +find_or_initialize_by_... can be rewritten using find_or_initialize_by(...).
    • +
    • +find_or_create_by_... can be rewritten using find_or_create_by(...).
    • +
    • +find_or_create_by_...! can be rewritten using find_or_create_by!(...).
    • +
    +
  • +
+

12 Credits

See the full list of contributors to Rails for the many people who spent many hours making Rails, the stable and robust framework it is. Kudos to all of them.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/4_1_release_notes.html b/4_1_release_notes.html new file mode 100644 index 0000000..c3324b9 --- /dev/null +++ b/4_1_release_notes.html @@ -0,0 +1,845 @@ + + + + + + + +Ruby on Rails 4.1 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 4.1 Release Notes

Highlights in Rails 4.1:

+
    +
  • Spring application preloader
  • +
  • config/secrets.yml
  • +
  • Action Pack variants
  • +
  • Action Mailer previews
  • +
+

These release notes cover only the major changes. To learn about various bug +fixes and changes, please refer to the change logs or check out the list of +commits in the main Rails +repository on GitHub.

+ + + +
+
+ +
+
+
+

1 Upgrading to Rails 4.1

If you're upgrading an existing application, it's a great idea to have good test +coverage before going in. You should also first upgrade to Rails 4.0 in case you +haven't and make sure your application still runs as expected before attempting +an update to Rails 4.1. A list of things to watch out for when upgrading is +available in the +Upgrading Ruby on Rails +guide.

2 Major Features

2.1 Spring Application Preloader

Spring is a Rails application preloader. It speeds up development by keeping +your application running in the background so you don't need to boot it every +time you run a test, rake task or migration.

New Rails 4.1 applications will ship with "springified" binstubs. This means +that bin/rails and bin/rake will automatically take advantage of preloaded +spring environments.

Running rake tasks:

+
+bin/rake test:models
+
+
+
+

Running a Rails command:

+
+bin/rails console
+
+
+
+

Spring introspection:

+
+$ bin/spring status
+Spring is running:
+
+ 1182 spring server | my_app | started 29 mins ago
+ 3656 spring app    | my_app | started 23 secs ago | test mode
+ 3746 spring app    | my_app | started 10 secs ago | development mode
+
+
+
+

Have a look at the +Spring README to +see all available features.

See the Upgrading Ruby on Rails +guide on how to migrate existing applications to use this feature.

2.2 config/secrets.yml +

Rails 4.1 generates a new secrets.yml file in the config folder. By default, +this file contains the application's secret_key_base, but it could also be +used to store other secrets such as access keys for external APIs.

The secrets added to this file are accessible via Rails.application.secrets. +For example, with the following config/secrets.yml:

+
+development:
+  secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
+  some_api_key: SOMEKEY
+
+
+
+

Rails.application.secrets.some_api_key returns SOMEKEY in the development +environment.

See the Upgrading Ruby on Rails +guide on how to migrate existing applications to use this feature.

2.3 Action Pack Variants

We often want to render different HTML/JSON/XML templates for phones, +tablets, and desktop browsers. Variants make it easy.

The request variant is a specialization of the request format, like :tablet, +:phone, or :desktop.

You can set the variant in a before_action:

+
+request.variant = :tablet if request.user_agent =~ /iPad/
+
+
+
+

Respond to variants in the action just like you respond to formats:

+
+respond_to do |format|
+  format.html do |html|
+    html.tablet # renders app/views/projects/show.html+tablet.erb
+    html.phone { extra_setup; render ... }
+  end
+end
+
+
+
+

Provide separate templates for each format and variant:

+
+app/views/projects/show.html.erb
+app/views/projects/show.html+tablet.erb
+app/views/projects/show.html+phone.erb
+
+
+
+

You can also simplify the variants definition using the inline syntax:

+
+respond_to do |format|
+  format.js         { render "trash" }
+  format.html.phone { redirect_to progress_path }
+  format.html.none  { render "trash" }
+end
+
+
+
+

2.4 Action Mailer Previews

Action Mailer previews provide a way to see how emails look by visiting +a special URL that renders them.

You implement a preview class whose methods return the mail object you'd like +to check:

+
+class NotifierPreview < ActionMailer::Preview
+  def welcome
+    Notifier.welcome(User.first)
+  end
+end
+
+
+
+

The preview is available in http://localhost:3000/rails/mailers/notifier/welcome, +and a list of them in http://localhost:3000/rails/mailers.

By default, these preview classes live in test/mailers/previews. +This can be configured using the preview_path option.

See its +documentation +for a detailed write up.

2.5 Active Record enums

Declare an enum attribute where the values map to integers in the database, but +can be queried by name.

+
+class Conversation < ActiveRecord::Base
+  enum status: [ :active, :archived ]
+end
+
+conversation.archived!
+conversation.active? # => false
+conversation.status  # => "archived"
+
+Conversation.archived # => Relation for all archived Conversations
+
+Conversation.statuses # => { "active" => 0, "archived" => 1 }
+
+
+
+

See its +documentation +for a detailed write up.

2.6 Message Verifiers

Message verifiers can be used to generate and verify signed messages. This can +be useful to safely transport sensitive data like remember-me tokens and +friends.

The method Rails.application.message_verifier returns a new message verifier +that signs messages with a key derived from secret_key_base and the given +message verifier name:

+
+signed_token = Rails.application.message_verifier(:remember_me).generate(token)
+Rails.application.message_verifier(:remember_me).verify(signed_token) # => token
+
+Rails.application.message_verifier(:remember_me).verify(tampered_token)
+# raises ActiveSupport::MessageVerifier::InvalidSignature
+
+
+
+

2.7 Module#concerning

A natural, low-ceremony way to separate responsibilities within a class:

+
+class Todo < ActiveRecord::Base
+  concerning :EventTracking do
+    included do
+      has_many :events
+    end
+
+    def latest_event
+      ...
+    end
+
+    private
+      def some_internal_method
+        ...
+      end
+  end
+end
+
+
+
+

This example is equivalent to defining a EventTracking module inline, +extending it with ActiveSupport::Concern, then mixing it in to the +Todo class.

See its +documentation +for a detailed write up and the intended use cases.

2.8 CSRF protection from remote <script> tags

Cross-site request forgery (CSRF) protection now covers GET requests with +JavaScript responses, too. That prevents a third-party site from referencing +your JavaScript URL and attempting to run it to extract sensitive data.

This means any of your tests that hit .js URLs will now fail CSRF protection +unless they use xhr. Upgrade your tests to be explicit about expecting +XmlHttpRequests. Instead of post :create, format: :js, switch to the explicit +xhr :post, :create, format: :js.

3 Railties

Please refer to the +Changelog +for detailed changes.

3.1 Removals

+
    +
  • Removed update:application_controller rake task.

  • +
  • Removed deprecated Rails.application.railties.engines.

  • +
  • Removed deprecated threadsafe! from Rails Config.

  • +
  • Removed deprecated ActiveRecord::Generators::ActiveModel#update_attributes in +favor of ActiveRecord::Generators::ActiveModel#update.

  • +
  • Removed deprecated config.whiny_nils option.

  • +
  • Removed deprecated rake tasks for running tests: rake test:uncommitted and +rake test:recent.

  • +
+

3.2 Notable changes

+
    +
  • The Spring application +preloader is now installed +by default for new applications. It uses the development group of +the Gemfile, so will not be installed in +production. (Pull Request)

  • +
  • BACKTRACE environment variable to show unfiltered backtraces for test +failures. (Commit)

  • +
  • Exposed MiddlewareStack#unshift to environment +configuration. (Pull Request)

  • +
  • Added Application#message_verifier method to return a message +verifier. (Pull Request)

  • +
  • The test_help.rb file which is required by the default generated test +helper will automatically keep your test database up-to-date with +db/schema.rb (or db/structure.sql). It raises an error if +reloading the schema does not resolve all pending migrations. Opt out +with config.active_record.maintain_test_schema = false. (Pull +Request)

  • +
  • Introduce Rails.gem_version as a convenience method to return +Gem::Version.new(Rails.version), suggesting a more reliable way to perform +version comparison. (Pull Request)

  • +
+

4 Action Pack

Please refer to the +Changelog +for detailed changes.

4.1 Removals

+
    +
  • Removed deprecated Rails application fallback for integration testing, set +ActionDispatch.test_app instead.

  • +
  • Removed deprecated page_cache_extension config.

  • +
  • Removed deprecated ActionController::RecordIdentifier, use +ActionView::RecordIdentifier instead.

  • +
  • Removed deprecated constants from Action Controller:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RemovedSuccessor
ActionController::AbstractRequestActionDispatch::Request
ActionController::RequestActionDispatch::Request
ActionController::AbstractResponseActionDispatch::Response
ActionController::ResponseActionDispatch::Response
ActionController::RoutingActionDispatch::Routing
ActionController::IntegrationActionDispatch::Integration
ActionController::IntegrationTestActionDispatch::IntegrationTest
+

4.2 Notable changes

+
    +
  • protect_from_forgery also prevents cross-origin <script> tags. +Update your tests to use xhr :get, :foo, format: :js instead of +get :foo, format: :js. +(Pull Request)

  • +
  • #url_for takes a hash with options inside an +array. (Pull Request)

  • +
  • Added session#fetch method fetch behaves similarly to +Hash#fetch, +with the exception that the returned value is always saved into the +session. (Pull Request)

  • +
  • Separated Action View completely from Action +Pack. (Pull Request)

  • +
  • Log which keys were affected by deep +munge. (Pull Request)

  • +
  • New config option config.action_dispatch.perform_deep_munge to opt out of +params "deep munging" that was used to address security vulnerability +CVE-2013-0155. (Pull Request)

  • +
  • New config option config.action_dispatch.cookies_serializer for specifying a +serializer for the signed and encrypted cookie jars. (Pull Requests +1, +2 / +More Details)

  • +
  • Added render :plain, render :html and render +:body. (Pull Request / +More Details)

  • +
+

5 Action Mailer

Please refer to the +Changelog +for detailed changes.

5.1 Notable changes

+
    +
  • Added mailer previews feature based on 37 Signals mail_view +gem. (Commit)

  • +
  • Instrument the generation of Action Mailer messages. The time it takes to +generate a message is written to the log. (Pull Request)

  • +
+

6 Active Record

Please refer to the +Changelog +for detailed changes.

6.1 Removals

+
    +
  • Removed deprecated nil-passing to the following SchemaCache methods: +primary_keys, tables, columns and columns_hash.

  • +
  • Removed deprecated block filter from ActiveRecord::Migrator#migrate.

  • +
  • Removed deprecated String constructor from ActiveRecord::Migrator.

  • +
  • Removed deprecated scope use without passing a callable object.

  • +
  • Removed deprecated transaction_joinable= in favor of begin_transaction +with a :joinable option.

  • +
  • Removed deprecated decrement_open_transactions.

  • +
  • Removed deprecated increment_open_transactions.

  • +
  • Removed deprecated PostgreSQLAdapter#outside_transaction? +method. You can use #transaction_open? instead.

  • +
  • Removed deprecated ActiveRecord::Fixtures.find_table_name in favor of +ActiveRecord::Fixtures.default_fixture_model_name.

  • +
  • Removed deprecated columns_for_remove from SchemaStatements.

  • +
  • Removed deprecated SchemaStatements#distinct.

  • +
  • Moved deprecated ActiveRecord::TestCase into the Rails test +suite. The class is no longer public and is only used for internal +Rails tests.

  • +
  • Removed support for deprecated option :restrict for :dependent +in associations.

  • +
  • Removed support for deprecated :delete_sql, :insert_sql, :finder_sql +and :counter_sql options in associations.

  • +
  • Removed deprecated method type_cast_code from Column.

  • +
  • Removed deprecated ActiveRecord::Base#connection method. +Make sure to access it via the class.

  • +
  • Removed deprecation warning for auto_explain_threshold_in_seconds.

  • +
  • Removed deprecated :distinct option from Relation#count.

  • +
  • Removed deprecated methods partial_updates, partial_updates? and +partial_updates=.

  • +
  • Removed deprecated method scoped.

  • +
  • Removed deprecated method default_scopes?.

  • +
  • Remove implicit join references that were deprecated in 4.0.

  • +
  • Removed activerecord-deprecated_finders as a dependency. +Please see the gem README +for more info.

  • +
  • Removed usage of implicit_readonly. Please use readonly method +explicitly to mark records as +readonly. (Pull Request)

  • +
+

6.2 Deprecations

+
    +
  • Deprecated quoted_locking_column method, which isn't used anywhere.

  • +
  • Deprecated ConnectionAdapters::SchemaStatements#distinct, +as it is no longer used by internals. (Pull Request)

  • +
  • Deprecated rake db:test:* tasks as the test database is now +automatically maintained. See railties release notes. (Pull +Request)

  • +
  • Deprecate unused ActiveRecord::Base.symbolized_base_class +and ActiveRecord::Base.symbolized_sti_name without +replacement. Commit

  • +
+

6.3 Notable changes

+
    +
  • Default scopes are no longer overridden by chained conditions.
  • +
+

Before this change when you defined a default_scope in a model + it was overridden by chained conditions in the same field. Now it + is merged like any other scope. More Details.

+
    +
  • Added ActiveRecord::Base.to_param for convenient "pretty" URLs derived from +a model's attribute or +method. (Pull Request)

  • +
  • Added ActiveRecord::Base.no_touching, which allows ignoring touch on +models. (Pull Request)

  • +
  • Unify boolean type casting for MysqlAdapter and Mysql2Adapter. +type_cast will return 1 for true and 0 for false. (Pull Request)

  • +
  • .unscope now removes conditions specified in +default_scope. (Commit)

  • +
  • Added ActiveRecord::QueryMethods#rewhere which will overwrite an existing, +named where condition. (Commit)

  • +
  • Extended ActiveRecord::Base#cache_key to take an optional list of timestamp +attributes of which the highest will be used. (Commit)

  • +
  • Added ActiveRecord::Base#enum for declaring enum attributes where the values +map to integers in the database, but can be queried by +name. (Commit)

  • +
  • Type cast json values on write, so that the value is consistent with reading +from the database. (Pull Request)

  • +
  • Type cast hstore values on write, so that the value is consistent +with reading from the database. (Commit)

  • +
  • Make next_migration_number accessible for third party +generators. (Pull Request)

  • +
  • Calling update_attributes will now throw an ArgumentError whenever it +gets a nil argument. More specifically, it will throw an error if the +argument that it gets passed does not respond to to +stringify_keys. (Pull Request)

  • +
  • CollectionAssociation#first/#last (e.g. has_many) use a LIMITed +query to fetch results rather than loading the entire +collection. (Pull Request)

  • +
  • inspect on Active Record model classes does not initiate a new +connection. This means that calling inspect, when the database is missing, +will no longer raise an exception. (Pull Request)

  • +
  • Removed column restrictions for count, let the database raise if the SQL is +invalid. (Pull Request)

  • +
  • Rails now automatically detects inverse associations. If you do not set the +:inverse_of option on the association, then Active Record will guess the +inverse association based on heuristics. (Pull Request)

  • +
  • Handle aliased attributes in ActiveRecord::Relation. When using symbol keys, +ActiveRecord will now translate aliased attribute names to the actual column +name used in the database. (Pull Request)

  • +
  • The ERB in fixture files is no longer evaluated in the context of the main +object. Helper methods used by multiple fixtures should be defined on modules +included in ActiveRecord::FixtureSet.context_class. (Pull Request)

  • +
  • Don't create or drop the test database if RAILS_ENV is specified +explicitly. (Pull Request)

  • +
  • Relation no longer has mutator methods like #map! and #delete_if. Convert +to an Array by calling #to_a before using these methods. (Pull Request)

  • +
  • find_in_batches, find_each, Result#each and Enumerable#index_by now +return an Enumerator that can calculate its +size. (Pull Request)

  • +
  • scope, enum and Associations now raise on "dangerous" name +conflicts. (Pull Request, +Pull Request)

  • +
  • second through fifth methods act like the first +finder. (Pull Request)

  • +
  • Make touch fire the after_commit and after_rollback +callbacks. (Pull Request)

  • +
  • Enable partial indexes for sqlite >= 3.8.0. +(Pull Request)

  • +
  • Make change_column_null +revertible. (Commit)

  • +
  • Added a flag to disable schema dump after migration. This is set to false +by default in the production environment for new applications. +(Pull Request)

  • +
+

7 Active Model

Please refer to the +Changelog +for detailed changes.

7.1 Deprecations

+
    +
  • Deprecate Validator#setup. This should be done manually now in the +validator's constructor. (Commit)
  • +
+

7.2 Notable changes

+
    +
  • Added new API methods reset_changes and changes_applied to +ActiveModel::Dirty that control changes state.

  • +
  • Ability to specify multiple contexts when defining a +validation. (Pull Request)

  • +
  • attribute_changed? now accepts a hash to check if the attribute was changed +:from and/or :to a given +value. (Pull Request)

  • +
+

8 Active Support

Please refer to the +Changelog +for detailed changes.

8.1 Removals

+
    +
  • Removed MultiJSON dependency. As a result, ActiveSupport::JSON.decode +no longer accepts an options hash for MultiJSON. (Pull Request / More Details)

  • +
  • Removed support for the encode_json hook used for encoding custom objects into +JSON. This feature has been extracted into the activesupport-json_encoder +gem. +(Related Pull Request / +More Details)

  • +
  • Removed deprecated ActiveSupport::JSON::Variable with no replacement.

  • +
  • Removed deprecated String#encoding_aware? core extensions (core_ext/string/encoding).

  • +
  • Removed deprecated Module#local_constant_names in favor of Module#local_constants.

  • +
  • Removed deprecated DateTime.local_offset in favor of DateTime.civil_from_format.

  • +
  • Removed deprecated Logger core extensions (core_ext/logger.rb).

  • +
  • Removed deprecated Time#time_with_datetime_fallback, Time#utc_time and +Time#local_time in favor of Time#utc and Time#local.

  • +
  • Removed deprecated Hash#diff with no replacement.

  • +
  • Removed deprecated Date#to_time_in_current_zone in favor of Date#in_time_zone.

  • +
  • Removed deprecated Proc#bind with no replacement.

  • +
  • Removed deprecated Array#uniq_by and Array#uniq_by!, use native +Array#uniq and Array#uniq! instead.

  • +
  • Removed deprecated ActiveSupport::BasicObject, use +ActiveSupport::ProxyObject instead.

  • +
  • Removed deprecated BufferedLogger, use ActiveSupport::Logger instead.

  • +
  • Removed deprecated assert_present and assert_blank methods, use assert +object.blank? and assert object.present? instead.

  • +
  • Remove deprecated #filter method for filter objects, use the corresponding +method instead (e.g. #before for a before filter).

  • +
  • Removed 'cow' => 'kine' irregular inflection from default +inflections. (Commit)

  • +
+

8.2 Deprecations

+
    +
  • Deprecated Numeric#{ago,until,since,from_now}, the user is expected to +explicitly convert the value into an AS::Duration, i.e. 5.ago => 5.seconds.ago +(Pull Request)

  • +
  • Deprecated the require path active_support/core_ext/object/to_json. Require +active_support/core_ext/object/json instead. (Pull Request)

  • +
  • Deprecated ActiveSupport::JSON::Encoding::CircularReferenceError. This feature +has been extracted into the activesupport-json_encoder +gem. +(Pull Request / +More Details)

  • +
  • Deprecated ActiveSupport.encode_big_decimal_as_string option. This feature has +been extracted into the activesupport-json_encoder +gem. +(Pull Request / +More Details)

  • +
  • Deprecate custom BigDecimal +serialization. (Pull Request)

  • +
+

8.3 Notable changes

+
    +
  • ActiveSupport's JSON encoder has been rewritten to take advantage of the +JSON gem rather than doing custom encoding in pure-Ruby. +(Pull Request / +More Details)

  • +
  • Improved compatibility with the JSON gem. +(Pull Request / +More Details)

  • +
  • Added ActiveSupport::Testing::TimeHelpers#travel and #travel_to. These +methods change current time to the given time or duration by stubbing +Time.now and Date.today.

  • +
  • Added ActiveSupport::Testing::TimeHelpers#travel_back. This method returns +the current time to the original state, by removing the stubs added by travel +and travel_to. (Pull Request)

  • +
  • Added Numeric#in_milliseconds, like 1.hour.in_milliseconds, so we can feed +them to JavaScript functions like +getTime(). (Commit)

  • +
  • Added Date#middle_of_day, DateTime#middle_of_day and Time#middle_of_day +methods. Also added midday, noon, at_midday, at_noon and +at_middle_of_day as +aliases. (Pull Request)

  • +
  • Added Date#all_week/month/quarter/year for generating date +ranges. (Pull Request)

  • +
  • Added Time.zone.yesterday and +Time.zone.tomorrow. (Pull Request)

  • +
  • Added String#remove(pattern) as a short-hand for the common pattern of +String#gsub(pattern,''). (Commit)

  • +
  • Added Hash#compact and Hash#compact! for removing items with nil value +from hash. (Pull Request)

  • +
  • blank? and present? commit to return +singletons. (Commit)

  • +
  • Default the new I18n.enforce_available_locales config to true, meaning +I18n will make sure that all locales passed to it must be declared in the +available_locales +list. (Pull Request)

  • +
  • Introduce Module#concerning: a natural, low-ceremony way to separate +responsibilities within a +class. (Commit)

  • +
  • Added Object#presence_in to simplify value whitelisting. +(Commit)

  • +
+

9 Credits

See the +full list of contributors to Rails for +the many people who spent many hours making Rails, the stable and robust +framework it is. Kudos to all of them.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/4_2_release_notes.html b/4_2_release_notes.html new file mode 100644 index 0000000..38d7817 --- /dev/null +++ b/4_2_release_notes.html @@ -0,0 +1,1029 @@ + + + + + + + +Ruby on Rails 4.2 Release Notes — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Ruby on Rails 4.2 Release Notes

Highlights in Rails 4.2:

+
    +
  • Active Job
  • +
  • Asynchronous mails
  • +
  • Adequate Record
  • +
  • Web Console
  • +
  • Foreign key support
  • +
+

These release notes cover only the major changes. To learn about other +features, bug fixes, and changes, please refer to the changelogs or check out +the list of commits in +the main Rails repository on GitHub.

+ + + +
+
+ +
+
+
+

1 Upgrading to Rails 4.2

If you're upgrading an existing application, it's a great idea to have good test +coverage before going in. You should also first upgrade to Rails 4.1 in case you +haven't and make sure your application still runs as expected before attempting +to upgrade to Rails 4.2. A list of things to watch out for when upgrading is +available in the guide Upgrading Ruby on +Rails.

2 Major Features

2.1 Active Job

Active Job is a new framework in Rails 4.2. It is a common interface on top of +queuing systems like Resque, Delayed +Job, +Sidekiq, and more.

Jobs written with the Active Job API run on any of the supported queues thanks +to their respective adapters. Active Job comes pre-configured with an inline +runner that executes jobs right away.

Jobs often need to take Active Record objects as arguments. Active Job passes +object references as URIs (uniform resource identifiers) instead of marshaling +the object itself. The new Global ID +library builds URIs and looks up the objects they reference. Passing Active +Record objects as job arguments just works by using Global ID internally.

For example, if trashable is an Active Record object, then this job runs +just fine with no serialization involved:

+
+class TrashableCleanupJob < ActiveJob::Base
+  def perform(trashable, depth)
+    trashable.cleanup(depth)
+  end
+end
+
+
+
+

See the Active Job Basics guide for more +information.

2.2 Asynchronous Mails

Building on top of Active Job, Action Mailer now comes with a deliver_later +method that sends emails via the queue, so it doesn't block the controller or +model if the queue is asynchronous (the default inline queue blocks).

Sending emails right away is still possible with deliver_now.

2.3 Adequate Record

Adequate Record is a set of performance improvements in Active Record that makes +common find and find_by calls and some association queries up to 2x faster.

It works by caching common SQL queries as prepared statements and reusing them +on similar calls, skipping most of the query-generation work on subsequent +calls. For more details, please refer to Aaron Patterson's blog +post.

Active Record will automatically take advantage of this feature on +supported operations without any user involvement or code changes. Here are +some examples of supported operations:

+
+Post.find(1)  # First call generates and cache the prepared statement
+Post.find(2)  # Subsequent calls reuse the cached prepared statement
+
+Post.find_by_title('first post')
+Post.find_by_title('second post')
+
+Post.find_by(title: 'first post')
+Post.find_by(title: 'second post')
+
+post.comments
+post.comments(true)
+
+
+
+

It's important to highlight that, as the examples above suggest, the prepared +statements do not cache the values passed in the method calls; rather, they +have placeholders for them.

Caching is not used in the following scenarios:

+
    +
  • The model has a default scope
  • +
  • The model uses single table inheritance
  • +
  • +find with a list of ids, e.g.:
  • +
+
+
+  # not cached
+  Post.find(1, 2, 3)
+  Post.find([1,2])
+
+
+
+ +
    +
  • +find_by with SQL fragments:
  • +
+
+
+  Post.find_by('published_at < ?', 2.weeks.ago)
+
+
+
+

2.4 Web Console

New applications generated with Rails 4.2 now come with the Web +Console gem by default. Web Console adds +an interactive Ruby console on every error page and provides a console view +and controller helpers.

The interactive console on error pages lets you execute code in the context of +the place where the exception originated. The console helper, if called +anywhere in a view or controller, launches an interactive console with the final +context, once rendering has completed.

2.5 Foreign Key Support

The migration DSL now supports adding and removing foreign keys. They are dumped +to schema.rb as well. At this time, only the mysql, mysql2 and postgresql +adapters support foreign keys.

+
+# add a foreign key to `articles.author_id` referencing `authors.id`
+add_foreign_key :articles, :authors
+
+# add a foreign key to `articles.author_id` referencing `users.lng_id`
+add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"
+
+# remove the foreign key on `accounts.branch_id`
+remove_foreign_key :accounts, :branches
+
+# remove the foreign key on `accounts.owner_id`
+remove_foreign_key :accounts, column: :owner_id
+
+
+
+

See the API documentation on +add_foreign_key +and +remove_foreign_key +for a full description.

3 Incompatibilities

Previously deprecated functionality has been removed. Please refer to the +individual components for new deprecations in this release.

The following changes may require immediate action upon upgrade.

3.1 render with a String Argument

Previously, calling render "foo/bar" in a controller action was equivalent to +render file: "foo/bar". In Rails 4.2, this has been changed to mean +render template: "foo/bar" instead. If you need to render a file, please +change your code to use the explicit form (render file: "foo/bar") instead.

3.2 respond_with / Class-Level respond_to +

respond_with and the corresponding class-level respond_to have been moved +to the responders gem. Add +gem 'responders', '~> 2.0' to your Gemfile to use it:

+
+# app/controllers/users_controller.rb
+
+class UsersController < ApplicationController
+  respond_to :html, :json
+
+  def show
+    @user = User.find(params[:id])
+    respond_with @user
+  end
+end
+
+
+
+

Instance-level respond_to is unaffected:

+
+# app/controllers/users_controller.rb
+
+class UsersController < ApplicationController
+  def show
+    @user = User.find(params[:id])
+    respond_to do |format|
+      format.html
+      format.json { render json: @user }
+    end
+  end
+end
+
+
+
+

3.3 Default Host for rails server +

Due to a change in Rack, +rails server now listens on localhost instead of 0.0.0.0 by default. This +should have minimal impact on the standard development workflow as both +http://127.0.0.1:3000 and http://localhost:3000 will continue to work as before +on your own machine.

However, with this change you will no longer be able to access the Rails +server from a different machine, for example if your development environment +is in a virtual machine and you would like to access it from the host machine. +In such cases, please start the server with rails server -b 0.0.0.0 to +restore the old behavior.

If you do this, be sure to configure your firewall properly such that only +trusted machines on your network can access your development server.

3.4 Changed status option symbols for render +

Due to a change in Rack, the symbols that the render method accepts for the :status option have changed:

+
    +
  • 306: :reserved has been removed.
  • +
  • 413: :request_entity_too_large has been renamed to :payload_too_large.
  • +
  • 414: :request_uri_too_long has been renamed to :uri_too_long.
  • +
  • 416: :requested_range_not_satisfiable has been renamed to :range_not_satisfiable.
  • +
+

Keep in mind that if calling render with an unknown symbol, the response status will default to 500.

3.5 HTML Sanitizer

The HTML sanitizer has been replaced with a new, more robust, implementation +built upon Loofah and +Nokogiri. The new sanitizer is +more secure and its sanitization is more powerful and flexible.

Due to the new algorithm, the sanitized output may be different for certain +pathological inputs.

If you have a particular need for the exact output of the old sanitizer, you +can add the rails-deprecated_sanitizer +gem to the Gemfile, to have the old behavior. The gem does not issue +deprecation warnings because it is opt-in.

rails-deprecated_sanitizer will be supported for Rails 4.2 only; it will not +be maintained for Rails 5.0.

See this blog post +for more details on the changes in the new sanitizer.

3.6 assert_select +

assert_select is now based on Nokogiri. +As a result, some previously-valid selectors are now unsupported. If your +application is using any of these spellings, you will need to update them:

+
    +
  • +

    Values in attribute selectors may need to be quoted if they contain +non-alphanumeric characters.

    +
    +
    +# before
    +a[href=/]
    +a[href$=/]
    +
    +# now
    +a[href="http://github.com/"]
    +a[href$="/"]
    +
    +
    +
    +
  • +
  • +

    DOMs built from HTML source containing invalid HTML with improperly +nested elements may differ.

    +

    For example:

    +
    +
    +# content: <div><i><p></i></div>
    +
    +# before:
    +assert_select('div > i')  # => true
    +assert_select('div > p')  # => false
    +assert_select('i > p')    # => true
    +
    +# now:
    +assert_select('div > i')  # => true
    +assert_select('div > p')  # => true
    +assert_select('i > p')    # => false
    +
    +
    +
    +
  • +
  • +

    If the data selected contains entities, the value selected for comparison +used to be raw (e.g. AT&amp;T), and now is evaluated +(e.g. AT&T).

    +
    +
    +# content: <p>AT&amp;T</p>
    +
    +# before:
    +assert_select('p', 'AT&amp;T')  # => true
    +assert_select('p', 'AT&T')      # => false
    +
    +# now:
    +assert_select('p', 'AT&T')      # => true
    +assert_select('p', 'AT&amp;T')  # => false
    +
    +
    +
    +
  • +
+

Furthermore substitutions have changed syntax.

Now you have to use a :match CSS-like selector:

+
+assert_select ":match('id', ?)", 'comment_1'
+
+
+
+

Additionally Regexp substitutions look different when the assertion fails. +Notice how /hello/ here:

+
+assert_select(":match('id', ?)", /hello/)
+
+
+
+

becomes "(?-mix:hello)":

+
+Expected at least 1 element matching "div:match('id', "(?-mix:hello)")", found 0..
+Expected 0 to be >= 1.
+
+
+
+

See the Rails Dom Testing documentation for more on assert_select.

4 Railties

Please refer to the Changelog for detailed changes.

4.1 Removals

+
    +
  • The --skip-action-view option has been removed from the +app generator. (Pull Request)

  • +
  • The rails application command has been removed without replacement. +(Pull Request)

  • +
+

4.2 Deprecations

+
    +
  • Deprecated missing config.log_level for production environments. +(Pull Request)

  • +
  • Deprecated rake test:all in favor of rake test as it now run all tests +in the test folder. +(Pull Request)

  • +
  • Deprecated rake test:all:db in favor of rake test:db. +(Pull Request)

  • +
  • Deprecated Rails::Rack::LogTailer without replacement. +(Commit)

  • +
+

4.3 Notable changes

+
    +
  • Introduced web-console in the default application Gemfile. +(Pull Request)

  • +
  • Added a required option to the model generator for associations. +(Pull Request)

  • +
  • +

    Introduced the x namespace for defining custom configuration options:

    +
    +
    +# config/environments/production.rb
    +config.x.payment_processing.schedule = :daily
    +config.x.payment_processing.retries  = 3
    +config.x.super_debugger              = true
    +
    +
    +
    +

    These options are then available through the configuration object:

    +
    +
    +Rails.configuration.x.payment_processing.schedule # => :daily
    +Rails.configuration.x.payment_processing.retries  # => 3
    +Rails.configuration.x.super_debugger              # => true
    +
    +
    +
    +

    (Commit)

    +
  • +
  • +

    Introduced Rails::Application.config_for to load a configuration for the +current environment.

    +
    +
    +# config/exception_notification.yml:
    +production:
    +  url: http://127.0.0.1:8080
    +  namespace: my_app_production
    +development:
    +  url: http://localhost:3001
    +  namespace: my_app_development
    +
    +# config/environments/production.rb
    +Rails.application.configure do
    +  config.middleware.use ExceptionNotifier, config_for(:exception_notification)
    +end
    +
    +
    +
    +

    (Pull Request)

    +
  • +
  • Introduced a --skip-turbolinks option in the app generator to not generate +turbolinks integration. +(Commit)

  • +
  • Introduced a bin/setup script as a convention for automated setup code when +bootstrapping an application. +(Pull Request)

  • +
  • Changed the default value for config.assets.digest to true in development. +(Pull Request)

  • +
  • Introduced an API to register new extensions for rake notes. +(Pull Request)

  • +
  • Introduced an after_bundle callback for use in Rails templates. +(Pull Request)

  • +
  • Introduced Rails.gem_version as a convenience method to return +Gem::Version.new(Rails.version). +(Pull Request)

  • +
+

5 Action Pack

Please refer to the Changelog for detailed changes.

5.1 Removals

+
    +
  • respond_with and the class-level respond_to have been removed from Rails and +moved to the responders gem (version 2.0). Add gem 'responders', '~> 2.0' +to your Gemfile to continue using these features. +(Pull Request, + More Details)

  • +
  • Removed deprecated AbstractController::Helpers::ClassMethods::MissingHelperError +in favor of AbstractController::Helpers::MissingHelperError. +(Commit)

  • +
+

5.2 Deprecations

+
    +
  • Deprecated the only_path option on *_path helpers. +(Commit)

  • +
  • Deprecated assert_tag, assert_no_tag, find_tag and find_all_tag in +favor of assert_select. +(Commit)

  • +
  • +

    Deprecated support for setting the :to option of a router to a symbol or a +string that does not contain a "#" character:

    +
    +
    +get '/posts', to: MyRackApp    => (No change necessary)
    +get '/posts', to: 'post#index' => (No change necessary)
    +get '/posts', to: 'posts'      => get '/posts', controller: :posts
    +get '/posts', to: :index       => get '/posts', action: :index
    +
    +
    +
    +

    (Commit)

    +
  • +
  • +

    Deprecated support for string keys in URL helpers:

    +
    +
    +# bad
    +root_path('controller' => 'posts', 'action' => 'index')
    +
    +# good
    +root_path(controller: 'posts', action: 'index')
    +
    +
    +
    +

    (Pull Request)

    +
  • +
+

5.3 Notable changes

+
    +
  • +

    The *_filter family of methods have been removed from the documentation. Their +usage is discouraged in favor of the *_action family of methods:

    +
    +
    +after_filter          => after_action
    +append_after_filter   => append_after_action
    +append_around_filter  => append_around_action
    +append_before_filter  => append_before_action
    +around_filter         => around_action
    +before_filter         => before_action
    +prepend_after_filter  => prepend_after_action
    +prepend_around_filter => prepend_around_action
    +prepend_before_filter => prepend_before_action
    +skip_after_filter     => skip_after_action
    +skip_around_filter    => skip_around_action
    +skip_before_filter    => skip_before_action
    +skip_filter           => skip_action_callback
    +
    +
    +
    +

    If your application currently depends on these methods, you should use the +replacement *_action methods instead. These methods will be deprecated in +the future and will eventually be removed from Rails.

    +

    (Commit 1, +2)

    +
  • +
  • render nothing: true or rendering a nil body no longer add a single +space padding to the response body. +(Pull Request)

  • +
  • Rails now automatically includes the template's digest in ETags. +(Pull Request)

  • +
  • Segments that are passed into URL helpers are now automatically escaped. +(Commit)

  • +
  • Introduced the always_permitted_parameters option to configure which +parameters are permitted globally. The default value of this configuration +is ['controller', 'action']. +(Pull Request)

  • +
  • Added the HTTP method MKCALENDAR from RFC 4791. +(Pull Request)

  • +
  • *_fragment.action_controller notifications now include the controller +and action name in the payload. +(Pull Request)

  • +
  • Improved the Routing Error page with fuzzy matching for route search. +(Pull Request)

  • +
  • Added an option to disable logging of CSRF failures. +(Pull Request)

  • +
  • When the Rails server is set to serve static assets, gzip assets will now be +served if the client supports it and a pre-generated gzip file (.gz) is on disk. +By default the asset pipeline generates .gz files for all compressible assets. +Serving gzip files minimizes data transfer and speeds up asset requests. Always +use a CDN if you are +serving assets from your Rails server in production. +(Pull Request)

  • +
  • +

    When calling the process helpers in an integration test the path needs to have +a leading slash. Previously you could omit it but that was a byproduct of the +implementation and not an intentional feature, e.g.:

    +
    +
    +test "list all posts" do
    +  get "/posts"
    +  assert_response :success
    +end
    +
    +
    +
    +
  • +
+

6 Action View

Please refer to the Changelog for detailed changes.

6.1 Deprecations

+
    +
  • Deprecated AbstractController::Base.parent_prefixes. +Override AbstractController::Base.local_prefixes when you want to change +where to find views. +(Pull Request)

  • +
  • Deprecated ActionView::Digestor#digest(name, format, finder, options = {}). +Arguments should be passed as a hash instead. +(Pull Request)

  • +
+

6.2 Notable changes

+
    +
  • render "foo/bar" now expands to render template: "foo/bar" instead of +render file: "foo/bar". +(Pull Request)

  • +
  • The form helpers no longer generate a <div> element with inline CSS around +the hidden fields. +(Pull Request)

  • +
  • Introduced a #{partial_name}_iteration special local variable for use with +partials that are rendered with a collection. It provides access to the +current state of the iteration via the index, size, first? and +last? methods. +(Pull Request)

  • +
  • Placeholder I18n follows the same convention as label I18n. +(Pull Request)

  • +
+

7 Action Mailer

Please refer to the Changelog for detailed changes.

7.1 Deprecations

+
    +
  • Deprecated *_path helpers in mailers. Always use *_url helpers instead. +(Pull Request)

  • +
  • Deprecated deliver / deliver! in favor of deliver_now / deliver_now!. +(Pull Request)

  • +
+

7.2 Notable changes

+
    +
  • link_to and url_for generate absolute URLs by default in templates, +it is no longer needed to pass only_path: false. +(Commit)

  • +
  • Introduced deliver_later which enqueues a job on the application's queue +to deliver emails asynchronously. +(Pull Request)

  • +
  • Added the show_previews configuration option for enabling mailer previews +outside of the development environment. +(Pull Request)

  • +
+

8 Active Record

Please refer to the Changelog for detailed changes.

8.1 Removals

+
    +
  • Removed cache_attributes and friends. All attributes are cached. +(Pull Request)

  • +
  • Removed deprecated method ActiveRecord::Base.quoted_locking_column. +(Pull Request)

  • +
  • Removed deprecated ActiveRecord::Migrator.proper_table_name. Use the +proper_table_name instance method on ActiveRecord::Migration instead. +(Pull Request)

  • +
  • Removed unused :timestamp type. Transparently alias it to :datetime +in all cases. Fixes inconsistencies when column types are sent outside of +Active Record, such as for XML serialization. +(Pull Request)

  • +
+

8.2 Deprecations

+
    +
  • Deprecated swallowing of errors inside after_commit and after_rollback. +(Pull Request)

  • +
  • Deprecated broken support for automatic detection of counter caches on +has_many :through associations. You should instead manually specify the +counter cache on the has_many and belongs_to associations for the +through records. +(Pull Request)

  • +
  • Deprecated passing Active Record objects to .find or .exists?. Call +id on the objects first. +(Commit 1, +2)

  • +
  • +

    Deprecated half-baked support for PostgreSQL range values with excluding +beginnings. We currently map PostgreSQL ranges to Ruby ranges. This conversion +is not fully possible because Ruby ranges do not support excluded beginnings.

    +

    The current solution of incrementing the beginning is not correct +and is now deprecated. For subtypes where we don't know how to increment +(e.g. succ is not defined) it will raise an ArgumentError for ranges +with excluding beginnings. +(Commit)

    +
  • +
  • Deprecated calling DatabaseTasks.load_schema without a connection. Use +DatabaseTasks.load_schema_current instead. +(Commit)

  • +
  • Deprecated sanitize_sql_hash_for_conditions without replacement. Using a +Relation for performing queries and updates is the preferred API. +(Commit)

  • +
  • Deprecated add_timestamps and t.timestamps without passing the :null +option. The default of null: true will change in Rails 5 to null: false. +(Pull Request)

  • +
  • Deprecated Reflection#source_macro without replacement as it is no longer +needed in Active Record. +(Pull Request)

  • +
  • Deprecated serialized_attributes without replacement. +(Pull Request)

  • +
  • Deprecated returning nil from column_for_attribute when no column +exists. It will return a null object in Rails 5.0. +(Pull Request)

  • +
  • Deprecated using .joins, .preload and .eager_load with associations +that depend on the instance state (i.e. those defined with a scope that +takes an argument) without replacement. +(Commit)

  • +
+

8.3 Notable changes

+
    +
  • SchemaDumper uses force: :cascade on create_table. This makes it +possible to reload a schema when foreign keys are in place.

  • +
  • Added a :required option to singular associations, which defines a +presence validation on the association. +(Pull Request)

  • +
  • ActiveRecord::Dirty now detects in-place changes to mutable values. +Serialized attributes on Active Record models are no longer saved when +unchanged. This also works with other types such as string columns and json +columns on PostgreSQL. +(Pull Requests 1, +2, +3)

  • +
  • Introduced the db:purge Rake task to empty the database for the +current environment. +(Commit)

  • +
  • Introduced ActiveRecord::Base#validate! that raises +ActiveRecord::RecordInvalid if the record is invalid. +(Pull Request)

  • +
  • Introduced validate as an alias for valid?. +(Pull Request)

  • +
  • touch now accepts multiple attributes to be touched at once. +(Pull Request)

  • +
  • The PostgreSQL adapter now supports the jsonb datatype in PostgreSQL 9.4+. +(Pull Request)

  • +
  • The PostgreSQL and SQLite adapters no longer add a default limit of 255 +characters on string columns. +(Pull Request)

  • +
  • Added support for the citext column type in the PostgreSQL adapter. +(Pull Request)

  • +
  • Added support for user-created range types in the PostgreSQL adapter. +(Commit)

  • +
  • sqlite3:///some/path now resolves to the absolute system path +/some/path. For relative paths, use sqlite3:some/path instead. +(Previously, sqlite3:///some/path resolved to the relative path +some/path. This behavior was deprecated on Rails 4.1). +(Pull Request)

  • +
  • Added support for fractional seconds for MySQL 5.6 and above. +(Pull Request 1, +2)

  • +
  • Added ActiveRecord::Base#pretty_print to pretty print models. +(Pull Request)

  • +
  • ActiveRecord::Base#reload now behaves the same as m = Model.find(m.id), +meaning that it no longer retains the extra attributes from custom +SELECTs. +(Pull Request)

  • +
  • ActiveRecord::Base#reflections now returns a hash with string keys instead +of symbol keys. (Pull Request)

  • +
  • The references method in migrations now supports a type option for +specifying the type of the foreign key (e.g. :uuid). +(Pull Request)

  • +
+

9 Active Model

Please refer to the Changelog for detailed changes.

9.1 Removals

+
    +
  • Removed deprecated Validator#setup without replacement. +(Pull Request)
  • +
+

9.2 Deprecations

+
    +
  • Deprecated reset_#{attribute} in favor of restore_#{attribute}. +(Pull Request)

  • +
  • Deprecated ActiveModel::Dirty#reset_changes in favor of +clear_changes_information. +(Pull Request)

  • +
+

9.3 Notable changes

+
    +
  • Introduced validate as an alias for valid?. +(Pull Request)

  • +
  • Introduced the restore_attributes method in ActiveModel::Dirty to restore +the changed (dirty) attributes to their previous values. +(Pull Request 1, +2)

  • +
  • has_secure_password no longer disallows blank passwords (i.e. passwords +that contains only spaces) by default. +(Pull Request)

  • +
  • has_secure_password now verifies that the given password is less than 72 +characters if validations are enabled. +(Pull Request)

  • +
+

10 Active Support

Please refer to the Changelog for detailed changes.

10.1 Removals

+
    +
  • Removed deprecated Numeric#ago, Numeric#until, Numeric#since, +Numeric#from_now. +(Commit)

  • +
  • Removed deprecated string based terminators for ActiveSupport::Callbacks. +(Pull Request)

  • +
+

10.2 Deprecations

+
    +
  • Deprecated Kernel#silence_stderr, Kernel#capture and Kernel#quietly +without replacement. +(Pull Request)

  • +
  • Deprecated Class#superclass_delegating_accessor, use +Class#class_attribute instead. +(Pull Request)

  • +
  • Deprecated ActiveSupport::SafeBuffer#prepend! as +ActiveSupport::SafeBuffer#prepend now performs the same function. +(Pull Request)

  • +
+

10.3 Notable changes

+
    +
  • Introduced a new configuration option active_support.test_order for +specifying the order test cases are executed. This option currently defaults +to :sorted but will be changed to :random in Rails 5.0. +(Commit)

  • +
  • Object#try and Object#try! can now be used without an explicit receiver in the block. +(Commit, +Pull Request)

  • +
  • The travel_to test helper now truncates the usec component to 0. +(Commit)

  • +
  • Introduced Object#itself as an identity function. +(Commit 1, +2)

  • +
  • Object#with_options can now be used without an explicit receiver in the block. +(Pull Request)

  • +
  • Introduced String#truncate_words to truncate a string by a number of words. +(Pull Request)

  • +
  • Added Hash#transform_values and Hash#transform_values! to simplify a +common pattern where the values of a hash must change, but the keys are left +the same. +(Pull Request)

  • +
  • The humanize inflector helper now strips any leading underscores. +(Commit)

  • +
  • Introduced Concern#class_methods as an alternative to +module ClassMethods, as well as Kernel#concern to avoid the +module Foo; extend ActiveSupport::Concern; end boilerplate. +(Commit)

  • +
  • New guide about constant autoloading and reloading.

  • +
+

11 Credits

See the +full list of contributors to Rails for +the many people who spent many hours making Rails the stable and robust +framework it is today. Kudos to all of them.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/5_0_release_notes.html b/5_0_release_notes.html new file mode 100644 index 0000000..82bda1a --- /dev/null +++ b/5_0_release_notes.html @@ -0,0 +1,672 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Ruby on Rails 5.0 发布记

Rails 5.0 的重要变化:

+
    +
  • Action Cable

  • +
  • Rails API

  • +
  • Active Record Attributes API

  • +
  • 测试运行程序

  • +
  • rails CLI 全面取代 Rake

  • +
  • Sprockets 3

  • +
  • Turbolinks 5

  • +
  • 要求 Ruby 2.2.2+

  • +
+

本文只涵盖重要变化。若想了解缺陷修正和小变化,请查看更新日志,或者 GitHub 中 Rails 主仓库的提交历史

1 升级到 Rails 5.0

如果升级现有应用,在继续之前,最好确保有足够的测试覆盖度。如果尚未升级到 Rails 4.2,应该先升级到 4.2 版,确保应用能正常运行之后,再尝试升级到 Rails 5.0。升级时的注意事项参见 Ruby on Rails 升级指南

2 主要功能

2.1 Action Cable

拉取请求

Action Cable 是 Rails 4 新增的框架,其作用是把 WebSockets 无缝集成到 Rails 应用中。

有了 Action Cable,你就可以使用与 Rails 应用其他部分一样的风格和形式使用 Ruby 编写实时功能,而且兼顾性能和可伸缩性。这是一个全栈框架,既提供了客户端 JavaScript 框架,也提供了服务器端 Ruby 框架。你对使用 Active Record 或其他 ORM 编写的领域模型有完全的访问能力。

详情参见Action Cable 概览

2.2 API 应用

Rails 现在可用于创建专门的 API 应用了。如此以来,我们便可以创建类似 TwitterGitHub 那样的 API,提供给公众使用,或者只供自己使用。

Rails API 应用通过下述命令生成:

+
+$ rails new my_api --api
+
+
+
+

上述命令主要做三件事:

+
    +
  • 配置应用,使用有限的中间件(比常规应用少)。具体而言,不含默认主要针对浏览器应用的中间件(如提供 cookie 支持的中间件)。

  • +
  • ApplicationController 继承 ActionController::API,而不继承 ActionController::Base。与中间件一样,这样做是为了去除主要针对浏览器应用的 Action Controller 模块。

  • +
  • 配置生成器,生成资源时不生成视图、辅助方法和静态资源。

  • +
+

生成的应用提供了基本的 API,你可以根据应用的需要配置,加入所需的功能

详情参见使用 Rails 开发只提供 API 的应用

2.3 Active Record Attributes API

为模型定义指定类型的属性。如果需要,会覆盖属性的当前类型。通过这一 API 可以控制属性的类型在模型和 SQL 之间的转换。此外,还可以改变传给 ActiveRecord::Base.where 的值的行为,以便让领域对象可以在 Active Record 的大多数地方使用,而不用依赖实现细节或使用猴子补丁。

通过这一 API 可以实现:

+
    +
  • 覆盖 Active Record 检测到的类型。

  • +
  • 提供默认类型。

  • +
  • 属性不一定对应于数据库列。

  • +
+
+
+# db/schema.rb
+create_table :store_listings, force: true do |t|
+  t.decimal :price_in_cents
+  t.string :my_string, default: "original default"
+end
+
+# app/models/store_listing.rb
+class StoreListing < ActiveRecord::Base
+end
+
+store_listing = StoreListing.new(price_in_cents: '10.1')
+
+# 以前
+store_listing.price_in_cents # => BigDecimal.new(10.1)
+StoreListing.new.my_string # => "original default"
+
+class StoreListing < ActiveRecord::Base
+  attribute :price_in_cents, :integer # custom type
+  attribute :my_string, :string, default: "new default" # default value
+  attribute :my_default_proc, :datetime, default: -> { Time.now } # default value
+  attribute :field_without_db_column, :integer, array: true
+end
+
+# 现在
+store_listing.price_in_cents # => 10
+StoreListing.new.my_string # => "new default"
+StoreListing.new.my_default_proc # => 2015-05-30 11:04:48 -0600
+model = StoreListing.new(field_without_db_column: ["1", "2", "3"])
+model.attributes # => {field_without_db_column: [1, 2, 3]}
+
+
+
+

创建自定义类型
+你可以自定义类型,只要它们能响应值类型定义的方法。deserializecast 会在自定义类型的对象上调用,传入从数据库或控制器获取的原始值。通过这一特性可以自定义转换方式,例如处理货币数据。

查询
+ActiveRecord::Base.where 会使用模型类定义的类型把值转换成 SQL,方法是在自定义类型对象上调用 serialize

这样,做 SQL 查询时可以指定如何转换值。

Dirty Tracking
+通过属性的类型可以改变 Dirty Tracking 的执行方式。

详情参见文档

2.4 测试运行程序

为了增强 Rails 运行测试的能力,这一版引入了新的测试运行程序。若想使用这个测试运行程序,输入 bin/rails test 即可。

这个测试运行程序受 RSpecminitest-reportersmaxitest 等启发,包含下述主要优势:

+
    +
  • 通过测试的行号运行单个测试。

  • +
  • 指定多个行号,运行多个测试。

  • +
  • 改进失败消息,也便于重新运行失败的测试。

  • +
  • 指定 -f 选项,尽早失败,一旦发现失败就停止测试,而不是等到整个测试组件运行完毕。

  • +
  • 指定 -d 选项,等到测试全部运行完毕再显示输出。

  • +
  • 指定 -b 选项,输出完整的异常回溯信息。

  • +
  • Minitest 集成,允许指定 -s 选项测试种子数据,指定 -n 选项运行指定名称的测试,指定 -v 选项输出更详细的信息,等等。

  • +
  • 以不同颜色显示测试输出。

  • +
+

3 Railties

变化详情参见 Changelog

3.1 删除

+
    +
  • 删除对 debugger 的支持,换用 byebug。因为 Ruby 2.2 不支持 debugger。(提交

  • +
  • 删除弃用的 test:alltest:all:db 任务。(提交

  • +
  • 删除弃用的 Rails::Rack::LogTailer。(提交

  • +
  • 删除弃用的 RAILS_CACHE 常量。(提交

  • +
  • 删除弃用的 serve_static_assets 配置。(提交

  • +
  • 删除 doc:appdoc:railsdoc:gudies 三个文档任务。(提交

  • +
  • 从默认栈中删除 Rack::ContentLength 中间件。(提交

  • +
+

3.2 弃用

+
    +
  • 弃用 config.static_cache_control,换成 config.public_file_server.headers。(拉取请求

  • +
  • 弃用 config.serve_static_files,换成 config.public_file_server.enabled。(拉取请求

  • +
  • 弃用 rails 命名空间下的任务,换成 app 命名空间(例如,rails:updaterails:template 任务变成了 app:updateapp:template)。(拉取请求

  • +
+

3.3 重要变化

+
    +
  • 添加 Rails 测试运行程序 bin/rails test。(拉取请求

  • +
  • 新生成的应用和插件的自述文件使用 Markdown 格式。(提交拉取请求

  • +
  • 添加 bin/rails restart 任务,通过 touch tmp/restart.txt 文件重启 Rails 应用。(拉取请求

  • +
  • 添加 bin/rails initializers 任务,按照 Rails 调用的顺序输出所有初始化脚本。(拉取请求

  • +
  • 添加 bin/rails dev:cache 任务,在开发环境启用或禁用缓存。(拉取请求

  • +
  • 添加 bin/update 脚本,自动更新开发环境。(拉取请求

  • +
  • 通过 bin/rails 代理 Rake 任务。(拉取请求拉取请求

  • +
  • 新生成的应用在 Linux 和 macOS 中启用文件系统事件监控。把 --skip-listen 传给生成器可以禁用这一功能。(提交提交

  • +
  • 使用环境变量 RAILS_LOG_TO_STDOUT 把生产环境的日志输出到 STDOUT。(拉取请求

  • +
  • 新应用通过 IncludeSudomains 首部启用 HSTS。(拉取请求

  • +
  • 应用生成器创建一个名为 config/spring.rb 的新文件,告诉 Spring 监视其他常见的文件。(提交

  • +
  • 添加 --skip-action-mailer,生成新应用时不生成 Action Mailer。(拉取请求

  • +
  • 删除 tmp/sessions 目录,以及与之对应的 Rake 清理任务。(拉取请求

  • +
  • 让脚手架生成的 _form.html.erb 使用局部变量。(拉取请求

  • +
  • 禁止在生产环境自动加载类。(提交

  • +
+

4 Action Pack

变化详情参见 Changelog

4.1 删除

+
    +
  • 删除 ActionDispatch::Request::Utils.deep_munge。(提交

  • +
  • 删除 ActionController::HideActions。(拉取请求

  • +
  • 删除占位方法 respond_torespond_with,提取为 responders gem。(提交)

  • +
  • 删除弃用的断言文件。(提交

  • +
  • 不再允许在 URL 辅助方法中使用字符串键。(提交

  • +
  • 删除弃用的 *_path 辅助方法的 only_path 选项。(提交

  • +
  • 删除弃用的 NamedRouteCollection#helpers。(提交

  • +
  • 不再允许使用不带 #:to 选项定义路由。(提交

  • +
  • 删除弃用的 ActionDispatch::Response#to_ary。(提交

  • +
  • 删除弃用的 ActionDispatch::Request#deep_munge。(提交

  • +
  • 删除弃用的 ActionDispatch::Http::Parameters#symbolized_path_parameters。(提交

  • +
  • 不再允许在控制器测试中使用 use_route 选项。(提交

  • +
  • 删除 assignsassert_template,提取为 rails-controller-testing gem 中。(拉取请求

  • +
+

4.2 弃用

+
    +
  • 弃用所有 *_filter 回调,换成 *_action。(拉取请求

  • +
  • 弃用 *_via_redirect 集成测试方法。请在请求后手动调用 follow_redirect!,效果一样。(拉取请求

  • +
  • 弃用 AbstractController#skip_action_callback,换成单独的 skip_callback 方法。(拉取请求

  • +
  • 弃用 render 方法的 :nothing 选项。(拉取请求

  • +
  • 以前,head 方法的第一个参数是一个 散列,而且可以设定默认的状态码;现在弃用了。(拉取请求

  • +
  • 弃用通过字符串或符号指定中间件类名。直接使用类名。(提交

  • +
  • 弃用通过常量访问 MIME 类型(如 Mime::HTML)。换成通过下标和符号访问(如 Mime[:html])。(拉取请求

  • +
  • 弃用 redirect_to :back,换成 redirect_back。后者必须指定 fallback_location 参数,从而避免出现 RedirectBackError 异常。(拉取请求

  • +
  • ActionDispatch::IntegrationTestActionController::TestCase 弃用位置参数,换成关键字参数。(拉取请求

  • +
  • 弃用 :controller:action 路径参数。(拉取请求

  • +
  • 弃用控制器实例的 env 方法。(提交

  • +
  • 启用了 ActionDispatch::ParamsParser,而且从中间件栈中删除了。若想配置参数解析程序,使用 ActionDispatch::Request.parameter_parsers=。(提交提交

  • +
+

4.3 重要变化

+
    +
  • 添加 ActionController::Renderer,在控制器动作之外渲染任意模板。(拉取请求

  • +
  • ActionController::TestCaseActionDispatch::Integration 的 HTTP 请求方法的参数换成关键字参数。(拉取请求

  • +
  • 为 Action Controller 添加 http_cache_forever,缓存响应,永不过期。(拉取请求

  • +
  • 为获取请求设备提供更友好的方式。(拉取请求

  • +
  • 对没有模板的动作来说,渲染 head :no_content,而不是抛出异常。(拉取请求

  • +
  • 支持覆盖控制器默认的表单构建程序。(拉取请求

  • +
  • 添加对只提供 API 的应用的支持。添加 ActionController::API,在这类应用中取代 ActionController::Base。(拉取请求

  • +
  • ActionController::Parameters 不再继承自 HashWithIndifferentAccess。(拉取请求

  • +
  • 减少 config.force_sslconfig.ssl_options 的危险性,更便于禁用。(拉取请求

  • +
  • 允许 ActionDispatch::Static 返回任意首部。(拉取请求

  • +
  • protect_from_forgery 提供的保护措施默认设为 false。(提交

  • +
  • ActionController::TestCase 将在 Rails 5.1 中移除,制成单独的 gem。换用 ActionDispatch::IntegrationTest。(提交

  • +
  • Rails 默认生成弱 ETag。(拉取请求

  • +
  • 如果控制器动作没有显式调用 render,而且没有对应的模板,隐式渲染 head :no_content,不再抛出异常。(拉取请求拉取请求

  • +
  • 添加一个选项,为每个表单指定单独的 CSRF 令牌。(拉取请求

  • +
  • 为集成测试添加请求编码和响应解析功能。(拉取请求

  • +
  • 添加 ActionController#helpers,在控制器层访问视图上下文。(拉取请求

  • +
  • 不用的闪现消息在存入会话之前删除。(拉取请求

  • +
  • fresh_whenstale? 支持解析记录集合。(拉取请求

  • +
  • ActionController::Live 变成一个 ActiveSupport::Concern。这意味着,不能直接将其引入其他模块,而不使用 ActiveSupport::Concern 扩展,否则,ActionController::Live 在生产环境无效。有些人还可能会使用其他模块引入处理 Warden/Devise 身份验证失败的特殊代码,因为中间件无法捕获派生的线程抛出的 :warden 异常——使用 ActionController::Live 时就是如此。(详情

  • +
  • 引入 Response#strong_etag=#weak_etag=,以及 fresh_whenstale? 的相应选项。(拉取请求

  • +
+

5 Action View

变化详情参见 Changelog

5.1 删除

+
    +
  • 删除弃用的 AbstractController::Base::parent_prefixes。(提交

  • +
  • 删除 ActionView::Helpers::RecordTagHelper,提取为 record_tag_helper gem。(拉取请求

  • +
  • 删除 translate 辅助方法的 :rescue_format 选项,因为 I18n 不再支持。(拉取请求

  • +
+

5.2 重要变化

+
    +
  • 把默认的模板处理程序由 ERB 改为 Raw。(提交

  • +
  • 对集合的渲染可以缓存,而且可以一次获取多个局部视图。(拉取请求提交

  • +
  • 为显式依赖增加通配符匹配。(拉取请求

  • +
  • disable_with 设为 submit 标签的默认行为。提交后禁用按钮能避免多次提交。(拉取请求

  • +
  • 局部模板的名称不再必须是有效的 Ruby 标识符。(提交

  • +
  • datetime_tag 辅助方法现在生成类型为 datetime-localinput 标签。(拉取请求

  • +
+

6 Action Mailer

变化详情参见 Changelog

6.1 删除

+
    +
  • 删除邮件视图中弃用的 *_path 辅助方法。(提交

  • +
  • 删除弃用的 deliverdeliver! 方法。(提交

  • +
+

6.2 重要变化

+
    +
  • 查找模板时会考虑默认的本地化设置和 I18n 后备机制。(提交

  • +
  • 为生成器创建的邮件程序添加 _mailer 后缀,让命名约定与控制器和作业相同。(拉取请求

  • +
  • 添加 assert_enqueued_emailsassert_no_enqueued_emails。(拉取请求

  • +
  • 添加 config.action_mailer.deliver_later_queue_name 选项,配置邮件程序队列的名称。(拉取请求

  • +
  • 支持片段缓存 Action Mailer 视图。新增 config.action_mailer.perform_caching 选项,设定是否缓存邮件模板。(拉取请求

  • +
+

7 Active Record

变化详情参见 Changelog

7.1 删除

+
    +
  • 不再允许使用嵌套数组作为查询值。(拉取请求

  • +
  • 删除弃用的 ActiveRecord::Tasks::DatabaseTasks#load_schema,替换为 ActiveRecord::Tasks::DatabaseTasks#load_schema_for。(提交

  • +
  • 删除弃用的 serialized_attributes。(提交

  • +
  • 删除 has_many :through 弃用的自动计数器缓存。(提交

  • +
  • 删除弃用的 sanitize_sql_hash_for_conditions。(提交

  • +
  • 删除弃用的 Reflection#source_macro。(提交

  • +
  • 删除弃用的 symbolized_base_classsymbolized_sti_name。(提交

  • +
  • 删除弃用的 ActiveRecord::Base.disable_implicit_join_references=。(提交

  • +
  • 不再允许使用字符串存取方法访问连接规范。(提交

  • +
  • 不再预加载依赖实例的关联。(提交

  • +
  • PostgreSQL 值域不再排除下限。(提交

  • +
  • 删除通过缓存的 Arel 修改关系时的弃用消息。现在抛出 ImmutableRelation 异常。(提交

  • +
  • 从核心中删除 ActiveRecord::Serialization::XmlSerializer,提取到 activemodel-serializers-xml gem 中。(拉取请求

  • +
  • 核心不再支持旧的 mysql 数据库适配器。多数用户应该使用 mysql2。找到维护人员后,会把对 mysql 的支持制成单独的 gem。(拉取请求拉取请求

  • +
  • 不再支持 protected_attributes gem。(提交

  • +
  • 不再支持低于 9.1 版的 PostgreSQL。(拉取请求

  • +
  • 不再支持 activerecord-deprecated_finders gem。(提交

  • +
  • 删除 ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES 常量。(提交

  • +
+

7.2 弃用

+
    +
  • 弃用在查询中把类作为值传递。应该传递字符串。(拉取请求

  • +
  • 弃用通过返回 false 停止 Active Record 回调链。建议的方式是 throw(:abort)。(拉取请求

  • +
  • 弃用 ActiveRecord::Base.errors_in_transactional_callbacks=。(提交

  • +
  • 弃用 Relation#uniq,换用 Relation#distinct。(提交

  • +
  • 弃用 PostgreSQL 的 :point 类型,换成返回 Point 对象,而不是数组。(拉取请求

  • +
  • 弃用通过为关联方法传入一个真值参数强制重新加载关联。(拉取请求

  • +
  • 弃用关联的错误键 restrict_dependent_destroy,换成更好的键名。(拉取请求

  • +
  • #tables 的同步行为。(拉取请求

  • +
  • 弃用 SchemaCache#tablesSchemaCache#table_exists?SchemaCache#clear_table_cache!,换成相应的数据源方法。(拉取请求

  • +
  • 弃用 SQLite3 和 MySQL 适配器的 connection.tables。(拉取请求

  • +
  • 弃用把参数传给 #tables:在某些适配器中(mysql2、sqlite3),它返回表和视图,而其他适配器(postgresql)只返回表。为了保持行为一致,未来 #tables 只返回表。(拉取请求

  • +
  • 弃用 table_exists? 方法:它既检查表,也检查视图。为了与 #tables 的行为一致,未来 #table_exists? 只检查表。(拉取请求

  • +
  • 弃用 find_nth 方法的 offset 参数。请在关系上使用 offset 方法。(拉取请求

  • +
  • 弃用 DatabaseStatements 中的 {insert|update|delete}_sql。换用公开方法 {insert|update|delete}。(拉取请求

  • +
  • 弃用 use_transactional_fixtures,换成更明确的 use_transactional_tests。(拉取请求

  • +
  • 弃用把一列传给 ActiveRecord::Connection#quote。(提交

  • +
  • find_in_batches 方法添加与 start 参数对应的 end 参数,指定在哪里停止批量处理。(拉取请求

  • +
+

7.3 重要变化

+
    +
  • 创建表时为 references 添加 foreign_key 选项。(提交

  • +
  • 新的 Attributes API。(提交

  • +
  • enum 添加 :_prefix/:_suffix 选项。(拉取请求拉取请求

  • +
  • ActiveRecord::Relation 添加 #cache_key 方法。(拉取请求

  • +
  • timestamps 默认的 null 值改为 false。(提交

  • +
  • 添加 ActiveRecord::SecureToken,在模型中使用 SecureRandom 为属性生成唯一令牌。(拉取请求

  • +
  • drop_table 添加 :if_exists 选项。(拉取请求

  • +
  • 添加 ActiveRecord::Base#accessed_fields,在模型中只从数据库中选择数据时快速查看读取哪些字段。(提交

  • +
  • ActiveRecord::Relation 添加 #or 方法,允许在 WHEREHAVING 子句中使用 OR 运算符。(提交

  • +
  • 添加 ActiveRecord::Base.suppress,禁止在指定的块执行时保存接收者。(拉取请求

  • +
  • 如果关联的对象不存在,belongs_to 现在默认触发验证错误。在具体的关联中可以通过 optional: true 选项禁止这一行为。因为添加了 optional 选项,所以弃用了 required 选项。(拉取请求

  • +
  • 添加 config.active_record.dump_schemas 选项,用于配置 db:structure:dump 的行为。(拉取请求

  • +
  • 添加 config.active_record.warn_on_records_fetched_greater_than 选项。(拉取请求

  • +
  • 为 MySQL 添加原生支持的 JSON 数据类型。(拉取请求

  • +
  • 支持在 PostgreSQL 中并发删除索引。(拉取请求

  • +
  • 为连接适配器添加 #views#view_exists? 方法。(拉取请求

  • +
  • 添加 ActiveRecord::Base.ignored_columns,让一些列对 Active Record 不可见。(拉取请求

  • +
  • 添加 connection.data_sourcesconnection.data_source_exists?。这两个方法判断什么关系可以用于支持 Active Record 模型(通常是表和视图)。(拉取请求

  • +
  • 允许在 YAML 固件文件中设定模型类。(拉取请求

  • +
  • 生成数据库迁移时允许把 uuid 用作主键。(拉取请求

  • +
  • 添加 ActiveRecord::Relation#left_joinsActiveRecord::Relation#left_outer_joins。(拉取请求

  • +
  • 添加 after_{create,update,delete}_commit 回调。(拉取请求

  • +
  • 为迁移类添加版本,这样便可以修改参数的默认值,而不破坏现有的迁移,或者通过弃用循环强制重写。(拉取请求

  • +
  • 现在,ApplicationRecord 是应用中所有模型的超类,这与控制器一样,控制器是 ApplicationController 的子类,而不是 ActionController::Base。因此,应用可以在一处全局配置模型的行为。(拉取请求

  • +
  • 添加 #second_to_last#third_to_last 方法。(拉取请求

  • +
  • 允许通过存储在 PostgreSQL 和 MySQL 数据库元数据中的注释注解数据库对象。(拉取请求

  • +
  • mysql2 适配器(0.4.4+)添加预处理语句支持。以前只支持弃用的 mysql 适配器。若想启用,在 config/database.yml 中设定 prepared_statements: true。(拉取请求

  • +
  • 允许在关系对象上调用 ActionRecord::Relation#update,在关系涉及的所有对象上运行回调。(拉取请求

  • +
  • save 方法添加 :touch 选项,允许保存记录时不更新时间戳。(拉取请求

  • +
  • 为 PostgreSQL 添加表达式索引和运算符类支持。(提交

  • +
  • 添加 :index_errors 选项,为嵌套属性的错误添加索引。(拉取请求

  • +
  • 添加对双向销毁依赖的支持。(拉取请求

  • +
  • 支持在事务型测试中使用 after_commit 回调。(拉取请求

  • +
  • 添加 foreign_key_exists? 方法,检查表中是否有外键。(拉取请求

  • +
  • touch 方法添加 :time 选项,使用当前时间之外的时间更新记录的时间戳。(拉取请求

  • +
+

8 Active Model

变化详情参见 Changelog

8.1 删除

+ +

8.2 弃用

+
    +
  • 弃用通过返回 false 停止 Active Model 和 ActiveModel::Validations 回调链的方式。推荐的方式是 throw(:abort)。(拉取请求

  • +
  • 弃用行为不一致的 ActiveModel::Errors#getActiveModel::Errors#setActiveModel::Errors#[]= 方法。(拉取请求

  • +
  • 弃用 validates_length_of:tokenizer 选项,换成普通的 Ruby。(拉取请求

  • +
  • 弃用 ActiveModel::Errors#add_on_emptyActiveModel::Errors#add_on_blank,而且没有替代方法。(拉取请求

  • +
+

8.3 重要变化

+
    +
  • 添加 ActiveModel::Errors#details,判断哪个验证失败。(拉取请求

  • +
  • ActiveRecord::AttributeAssignment 提取为 ActiveModel::AttributeAssignment,以便把任意对象作为引入的模块使用。(拉取请求

  • +
  • 添加 ActiveModel::Dirty#[attr_name]_previously_changed?ActiveModel::Dirty#[attr_name]_previous_change,更好地访问保存模型后有变的记录。(拉取请求

  • +
  • valid?invalid? 一次验证多个上下文。(拉取请求

  • +
  • validates_acceptance_of 除了 1 之外接受 true 为默认值。(拉取请求

  • +
+

9 Active Job

变化详情参见 Changelog

9.1 重要变化

+
    +
  • ActiveJob::Base.deserialize 委托给作业类,以便序列化作业时依附任意元数据,并在执行时读取。(拉取请求

  • +
  • 允许在单个作业中配置队列适配器,防止相互影响。(拉取请求

  • +
  • 生成的作业现在默认继承自 app/jobs/application_job.rb。(拉取请求

  • +
  • 允许 DelayedJobSidekiqququequeue_classic 把作业 ID 报给 ActiveJob::Base,通过 provider_job_id 获取。(拉取请求拉取请求提交

  • +
  • 实现一个简单的 AsyncJob 处理程序和相关的 AsyncAdapter,把作业队列放入一个 concurrent-ruby 线程池。(拉取请求

  • +
  • 把默认的适配器由 inline 改为 async。这是更好的默认值,因为测试不会错误地依赖同步行为。(提交

  • +
+

10 Active Support

变化详情参见 Changelog

10.1 删除

+
    +
  • 删除弃用的 ActiveSupport::JSON::Encoding::CircularReferenceError。(提交

  • +
  • 删除弃用的 ActiveSupport::JSON::Encoding.encode_big_decimal_as_string=ActiveSupport::JSON::Encoding.encode_big_decimal_as_string 方法。(提交

  • +
  • 删除弃用的 ActiveSupport::SafeBuffer#prepend。(提交

  • +
  • 删除 Kernel 中弃用的方法:silence_stderrsilence_streamcapturequietly。(提交

  • +
  • 删除弃用的 active_support/core_ext/big_decimal/yaml_conversions 文件。(提交

  • +
  • 删除弃用的 ActiveSupport::Cache::Store.instrumentActiveSupport::Cache::Store.instrument= 方法。(提交

  • +
  • 删除弃用的 Class#superclass_delegating_accessor,换用 Class#class_attribute。(拉取请求

  • +
  • 删除弃用的 ThreadSafe::Cache,换用 Concurrent::Map。(拉取请求

  • +
  • 删除 Object#itself,因为 Ruby 2.2 自带了。(拉取请求

  • +
+

10.2 弃用

+
    +
  • 弃用 MissingSourceFile,换用 LoadError。(提交

  • +
  • 弃用 alias_method_chain,换用 Ruby 2.0 引入的 Module#prepend。(拉取请求

  • +
  • 弃用 ActiveSupport::Concurrency::Latch,换用 concurrent-ruby 中的 Concurrent::CountDownLatch。(拉取请求

  • +
  • 弃用 number_to_human_size:prefix 选项,而且没有替代选项。(拉取请求

  • +
  • 弃用 Module#qualified_const_,换用内置的 Module#const_ 方法。(拉取请求

  • +
  • 弃用通过字符串定义回调。(拉取请求

  • +
  • 弃用 ActiveSupport::Cache::Store#namespaced_keyActiveSupport::Cache::MemCachedStore#escape_keyActiveSupport::Cache::FileStore#key_file_path,换用 normalize_key。(拉取请求提交

  • +
  • 弃用 ActiveSupport::Cache::LocaleCache#set_cache_value,换用 write_cache_value。(拉取请求

  • +
  • 弃用 assert_nothing_raised 的参数。(拉取请求

  • +
  • 弃用 Module.local_constants,换用 Module.constants(false)。(拉取请求

  • +
+

10.3 重要变化

+
    +
  • ActiveSupport::MessageVerifier 添加 #verified#valid_message? 方法。(拉取请求

  • +
  • 改变回调链停止的方式。现在停止回调链的推荐方式是明确使用 throw(:abort)。(拉取请求

  • +
  • 新增配置选项 config.active_support.halt_callback_chains_on_return_false,指定是否允许在前置回调中停止 ActiveRecord、ActiveModel 和 ActiveModel::Validations 回调链。(拉取请求

  • +
  • 把默认的测试顺序由 :sorted 改为 :random。(提交

  • +
  • DateTimeDateTime 添加 #on_weekend?#on_weekday?#next_weekday#prev_weekday 方法。(拉取请求拉取请求

  • +
  • DateTimeDateTime#next_week#prev_week 方法添加 same_time 选项。(拉取请求

  • +
  • DateTimeDateTime 添加 #yesterday#tomorrow 对应的 #prev_day#next_day 方法。

  • +
  • 添加 SecureRandom.base58,生成 base58 字符串。(提交

  • +
  • ActiveSupport::TestCase 添加 file_fixture。这样更便于在测试用例中访问示例文件。(拉取请求

  • +
  • EnumerableArray 添加 #without,返回一个可枚举对象副本,但是不含指定的元素。(拉取请求

  • +
  • 添加 ActiveSupport::ArrayInquirerArray#inquiry。(拉取请求

  • +
  • 添加 ActiveSupport::TimeZone#strptime,使用指定的时区解析时间。(提交

  • +
  • Integer#zero? 启发,添加 Integer#positive?Integer#negative?。(提交

  • +
  • ActiveSupport::OrderedOptions 中的读值方法添加炸弹版本,如果没有值,抛出 KeyError。(拉取请求

  • +
  • 添加 Time.days_in_year,返回指定年份中的日数,如果没有参数,返回当前年份。(提交

  • +
  • 添加一个文件事件监视程序,异步监测应用源码、路由、本地化文件等的变化。(拉取请求

  • +
  • 添加 thread_m/cattr_accessor/reader/writer 方法,声明存活在各个线程中的类和模块变量。(拉取请求

  • +
  • 添加 Array#second_to_lastArray#third_to_last 方法。(拉取请求

  • +
  • 发布 ActiveSupport::ExecutorActiveSupport::Reloader API,允许组件和库管理并参与应用代码的执行以及应用重新加载过程。(拉取请求

  • +
  • ActiveSupport::Duration 现在支持使用和解析 ISO8601 格式。(拉取请求

  • +
  • 启用 parse_json_times 后,ActiveSupport::JSON.decode 支持解析 ISO8601 本地时间。(拉取请求

  • +
  • ActiveSupport::JSON.decode 现在解析日期字符串后返回 Date 对象。(拉取请求

  • +
  • TaggedLogging 支持多次实例化日志记录器,避免共享标签。(拉取请求

  • +
+

11 名誉榜

得益于众多贡献者,Rails 才能变得这么稳定和强健。向他们致敬!

英语原文还有 Rails 4.24.14.0 等版本的发布记,由于版本旧,不再翻译,敬请谅解。——译者注

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/_license.html b/_license.html new file mode 100644 index 0000000..ccc3731 --- /dev/null +++ b/_license.html @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+

本著作采用 创作共用 署名-相同方式共享 4.0 国际 授权

+

“Rails”,“Ruby on Rails”,以及 Rails Logo 为 David Heinemeier Hansson 的商标。版权所有

+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/_welcome.html b/_welcome.html new file mode 100644 index 0000000..4cc7f0a --- /dev/null +++ b/_welcome.html @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+

Ruby on Rails 指南 (v5.0.1)

+ +

+ 这是 Rails 5.0 的最新指南,基于 v5.0.1。 + 这份指南旨在使您立即获得 Rails 的生产力,并帮助您了解所有组件如何组合在一起。 +

+

+早前版本的指南: +Rails 4.2, +Rails 4.1, +Rails 4.0, +Rails 3.2,和 +Rails 2.3。 +

+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/action_cable_overview.html b/action_cable_overview.html new file mode 100644 index 0000000..dfbe4db --- /dev/null +++ b/action_cable_overview.html @@ -0,0 +1,232 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+

Action Cable 概览

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/action_controller_overview.html b/action_controller_overview.html new file mode 100644 index 0000000..63e853e --- /dev/null +++ b/action_controller_overview.html @@ -0,0 +1,1184 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Action Controller 概览

本文介绍控制器的工作原理,以及控制器在应用请求周期中扮演的角色。

读完本文后,您将学到:

+
    +
  • 请求如何进入控制器;

  • +
  • 如何限制传入控制器的参数;

  • +
  • 为什么以及如何把数据存储在会话或 cookie 中;

  • +
  • 处理请求时,如何使用过滤器执行代码;

  • +
  • 如何使用 Action Controller 内置的 HTTP 身份验证功能;

  • +
  • 如何把数据流直接发送给用户的浏览器;

  • +
  • 如何过滤敏感信息,不写入应用的日志;

  • +
  • 如何处理请求过程中可能出现的异常。

  • +
+

1 控制器的作用

Action Controller 是 MVC 中的 C(控制器)。路由决定使用哪个控制器处理请求后,控制器负责解析请求,生成相应的输出。Action Controller 会代为处理大多数底层工作,使用智能的约定,让整个过程清晰明了。

在大多数按照 REST 架构开发的应用中,控制器会接收请求(开发者不可见),从模型中获取数据,或把数据写入模型,再通过视图生成 HTML。如果控制器需要做其他操作,也没问题,以上只不过是控制器的主要作用。

因此,控制器可以视作模型和视图的中间人,让模型中的数据可以在视图中使用,把数据显示给用户,再把用户提交的数据保存或更新到模型中。

路由的处理细节参阅Rails 路由全解

2 控制器命名约定

Rails 控制器的命名约定是,最后一个单词使用复数形式,但也有例外,比如 ApplicationController。例如:用 ClientsController,而不是 ClientController;用 SiteAdminsController,而不是 SiteAdminControllerSitesAdminsController

遵守这一约定便可享用默认的路由生成器(例如 resources 等),无需再指定 :path:controller 选项,而且 URL 和路径的辅助方法也能保持一致性。详情参阅Rails 布局和视图渲染

控制器的命名约定与模型不同,模型的名字习惯使用单数形式。

3 方法和动作

一个控制器是一个 Ruby 类,继承自 ApplicationController,和其他类一样,定义了很多方法。应用接到请求时,路由决定运行哪个控制器和哪个动作,然后 Rails 创建该控制器的实例,运行与动作同名的方法。

+
+class ClientsController < ApplicationController
+  def new
+  end
+end
+
+
+
+

例如,用户访问 /clients/new 添加新客户,Rails 会创建一个 ClientsController 实例,然后调用 new 方法。注意,在上面这段代码中,即使 new 方法是空的也没关系,因为 Rails 默认会渲染 new.html.erb 视图,除非动作指定做其他操作。在 new 方法中,可以声明在视图中使用的 @client 实例变量,创建一个新的 Client 实例:

+
+def new
+  @client = Client.new
+end
+
+
+
+

详情参阅Rails 布局和视图渲染

ApplicationController 继承自 ActionController::Base。后者定义了许多有用的方法。本文会介绍部分方法,如果想知道定义了哪些方法,可查阅 API 文档或源码。

只有公开方法才作为动作调用。所以最好减少对外可见的方法数量(使用 privateprotected),例如辅助方法和过滤器方法。

4 参数

在控制器的动作中,往往需要获取用户发送的数据或其他参数。在 Web 应用中参数分为两类。第一类随 URL 发送,叫做“查询字符串参数”,即 URL 中 ? 符号后面的部分。第二类经常称为“POST 数据”,一般来自用户填写的表单。之所以叫做“POST 数据”,是因为这类数据只能随 HTTP POST 请求发送。Rails 不区分这两种参数,在控制器中都可通过 params 散列获取:

+
+class ClientsController < ApplicationController
+  # 这个动作使用查询字符串参数,因为它响应的是 HTTP GET 请求
+  # 但是,访问参数的方式没有不同
+  # 列出激活客户的 URL 可能是这样的:/clients?status=activated
+  def index
+    if params[:status] == "activated"
+      @clients = Client.activated
+    else
+      @clients = Client.inactivated
+    end
+  end
+
+  # 这个动作使用 POST 参数
+  # 这种参数最常来自用户提交的 HTML 表单
+  # 在 REST 式架构中,这个动作响应的 URL 是“/clients”
+  # 数据在请求主体中发送
+  def create
+    @client = Client.new(params[:client])
+    if @client.save
+      redirect_to @client
+    else
+      # 这一行代码覆盖默认的渲染行为
+      # 默认渲染的是“create”视图
+      render "new"
+    end
+  end
+end
+
+
+
+

4.1 散列和数组参数

params 散列不局限于只能使用一维键值对,其中可以包含数组和嵌套的散列。若想发送数组,要在键名后加上一对空方括号([]):

+
+GET /clients?ids[]=1&ids[]=2&ids[]=3
+
+
+
+

“[”和“]”这两个符号不允许出现在 URL 中,所以上面的地址会被编码成 /clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3。多数情况下,无需你费心,浏览器会代为编码,接收到这样的请求后,Rails 也会自动解码。如果你要手动向服务器发送这样的请求,就要留心了。

此时,params[:ids] 的值是 ["1", "2", "3"]。注意,参数的值始终是字符串,Rails 不会尝试转换类型。

默认情况下,基于安全考虑,参数中的 [nil][nil, nil, …​] 会替换成 []。详情参见 Ruby on Rails 安全指南

若想发送一个散列,要在方括号内指定键名:

+
+<form accept-charset="UTF-8" action="http://github.com/clients" method="post">
+  <input type="text" name="client[name]" value="Acme" />
+  <input type="text" name="client[phone]" value="12345" />
+  <input type="text" name="client[address][postcode]" value="12345" />
+  <input type="text" name="client[address][city]" value="Carrot City" />
+</form>
+
+
+
+

提交这个表单后,params[:client] 的值是 { "name" => "Acme", "phone" => "12345", "address" => { "postcode" => "12345", "city" => "Carrot City" } }。注意 params[:client][:address] 是个嵌套散列。

params 对象的行为类似于散列,但是键可以混用符号和字符串。

4.2 JSON 参数

开发 Web 服务应用时,你会发现,接收 JSON 格式的参数更容易处理。如果请求的 Content-Type 首部是 application/json,Rails 会自动将其转换成 params 散列,这样就可以按照常规的方式使用了。

例如,如果发送如下的 JSON 内容:

+
+{ "company": { "name": "acme", "address": "123 Carrot Street" } }
+
+
+
+

控制器收到的 params[:company]{ "name" => "acme", "address" => "123 Carrot Street" }

如果在初始化脚本中开启了 config.wrap_parameters 选项,或者在控制器中调用了 wrap_parameters 方法,可以放心地省去 JSON 参数中的根元素。此时,Rails 会以控制器名新建一个键,复制参数,将其存入这个键名下。因此,上面的参数可以写成:

+
+{ "name": "acme", "address": "123 Carrot Street" }
+
+
+
+

假设把上述数据发给 CompaniesController,那么参数会存入 :company 键名下:

+
+{ name: "acme", address: "123 Carrot Street", company: { name: "acme", address: "123 Carrot Street" } }
+
+
+
+

如果想修改默认使用的键名,或者把其他参数存入其中,请参阅 API 文档

解析 XML 格式参数的功能现已抽出,制成了 gem,名为 actionpack-xml_parser

4.3 路由参数

params 散列始终有 :controller:action 两个键,但获取这两个值应该使用 controller_nameaction_name 方法。路由中定义的参数,例如 :id,也可通过 params 散列获取。例如,假设有个客户列表,可以列出激活和未激活的客户。我们可以定义一个路由,捕获下面这个 URL 中的 :status 参数:

+
+get '/clients/:status' => 'clients#index', foo: 'bar'
+
+
+
+

此时,用户访问 /clients/active 时,params[:status] 的值是 "active"。同时,params[:foo] 的值会被设为 "bar",就像通过查询字符串传入的一样。控制器还会收到 params[:action],其值为 "index",以及 params[:controller],其值为 "clients"

4.4 default_url_options +

在控制器中定义名为 default_url_options 的方法,可以设置所生成的 URL 中都包含的参数。这个方法必须返回一个散列,其值为所需的参数值,而且键必须使用符号:

+
+class ApplicationController < ActionController::Base
+  def default_url_options
+    { locale: I18n.locale }
+  end
+end
+
+
+
+

这个方法定义的只是预设参数,可以被 url_for 方法的参数覆盖。

如果像上面的代码那样在 ApplicationController 中定义 default_url_options,设定的默认参数会用于生成所有的 URL。default_url_options 也可以在具体的控制器中定义,此时只影响与该控制器有关的 URL。

其实,不是生成的每个 URL 都会调用这个方法。为了提高性能,返回的散列会缓存,因此一次请求至少会调用一次。

4.5 健壮参数

加入健壮参数功能后,Action Controller 的参数禁止在 Avtive Model 中批量赋值,除非参数在白名单中。也就是说,你要明确选择哪些属性可以批量更新,以防不小心允许用户更新模型中敏感的属性。

此外,还可以标记哪些参数是必须传入的,如果没有收到,会交由预定义的 raise/rescue 流程处理,返回“400 Bad Request”。

+
+class PeopleController < ActionController::Base
+  # 这会导致 ActiveModel::ForbiddenAttributes 异常抛出
+  # 因为没有明确指明允许赋值的属性就批量更新了
+  def create
+    Person.create(params[:person])
+  end
+
+  # 只要参数中有 person 键,这个动作就能顺利执行
+  # 否则,抛出 ActionController::ParameterMissing 异常
+  # ActionController::Base 会捕获这个异常,返回 400 Bad Request 响应
+  def update
+    person = current_account.people.find(params[:id])
+    person.update!(person_params)
+    redirect_to person
+  end
+
+  private
+    # 在一个私有方法中封装允许的参数是个好做法
+    # 这样可以在 create 和 update 动作中复用
+    # 此外,可以细化这个方法,针对每个用户检查允许的属性
+    def person_params
+      params.require(:person).permit(:name, :age)
+    end
+end
+
+
+
+
4.5.1 允许使用的标量值

假如允许传入 :id

+
+params.permit(:id)
+
+
+
+

params 中有 :id 键,且 :id 是标量值,就可以通过白名单检查;否则 :id 会被过滤掉。因此,不能传入数组、散列或其他对象。

允许使用的标量类型有:StringSymbolNilClassNumericTrueClassFalseClassDateTimeDateTimeStringIOIOActionDispatch::Http::UploadedFileRack::Test::UploadedFile

若想指定 params 中的值必须为标量数组,可以把键对应的值设为空数组:

+
+params.permit(id: [])
+
+
+
+

若想允许传入整个参数散列,可以使用 permit! 方法:

+
+params.require(:log_entry).permit!
+
+
+
+

此时,允许传入整个 :log_entry 散列及嵌套散列。使用 permit! 时要特别注意,因为这么做模型中所有现有的属性及后续添加的属性都允许进行批量赋值。

4.5.2 嵌套参数

也可以允许传入嵌套参数,例如:

+
+params.permit(:name, { emails: [] },
+              friends: [ :name,
+                         { family: [ :name ], hobbies: [] }])
+
+
+
+

此时,允许传入 nameemailsfriends 属性。其中,emails 是标量数组;friends 是一个由资源组成的数组:应该有个 name 属性(任何允许使用的标量值),有个 hobbies 属性,其值是标量数组,以及一个 family 属性,其值只能包含 name 属性(也是任何允许使用的标量值)。

4.5.3 更多示例

你可能还想在 new 动作中限制允许传入的属性。不过,此时无法在根键上调用 require 方法,因为调用 new 时根键还不存在:

+
+# 使用 `fetch` 可以提供一个默认值
+# 这样就可以使用健壮参数了
+params.fetch(:blog, {}).permit(:title, :author)
+
+
+
+

使用模型的类方法 accepts_nested_attributes_for 可以更新或销毁关联的记录。这个方法基于 id_destroy 参数:

+
+# 允许 :id 和 :_destroy
+params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy])
+
+
+
+

如果散列的键是数字,处理方式有所不同。此时可以把属性作为散列的直接子散列。accepts_nested_attributes_forhas_many 关联同时使用时会得到这种参数:

+
+# 为下面这种数据添加白名单:
+# {"book" => {"title" => "Some Book",
+#             "chapters_attributes" => { "1" => {"title" => "First Chapter"},
+#                                        "2" => {"title" => "Second Chapter"}}}}
+
+params.require(:book).permit(:title, chapters_attributes: [:title])
+
+
+
+
4.5.4 不用健壮参数

健壮参数的目的是为了解决常见问题,不是万用良药。不过,你可以很方便地与自己的代码结合,解决复杂需求。

假设有个参数包含产品名称和一个由任意数据组成的产品附加信息散列,你想过滤产品名称和整个附加数据散列。健壮参数不能过滤由任意键组成的嵌套散列,不过可以使用嵌套散列的键定义过滤规则:

+
+def product_params
+  params.require(:product).permit(:name, data: params[:product][:data].try(:keys))
+end
+
+
+
+

5 会话

应用中的每个用户都有一个会话(session),用于存储少量数据,在多次请求中永久存储。会话只能在控制器和视图中使用,可以通过以下几种存储机制实现:

+
    +
  • ActionDispatch::Session::CookieStore:所有数据都存储在客户端

  • +
  • ActionDispatch::Session::CacheStore:数据存储在 Rails 缓存里

  • +
  • ActionDispatch::Session::ActiveRecordStore:使用 Active Record 把数据存储在数据库中(需要使用 activerecord-session_store gem)

  • +
  • ActionDispatch::Session::MemCacheStore:数据存储在 Memcached 集群中(这是以前的实现方式,现在应该改用 CacheStore)

  • +
+

所有存储机制都会用到一个 cookie,存储每个会话的 ID(必须使用 cookie,因为 Rails 不允许在 URL 中传递会话 ID,这么做不安全)。

多数存储机制都会使用这个 ID 在服务器中查询会话数据,例如在数据库中查询。不过有个例外,即默认也是推荐使用的存储方式——CookieStore。这种机制把所有会话数据都存储在 cookie 中(如果需要,还是可以访问 ID)。CookieStore 的优点是轻量,而且在新应用中使用会话也不用额外的设置。cookie 中存储的数据会使用密令签名,以防篡改。cookie 还会被加密,因此任何能访问 cookie 的人都无法读取其内容。(如果修改了 cookie,Rails 会拒绝使用。)

CookieStore 可以存储大约 4KB 数据,比其他几种存储机制少很多,但一般也够用了。不管使用哪种存储机制,都不建议在会话中存储大量数据。尤其要避免在会话中存储复杂的对象(Ruby 基本对象之外的一切对象,最常见的是模型实例),因为服务器可能无法在多次请求中重组数据,从而导致错误。

如果用户会话中不存储重要的数据,或者不需要持久存储(例如存储闪现消息),可以考虑使用 ActionDispatch::Session::CacheStore。这种存储机制使用应用所配置的缓存方式。CacheStore 的优点是,可以直接使用现有的缓存方式存储会话,不用额外设置。不过缺点也很明显:会话存在时间很短,随时可能消失。

关于会话存储的更多信息,参阅Ruby on Rails 安全指南

如果想使用其他会话存储机制,可以在 config/initializers/session_store.rb 文件中修改:

+
+# Use the database for sessions instead of the cookie-based default,
+# which shouldn't be used to store highly confidential information
+# (create the session table with "rails g active_record:session_migration")
+# Rails.application.config.session_store :active_record_store
+
+
+
+

签署会话数据时,Rails 会用到会话的键(cookie 的名称)。这个值可以在 config/initializers/session_store.rb 中修改:

+
+# Be sure to restart your server when you modify this file.
+Rails.application.config.session_store :cookie_store, key: '_your_app_session'
+
+
+
+

还可以传入 :domain 键,指定可使用此 cookie 的域名:

+
+# Be sure to restart your server when you modify this file.
+Rails.application.config.session_store :cookie_store, key: '_your_app_session', domain: ".example.com"
+
+
+
+

Rails 为 CookieStore 提供了一个密钥,用于签署会话数据。这个密钥可以在 config/secrets.yml 文件中修改:

+
+# Be sure to restart your server when you modify this file.
+
+# Your secret key is used for verifying the integrity of signed cookies.
+# If you change this key, all old signed cookies will become invalid!
+
+# Make sure the secret is at least 30 characters and all random,
+# no regular words or you'll be exposed to dictionary attacks.
+# You can use `rails secret` to generate a secure secret key.
+
+# Make sure the secrets in this file are kept private
+# if you're sharing your code publicly.
+
+development:
+  secret_key_base: a75d...
+
+test:
+  secret_key_base: 492f...
+
+# Do not keep production secrets in the repository,
+# instead read values from the environment.
+production:
+  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
+
+
+
+

使用 CookieStore 时,如果修改了密钥,之前所有的会话都会失效。

5.1 访问会话

在控制器中,可以通过实例方法 session 访问会话。

会话是惰性加载的。如果在动作中不访问,不会自动加载。因此任何时候都无需禁用会话,不访问即可。

会话中的数据以键值对的形式存储,与散列类似:

+
+class ApplicationController < ActionController::Base
+
+  private
+
+  # 使用会话中 :current_user_id  键存储的 ID 查找用户
+  # Rails 应用经常这样处理用户登录
+  # 登录后设定这个会话值,退出后删除这个会话值
+  def current_user
+    @_current_user ||= session[:current_user_id] &&
+      User.find_by(id: session[:current_user_id])
+  end
+end
+
+
+
+

若想把数据存入会话,像散列一样,给键赋值即可:

+
+class LoginsController < ApplicationController
+  # “创建”登录,即“登录用户”
+  def create
+    if user = User.authenticate(params[:username], params[:password])
+      # 把用户的 ID 存储在会话中,以便后续请求使用
+      session[:current_user_id] = user.id
+      redirect_to root_url
+    end
+  end
+end
+
+
+
+

若想从会话中删除数据,把键的值设为 nil 即可:

+
+class LoginsController < ApplicationController
+  # “删除”登录,即“退出用户”
+  def destroy
+    # 从会话中删除用户的 ID
+    @_current_user = session[:current_user_id] = nil
+    redirect_to root_url
+  end
+end
+
+
+
+

若想重设整个会话,使用 reset_session 方法。

5.2 闪现消息

闪现消息是会话的一个特殊部分,每次请求都会清空。也就是说,其中存储的数据只能在下次请求时使用,因此可用于传递错误消息等。

闪现消息的访问方式与会话差不多,类似于散列。(闪现消息是 FlashHash 实例。)

下面以退出登录为例。控制器可以发送一个消息,在下次请求时显示:

+
+class LoginsController < ApplicationController
+  def destroy
+    session[:current_user_id] = nil
+    flash[:notice] = "You have successfully logged out."
+    redirect_to root_url
+  end
+end
+
+
+
+

注意,重定向也可以设置闪现消息。可以指定 :notice:alert 或者常规的 :flash

+
+redirect_to root_url, notice: "You have successfully logged out."
+redirect_to root_url, alert: "You're stuck here!"
+redirect_to root_url, flash: { referral_code: 1234 }
+
+
+
+

上例中,destroy 动作重定向到应用的 root_url,然后显示那个闪现消息。注意,只有下一个动作才能处理前一个动作设置的闪现消息。一般会在应用的布局中加入显示警告或提醒消息的代码:

+
+<html>
+  <!-- <head/> -->
+  <body>
+    <% flash.each do |name, msg| -%>
+      <%= content_tag :div, msg, class: name %>
+    <% end -%>
+
+    <!-- more content -->
+  </body>
+</html>
+
+
+
+

如此一來,如果动作中设置了警告或提醒消息,就会出现在布局中。

闪现消息不局限于警告和提醒,可以设置任何可在会话中存储的内容:

+
+<% if flash[:just_signed_up] %>
+  <p class="welcome">Welcome to our site!</p>
+<% end %>
+
+
+
+

如果希望闪现消息保留到其他请求,可以使用 keep 方法:

+
+class MainController < ApplicationController
+  # 假设这个动作对应 root_url,但是想把针对这个
+  # 动作的请求都重定向到 UsersController#index。
+  # 如果是从其他动作重定向到这里的,而且那个动作
+  # 设定了闪现消息,通常情况下,那个闪现消息会丢失。
+  # 但是我们可以使用 keep 方法,将其保留到下一个请求。
+  def index
+    # 持久存储所有闪现消息
+    flash.keep
+
+    # 还可以指定一个键,只保留某种闪现消息
+    # flash.keep(:notice)
+    redirect_to users_url
+  end
+end
+
+
+
+
5.2.1 flash.now +

默认情况下,闪现消息中的内容只在下一次请求中可用,但有时希望在同一个请求中使用。例如,create 动作没有成功保存资源时,会直接渲染 new 模板,这并不是一个新请求,但却希望显示一个闪现消息。针对这种情况,可以使用 flash.now,其用法和常规的 flash 一样:

+
+class ClientsController < ApplicationController
+  def create
+    @client = Client.new(params[:client])
+    if @client.save
+      # ...
+    else
+      flash.now[:error] = "Could not save client"
+      render action: "new"
+    end
+  end
+end
+
+
+
+

6 cookies

应用可以在客户端存储少量数据(称为 cookie),在多次请求中使用,甚至可以用作会话。在 Rails 中可以使用 cookies 方法轻易访问 cookie,用法和 session 差不多,就像一个散列:

+
+class CommentsController < ApplicationController
+  def new
+    # 如果 cookie 中存有评论者的名字,自动填写
+    @comment = Comment.new(author: cookies[:commenter_name])
+  end
+
+  def create
+    @comment = Comment.new(params[:comment])
+    if @comment.save
+      flash[:notice] = "Thanks for your comment!"
+      if params[:remember_name]
+        # 记住评论者的名字
+        cookies[:commenter_name] = @comment.author
+      else
+        # 从 cookie 中删除评论者的名字(如果有的话)
+        cookies.delete(:commenter_name)
+      end
+      redirect_to @comment.article
+    else
+      render action: "new"
+    end
+  end
+end
+
+
+
+

注意,删除会话中的数据是把键的值设为 nil,但若想删除 cookie 中的值,要使用 cookies.delete(:key) 方法。

Rails 还提供了签名 cookie 和加密 cookie,用于存储敏感数据。签名 cookie 会在 cookie 的值后面加上一个签名,确保值没被修改。加密 cookie 除了做签名之外,还会加密,让终端用户无法读取。详情参阅 API 文档

这两种特殊的 cookie 会序列化签名后的值,生成字符串,读取时再反序列化成 Ruby 对象。

序列化所用的方式可以指定:

+
+Rails.application.config.action_dispatch.cookies_serializer = :json
+
+
+
+

新应用默认的序列化方式是 :json。为了兼容旧应用的 cookie,如果没设定 cookies_serializer 选项,会使用 :marshal

这个选项还可以设为 :hybrid,读取时,Rails 会自动反序列化使用 Marshal 序列化的 cookie,写入时使用 JSON 格式。把现有应用迁移到使用 :json 序列化方式时,这么设定非常方便。

序列化方式还可以使用其他方式,只要定义了 loaddump 方法即可:

+
+Rails.application.config.action_dispatch.cookies_serializer = MyCustomSerializer
+
+
+
+

使用 :json:hybrid 方式时,要知道,不是所有 Ruby 对象都能序列化成 JSON。例如,DateTime 对象序列化成字符串,而散列的键会变成字符串。

+
+class CookiesController < ApplicationController
+  def set_cookie
+    cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014
+    redirect_to action: 'read_cookie'
+  end
+
+  def read_cookie
+    cookies.encrypted[:expiration_date] # => "2014-03-20"
+  end
+end
+
+
+
+

建议只在 cookie 中存储简单的数据(字符串和数字)。如果不得不存储复杂的对象,在后续请求中要自行负责转换。

如果使用 cookie 存储会话,sessionflash 散列也是如此。

7 渲染 XML 和 JSON 数据

ActionController 中渲染 XMLJSON 数据非常简单。使用脚手架生成的控制器如下所示:

+
+class UsersController < ApplicationController
+  def index
+    @users = User.all
+    respond_to do |format|
+      format.html # index.html.erb
+      format.xml  { render xml: @users}
+      format.json { render json: @users}
+    end
+  end
+end
+
+
+
+

你可能注意到了,在这段代码中,我们使用的是 render xml: @users 而不是 render xml: @users.to_xml。如果不是字符串对象,Rails 会自动调用 to_xml 方法。

8 过滤器

过滤器(filter)是一种方法,在控制器动作运行之前、之后,或者前后运行。

过滤器会继承,如果在 ApplicationController 中定义了过滤器,那么应用的每个控制器都可使用。

前置过滤器有可能会终止请求循环。前置过滤器经常用于确保动作运行之前用户已经登录。这种过滤器可以像下面这样定义:

+
+class ApplicationController < ActionController::Base
+  before_action :require_login
+
+  private
+
+  def require_login
+    unless logged_in?
+      flash[:error] = "You must be logged in to access this section"
+      redirect_to new_login_url # halts request cycle
+    end
+  end
+end
+
+
+
+

如果用户没有登录,这个方法会在闪现消息中存储一个错误消息,然后重定向到登录表单页面。如果前置过滤器渲染了页面或者做了重定向,动作就不会运行。如果动作上还有后置过滤器,也不会运行。

在上面的例子中,过滤器在 ApplicationController 中定义,所以应用中的所有控制器都会继承。此时,应用中的所有页面都要求用户登录后才能访问。很显然(这样用户根本无法登录),并不是所有控制器或动作都要做这种限制。如果想跳过某个动作,可以使用 skip_before_action

+
+class LoginsController < ApplicationController
+  skip_before_action :require_login, only: [:new, :create]
+end
+
+
+
+

此时,LoginsControllernew 动作和 create 动作就不需要用户先登录。:only 选项的意思是只跳过这些动作。此外,还有个 :except 选项,用法类似。定义过滤器时也可使用这些选项,指定只在选中的动作上运行。

8.1 后置过滤器和环绕过滤器

除了前置过滤器之外,还可以在动作运行之后,或者在动作运行前后执行过滤器。

后置过滤器类似于前置过滤器,不过因为动作已经运行了,所以可以获取即将发送给客户端的响应数据。显然,后置过滤器无法阻止运行动作。

环绕过滤器会把动作拉入(yield)过滤器中,工作方式类似 Rack 中间件。

假如网站的改动需要经过管理员预览,然后批准。可以把这些操作定义在一个事务中:

+
+class ChangesController < ApplicationController
+  around_action :wrap_in_transaction, only: :show
+
+  private
+
+  def wrap_in_transaction
+    ActiveRecord::Base.transaction do
+      begin
+        yield
+      ensure
+        raise ActiveRecord::Rollback
+      end
+    end
+  end
+end
+
+
+
+

注意,环绕过滤器还包含了渲染操作。在上面的例子中,视图本身是从数据库中读取出来的(例如,通过作用域),读取视图的操作在事务中完成,然后提供预览数据。

也可以不拉入动作,自己生成响应,不过此时动作不会运行。

8.2 过滤器的其他用法

一般情况下,过滤器的使用方法是定义私有方法,然后调用相应的 *_action 方法添加过滤器。不过过滤器还有其他两种用法。

第一种,直接在 *_action 方法中使用代码块。代码块接收控制器作为参数。使用这种方式,前面的 require_login 过滤器可以改写成:

+
+class ApplicationController < ActionController::Base
+  before_action do |controller|
+    unless controller.send(:logged_in?)
+      flash[:error] = "You must be logged in to access this section"
+      redirect_to new_login_url
+    end
+  end
+end
+
+
+
+

注意,此时在过滤器中使用的是 send 方法,因为 logged_in? 是私有方法,而过滤器和控制器不在同一个作用域内。定义 require_login 过滤器不推荐使用这种方式,但是比较简单的过滤器可以这么做。

第二种,在类(其实任何能响应正确方法的对象都可以)中定义过滤器。这种方式用于实现复杂的过滤器,使用前面的两种方式无法保证代码可读性和重用性。例如,可以在一个类中定义前面的 require_login 过滤器:

+
+class ApplicationController < ActionController::Base
+  before_action LoginFilter
+end
+
+class LoginFilter
+  def self.before(controller)
+    unless controller.send(:logged_in?)
+      controller.flash[:error] = "You must be logged in to access this section"
+      controller.redirect_to controller.new_login_url
+    end
+  end
+end
+
+
+
+

这种方式也不是定义 require_login 过滤器的理想方式,因为与控制器不在同一作用域,要把控制器作为参数传入。定义过滤器的类,必须有一个和过滤器种类同名的方法。对于 before_action 过滤器,类中必须定义 before 方法。其他类型的过滤器以此类推。around 方法必须调用 yield 方法执行动作。

9 请求伪造防护

跨站请求伪造(Cross-Site Request Forgery,CSRF)是一种攻击方式,A 网站的用户伪装成 B 网站的用户发送请求,在 B 站中添加、修改或删除数据,而 B 站的用户浑然不知。

防止这种攻击的第一步是,确保所有破坏性动作(createupdatedestroy)只能通过 GET 之外的请求方法访问。如果遵从 REST 架构,已经做了这一步。不过,恶意网站还是可以轻易地发起非 GET 请求,这时就要用到其他跨站攻击防护措施了。

防止跨站攻击的方式是,在各个请求中添加一个只有服务器才知道的难以猜测的令牌。如果请求中没有正确的令牌,服务器会拒绝访问。

如果使用下面的代码生成一个表单:

+
+<%= form_for @user do |f| %>
+  <%= f.text_field :username %>
+  <%= f.text_field :password %>
+<% end %>
+
+
+
+

会看到 Rails 自动添加了一个隐藏字段,用于设定令牌:

+
+<form accept-charset="UTF-8" action="http://github.com/users/1" method="post">
+<input type="hidden"
+       value="67250ab105eb5ad10851c00a5621854a23af5489"
+       name="authenticity_token"/>
+<!-- fields -->
+</form>
+
+
+
+

使用表单辅助方法生成的所有表单都有这样一个令牌,因此多数时候你都无需担心。如果想自己编写表单,或者基于其他原因想添加令牌,可以使用 form_authenticity_token 方法。

form_authenticity_token 会生成一个有效的令牌。在 Rails 没有自动添加令牌的地方(例如 Ajax)可以使用这个方法。

Ruby on Rails 安全指南将更为深入地说明请求伪造防护措施,还有一些开发 Web 应用需要知道的其他安全隐患。

10 请求和响应对象

在每个控制器中都有两个存取方法,分别用于获取当前请求循环的请求对象和响应对象。request 方法的返回值是一个 ActionDispatch::Request 实例,response 方法的返回值是一个响应对象,表示回送客户端的数据。

10.1 request 对象

request 对象中有很多客户端请求的有用信息。可用方法的完整列表参阅 API 文档。下面说明部分属性:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
request 对象的属性作用
host请求的主机名
domain(n=2)主机名的前 n 个片段,从顶级域名的右侧算起
format客户端请求的内容类型
method请求使用的 HTTP 方法
get?, post?, patch?, put?, delete?, head?如果 HTTP 方法是 GET/POST/PATCH/PUT/DELETE/HEAD,返回 true
headers返回一个散列,包含请求的首部
port请求的端口号(整数)
protocol返回所用的协议外加 "://",例如 "http://"
query_stringURL 中的查询字符串,即 ? 后面的全部内容
remote_ip客户端的 IP 地址
url请求的完整 URL
+
10.1.1 path_parametersquery_parametersrequest_parameters +

不管请求中的参数通过查询字符串发送,还是通过 POST 主体提交,Rails 都会把这些参数存入 params 散列中。request 对象有三个存取方法,用于获取各种类型的参数。query_parameters 散列中的参数来自查询参数;request_parameters 散列中的参数来自 POST 主体;path_parameters 散列中的参数来自路由,传入相应的控制器和动作。

10.2 response 对象

response 对象通常不直接使用。response 对象在动作的执行过程中构建,把渲染的数据回送给用户。不过有时可能需要直接访问响应,比如在后置过滤器中。response 对象上的方法有些可以用于赋值。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
response 对象的属性作用
body回送客户端的数据,字符串格式。通常是 HTML。
status响应的 HTTP 状态码,例如,请求成功时是 200,文件未找到时是 404。
location重定向的 URL(如果重定向的话)。
content_type响应的内容类型。
charset响应使用的字符集。默认是 "utf-8"。
headers响应的首部。
+
10.2.1 设置自定义首部

如果想设置自定义首部,可以使用 response.headers 方法。headers 属性是一个散列,键为首部名,值为首部的值。Rails 会自动设置一些首部。如果想添加或者修改首部,赋值给 response.headers 即可,例如:

+
+response.headers["Content-Type"] = "application/pdf"
+
+
+
+

注意,上面这段代码直接使用 content_type= 方法更合理。

11 HTTP 身份验证

Rails 内置了两种 HTTP 身份验证机制:

+
    +
  • 基本身份验证

  • +
  • 摘要身份验证

  • +
+

11.1 HTTP 基本身份验证

大多数浏览器和 HTTP 客户端都支持 HTTP 基本身份验证。例如,在浏览器中如果要访问只有管理员才能查看的页面,会出现一个对话框,要求输入用户名和密码。使用内置的这种身份验证非常简单,只要使用一个方法,即 http_basic_authenticate_with

+
+class AdminsController < ApplicationController
+  http_basic_authenticate_with name: "humbaba", password: "5baa61e4"
+end
+
+
+
+

添加 http_basic_authenticate_with 方法后,可以创建具有命名空间的控制器,继承自 AdminsControllerhttp_basic_authenticate_with 方法会在这些控制器的所有动作运行之前执行,启用 HTTP 基本身份验证。

11.2 HTTP 摘要身份验证

HTTP 摘要身份验证比基本验证高级,因为客户端不会在网络中发送明文密码(不过在 HTTPS 中基本验证是安全的)。在 Rails 中使用摘要验证非常简单,只需使用一个方法,即 authenticate_or_request_with_http_digest

+
+class AdminsController < ApplicationController
+  USERS = { "lifo" => "world" }
+
+  before_action :authenticate
+
+  private
+
+    def authenticate
+      authenticate_or_request_with_http_digest do |username|
+        USERS[username]
+      end
+    end
+end
+
+
+
+

如上面的代码所示,authenticate_or_request_with_http_digest 方法的块只接受一个参数,用户名,返回值是密码。如果 authenticate_or_request_with_http_digest 返回 falsenil,表明身份验证失败。

12 数据流和文件下载

有时不想渲染 HTML 页面,而是把文件发送给用户。在所有的控制器中都可以使用 send_datasend_file 方法。这两个方法都会以数据流的方式发送数据。send_file 方法很方便,只要提供磁盘中文件的名称,就会用数据流发送文件内容。

若想把数据以流的形式发送给客户端,使用 send_data 方法:

+
+require "prawn"
+class ClientsController < ApplicationController
+  # 使用客户信息生成一份 PDF 文档
+  # 然后返回文档,让用户下载
+  def download_pdf
+    client = Client.find(params[:id])
+    send_data generate_pdf(client),
+              filename: "#{client.name}.pdf",
+              type: "application/pdf"
+  end
+
+  private
+
+    def generate_pdf(client)
+      Prawn::Document.new do
+        text client.name, align: :center
+        text "Address: #{client.address}"
+        text "Email: #{client.email}"
+      end.render
+    end
+end
+
+
+
+

在上面的代码中,download_pdf 动作调用一个私有方法,生成 PDF 文档,然后返回字符串形式。返回的字符串会以数据流的形式发送给客户端,并为用户推荐一个文件名。有时发送文件流时,并不希望用户下载这个文件,比如嵌在 HTML 页面中的图像。若想告诉浏览器文件不是用来下载的,可以把 :disposition 选项设为 "inline"。这个选项的另外一个值,也是默认值,是 "attachment"

12.1 发送文件

如果想发送磁盘中已经存在的文件,可以使用 send_file 方法。

+
+class ClientsController < ApplicationController
+  # 以流的形式发送磁盘中现有的文件
+  def download_pdf
+    client = Client.find(params[:id])
+    send_file("#{Rails.root}/files/clients/#{client.id}.pdf",
+              filename: "#{client.name}.pdf",
+              type: "application/pdf")
+  end
+end
+
+
+
+

send_file 一次只发送 4kB,而不是把整个文件都写入内存。如果不想使用数据流方式,可以把 :stream 选项设为 false。如果想调整数据块大小,可以设置 :buffer_size 选项。

如果没有指定 :type 选项,Rails 会根据 :filename 的文件扩展名猜测。如果没有注册扩展名对应的文件类型,则使用 application/octet-stream

要谨慎处理用户提交数据(参数、cookies 等)中的文件路径,这有安全隐患,可能导致不该下载的文件被下载了。

不建议通过 Rails 以数据流的方式发送静态文件,你可以把静态文件放在服务器的公共文件夹中。使用 Apache 或其他 Web 服务器下载效率更高,因为不用经由整个 Rails 栈处理。

12.2 REST 式下载

虽然可以使用 send_data 方法发送数据,但是在 REST 架构的应用中,单独为下载文件操作写个动作有些多余。在 REST 架构下,上例中的 PDF 文件可以视作一种客户资源。Rails 提供了一种更符合 REST 架构的文件下载方法。下面这段代码重写了前面的例子,把下载 PDF 文件的操作放到 show 动作中,不使用数据流:

+
+class ClientsController < ApplicationController
+  # 用户可以请求接收 HTML 或 PDF 格式的资源
+  def show
+    @client = Client.find(params[:id])
+
+    respond_to do |format|
+      format.html
+      format.pdf { render pdf: generate_pdf(@client) }
+    end
+  end
+end
+
+
+
+

为了让这段代码能顺利运行,要把 PDF 的 MIME 类型加入 Rails。在 config/initializers/mime_types.rb 文件中加入下面这行代码即可:

+
+Mime::Type.register "application/pdf", :pdf
+
+
+
+

配置文件不会在每次请求中都重新加载,为了让改动生效,需要重启服务器。

现在,如果用户想请求 PDF 版本,只要在 URL 后加上 ".pdf" 即可:

+
+GET /clients/1.pdf
+
+
+
+

12.3 任意数据的实时流

在 Rails 中,不仅文件可以使用数据流的方式处理,在响应对象中,任何数据都可以视作数据流。ActionController::Live 模块可以和浏览器建立持久连接,随时随地把数据传送给浏览器。

12.3.1 使用实时流

ActionController::Live 模块引入控制器中后,所有的动作都可以处理数据流。你可以像下面这样引入那个模块:

+
+class MyController < ActionController::Base
+  include ActionController::Live
+
+  def stream
+    response.headers['Content-Type'] = 'text/event-stream'
+    100.times {
+      response.stream.write "hello world\n"
+      sleep 1
+    }
+  ensure
+    response.stream.close
+  end
+end
+
+
+
+

上面的代码会和浏览器建立持久连接,每秒一次,共发送 100 次 "hello world\n"

关于这段代码有一些注意事项。必须关闭响应流。如果忘记关闭,套接字就会一直处于打开状态。发送数据流之前,还要把内容类型设为 text/event-stream。这是因为在响应流上调用 writecommit 发送响应后(response.committed? 返回真值)就无法设置首部了。

12.3.2 使用举例

假设你在制作一个卡拉 OK 机,用户想查看某首歌的歌词。每首歌(Song)都有很多行歌词,每一行歌词都要花一些时间(num_beats)才能唱完。

如果按照卡拉 OK 机的工作方式,等上一句唱完才显示下一行,可以像下面这样使用 ActionController::Live

+
+class LyricsController < ActionController::Base
+  include ActionController::Live
+
+  def show
+    response.headers['Content-Type'] = 'text/event-stream'
+    song = Song.find(params[:id])
+
+    song.each do |line|
+      response.stream.write line.lyrics
+      sleep line.num_beats
+    end
+  ensure
+    response.stream.close
+  end
+end
+
+
+
+

在这段代码中,只有上一句唱完才会发送下一句歌词。

12.3.3 使用数据流的注意事项

以数据流的方式发送任意数据是个强大的功能,如前面几个例子所示,你可以选择何时发送什么数据。不过,在使用时,要注意以下事项:

+
    +
  • 每次以数据流形式发送响应都会新建一个线程,然后把原线程中的局部变量复制过来。线程中有太多局部变量会降低性能。而且,线程太多也会影响性能。

  • +
  • 忘记关闭响应流会导致套接字一直处于打开状态。使用响应流时一定要记得调用 close 方法。

  • +
  • WEBrick 会缓冲所有响应,因此引入 ActionController::Live 也不会有任何效果。你应该使用不自动缓冲响应的服务器。

  • +
+

13 日志过滤

Rails 在 log 文件夹中为每个环境都准备了一个日志文件。这些文件在调试时特别有用,但是线上应用并不用把所有信息都写入日志。

13.1 参数过滤

若想过滤特定的请求参数,禁止写入日志文件,可以在应用的配置文件中设置 config.filter_parameters 选项。过滤掉的参数在日志中显示为 [FILTERED]

+
+config.filter_parameters << :password
+
+
+
+

指定的参数通过部分匹配正则表达式过滤掉。Rails 默认在相应的初始化脚本(initializers/filter_parameter_logging.rb)中过滤 :password,以及应用中常见的 passwordpassword_confirmation 参数。

13.2 重定向过滤

有时需要从日志文件中过滤掉一些重定向的敏感数据,此时可以设置 config.filter_redirect 选项:

+
+config.filter_redirect << 's3.amazonaws.com'
+
+
+
+

过滤规则可以使用字符串、正则表达式,或者一个数组,包含字符串或正则表达式:

+
+config.filter_redirect.concat ['s3.amazonaws.com', /private_path/]
+
+
+
+

匹配的 URL 会显示为 '[FILTERED]'

14 异常处理

应用很有可能出错,错误发生时会抛出异常,这些异常是需要处理的。例如,如果用户访问一个链接,但数据库中已经没有对应的资源了,此时 Active Record 会抛出 ActiveRecord::RecordNotFound 异常。

在 Rails 中,异常的默认处理方式是显示“500 Server Error”消息。如果应用在本地运行,出错后会显示一个精美的调用跟踪,以及其他附加信息,让开发者快速找到出错的地方,然后修正。如果应用已经上线,Rails 则会简单地显示“500 Server Error”消息;如果是路由错误或记录不存在,则显示“404 Not Found”。有时你可能想换种方式捕获错误,以不同的方式显示报错信息。在 Rails 中,有很多层异常处理,详解如下。

14.1 默认的 500 和 404 模板

默认情况下,生产环境中的应用出错时会显示 404 或 500 错误消息,在开发环境中则抛出未捕获的异常。错误消息在 public 文件夹里的静态 HTML 文件中,分别是 404.html500.html。你可以修改这两个文件,添加其他信息和样式,不过要记住,这两个是静态文件,不能使用 ERB、SCSS、CoffeeScript 或布局。

14.2 rescue_from +

捕获错误后如果想做更详尽的处理,可以使用 rescue_fromrescue_from 可以处理整个控制器及其子类中的某种(或多种)异常。

异常发生时,会被 rescue_from 捕获,异常对象会传入处理程序。处理程序可以是方法,也可以是 Proc 对象,由 :with 选项指定。也可以不用 Proc 对象,直接使用块。

下面的代码使用 rescue_from 截获所有 ActiveRecord::RecordNotFound 异常,然后做些处理。

+
+class ApplicationController < ActionController::Base
+  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
+
+  private
+
+    def record_not_found
+      render plain: "404 Not Found", status: 404
+    end
+end
+
+
+
+

这段代码对异常的处理并不详尽,比默认的处理方式也没好多少。不过只要你能捕获异常,就可以做任何想做的处理。例如,可以新建一个异常类,当用户无权查看页面时抛出:

+
+class ApplicationController < ActionController::Base
+  rescue_from User::NotAuthorized, with: :user_not_authorized
+
+  private
+
+    def user_not_authorized
+      flash[:error] = "You don't have access to this section."
+      redirect_back(fallback_location: root_path)
+    end
+end
+
+class ClientsController < ApplicationController
+  # 检查是否授权用户访问客户信息
+  before_action :check_authorization
+
+  # 注意,这个动作无需关心任何身份验证操作
+  def edit
+    @client = Client.find(params[:id])
+  end
+
+  private
+
+    # 如果用户没有授权,抛出异常
+    def check_authorization
+      raise User::NotAuthorized unless current_user.admin?
+    end
+end
+
+
+
+

如果没有特别的原因,不要使用 rescue_from Exceptionrescue_from StandardError,因为这会导致严重的副作用(例如,在开发环境中看不到异常详情和调用跟踪)。

在生产环境中,所有 ActiveRecord::RecordNotFound 异常都会导致渲染 404 错误页面。如果不想定制这一行为,无需处理这个异常。

某些异常只能在 ApplicationController 类中捕获,因为在异常抛出前控制器还没初始化,动作也没执行。

15 强制使用 HTTPS 协议

有时,基于安全考虑,可能希望某个控制器只能通过 HTTPS 协议访问。为了达到这一目的,可以在控制器中使用 force_ssl 方法:

+
+class DinnerController
+  force_ssl
+end
+
+
+
+

与过滤器类似,也可指定 :only:except 选项,设置只在某些动作上强制使用 HTTPS:

+
+class DinnerController
+  force_ssl only: :cheeseburger
+  # 或者
+  force_ssl except: :cheeseburger
+end
+
+
+
+

注意,如果你在很多控制器中都使用了 force_ssl,或许你想让整个应用都使用 HTTPS。此时,你可以在环境配置文件中设定 config.force_ssl 选项。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/action_mailer_basics.html b/action_mailer_basics.html new file mode 100644 index 0000000..14c1bc1 --- /dev/null +++ b/action_mailer_basics.html @@ -0,0 +1,872 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Action Mailer 基础

本文全面介绍如何在应用中收发邮件、Action Mailer 的内部机理,以及如何测试邮件程序(mailer)。

读完本文后,您将学到:

+
    +
  • 如何在 Rails 应用中收发邮件;

  • +
  • 如何生成及编辑 Action Mailer 类和邮件视图;

  • +
  • 如何配置 Action Mailer;

  • +
  • 如何测试 Action Mailer 类。

  • +
+

1 简介

Rails 使用 Action Mailer 实现发送邮件功能,邮件由邮件程序和视图控制。邮件程序继承自 ActionMailer::Base,作用与控制器类似,保存在 app/mailers 文件夹中,对应的视图保存在 app/views 文件夹中。

2 发送邮件

本节逐步说明如何创建邮件程序及其视图。

2.1 生成邮件程序的步骤

2.1.1 创建邮件程序
+
+$ bin/rails generate mailer UserMailer
+create  app/mailers/user_mailer.rb
+create  app/mailers/application_mailer.rb
+invoke  erb
+create    app/views/user_mailer
+create    app/views/layouts/mailer.text.erb
+create    app/views/layouts/mailer.html.erb
+invoke  test_unit
+create    test/mailers/user_mailer_test.rb
+create    test/mailers/previews/user_mailer_preview.rb
+
+
+
+
+
+# app/mailers/application_mailer.rb
+class ApplicationMailer < ActionMailer::Base
+  default from: "from@example.com"
+  layout 'mailer'
+end
+
+# app/mailers/user_mailer.rb
+class UserMailer < ApplicationMailer
+end
+
+
+
+

如上所示,生成邮件程序的方法与使用其他生成器一样。邮件程序在某种程度上就是控制器。执行上述命令后,生成了一个邮件程序、一个视图文件夹和一个测试文件。

如果不想使用生成器,可以手动在 app/mailers 文件夹中新建文件,但要确保继承自 ActionMailer::Base

+
+class MyMailer < ActionMailer::Base
+end
+
+
+
+
2.1.2 编辑邮件程序

邮件程序和控制器类似,也有称为“动作”的方法,而且使用视图组织内容。控制器生成的内容,例如 HTML,发送给客户端;邮件程序生成的消息则通过电子邮件发送。

app/mailers/user_mailer.rb 文件中有一个空的邮件程序:

+
+class UserMailer < ApplicationMailer
+end
+
+
+
+

下面我们定义一个名为 welcome_email 的方法,向用户注册时填写的电子邮件地址发送一封邮件:

+
+class UserMailer < ApplicationMailer
+  default from: 'notifications@example.com'
+
+  def welcome_email(user)
+    @user = user
+    @url  = 'http://example.com/login'
+    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
+  end
+end
+
+
+
+

下面简单说明一下这段代码。可用选项的详细说明请参见 Action Mailer 方法详解

+
    +
  • default:一个散列,该邮件程序发出邮件的默认设置。上例中,我们把 :from 邮件头设为一个值,这个类中的所有动作都会使用这个值,不过可以在具体的动作中覆盖。

  • +
  • mail:用于发送邮件的方法,我们传入了 :to:subject 邮件头。

  • +
+

与控制器一样,动作中定义的实例变量可以在视图中使用。

2.1.3 创建邮件视图

app/views/user_mailer/ 文件夹中新建文件 welcome_email.html.erb。这个视图是邮件的模板,使用 HTML 编写:

+
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
+  </head>
+  <body>
+    <h1>Welcome to example.com, <%= @user.name %></h1>
+    <p>
+      You have successfully signed up to example.com,
+      your username is: <%= @user.login %>.<br>
+    </p>
+    <p>
+      To login to the site, just follow this link: <%= @url %>.
+    </p>
+    <p>Thanks for joining and have a great day!</p>
+  </body>
+</html>
+
+
+
+

我们再创建一个纯文本视图。并不是所有客户端都可以显示 HTML 邮件,所以最好两种格式都发送。在 app/views/user_mailer/ 文件夹中新建文件 welcome_email.text.erb,写入以下代码:

+
+Welcome to example.com, <%= @user.name %>
+===============================================
+
+You have successfully signed up to example.com,
+your username is: <%= @user.login %>.
+
+To login to the site, just follow this link: <%= @url %>.
+
+Thanks for joining and have a great day!
+
+
+
+

调用 mail 方法后,Action Mailer 会检测到这两个模板(纯文本和 HTML),自动生成一个类型为 multipart/alternative 的邮件。

2.1.4 调用邮件程序

其实,邮件程序就是渲染视图的另一种方式,只不过渲染的视图不通过 HTTP 协议发送,而是通过电子邮件协议发送。因此,应该由控制器调用邮件程序,在成功注册用户后给用户发送一封邮件。

过程相当简单。

首先,生成一个简单的 User 脚手架:

+
+$ bin/rails generate scaffold user name email login
+$ bin/rails db:migrate
+
+
+
+

这样就有一个可用的用户模型了。我们需要编辑的是文件 app/controllers/users_controller.rb,修改 create 动作,在成功保存用户后调用 UserMailer.welcome_email 方法,向刚注册的用户发送邮件。

Action Mailer 与 Active Job 集成得很好,可以在请求-响应循环之外发送电子邮件,因此用户无需等待。

+
+class UsersController < ApplicationController
+  # POST /users
+  # POST /users.json
+  def create
+    @user = User.new(params[:user])
+
+    respond_to do |format|
+      if @user.save
+        # 让 UserMailer 在保存之后发送一封欢迎邮件
+        UserMailer.welcome_email(@user).deliver_later
+
+        format.html { redirect_to(@user, notice: 'User was successfully created.') }
+        format.json { render json: @user, status: :created, location: @user }
+      else
+        format.html { render action: 'new' }
+        format.json { render json: @user.errors, status: :unprocessable_entity }
+      end
+    end
+  end
+end
+
+
+
+

Active Job 的默认行为是通过 :async 适配器执行作业。因此,这里可以使用 deliver_later,异步发送电子邮件。 Active Job 的默认适配器在一个进程内线程池里运行作业。这一行为特别适合开发和测试环境,因为无需额外的基础设施,但是不适合在生产环境中使用,因为重启服务器后,待执行的作业会被丢弃。如果需要持久性后端,要使用支持持久后端的 Active Job 适配器(Sidekiq、Resque,等等)。

如果想立即发送电子邮件(例如,使用 cronjob),调用 deliver_now 即可:

+
+class SendWeeklySummary
+  def run
+    User.find_each do |user|
+      UserMailer.weekly_summary(user).deliver_now
+    end
+  end
+end
+
+
+
+

welcome_email 方法返回一个 ActionMailer::MessageDelivery 对象,在其上调用 deliver_nowdeliver_later 方法即可发送邮件。ActionMailer::MessageDelivery 对象只是对 Mail::Message 对象的包装。如果想审查、调整或对 Mail::Message 对象做其他处理,可以在 ActionMailer::MessageDelivery 对象上调用 message 方法,获取 Mail::Message 对象。

2.2 自动编码邮件头

Action Mailer 会自动编码邮件头和邮件主体中的多字节字符。

更复杂的需求,例如使用其他字符集和自编码文字,请参考 Mail 库。

2.3 Action Mailer 方法详解

下面这三个方法是邮件程序中最重要的方法:

+
    +
  • headers:设置邮件头,可以指定一个由字段名和值组成的散列,也可以使用 headers[:field_name] = 'value' 形式;

  • +
  • attachments:添加邮件的附件,例如,attachments['file-name.jpg'] = File.read('file-name.jpg')

  • +
  • mail:发送邮件,传入的值为散列形式的邮件头,mail 方法负责创建邮件——纯文本或多种格式,这取决于定义了哪种邮件模板;

  • +
+
2.3.1 添加附件

在 Action Mailer 中添加附件十分方便。

+
    +
  • +

    传入文件名和内容,Action Mailer 和 Mail gem 会自动猜测附件的 MIME 类型,设置编码并创建附件。

    +
    +
    +attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
    +
    +
    +
    +

    触发 mail 方法后,会发送一个由多部分组成的邮件,附件嵌套在类型为 multipart/mixed 的顶级结构中,其中第一部分的类型为 multipart/alternative,包含纯文本和 HTML 格式的邮件内容。

    +

    Mail gem 会自动使用 Base64 编码附件。如果想使用其他编码方式,可以先编码好,再把编码后的附件通过散列传给 attachments 方法。

    +
  • +
  • +

    传入文件名,指定邮件头和内容,Action Mailer 和 Mail gem 会使用传入的参数添加附件。

    +
    +
    +encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
    +attachments['filename.jpg'] = {
    +  mime_type: 'application/gzip',
    +  encoding: 'SpecialEncoding',
    +  content: encoded_content
    +}
    +
    +
    +
    +

    如果指定编码,Mail gem 会认为附件已经编码了,不会再使用 Base64 编码附件。

    +
  • +
+
2.3.2 使用行间附件

在 Action Mailer 3.0 中使用行间附件比之前版本简单得多。

+
    +
  • +

    首先,在 attachments 方法上调用 inline 方法,告诉 Mail 这是个行间附件:

    +
    +
    +def welcome
    +  attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')
    +end
    +
    +
    +
    +
  • +
  • +

    在视图中,可以直接使用 attachments 方法,将其视为一个散列,指定想要使用的附件,在其上调用 url 方法,再把结果传给 image_tag 方法:

    +
    +
    +<p>Hello there, this is our image</p>
    +
    +<%= image_tag attachments['image.jpg'].url %>
    +
    +
    +
    +
  • +
  • +

    因为我们只是简单地调用了 image_tag 方法,所以和其他图像一样,在附件地址之后,还可以传入选项散列:

    +
    +
    +<p>Hello there, this is our image</p>
    +
    +<%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
    +
    +
    +
    +
  • +
+
2.3.3 把邮件发给多个收件人

若想把一封邮件发送给多个收件人,例如通知所有管理员有新用户注册,可以把 :to 键的值设为一组邮件地址。这一组邮件地址可以是一个数组;也可以是一个字符串,使用逗号分隔各个地址。

+
+class AdminMailer < ApplicationMailer
+  default to: Proc.new { Admin.pluck(:email) },
+          from: 'notification@example.com'
+
+  def new_registration(user)
+    @user = user
+    mail(subject: "New User Signup: #{@user.email}")
+  end
+end
+
+
+
+

使用类似的方式还可添加抄送和密送,分别设置 :cc:bcc 键即可。

2.3.4 发送带名字的邮件

有时希望收件人在邮件中看到自己的名字,而不只是邮件地址。实现这种需求的方法是把邮件地址写成 "Full Name <email>" 格式。

+
+def welcome_email(user)
+  @user = user
+  email_with_name = %("#{@user.name}" <#{@user.email}>)
+  mail(to: email_with_name, subject: 'Welcome to My Awesome Site')
+end
+
+
+
+

2.4 邮件视图

邮件视图保存在 app/views/name_of_mailer_class 文件夹中。邮件程序之所以知道使用哪个视图,是因为视图文件名和邮件程序的方法名一致。在前例中,welcome_email 方法的 HTML 格式视图是 app/views/user_mailer/welcome_email.html.erb,纯文本格式视图是 welcome_email.text.erb

若想修改动作使用的视图,可以这么做:

+
+class UserMailer < ApplicationMailer
+  default from: 'notifications@example.com'
+
+  def welcome_email(user)
+    @user = user
+    @url  = 'http://example.com/login'
+    mail(to: @user.email,
+         subject: 'Welcome to My Awesome Site',
+         template_path: 'notifications',
+         template_name: 'another')
+  end
+end
+
+
+
+

此时,邮件程序会在 app/views/notifications 文件夹中寻找名为 another 的视图。template_path 的值还可以是一个路径数组,按照顺序查找视图。

如果想获得更多灵活性,可以传入一个块,渲染指定的模板,或者不使用模板,渲染行间代码或纯文本:

+
+class UserMailer < ApplicationMailer
+  default from: 'notifications@example.com'
+
+  def welcome_email(user)
+    @user = user
+    @url  = 'http://example.com/login'
+    mail(to: @user.email,
+         subject: 'Welcome to My Awesome Site') do |format|
+      format.html { render 'another_template' }
+      format.text { render text: 'Render text' }
+    end
+  end
+end
+
+
+
+

上述代码会使用 another_template.html.erb 渲染 HTML,使用 'Render text' 渲染纯文本。这里用到的 render 方法和控制器中的一样,所以选项也都是一样的,例如 :text:inline 等。

2.4.1 缓存邮件视图

在邮件视图中可以像在应用的视图中一样使用 cache 方法缓存视图。

+
+<% cache do %>
+  <%= @company.name %>
+<% end %>
+
+
+
+

若想使用这个功能,要在应用中做下述配置:

+
+config.action_mailer.perform_caching = true
+
+
+
+

2.5 Action Mailer 布局

和控制器一样,邮件程序也可以使用布局。布局的名称必须和邮件程序一样,例如 user_mailer.html.erbuser_mailer.text.erb 会自动识别为邮件程序的布局。

如果想使用其他布局文件,可以在邮件程序中调用 layout 方法:

+
+class UserMailer < ApplicationMailer
+  layout 'awesome' # 使用 awesome.(html|text).erb 做布局
+end
+
+
+
+

还是跟控制器视图一样,在邮件程序的布局中调用 yield 方法可以渲染视图。

format 块中可以把 layout: 'layout_name' 选项传给 render 方法,指定某个格式使用其他布局:

+
+class UserMailer < ApplicationMailer
+  def welcome_email(user)
+    mail(to: user.email) do |format|
+      format.html { render layout: 'my_layout' }
+      format.text
+    end
+  end
+end
+
+
+
+

上述代码会使用 my_layout.html.erb 文件渲染 HTML 格式;如果 user_mailer.text.erb 文件存在,会用来渲染纯文本格式。

2.6 预览电子邮件

Action Mailer 提供了预览功能,通过一个特殊的 URL 访问。对上述示例来说,UserMailer 的预览类是 UserMailerPreview,存储在 test/mailers/previews/user_mailer_preview.rb 文件中。如果想预览 welcome_email,实现一个同名方法,在里面调用 UserMailer.welcome_email

+
+class UserMailerPreview < ActionMailer::Preview
+  def welcome_email
+    UserMailer.welcome_email(User.first)
+  end
+end
+
+
+
+

然后便可以访问 http://localhost:3000/rails/mailers/user_mailer/welcome_email 预览。

如果修改 app/views/user_mailer/welcome_email.html.erb 文件或邮件程序本身,预览会自动重新加载,立即让你看到新样式。预览列表可以访问 http://localhost:3000/rails/mailers 查看。

默认情况下,预览类存放在 test/mailers/previews 文件夹中。这个位置可以使用 preview_path 选项配置。假如想把它改成 lib/mailer_previews,可以在 config/application.rb 文件中这样配置:

+
+config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
+
+
+
+

2.7 在邮件视图中生成 URL

与控制器不同,邮件程序不知道请求的上下文,因此要自己提供 :host 参数。

一个应用的 :host 参数一般是不变的,可以在 config/application.rb 文件中做全局配置:

+
+config.action_mailer.default_url_options = { host: 'example.com' }
+
+
+
+

鉴于此,在邮件视图中不能使用任何 *_path 辅助方法,而要使用相应的 *_url 辅助方法。例如,不能这样写:

+
+<%= link_to 'welcome', welcome_path %>
+
+
+
+

而要这样写:

+
+<%= link_to 'welcome', welcome_url %>
+
+
+
+

使用完整的 URL,电子邮件中的链接才有效。

2.7.1 使用 url_for 方法生成 URL

默认情况下,url_for 在模板中生成完整的 URL。

如果没有配置全局的 :host 选项,别忘了把它传给 url_for 方法。

+
+<%= url_for(host: 'example.com',
+            controller: 'welcome',
+            action: 'greeting') %>
+
+
+
+
2.7.2 使用具名路由生成 URL

电子邮件客户端不能理解网页的上下文,没有生成完整地址的基地址,所以使用具名路由辅助方法时一定要使用 _url 形式。

如果没有设置全局的 :host 选项,一定要将其传给 URL 辅助方法。

+
+<%= user_url(http://github.com/@user,%20host:%20'example.com') %>
+
+
+
+

GET 之外的链接需要 jQuery UJS,在邮件模板中无法使用。如若不然,都会变成常规的 GET 请求。

2.8 在邮件视图中添加图像

与控制器不同,邮件程序不知道请求的上下文,因此要自己提供 :asset_host 参数。

一个应用的 :asset_host 参数一般是不变的,可以在 config/application.rb 文件中做全局配置:

+
+config.action_mailer.asset_host = 'http://example.com/'
+
+
+
+

现在可以在电子邮件中显示图像了:

+
+<%= image_tag 'image.jpg' %>
+
+
+
+

2.9 发送多种格式邮件

如果一个动作有多个模板,Action Mailer 会自动发送多种格式的邮件。例如前面的 UserMailer,如果在 app/views/user_mailer 文件夹中有 welcome_email.text.erbwelcome_email.html.erb 两个模板,Action Mailer 会自动发送 HTML 和纯文本格式的邮件。

格式的顺序由 ActionMailer::Base.default 方法的 :parts_order 选项决定。

2.10 发送邮件时动态设置发送选项

如果在发送邮件时想覆盖发送选项(例如,SMTP 凭据),可以在邮件程序的动作中设定 delivery_method_options 选项。

+
+class UserMailer < ApplicationMailer
+  def welcome_email(user, company)
+    @user = user
+    @url  = user_url(http://github.com/@user)
+    delivery_options = { user_name: company.smtp_user,
+                         password: company.smtp_password,
+                         address: company.smtp_host }
+    mail(to: @user.email,
+         subject: "Please see the Terms and Conditions attached",
+         delivery_method_options: delivery_options)
+  end
+end
+
+
+
+

2.11 不渲染模板

有时可能不想使用布局,而是直接使用字符串渲染邮件内容,为此可以使用 :body 选项。但是别忘了指定 :content_type 选项,否则 Rails 会使用默认值 text/plain

+
+class UserMailer < ApplicationMailer
+  def welcome_email(user, email_body)
+    mail(to: user.email,
+         body: email_body,
+         content_type: "text/html",
+         subject: "Already rendered!")
+  end
+end
+
+
+
+

3 接收电子邮件

使用 Action Mailer 接收和解析电子邮件是件相当麻烦的事。接收电子邮件之前,要先配置系统,把邮件转发给 Rails 应用,然后做监听。因此,在 Rails 应用中接收电子邮件要完成以下步骤:

+
    +
  • 在邮件程序中实现 receive 方法;

  • +
  • 配置电子邮件服务器,把想通过应用接收的地址转发到 /path/to/app/bin/rails runner 'UserMailer.receive(STDIN.read)'

  • +
+

在邮件程序中定义 receive 方法后,Action Mailer 会解析收到的原始邮件,生成邮件对象,解码邮件内容,实例化一个邮件程序,把邮件对象传给邮件程序的 receive 实例方法。下面举个例子:

+
+class UserMailer < ApplicationMailer
+  def receive(email)
+    page = Page.find_by(address: email.to.first)
+    page.emails.create(
+      subject: email.subject,
+      body: email.body
+    )
+
+    if email.has_attachments?
+      email.attachments.each do |attachment|
+        page.attachments.create({
+          file: attachment,
+          description: email.subject
+        })
+      end
+    end
+  end
+end
+
+
+
+

4 Action Mailer 回调

在 Action Mailer 中也可设置 before_actionafter_actionaround_action

+
    +
  • 与控制器中的回调一样,可以指定块,或者方法名的符号形式;

  • +
  • before_action 中可以使用 defaultsdelivery_method_options 方法,或者指定默认的邮件头和附件;

  • +
  • +

    after_action 可以实现类似 before_action 的功能,而且在 after_action 中可以使用邮件程序动作中设定的实例变量;

    +
    +
    +class UserMailer < ApplicationMailer
    +  after_action :set_delivery_options,
    +               :prevent_delivery_to_guests,
    +               :set_business_headers
    +
    +  def feedback_message(business, user)
    +    @business = business
    +    @user = user
    +    mail
    +  end
    +
    +  def campaign_message(business, user)
    +    @business = business
    +    @user = user
    +  end
    +
    +  private
    +
    +    def set_delivery_options
    +      # 在这里可以访问 mail 实例,以及实例变量 @business 和 @user
    +      if @business && @business.has_smtp_settings?
    +        mail.delivery_method.settings.merge!(@business.smtp_settings)
    +      end
    +    end
    +
    +    def prevent_delivery_to_guests
    +      if @user && @user.guest?
    +        mail.perform_deliveries = false
    +      end
    +    end
    +
    +    def set_business_headers
    +      if @business
    +        headers["X-SMTPAPI-CATEGORY"] = @business.code
    +      end
    +    end
    +end
    +
    +
    +
    +
  • +
  • 如果在回调中把邮件主体设为 nil 之外的值,会阻止执行后续操作;

  • +
+

5 使用 Action Mailer 辅助方法

Action Mailer 继承自 AbstractController,因此为控制器定义的辅助方法都可以在邮件程序中使用。

6 配置 Action Mailer

下述配置选项最好在环境相关的文件(environment.rbproduction.rb,等等)中设置。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
配置项说明
logger运行邮件程序时生成日志信息。设为 nil 时禁用日志。可设为 Ruby 自带的 Logger 或 Log4r 库。
smtp_settings设置 :smtp 发送方式的详情:
    +
  • +:address:设置要使用的远程邮件服务器。默认值为 "localhost"
  • +
  • +:port:如果邮件服务器不在端口 25 上运行(很少见),修改这个选项。
  • +
  • +:domain:用于指定 HELO 域名。
  • +:user_name:如果邮件服务器要验证身份,使用这个选项设定用户名。
  • +
  • +:password:如果邮件服务器要验证身份,使用这个选项设定密码。
  • +
  • +:authentication:如果邮件服务器要验证身份,使用这个选项指定验证类型。这个选项的值是一个符号,可以是 :plain(发送明文密码)、:login(发送 Base64 编码的密码)或 :cram_md5(使用挑战-应答机制交换信息,使用 MD5 算法哈希重要的信息)。
  • +
  • +:enable_starttls_auto:检测 SMTP 服务器有没有启用 STARTTLS,如果有,就使用它。默认值为 true。
  • +
  • `:openssl_verify_mode:使用 TLS 时,可以设定 OpenSSL 检查证书的方式。验证自签或泛域名证书时这特别有用。可以使用某个 OpenSSL 验证常量('none''peer''client_once''fail_if_no_peer_cert'))或直接使用常量(OpenSSL::SSL::VERIFY_NONEOpenSSL::SSL::VERIFY_PEER ……)。
  • +
+
sendmail_settings覆盖 :sendmail 发送方式的选项:
    +
  • +:location:sendmail 可执行文件的位置。默认为 /usr/sbin/sendmail。
  • +
  • +:arguments:传给 sendmail 的命令行参数。默认为 -i -t。
  • +
+
raise_delivery_errors如果邮件发送失败,是否抛出异常。仅当外部邮件服务器设置为立即发送才有效。
delivery_method设置发送方式,可以使用的值有:
    +
  • +:smtp(默认),可以使用 config.action_mailer.smtp_settings 配置。
  • +
  • +:sendmail,可以使用 config.action_mailer.sendmail_settings 配置。
  • +
  • +:file:把电子邮件保存到文件中,可以使用 config.action_mailer.file_settings 配置。
  • +
  • +:test:把电子邮件保存到 ActionMailer::Base.deliveries 数组中。
  • +
详情参阅 API 文档。
perform_deliveries调用 deliver 方法时是否真发送邮件。默认情况下会真的发送,但在功能测试中可以不发送。
deliveries把通过 Action Mailer 使用 :test 方式发送的邮件保存到一个数组中,协助单元测试和功能测试。
default_options为 mail 方法设置默认选项值(:from:reply_to,等等)。
+

完整的配置说明参见 配置 Action Mailer

6.1 Action Mailer 设置示例

可以把下面的代码添加到 config/environments/$RAILS_ENV.rb 文件中:

+
+config.action_mailer.delivery_method = :sendmail
+# Defaults to:
+# config.action_mailer.sendmail_settings = {
+#   location: '/usr/sbin/sendmail',
+#   arguments: '-i -t'
+# }
+config.action_mailer.perform_deliveries = true
+config.action_mailer.raise_delivery_errors = true
+config.action_mailer.default_options = {from: 'no-reply@example.com'}
+
+
+
+

6.2 配置 Action Mailer 使用 Gmail

Action Mailer 现在使用 Mail gem,配置使用 Gmail 更简单,把下面的代码添加到 config/environments/$RAILS_ENV.rb 文件中即可:

+
+config.action_mailer.delivery_method = :smtp
+config.action_mailer.smtp_settings = {
+  address:              'smtp.gmail.com',
+  port:                 587,
+  domain:               'example.com',
+  user_name:            '<username>',
+  password:             '<password>',
+  authentication:       'plain',
+  enable_starttls_auto: true  }
+
+
+
+

从 2014 年 7 月 15 日起,Google 增强了安全措施,会阻止它认为不安全的应用访问。你可以在这里修改 Gmail 的设置,允许访问,或者使用其他 ESP 发送电子邮件:把上面的 'smtp.gmail.com' 换成提供商的地址。

7 测试邮件程序

邮件程序的测试参阅 测试邮件程序

8 拦截电子邮件

有时,在邮件发送之前需要做些修改。Action Mailer 提供了相应的钩子,可以拦截每封邮件。你可以注册一个拦截器,在交给发送程序之前修改邮件。

+
+class SandboxEmailInterceptor
+  def self.delivering_email(message)
+    message.to = ['sandbox@example.com']
+  end
+end
+
+
+
+

使用拦截器之前要在 Action Mailer 框架中注册,方法是在初始化脚本 config/initializers/sandbox_email_interceptor.rb 中添加以下代码:

+
+if Rails.env.staging?
+  ActionMailer::Base.register_interceptor(SandboxEmailInterceptor)
+end
+
+
+
+

上述代码中使用的是自定义环境,名为“staging”。这个环境和生产环境一样,但只做测试之用。关于自定义环境的详细说明,参阅 创建 Rails 环境

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/action_view_overview.html b/action_view_overview.html new file mode 100644 index 0000000..f5cb2b9 --- /dev/null +++ b/action_view_overview.html @@ -0,0 +1,1439 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Action View 概述

读完本文后,您将学到:

+
    +
  • Action View 是什么,如何在 Rails 中使用 Action View;

  • +
  • 模板、局部视图和布局的最佳使用方法;

  • +
  • Action View 提供了哪些辅助方法,如何自己编写辅助方法;

  • +
  • 如何使用本地化视图。

  • +
+

本文原文尚未完工!

1 Action View 是什么

在 Rails 中,Web 请求由 Action Controller(请参阅Action Controller 概览)和 Action View 处理。通常,Action Controller 参与和数据库的通信,并在需要时执行 CRUD 操作,然后由 Action View 负责编译响应。

Action View 模板使用混合了 HTML 标签的嵌入式 Ruby 语言编写。为了避免样板代码把模板弄乱,Action View 提供了许多辅助方法,用于创建表单、日期和字符串等常用组件。随着开发的深入,为应用添加新的辅助方法也很容易。

Action View 的某些特性与 Active Record 有关,但这并不意味着 Action View 依赖 Active Record。Action View 是独立的软件包,可以和任何类型的 Ruby 库一起使用。

2 在 Rails 中使用 Action View

app/views 文件夹中,每个控制器都有一个对应的文件夹,其中保存了控制器对应视图的模板文件。这些模板文件用于显示每个控制器动作产生的视图。

在 Rails 中使用脚手架生成器新建资源时,默认会执行下面的操作:

+
+$ bin/rails generate scaffold article
+      [...]
+      invoke  scaffold_controller
+      create    app/controllers/articles_controller.rb
+      invoke    erb
+      create      app/views/articles
+      create      app/views/articles/index.html.erb
+      create      app/views/articles/edit.html.erb
+      create      app/views/articles/show.html.erb
+      create      app/views/articles/new.html.erb
+      create      app/views/articles/_form.html.erb
+      [...]
+
+
+
+

在上面的输出结果中我们可以看到 Rails 中视图的命名约定。通常,视图和对应的控制器动作共享名称。例如,articles_controller.rb 控制器文件中的 index 动作对应 app/views/articles 文件夹中的 index.html.erb 视图文件。返回客户端的完整 HTML 由 ERB 视图文件和包装它的布局文件,以及视图可能引用的所有局部视图文件组成。后文会详细说明这三种文件。

3 模板、局部视图和布局

前面说过,最后输出的 HTML 由模板、局部视图和布局这三种 Rails 元素组成。下面分别进行简要介绍。

3.1 模板

Action View 模板可以用多种方式编写。扩展名是 .erb 的模板文件混合使用 ERB(嵌入式 Ruby)和 HTML 编写,扩展名是 .builder 的模板文件使用 Builder::XmlMarkup 库编写。

Rails 支持多种模板系统,并使用文件扩展名加以区分。例如,使用 ERB 模板系统的 HTML 文件的扩展名是 .html.erb

3.1.1 ERB 模板

在 ERB 模板中,可以使用 <% %><%= %> 标签来包含 Ruby 代码。<% %> 标签用于执行不返回任何内容的 Ruby 代码,例如条件、循环或块,而 <%= %> 标签用于输出 Ruby 代码的执行结果。

下面是一个循环输出名称的例子:

+
+<h1>Names of all the people</h1>
+<% @people.each do |person| %>
+  Name: <%= person.name %><br>
+<% end %>
+
+
+
+

在上面的代码中,使用普通嵌入标签(<% %>)建立循环,使用输出嵌入标签(<%= %>)插入名称。请注意,这种用法不仅仅是建议用法(而是必须这样使用),因为在 ERB 模板中,普通的输出方法,例如 printputs 方法,无法正常渲染。因此,下面的代码是错误的:

+
+<%# WRONG %>
+Hi, Mr. <% puts "Frodo" %>
+
+
+
+

要想删除前导和结尾空格,可以把 <% %> 标签替换为 <%- -%> 标签。

3.1.2 Builder 模板

和 ERB 模板相比,Builder 模板更加按部就班,常用于生成 XML 内容。在扩展名为 .builder 的模板中,可以直接使用名为 xml 的 XmlMarkup 对象。

下面是一些简单的例子:

+
+xml.em("emphasized")
+xml.em { xml.b("emph & bold") }
+xml.a("A Link", "href" => "http://rubyonrails.org/")
+xml.target("name" => "compile", "option" => "fast")
+
+
+
+

上面的代码会生成下面的 XML:

+
+<em>emphasized</em>
+<em><b>emph &amp; bold</b></em>
+<a href="http://rubyonrails.org/">A link</a>
+<target option="fast" name="compile" />
+
+
+
+

带有块的方法会作为 XML 标签处理,块中的内容会嵌入这个标签中。例如:

+
+xml.div {
+  xml.h1(@person.name)
+  xml.p(@person.bio)
+}
+
+
+
+

上面的代码会生成下面的 XML:

+
+<div>
+  <h1>David Heinemeier Hansson</h1>
+  <p>A product of Danish Design during the Winter of '79...</p>
+</div>
+
+
+
+

下面是 Basecamp 网站用于生成 RSS 的完整的实际代码:

+
+xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") 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)) if item_description(item)
+        xml.pubDate(item_pubDate(item))
+        xml.guid(@person.firm.account.url + @recent_items.url(http://github.com/item))
+        xml.link(@person.firm.account.url + @recent_items.url(http://github.com/item))
+        xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
+      end
+    end
+  end
+end
+
+
+
+
3.1.3 Jbuilder 模板系统

Jbuilder 是由 Rails 团队维护并默认包含在 Rails Gemfile 中的 gem。它类似 Builder,但用于生成 JSON,而不是 XML。

如果你的应用中没有 Jbuilder 这个 gem,可以把下面的代码添加到 Gemfile:

+
+gem 'jbuilder'
+
+
+
+

在扩展名为 .jbuilder 的模板中,可以直接使用名为 json 的 Jbuilder 对象。

下面是一个简单的例子:

+
+json.name("Alex")
+json.email("alex@example.com")
+
+
+
+

上面的代码会生成下面的 JSON:

+
+{
+  "name": "Alex",
+  "email": "alex@example.com"
+}
+
+
+
+

关于 Jbuilder 模板的更多例子和信息,请参阅 Jbuilder 文档

3.1.4 模板缓存

默认情况下,Rails 会把所有模板分别编译为方法,以便进行渲染。在开发环境中,当我们修改了模板时,Rails 会检查文件的修改时间并自动重新编译。

3.2 局部视图

局部视图模板,通常直接称为“局部视图”,作用是把渲染过程分成多个更容易管理的部分。局部视图从模板中提取代码片断并保存在独立的文件中,然后在模板中重用。

3.2.1 局部视图的名称

在视图中我们使用 render 方法来渲染局部视图:

+
+<%= render "menu" %>
+
+
+
+

在渲染视图的过程中,上面的代码会渲染 _menu.html.erb 局部视图文件。请注意开头的下划线:局部视图的文件名总是以下划线开头,以便和普通视图文件区分开来,但在引用局部视图时不写下划线。从其他文件夹中加载局部视图文件时同样遵守这一规则:

+
+<%= render "shared/menu" %>
+
+
+
+

上面的代码会加载 app/views/shared/_menu.html.erb 局部视图文件。

3.2.2 使用局部视图来简化视图

使用局部视图的一种方式是把它们看作子程序(subroutine),也就是把细节内容从视图中移出来,这样会使视图更容易理解。例如:

+
+<%= render "shared/ad_banner" %>
+
+<h1>Products</h1>
+
+<p>Here are a few of our fine products:</p>
+<% @products.each do |product| %>
+  <%= render partial: "product", locals: { product: product } %>
+<% end %>
+
+<%= render "shared/footer" %>
+
+
+
+

在上面的代码中,_ad_banner.html.erb_footer.html.erb 局部视图可以在多个页面中使用。当我们专注于实现某个页面时,不必关心这些局部视图的细节。

3.2.3 不使用 partiallocals 选项进行渲染

在前面的例子中,render 方法有两个选项:partiallocals。如果一共只有这两个选项,那么可以跳过不写。例如,下面的代码:

+
+<%= render partial: "product", locals: { product: @product } %>
+
+
+
+

可以改写为:

+
+<%= render "product", product: @product %>
+
+
+
+
3.2.4 asobject 选项

默认情况下,ActionView::Partials::PartialRenderer 的对象储存在和模板同名的局部变量中。因此,我们可以扩展下面的代码:

+
+<%= render partial: "product" %>
+
+
+
+

_product 局部视图中,我们可以通过局部变量 product 引用 @product 实例变量:

+
+<%= render partial: "product", locals: { product: @product } %>
+
+
+
+

as 选项用于为局部变量指定不同的名称。例如,把局部变量的名称由 product 改为 item

+
+<%= render partial: "product", as: "item" %>
+
+
+
+

object 选项用于直接指定想要在局部视图中使用的对象,常用于模板对象位于其他地方(例如位于其他实例变量或局部变量中)的情况。例如,下面的代码:

+
+<%= render partial: "product", locals: { product: @item } %>
+
+
+
+

可以改写为:

+
+<%= render partial: "product", object: @item %>
+
+
+
+

objectas 选项还可一起使用:

+
+<%= render partial: "product", object: @item, as: "item" %>
+
+
+
+
3.2.5 渲染集合

模板经常需要遍历集合并使用集合中的每个元素分别渲染子模板。在 Rails 中我们只需一行代码就可以完成这项工作。例如,下面这段渲染产品局部视图的代码:

+
+<% @products.each do |product| %>
+  <%= render partial: "product", locals: { product: product } %>
+<% end %>
+
+
+
+

可以改写为:

+
+<%= render partial: "product", collection: @products %>
+
+
+
+

当使用集合来渲染局部视图时,在每个局部视图实例中,都可以使用和局部视图同名的局部变量来访问集合中的元素。在本例中,局部视图是 _product,在这个局部视图中我们可以通过 product 局部变量来访问用于渲染局部视图的集合中的元素。

渲染集合还有一个简易写法。假设 @productsProduct 实例的集合,上面的代码可以改写为:

+
+<%= render @products %>
+
+
+
+

Rails 会根据集合中的模型名来确定应该使用哪个局部视图,在本例中模型名是 Product。实际上,我们甚至可以使用这种简易写法来渲染由不同模型实例组成的集合,Rails 会为集合中的每个元素选择适当的局部视图。

3.2.6 间隔模板

我们还可以使用 :spacer_template 选项来指定第二个局部视图(也就是间隔模板),在渲染第一个局部视图(也就是主局部视图)的两个实例之间会渲染这个间隔模板:

+
+<%= render partial: @products, spacer_template: "product_ruler" %>
+
+
+
+

上面的代码会在两个 _product 局部视图(主局部视图)之间渲染 _product_ruler 局部视图(间隔模板)。

3.3 布局

布局是渲染 Rails 控制器返回结果时使用的公共视图模板。通常,Rails 应用中会包含多个视图用于渲染不同页面。例如,网站中用户登录后页面的布局,营销或销售页面的布局。用户登录后页面的布局可以包含在多个控制器动作中出现的顶级导航。SaaS 应用的销售页面布局可以包含指向“定价”和“联系我们”页面的顶级导航。不同布局可以有不同的外观和感官。关于布局的更多介绍,请参阅Rails 布局和视图渲染

4 局部布局

应用于局部视图的布局称为局部布局。局部布局和应用于控制器动作的全局布局不一样,但两者的工作方式类似。

比如说我们想在页面中显示文章,并把文章放在 div 标签里。首先,我们新建一个 Article 实例:

+
+Article.create(body: 'Partial Layouts are cool!')
+
+
+
+

show 模板中,我们要在 box 布局中渲染 _article 局部视图:

articles/show.html.erb

+
+<%= render partial: 'article', layout: 'box', locals: { article: @article } %>
+
+
+
+

box 布局只是把 _article 局部视图放在 div 标签里:

articles/_box.html.erb

+
+<div class='box'>
+  <%= yield %>
+</div>
+
+
+
+

请注意,局部布局可以访问传递给 render 方法的局部变量 article。不过,和全局部局不同,局部布局的文件名以下划线开头。

我们还可以直接渲染代码块而不调用 yield 方法。例如,如果不使用 _article 局部视图,我们可以像下面这样编写代码:

articles/show.html.erb

+
+<% render(layout: 'box', locals: { article: @article }) do %>
+  <div>
+    <p><%= article.body %></p>
+  </div>
+<% end %>
+
+
+
+

假设我们使用的 _box 局部布局和前面一样,那么这里模板的渲染结果也会和前面一样。

5 视图路径

在渲染响应时,控制器需要解析不同视图所在的位置。默认情况下,控制器只查找 app/views 文件夹。

我们可以使用 prepend_view_pathappend_view_path 方法分别在查找路径的开头和结尾添加其他位置。

5.1 在开头添加视图路径

例如,当需要把视图放在子域名的不同文件夹中时,我们可以使用下面的代码:

+
+prepend_view_path "app/views/#{request.subdomain}"
+
+
+
+

这样在解析视图时,Action View 会首先查找这个文件夹。

5.2 在末尾添加视图路径

同样,我们可以在查找路径的末尾添加视图路径:

+
+append_view_path "app/views/direct"
+
+
+
+

上面的代码会在查找路径的末尾添加 app/views/direct 文件夹。

6 Action View 提供的辅助方法概述

本节内容仍在完善中,目前并没有列出所有辅助方法。关于辅助方法的完整列表,请参阅 API 文档

本节内容只是对 Action View 中可用辅助方法的简要概述。在阅读本节内容之后,推荐查看 API 文档,文档详细介绍了所有辅助方法。

6.1 AssetTagHelper 模块

AssetTagHelper 模块提供的方法用于生成链接静态资源文件的 HTML 代码,例如链接图像、JavaScript 文件和订阅源的 HTML 代码。

默认情况下,Rails 会链接当前主机 public 文件夹中的静态资源文件。要想链接专用的静态资源文件服务器上的文件,可以设置 Rails 应用配置文件(通常是 config/environments/production.rb 文件)中的 config.action_controller.asset_host 选项。假如静态资源文件服务器的域名是 assets.example.com,我们可以像下面这样设置:

+
+config.action_controller.asset_host = "assets.example.com"
+image_tag("rails.png") # => <img src="http://assets.example.com/images/rails.png" alt="Rails" />
+
+
+
+

auto_discovery_link_tag 方法用于返回链接标签,使浏览器和订阅阅读器可以自动检测 RSS 或 Atom 订阅源。

+
+auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", { title: "RSS Feed" })
+# => <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://www.example.com/feed.rss" />
+
+
+
+
6.1.2 image_path 方法

image_path 方法用于计算 app/assets/images 文件夹中图像资源的路径,得到的路径是从根目录开始的完整路径(也就是绝对路径)。image_tag 方法在内部使用 image_path 方法生成图像路径。

+
+image_path("edit.png") # => /assets/edit.png
+
+
+
+

config.assets.digest 选项设置为 true 时,Rails 会为图像资源的文件名添加指纹。

+
+image_path("edit.png") # => /assets/edit-2d1a2db63fc738690021fedb5a65b68e.png
+
+
+
+
6.1.3 image_url 方法

image_url 方法用于计算 app/assets/images 文件夹中图像资源的 URL 地址。image_url 方法在内部调用了 image_path 方法,并把得到的图像资源路径和当前主机或静态资源文件服务器的 URL 地址合并。

+
+image_url("http://github.com/edit.png") # => http://www.example.com/assets/edit.png
+
+
+
+
6.1.4 image_tag 方法

image_tag 方法用于返回 HTML 图像标签。此方法接受图像的完整路径或 app/assets/images 文件夹中图像的文件名作为参数。

+
+image_tag("icon.png") # => <img src="http://github.com/assets/icon.png" alt="Icon" />
+
+
+
+
6.1.5 javascript_include_tag 方法

javascript_include_tag 方法用于返回 HTML 脚本标签。此方法接受 app/assets/javascripts 文件夹中 JavaScript 文件的文件名(.js 后缀可以省略)或 JavaScript 文件的完整路径(绝对路径)作为参数。

+
+javascript_include_tag "common" # => <script src="http://github.com/assets/common.js"></script>
+
+
+
+

如果 Rails 应用不使用 Asset Pipeline,就需要向 javascript_include_tag 方法传递 :defaults 参数来包含 jQuery JavaScript 库。此时,如果 app/assets/javascripts 文件夹中存在 application.js 文件,那么这个文件也会包含到页面中。

+
+javascript_include_tag :defaults
+
+
+
+

通过向 javascript_include_tag 方法传递 :all 参数,可以把 app/assets/javascripts 文件夹下的所有 JavaScript 文件包含到页面中。

+
+javascript_include_tag :all
+
+
+
+

我们还可以把多个 JavaScript 文件缓存为一个文件,这样可以减少下载时的 HTTP 连接数,同时还可以启用 gzip 压缩来提高传输速度。当 ActionController::Base.perform_caching 选项设置为 true 时才会启用缓存,此选项在生产环境下默认为 true,在开发环境下默认为 false

+
+javascript_include_tag :all, cache: true
+# => <script src="http://github.com/javascripts/all.js"></script>
+
+
+
+
6.1.6 javascript_path 方法

javascript_path 方法用于计算 app/assets/javascripts 文件夹中 JavaScript 资源的路径。如果没有指定文件的扩展名,Rails 会自动添加 .jsjavascript_path 方法返回 JavaScript 资源的完整路径(绝对路径)。javascript_include_tag 方法在内部使用 javascript_path 方法生成脚本路径。

+
+javascript_path "common" # => /assets/common.js
+
+
+
+
6.1.7 javascript_url 方法

javascript_url 方法用于计算 app/assets/javascripts 文件夹中 JavaScript 资源的 URL 地址。javascript_url 方法在内部调用了 javascript_path 方法,并把得到的 JavaScript 资源的路径和当前主机或静态资源文件服务器的 URL 地址合并。

+
+javascript_url "common" # => http://www.example.com/assets/common.js
+
+
+
+

stylesheet_link_tag 方法用于返回样式表链接标签。如果没有指定文件的扩展名,Rails 会自动添加 .css

+
+stylesheet_link_tag "application"
+# => <link href="http://github.com/assets/application.css" media="screen" rel="stylesheet" />
+
+
+
+

通过向 stylesheet_link_tag 方法传递 :all 参数,可以把样式表文件夹中的所有样式表包含到页面中。

+
+stylesheet_link_tag :all
+
+
+
+

我们还可以把多个样式表缓存为一个文件,这样可以减少下载时的 HTTP 连接数,同时还可以启用 gzip 压缩来提高传输速度。当 ActionController::Base.perform_caching 选项设置为 true 时才会启用缓存,此选项在生产环境下默认为 true,在开发环境下默认为 false

+
+stylesheet_link_tag :all, cache: true
+# => <link href="http://github.com/assets/all.css" media="screen" rel="stylesheet" />
+
+
+
+
6.1.9 stylesheet_path 方法

stylesheet_path 方法用于计算 app/assets/stylesheets 文件夹中样式表资源的路径。如果没有指定文件的扩展名,Rails 会自动添加 .cssstylesheet_path 方法返回样式表资源的完整路径(绝对路径)。stylesheet_link_tag 方法在内部使用 stylesheet_path 方法生成样式表路径。

+
+stylesheet_path "application" # => /assets/application.css
+
+
+
+
6.1.10 stylesheet_url 方法

stylesheet_url 方法用于计算 app/assets/stylesheets 文件夹中样式表资源的 URL 地址。stylesheet_url 方法在内部调用了 stylesheet_path 方法,并把得到的样式表资源路径和当前主机或静态资源文件服务器的 URL 地址合并。

+
+stylesheet_url "application" # => http://www.example.com/assets/application.css
+
+
+
+

6.2 AtomFeedHelper 模块

6.2.1 atom_feed 方法

通过 atom_feed 辅助方法我们可以轻松创建 Atom 订阅源。下面是一个完整的示例:

config/routes.rb

+
+resources :articles
+
+
+
+

app/controllers/articles_controller.rb

+
+def index
+  @articles = Article.all
+
+  respond_to do |format|
+    format.html
+    format.atom
+  end
+end
+
+
+
+

app/views/articles/index.atom.builder

+
+atom_feed do |feed|
+  feed.title("Articles Index")
+  feed.updated(@articles.first.created_at)
+
+  @articles.each do |article|
+    feed.entry(article) do |entry|
+      entry.title(article.title)
+      entry.content(article.body, type: 'html')
+
+      entry.author do |author|
+        author.name(article.author_name)
+      end
+    end
+  end
+end
+
+
+
+

6.3 BenchmarkHelper 模块

6.3.1 benchmark 方法

benchmark 方法用于测量模板中某个块的执行时间,并把测量结果写入日志。benchmark 方法常用于测量耗时操作或可能的性能瓶颈的执行时间。

+
+<% benchmark "Process data files" do %>
+  <%= expensive_files_operation %>
+<% end %>
+
+
+
+

上面的代码会在日志中写入类似 Process data files (0.34523) 的测量结果,我们可以通过比较执行时间来优化代码。

6.4 CacheHelper 模块

6.4.1 cache 方法

cache 方法用于缓存视图片断而不是整个动作或页面。此方法常用于缓存页面中诸如菜单、新闻主题列表、静态 HTML 片断等内容。cache 方法接受块作为参数,块中包含要缓存的内容。关于 cache 方法的更多介绍,请参阅 AbstractController::Caching::Fragments 模块的文档。

+
+<% cache do %>
+  <%= render "shared/footer" %>
+<% end %>
+
+
+
+

6.5 CaptureHelper 模块

6.5.1 capture 方法

capture 方法用于取出模板的一部分并储存在变量中,然后我们可以在模板或布局中的任何地方使用这个变量。

+
+<% @greeting = capture do %>
+  <p>Welcome! The date and time is <%= Time.now %></p>
+<% end %>
+
+
+
+

可以在模板或布局中的任何地方使用 @greeting 变量。

+
+<html>
+  <head>
+    <title>Welcome!</title>
+  </head>
+  <body>
+    <%= @greeting %>
+  </body>
+</html>
+
+
+
+
6.5.2 content_for 方法

content_for 方法以块的方式把模板内容保存在标识符中,然后我们可以在模板或布局中把这个标识符传递给 yield 方法作为参数来调用所保存的内容。

假如应用拥有标准布局,同时拥有一个特殊页面,这个特殊页面需要包含其他页面都不需要的 JavaScript 脚本。为此我们可以在这个特殊页面中使用 content_for 方法来包含所需的 JavaScript 脚本,而不必增加其他页面的体积。

app/views/layouts/application.html.erb

+
+<html>
+  <head>
+    <title>Welcome!</title>
+    <%= yield :special_script %>
+  </head>
+  <body>
+    <p>Welcome! The date and time is <%= Time.now %></p>
+  </body>
+</html>
+
+
+
+

app/views/articles/special.html.erb

+
+<p>This is a special page.</p>
+
+<% content_for :special_script do %>
+  <script>alert('Hello!')</script>
+<% end %>
+
+
+
+

6.6 DateHelper 模块

6.6.1 date_select 方法

date_select 方法返回年、月、日的选择列表标签,用于设置 date 类型的属性的值。

+
+date_select("article", "published_on")
+
+
+
+
6.6.2 datetime_select 方法

datetime_select 方法返回年、月、日、时、分的选择列表标签,用于设置 datetime 类型的属性的值。

+
+datetime_select("article", "published_on")
+
+
+
+
6.6.3 distance_of_time_in_words 方法

distance_of_time_in_words 方法用于计算两个 Time 对象、Date 对象或秒数的大致时间间隔。把 include_seconds 选项设置为 true 可以得到更精确的时间间隔。

+
+distance_of_time_in_words(Time.now, Time.now + 15.seconds)        # => less than a minute
+distance_of_time_in_words(Time.now, Time.now + 15.seconds, include_seconds: true)  # => less than 20 seconds
+
+
+
+
6.6.4 select_date 方法

select_date 方法返回年、月、日的选择列表标签,并通过 Date 对象来设置默认值。

+
+# 生成一个日期选择列表,默认选中指定的日期(六天以后)
+select_date(Time.today + 6.days)
+
+# 生成一个日期选择列表,默认选中今天(未指定日期)
+select_date()
+
+
+
+
6.6.5 select_datetime 方法

select_datetime 方法返回年、月、日、时、分的选择列表标签,并通过 Datetime 对象来设置默认值。

+
+# 生成一个日期时间选择列表,默认选中指定的日期时间(四天以后)
+select_datetime(Time.now + 4.days)
+
+# 生成一个日期时间选择列表,默认选中今天(未指定日期时间)
+select_datetime()
+
+
+
+
6.6.6 select_day 方法

select_day 方法返回当月全部日子的选择列表标签,如 1 到 31,并把当日设置为默认值。

+
+# 生成一个日子选择列表,默认选中指定的日子
+select_day(Time.today + 2.days)
+
+# 生成一个日子选择列表,默认选中指定数字对应的日子
+select_day(5)
+
+
+
+
6.6.7 select_hour 方法

select_hour 方法返回一天中 24 小时的选择列表标签,即 0 到 23,并把当前小时设置为默认值。

+
+# 生成一个小时选择列表,默认选中指定的小时
+select_hour(Time.now + 6.hours)
+
+
+
+
6.6.8 select_minute 方法

select_minute 方法返回一小时中 60 分钟的选择列表标签,即 0 到 59,并把当前分钟设置为默认值。

+
+# 生成一个分钟选择列表,默认选中指定的分钟
+select_minute(Time.now + 10.minutes)
+
+
+
+
6.6.9 select_month 方法

select_month 方法返回一年中 12 个月的选择列表标签,并把当月设置为默认值。

+
+# 生成一个月份选择列表,默认选中当前月份
+select_month(Date.today)
+
+
+
+
6.6.10 select_second 方法

select_second 方法返回一分钟中 60 秒的选择列表标签,即 0 到 59,并把当前秒设置为默认值。

+
+# 生成一个秒数选择列表,默认选中指定的秒数
+select_second(Time.now + 16.seconds)
+
+
+
+
6.6.11 select_time 方法

select_time 方法返回时、分的选择列表标签,并通过 Time 对象来设置默认值。

+
+# 生成一个时间选择列表,默认选中指定的时间
+select_time(Time.now)
+
+
+
+
6.6.12 select_year 方法

select_year 方法返回当年和前后各五年的选择列表标签,并把当年设置为默认值。可以通过 :start_year:end_year 选项自定义年份范围。

+
+# 选择今天所在年份前后五年的年份选择列表,默认选中当年
+select_year(Date.today)
+
+# 选择一个从 1900 年到 20009 年的年份选择列表,默认选中当年
+select_year(Date.today, start_year: 1900, end_year: 2009)
+
+
+
+
6.6.13 time_ago_in_words 方法

time_ago_in_words 方法和 distance_of_time_in_words 方法类似,区别在于 time_ago_in_words 方法计算的是指定时间到 Time.now 对应的当前时间的时间间隔。

+
+time_ago_in_words(3.minutes.from_now)  # => 3 minutes
+
+
+
+
6.6.14 time_select 方法

time_select 方返回时、分、秒的选择列表标签(其中秒可选),用于设置 time 类型的属性的值。选择的结果作为多个参数赋值给 Active Record 对象。

+
+# 生成一个时间选择标签,通过 POST 发送后存储在提交的属性中的 order 变量中
+time_select("order", "submitted")
+
+
+
+

6.7 DebugHelper 模块

debug 方法返回放在 pre 标签里的 YAML 格式的对象内容。这种审查对象的方式可读性很好。

+
+my_hash = { 'first' => 1, 'second' => 'two', 'third' => [1,2,3] }
+debug(my_hash)
+
+
+
+
+
+<pre class='debug_dump'>---
+first: 1
+second: two
+third:
+- 1
+- 2
+- 3
+</pre>
+
+
+
+

6.8 FormHelper 模块

和仅使用标准 HTML 元素相比,表单辅助方法提供了一组基于模型创建表单的方法,可以大大简化模型的处理过程。表单辅助方法生成表单的 HTML 代码,并提供了用于生成各种输入组件(如文本框、密码框、选择列表等)的 HTML 代码的辅助方法。在提交表单时(用户点击提交按钮或通过 JavaScript 调用 form.submit),表单输入会绑定到 params 对象上并回传给控制器。

表单辅助方法分为两类:一类专门用于处理模型属性,另一类不处理模型属性。本节中介绍的辅助方法都属于前者,后者的例子可参阅 ActionView::Helpers::FormTagHelper 模块的文档。

form_for 辅助方法是 FormHelper 模块中最核心的方法,用于创建处理模型实例的表单。例如,假设我们想为 Person 模型创建实例:

+
+# 注意:要在控制器中创建 @person 变量(例如 @person = Person.new)
+<%= form_for @person, url: { action: "create" } do |f| %>
+  <%= f.text_field :first_name %>
+  <%= f.text_field :last_name %>
+  <%= submit_tag 'Create' %>
+<% end %>
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<form action="http://github.com/people/create" method="post">
+  <input id="person_first_name" name="person[first_name]" type="text" />
+  <input id="person_last_name" name="person[last_name]" type="text" />
+  <input name="commit" type="submit" value="Create" />
+</form>
+
+
+
+

提交表单时创建的 params 对象会像下面这样:

+
+{ "action" => "create", "controller" => "people", "person" => { "first_name" => "William", "last_name" => "Smith" } }
+
+
+
+

params 散列包含了嵌套的 person 值,这个值可以在控制器中通过 params[:person] 访问。

6.8.1 check_box 方法

check_box 方法返回用于处理指定模型属性的复选框标签。

+
+# 假设 @article.validated? 的值是 1
+check_box("article", "validated")
+# => <input type="checkbox" id="article_validated" name="article[validated]" value="1" />
+#    <input name="article[validated]" type="hidden" value="0" />
+
+
+
+
6.8.2 fields_for 方法

form_for 方法类似,fields_for 方法创建用于处理指定模型对象的作用域,区别在于 fields_for 方法不会创建 form 标签。fields_for 方法适用于在同一个表单中指明附加的模型对象。

+
+<%= form_for @person, url: { action: "update" } do |person_form| %>
+  First name: <%= person_form.text_field :first_name %>
+  Last name : <%= person_form.text_field :last_name %>
+
+  <%= fields_for @person.permission do |permission_fields| %>
+    Admin?  : <%= permission_fields.check_box :admin %>
+  <% end %>
+<% end %>
+
+
+
+
6.8.3 file_field 方法

file_field 方法返回用于处理指定模型属性的文件上传组件标签。

+
+file_field(:user, :avatar)
+# => <input type="file" id="user_avatar" name="user[avatar]" />
+
+
+
+
6.8.4 form_for 方法

form_for 方法创建用于处理指定模型对象的表单和作用域,表单的各个组件用于处理模型对象的对应属性。

+
+<%= form_for @article do |f| %>
+  <%= f.label :title, 'Title' %>:
+  <%= f.text_field :title %><br>
+  <%= f.label :body, 'Body' %>:
+  <%= f.text_area :body %><br>
+<% end %>
+
+
+
+
6.8.5 hidden_​​field 方法

hidden_​​field 方法返回用于处理指定模型属性的隐藏输入字段标签。

+
+hidden_field(:user, :token)
+# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
+
+
+
+
6.8.6 label 方法

label 方法返回用于处理指定模型属性的文本框的 label 标签。

+
+label(:article, :title)
+# => <label for="article_title">Title</label>
+
+
+
+
6.8.7 password_field 方法

password_field 方法返回用于处理指定模型属性的密码框标签。

+
+password_field(:login, :pass)
+# => <input type="text" id="login_pass" name="login[pass]" value="#{@login.pass}" />
+
+
+
+
6.8.8 radio_button 方法

radio_button 方法返回用于处理指定模型属性的单选按钮标签。

+
+# 假设 @article.category 的值是“rails”
+radio_button("article", "category", "rails")
+radio_button("article", "category", "java")
+# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
+#    <input type="radio" id="article_category_java" name="article[category]" value="java" />
+
+
+
+
6.8.9 text_area 方法

text_area 方法返回用于处理指定模型属性的文本区域标签。

+
+text_area(:comment, :text, size: "20x30")
+# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
+#      #{@comment.text}
+#    </textarea>
+
+
+
+
6.8.10 text_field 方法

text_field 方法返回用于处理指定模型属性的文本框标签。

+
+text_field(:article, :title)
+# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" />
+
+
+
+
6.8.11 email_field 方法

email_field 方法返回用于处理指定模型属性的电子邮件地址输入框标签。

+
+email_field(:user, :email)
+# => <input type="email" id="user_email" name="user[email]" value="#{@user.email}" />
+
+
+
+
6.8.12 url_field 方法

url_field 方法返回用于处理指定模型属性的 URL 地址输入框标签。

+
+url_field(:user, :url)
+# => <input type="url" id="user_url" name="user[url]" value="#{@user.url}" />
+
+
+
+

6.9 FormOptionsHelper 模块

FormOptionsHelper 模块提供了许多方法,用于把不同类型的容器转换为一组选项标签。

6.9.1 collection_select 方法

collection_select 方法返回一个集合的选择列表标签,其中每个集合元素的两个指定方法的返回值分别是每个选项的值和文本。

在下面的示例代码中,我们定义了两个模型:

+
+class Article < ApplicationRecord
+  belongs_to :author
+end
+
+class Author < ApplicationRecord
+  has_many :articles
+  def name_with_initial
+    "#{first_name.first}. #{last_name}"
+  end
+end
+
+
+
+

在下面的示例代码中,collection_select 方法用于生成 Article 模型的实例 @article 的相关作者的选择列表:

+
+collection_select(:article, :author_id, Author.all, :id, :name_with_initial, { prompt: true })
+
+
+
+

如果 @article.author_id 的值为 1,上面的代码会生成下面的 HTML:

+
+<select name="article[author_id]">
+  <option value="">Please select</option>
+  <option value="1" selected="selected">D. Heinemeier Hansson</option>
+  <option value="2">D. Thomas</option>
+  <option value="3">M. Clark</option>
+</select>
+
+
+
+
6.9.2 collection_radio_buttons 方法

collection_radio_buttons 方法返回一个集合的单选按钮标签,其中每个集合元素的两个指定方法的返回值分别是每个选项的值和文本。

在下面的示例代码中,我们定义了两个模型:

+
+class Article < ApplicationRecord
+  belongs_to :author
+end
+
+class Author < ApplicationRecord
+  has_many :articles
+  def name_with_initial
+    "#{first_name.first}. #{last_name}"
+  end
+end
+
+
+
+

在下面的示例代码中,collection_radio_buttons 方法用于生成 Article 模型的实例 @article 的相关作者的单选按钮:

+
+collection_radio_buttons(:article, :author_id, Author.all, :id, :name_with_initial)
+
+
+
+

如果 @article.author_id 的值为 1,上面的代码会生成下面的 HTML:

+
+<input id="article_author_id_1" name="article[author_id]" type="radio" value="1" checked="checked" />
+<label for="article_author_id_1">D. Heinemeier Hansson</label>
+<input id="article_author_id_2" name="article[author_id]" type="radio" value="2" />
+<label for="article_author_id_2">D. Thomas</label>
+<input id="article_author_id_3" name="article[author_id]" type="radio" value="3" />
+<label for="article_author_id_3">M. Clark</label>
+
+
+
+
6.9.3 collection_check_boxes 方法

collection_check_boxes 方法返回一个集合的复选框标签,其中每个集合元素的两个指定方法的返回值分别是每个选项的值和文本。

在下面的示例代码中,我们定义了两个模型:

+
+class Article < ApplicationRecord
+  has_and_belongs_to_many :authors
+end
+
+class Author < ApplicationRecord
+  has_and_belongs_to_many :articles
+  def name_with_initial
+    "#{first_name.first}. #{last_name}"
+  end
+end
+
+
+
+

在下面的示例代码中,collection_check_boxes 方法用于生成 Article 模型的实例 @article 的相关作者的复选框:

+
+collection_check_boxes(:article, :author_ids, Author.all, :id, :name_with_initial)
+
+
+
+

如果 @article.author_ids 的值为 [1],上面的代码会生成下面的 HTML:

+
+<input id="article_author_ids_1" name="article[author_ids][]" type="checkbox" value="1" checked="checked" />
+<label for="article_author_ids_1">D. Heinemeier Hansson</label>
+<input id="article_author_ids_2" name="article[author_ids][]" type="checkbox" value="2" />
+<label for="article_author_ids_2">D. Thomas</label>
+<input id="article_author_ids_3" name="article[author_ids][]" type="checkbox" value="3" />
+<label for="article_author_ids_3">M. Clark</label>
+<input name="article[author_ids][]" type="hidden" value="" />
+
+
+
+
6.9.4 option_groups_from_collection_for_select 方法

options_from_collection_for_select 方法类似,option_groups_from_collection_for_select 方法返回一组选项标签,区别在于使用 option_groups_from_collection_for_select 方法时这些选项会根据模型的关联关系用 optgroup 标签分组。

在下面的示例代码中,我们定义了两个模型:

+
+class Continent < ApplicationRecord
+  has_many :countries
+  # attribs: id, name
+end
+
+class Country < ApplicationRecord
+  belongs_to :continent
+  # attribs: id, name, continent_id
+end
+
+
+
+

示例用法:

+
+option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)
+
+
+
+

可能的输出结果:

+
+<optgroup label="Africa">
+  <option value="1">Egypt</option>
+  <option value="4">Rwanda</option>
+  ...
+</optgroup>
+<optgroup label="Asia">
+  <option value="3" selected="selected">China</option>
+  <option value="12">India</option>
+  <option value="5">Japan</option>
+  ...
+</optgroup>
+
+
+
+

注意:option_groups_from_collection_for_select 方法只返回 optgroupoption 标签,我们要把这些 optgroupoption 标签放在 select 标签里。

6.9.5 options_for_select 方法

options_for_select 方法接受容器(如散列、数组、可枚举对象、自定义类型)作为参数,返回一组选项标签。

+
+options_for_select([ "VISA", "MasterCard" ])
+# => <option>VISA</option> <option>MasterCard</option>
+
+
+
+

注意:options_for_select 方法只返回 option 标签,我们要把这些 option 标签放在 select 标签里。

6.9.6 options_from_collection_for_select 方法

options_from_collection_for_select 方法通过遍历集合返回一组选项标签,其中每个集合元素的 value_methodtext_method 方法的返回值分别是每个选项的值和文本。

+
+# options_from_collection_for_select(collection, value_method, text_method, selected = nil)
+
+
+
+

在下面的示例代码中,我们遍历 @project.people 集合得到 person 元素,person.idperson.name 方法分别是前面提到的 value_methodtext_method 方法,这两个方法分别返回选项的值和文本:

+
+options_from_collection_for_select(@project.people, "id", "name")
+# => <option value="#{person.id}">#{person.name}</option>
+
+
+
+

注意:options_from_collection_for_select 方法只返回 option 标签,我们要把这些 option 标签放在 select 标签里。

6.9.7 select 方法

select 方法使用指定对象和方法创建选择列表标签。

示例用法:

+
+select("article", "person_id", Person.all.collect { |p| [ p.name, p.id ] }, { include_blank: true })
+
+
+
+

如果 @article.persion_id 的值为 1,上面的代码会生成下面的 HTML:

+
+<select name="article[person_id]">
+  <option value=""></option>
+  <option value="1" selected="selected">David</option>
+  <option value="2">Eileen</option>
+  <option value="3">Rafael</option>
+</select>
+
+
+
+
6.9.8 time_zone_options_for_select 方法

time_zone_options_for_select 方法返回一组选项标签,其中每个选项对应一个时区,这些时区几乎包含了世界上所有的时区。

6.9.9 time_zone_select 方法

time_zone_select 方法返回时区的选择列表标签,其中选项标签是通过 time_zone_options_for_select 方法生成的。

+
+time_zone_select( "user", "time_zone")
+
+
+
+
6.9.10 date_field 方法

date_field 方法返回用于处理指定模型属性的日期输入框标签。

+
+date_field("user", "dob")
+
+
+
+

6.10 FormTagHelper 模块

FormTagHelper 模块提供了许多用于创建表单标签的方法。和 FormHelper 模块不同,FormTagHelper 模块提供的方法不依赖于传递给模板的 Active Record 对象。作为替代,我们可以手动为表单的各个组件的标签提供 namevalue 属性。

6.10.1 check_box_tag 方法

check_box_tag 方法用于创建复选框标签。

+
+check_box_tag 'accept'
+# => <input id="accept" name="accept" type="checkbox" value="1" />
+
+
+
+
6.10.2 field_set_tag 方法

field_set_tag 方法用于创建 fieldset 标签。

+
+<%= field_set_tag do %>
+  <p><%= text_field_tag 'name' %></p>
+<% end %>
+# => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>
+
+
+
+
6.10.3 file_field_tag 方法

file_field_tag 方法用于创建文件上传组件标签。

+
+<%= form_tag({ action: "post" }, multipart: true) do %>
+  <label for="file">File to Upload</label> <%= file_field_tag "file" %>
+  <%= submit_tag %>
+<% end %>
+
+
+
+

示例输出:

+
+file_field_tag 'attachment'
+# => <input id="attachment" name="attachment" type="file" />
+
+
+
+
6.10.4 form_tag 方法

form_tag 方法用于创建表单标签。和 ActionController::Base#url_for 方法类似,form_tag 方法的第一个参数是 url_for_options 选项,用于说明提交表单的 URL。

+
+<%= form_tag '/articles' do %>
+  <div><%= submit_tag 'Save' %></div>
+<% end %>
+# => <form action="http://github.com/articles" method="post"><div><input type="submit" name="submit" value="Save" /></div></form>
+
+
+
+
6.10.5 hidden_​​field_tag 方法

hidden_​​field_tag 方法用于创建隐藏输入字段标签。隐藏输入字段用于传递因 HTTP 无状态特性而丢失的数据,或不想让用户看到的数据。

+
+hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
+# => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />
+
+
+
+
6.10.6 image_submit_tag 方法

image_submit_tag 方法会显示一张图像,点击这张图像会提交表单。

+
+image_submit_tag("login.png")
+# => <input src="http://github.com/images/login.png" type="image" />
+
+
+
+
6.10.7 label_tag 方法

label_tag 方法用于创建 label 标签。

+
+label_tag 'name'
+# => <label for="name">Name</label>
+
+
+
+
6.10.8 password_field_tag 方法

password_field_tag 方法用于创建密码框标签。用户在密码框中输入的密码会被隐藏起来。

+
+password_field_tag 'pass'
+# => <input id="pass" name="pass" type="password" />
+
+
+
+
6.10.9 radio_button_tag 方法

radio_button_tag 方法用于创建单选按钮标签。为一组单选按钮设置相同的 name 属性即可实现对一组选项进行单选。

+
+radio_button_tag 'gender', 'male'
+# => <input id="gender_male" name="gender" type="radio" value="male" />
+
+
+
+
6.10.10 select_tag 方法

select_tag 方法用于创建选择列表标签。

+
+select_tag "people", "<option>David</option>"
+# => <select id="people" name="people"><option>David</option></select>
+
+
+
+
6.10.11 submit_tag 方法

submit_tag 方法用于创建提交按钮标签,并在按钮上显示指定的文本。

+
+submit_tag "Publish this article"
+# => <input name="commit" type="submit" value="Publish this article" />
+
+
+
+
6.10.12 text_area_tag 方法

text_area_tag 方法用于创建文本区域标签。文本区域用于输入较长的文本,如博客帖子或页面描述。

+
+text_area_tag 'article'
+# => <textarea id="article" name="article"></textarea>
+
+
+
+
6.10.13 text_field_tag 方法

text_field_tag 方法用于创建文本框标签。文本框用于输入较短的文本,如用户名或搜索关键词。

+
+text_field_tag 'name'
+# => <input id="name" name="name" type="text" />
+
+
+
+
6.10.14 email_field_tag 方法

email_field_tag 方法用于创建电子邮件地址输入框标签。

+
+email_field_tag 'email'
+# => <input id="email" name="email" type="email" />
+
+
+
+
6.10.15 url_field_tag 方法

url_field_tag 方法用于创建 URL 地址输入框标签。

+
+url_field_tag 'url'
+# => <input id="url" name="url" type="url" />
+
+
+
+
6.10.16 date_field_tag 方法

date_field_tag 方法用于创建日期输入框标签。

+
+date_field_tag "dob"
+# => <input id="dob" name="dob" type="date" />
+
+
+
+

6.11 JavaScriptHelper 模块

JavaScriptHelper 模块提供在视图中使用 JavaScript 的相关方法。

6.11.1 escape_javascript 方法

escape_javascript 方法转义 JavaScript 代码中的回车符、单引号和双引号。

6.11.2 javascript_tag 方法

javascript_tag 方法返回放在 script 标签里的 JavaScript 代码。

+
+javascript_tag "alert('All is good')"
+
+
+
+
+
+<script>
+//<![CDATA[
+alert('All is good')
+//]]>
+</script>
+
+
+
+

6.12 NumberHelper 模块

NumberHelper 模块提供把数字转换为格式化字符串的方法,包括把数字转换为电话号码、货币、百分数、具有指定精度的数字、带有千位分隔符的数字和文件大小的方法。

6.12.1 number_to_currency 方法

number_to_currency 方法用于把数字转换为货币字符串(例如 $13.65)。

+
+number_to_currency(1234567890.50) # => $1,234,567,890.50
+
+
+
+
6.12.2 number_to_human_size 方法

number_to_human_size 方法用于把数字转换为容易阅读的形式,常用于显示文件大小。

+
+number_to_human_size(1234)          # => 1.2 KB
+number_to_human_size(1234567)       # => 1.2 MB
+
+
+
+
6.12.3 number_to_percentage 方法

number_to_percentage 方法用于把数字转换为百分数字符串。

+
+number_to_percentage(100, precision: 0)        # => 100%
+
+
+
+
6.12.4 number_to_phone 方法

number_to_phone 方法用于把数字转换为电话号码(默认为美国)。

+
+number_to_phone(1235551234) # => 123-555-1234
+
+
+
+
6.12.5 number_with_delimiter 方法

number_with_delimiter 方法用于把数字转换为带有千位分隔符的数字。

+
+number_with_delimiter(12345678) # => 12,345,678
+
+
+
+
6.12.6 number_with_precision 方法

number_with_precision 方法用于把数字转换为具有指定精度的数字,默认精度为 3。

+
+number_with_precision(111.2345)     # => 111.235
+number_with_precision(111.2345, 2)  # => 111.23
+
+
+
+

6.13 SanitizeHelper 模块

SanitizeHelper 模块提供从文本中清除不需要的 HTML 元素的方法。

6.13.1 sanitize 方法

sanitize 方法会对所有标签进行 HTML 编码,并清除所有未明确允许的属性。

+
+sanitize @article.body
+
+
+
+

如果指定了 :attributes:tags 选项,那么只有指定的属性或标签才不会被清除。

+
+sanitize @article.body, tags: %w(table tr td), attributes: %w(id class style)
+
+
+
+

要想修改 sanitize 方法的默认选项,例如把表格标签设置为允许的属性,可以按下面的方式设置:

+
+class Application < Rails::Application
+  config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
+end
+
+
+
+
6.13.2 sanitize_css(style) 方法

sanitize_css(style) 方法用于净化 CSS 代码。

6.13.3 strip_links(html) 方法

strip_links(html) 方法用于清除文本中所有的链接标签,只保留链接文本。

+
+strip_links('<a href="http://rubyonrails.org/">Ruby on Rails</a>')
+# => Ruby on Rails
+
+
+
+
+
+strip_links('emails to <a href="/service/mailto:me@email.com">me@email.com</a>.')
+# => emails to me@email.com.
+
+
+
+
+
+strip_links('Blog: <a href="http://myblog.com/">Visit</a>.')
+# => Blog: Visit.
+
+
+
+
6.13.4 strip_tags(html) 方法

strip_tags(html) 方法用于清除包括注释在内的所有 HTML 标签。此方法使用 html-scanner 解析 HTML,因此其 HTML 解析能力受到 html-scanner 的限制。

+
+strip_tags("Strip <i>these</i> tags!")
+# => Strip these tags!
+
+
+
+
+
+strip_tags("<b>Bold</b> no more!  <a href='http://github.com/more.html'>See more</a>")
+# => Bold no more!  See more
+
+
+
+

注意:使用 strip_tags(html) 方法清除后的文本仍然可能包含 <、> 和 & 字符,从而导致浏览器显示异常。

6.14 CsrfHelper 模块

csrf_meta_tags 方法用于生成 csrf-paramcsrf-token 这两个元标签,它们分别是跨站请求伪造保护的参数和令牌。

+
+<%= csrf_meta_tags %>
+
+
+
+

普通表单生成隐藏字段,因此不使用这些标签。关于这个问题的更多介绍,请参阅 Ruby on Rails 安全指南

7 本地化视图

Action View 可以根据当前的本地化设置渲染不同的模板。

假如 ArticlesController 控制器中有 show 动作。默认情况下,调用 show 动作会渲染 app/views/articles/show.html.erb 模板。如果我们设置了 I18n.locale = :de,那么调用 show 动作会渲染 app/views/articles/show.de.html.erb 模板。如果对应的本地化模板不存在,就会使用对应的默认模板。这意味着我们不需要为所有情况提供本地化视图,但如果本地化视图可用就会优先使用。

我们可以使用相同的技术来本地化公共目录中的错误文件。例如,通过设置 I18n.locale = :de 并创建 public/500.de.htmlpublic/404.de.html 文件,我们就拥有了本地化的错误文件。

由于 Rails 不会限制用于设置 I18n.locale 的符号,我们可以利用本地化视图根据我们喜欢的任何东西来显示不同的内容。例如,假设专家用户应该看到和普通用户不同的页面,我们可以在 app/controllers/application.rb 配置文件中进行如下设置:

+
+before_action :set_expert_locale
+
+def set_expert_locale
+  I18n.locale = :expert if current_user.expert?
+end
+
+
+
+

然后创建 app/views/articles/show.expert.html.erb 这样的显示给专家用户看的特殊视图。

关于 Rails 国际化的更多介绍,请参阅Rails 国际化 API

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_job_basics.html b/active_job_basics.html new file mode 100644 index 0000000..a1d50f6 --- /dev/null +++ b/active_job_basics.html @@ -0,0 +1,535 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Job 基础

本文全面说明创建、入队和执行后台作业的基础知识。

读完本文后,您将学到:

+
    +
  • 如何创建作业;

  • +
  • 如何入队作业;

  • +
  • 如何在后台运行作业;

  • +
  • 如何在应用中异步发送电子邮件。

  • +
+

1 简介

Active Job 框架负责声明作业,在各种队列后端中运行。作业各种各样,可以是定期清理、账单支付和寄信。其实,任何可以分解且并行运行的工作都可以。

2 Active Job 的作用

主要作用是确保所有 Rails 应用都有作业基础设施。这样便可以在此基础上构建各种功能和其他 gem,而无需担心不同作业运行程序(如 Delayed Job 和 Resque)的 API 之间的差异。此外,选用哪个队列后端只是战术问题。而且,切换队列后端也不用重写作业。

Rails 默认实现了立即运行的队列运行程序。因此,队列中的各个作业会立即运行。

3 创建作业

本节逐步说明创建和入队作业的过程。

3.1 创建作业

Active Job 提供了一个 Rails 生成器,用于创建作业。下述命令在 app/jobs 目录中创建一个作业(还在 test/jobs 目录中创建相关的测试用例):

+
+$ bin/rails generate job guests_cleanup
+invoke  test_unit
+create    test/jobs/guests_cleanup_job_test.rb
+create  app/jobs/guests_cleanup_job.rb
+
+
+
+

还可以创建在指定队列中运行的作业:

+
+$ bin/rails generate job guests_cleanup --queue urgent
+
+
+
+

如果不想使用生成器,可以自己动手在 app/jobs 目录中新建文件,不过要确保继承自 ApplicationJob

看一下作业:

+
+class GuestsCleanupJob < ApplicationJob
+  queue_as :default
+
+  def perform(*guests)
+    # 稍后做些事情
+  end
+end
+
+
+
+

注意,perform 方法的参数是任意个。

3.2 入队作业

像下面这样入队作业:

+
+# 入队作业,作业在队列系统空闲时立即执行
+GuestsCleanupJob.perform_later guest
+
+
+
+
+
+# 入队作业,在明天中午执行
+GuestsCleanupJob.set(wait_until: Date.tomorrow.noon).perform_later(guest)
+
+
+
+
+
+# 入队作业,在一周以后执行
+GuestsCleanupJob.set(wait: 1.week).perform_later(guest)
+
+
+
+
+
+# `perform_now` 和 `perform_later` 会在幕后调用 `perform`
+# 因此可以传入任意个参数
+GuestsCleanupJob.perform_later(guest1, guest2, filter: 'some_filter')
+
+
+
+

就这么简单!

4 执行作业

在生产环境中入队和执行作业需要使用队列后端,即要为 Rails 提供一个第三方队列库。Rails 本身只提供了一个进程内队列系统,把作业存储在 RAM 中。如果进程崩溃,或者设备重启了,默认的异步后端会丢失所有作业。这对小型应用或不重要的作业来说没什么,但是生产环境中的多数应用应该挑选一个持久后端。

4.1 后端

Active Job 为多种队列后端(Sidekiq、Resque、Delayed Job,等等)内置了适配器。最新的适配器列表参见 ActiveJob::QueueAdapters 的 API 文档

4.2 设置后端

队列后端易于设置:

+
+# config/application.rb
+module YourApp
+  class Application < Rails::Application
+    # 要把适配器的 gem 写入 Gemfile
+    # 请参照适配器的具体安装和部署说明
+    config.active_job.queue_adapter = :sidekiq
+  end
+end
+
+
+
+

也可以在各个作业中配置后端:

+
+class GuestsCleanupJob < ApplicationJob
+  self.queue_adapter = :resque
+  #....
+end
+
+# 现在,这个作业使用 `resque` 作为后端队列适配器
+# 把 `config.active_job.queue_adapter` 配置覆盖了
+
+
+
+

4.3 启动后端

Rails 应用中的作业并行运行,因此多数队列库要求为自己启动专用的队列服务(与启动 Rails 应用的服务不同)。启动队列后端的说明参见各个库的文档。

下面列出部分文档:

+ +

5 队列

多数适配器支持多个队列。Active Job 允许把作业调度到具体的队列中:

+
+class GuestsCleanupJob < ApplicationJob
+  queue_as :low_priority
+  #....
+end
+
+
+
+

队列名称可以使用 application.rb 文件中的 config.active_job.queue_name_prefix 选项配置前缀:

+
+# config/application.rb
+module YourApp
+  class Application < Rails::Application
+    config.active_job.queue_name_prefix = Rails.env
+  end
+end
+
+# app/jobs/guests_cleanup_job.rb
+class GuestsCleanupJob < ApplicationJob
+  queue_as :low_priority
+  #....
+end
+
+# 在生产环境中,作业在 production_low_priority 队列中运行
+# 在交付准备环境中,作业在 staging_low_priority 队列中运行
+
+
+
+

默认的队列名称前缀分隔符是 '_'。这个值可以使用 application.rb 文件中的 config.active_job.queue_name_delimiter 选项修改:

+
+# config/application.rb
+module YourApp
+  class Application < Rails::Application
+    config.active_job.queue_name_prefix = Rails.env
+    config.active_job.queue_name_delimiter = '.'
+  end
+end
+
+# app/jobs/guests_cleanup_job.rb
+class GuestsCleanupJob < ApplicationJob
+  queue_as :low_priority
+  #....
+end
+
+# 在生产环境中,作业在 production.low_priority 队列中运行
+# 在交付准备环境中,作业在 staging.low_priority 队列中运行
+
+
+
+

如果想更进一步控制作业在哪个队列中运行,可以把 :queue 选项传给 #set 方法:

+
+MyJob.set(queue: :another_queue).perform_later(record)
+
+
+
+

如果想在作业层控制队列,可以把一个块传给 #queue_as 方法。那个块在作业的上下文中执行(因此可以访问 self.arguments),必须返回队列的名称:

+
+class ProcessVideoJob < ApplicationJob
+  queue_as do
+    video = self.arguments.first
+    if video.owner.premium?
+      :premium_videojobs
+    else
+      :videojobs
+    end
+  end
+
+  def perform(video)
+    # 处理视频
+  end
+end
+
+ProcessVideoJob.perform_later(Video.last)
+
+
+
+

确保队列后端“监听”着队列名称。某些后端要求指定要监听的队列。

6 回调

Active Job 在作业的生命周期内提供了多个钩子。回调用于在作业的生命周期内触发逻辑。

6.1 可用的回调

+
    +
  • before_enqueue

  • +
  • around_enqueue

  • +
  • after_enqueue

  • +
  • before_perform

  • +
  • around_perform

  • +
  • after_perform

  • +
+

6.2 用法

+
+class GuestsCleanupJob < ApplicationJob
+  queue_as :default
+
+  before_enqueue do |job|
+    # 对作业实例做些事情
+  end
+
+  around_perform do |job, block|
+    # 在执行之前做些事情
+    block.call
+    # 在执行之后做些事情
+  end
+
+  def perform
+    # 稍后做些事情
+  end
+end
+
+
+
+

7 Action Mailer

对现代的 Web 应用来说,最常见的作业是在请求-响应循环之外发送电子邮件,这样用户无需等待。Active Job 与 Action Mailer 是集成的,因此可以轻易异步发送电子邮件:

+
+# 如需想现在发送电子邮件,使用 #deliver_now
+UserMailer.welcome(@user).deliver_now
+
+# 如果想通过 Active Job 发送电子邮件,使用 #deliver_later
+UserMailer.welcome(@user).deliver_later
+
+
+
+

8 国际化

创建作业时,使用 I18n.locale 设置。如果异步发送电子邮件,可能用得到:

+
+I18n.locale = :eo
+
+UserMailer.welcome(@user).deliver_later # 使用世界语本地化电子邮件
+
+
+
+

9 GlobalID

Active Job 支持参数使用 GlobalID。这样便可以把 Active Record 对象传给作业,而不用传递类和 ID,再自己反序列化。以前,要这么定义作业:

+
+class TrashableCleanupJob < ApplicationJob
+  def perform(trashable_class, trashable_id, depth)
+    trashable = trashable_class.constantize.find(trashable_id)
+    trashable.cleanup(depth)
+  end
+end
+
+
+
+

现在可以简化成这样:

+
+class TrashableCleanupJob < ApplicationJob
+  def perform(trashable, depth)
+    trashable.cleanup(depth)
+  end
+end
+
+
+
+

为此,模型类要混入 GlobalID::Identification。Active Record 模型类默认都混入了。

10 异常

Active Job 允许捕获执行作业过程中抛出的异常:

+
+class GuestsCleanupJob < ApplicationJob
+  queue_as :default
+
+  rescue_from(ActiveRecord::RecordNotFound) do |exception|
+   # 处理异常
+  end
+
+  def perform
+    # 稍后做些事情
+  end
+end
+
+
+
+

10.1 反序列化

有了 GlobalID,可以序列化传给 #perform 方法的整个 Active Record 对象。

如果在作业入队之后、调用 #perform 方法之前删除了传入的记录,Active Job 会抛出 ActiveJob::DeserializationError 异常。

11 测试作业

测试作业的详细说明参见 测试指南

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_model_basics.html b/active_model_basics.html new file mode 100644 index 0000000..7233281 --- /dev/null +++ b/active_model_basics.html @@ -0,0 +1,678 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Model 基础

本文简述模型类。Active Model 允许使用 Action Pack 辅助方法与普通的 Ruby 类交互。Active Model 还协助构建自定义的 ORM,可在 Rails 框架外部使用。

读完本文后,您将学到:

+
    +
  • Active Record 模型的行为;

  • +
  • 回调和数据验证的工作方式;

  • +
  • 序列化程序的工作方式;

  • +
  • Active Model 与 Rails 国际化(i18n)框架的集成。

  • +
+

本文原文尚未完工!

1 简介

Active Model 库包含很多模块,用于开发要在 Active Record 中存储的类。下面说明其中部分模块。

1.1 属性方法

ActiveModel::AttributeMethods 模块可以为类中的方法添加自定义的前缀和后缀。它用于定义前缀和后缀,对象中的方法将使用它们。

+
+class Person
+  include ActiveModel::AttributeMethods
+
+  attribute_method_prefix 'reset_'
+  attribute_method_suffix '_highest?'
+  define_attribute_methods 'age'
+
+  attr_accessor :age
+
+  private
+    def reset_attribute(attribute)
+      send("#{attribute}=", 0)
+    end
+
+    def attribute_highest?(attribute)
+      send(attribute) > 100
+    end
+end
+
+person = Person.new
+person.age = 110
+person.age_highest?  # => true
+person.reset_age     # => 0
+person.age_highest?  # => false
+
+
+
+

1.2 回调

ActiveModel::Callbacks 模块为 Active Record 提供回调,在某个时刻运行。定义回调之后,可以使用前置、后置和环绕方法包装。

+
+class Person
+  extend ActiveModel::Callbacks
+
+  define_model_callbacks :update
+
+  before_update :reset_me
+
+  def update
+    run_callbacks(:update) do
+      # 在对象上调用 update 时执行这个方法
+    end
+  end
+
+  def reset_me
+    # 在对象上调用 update 方法时执行这个方法
+    # 因为把它定义为 before_update 回调了
+  end
+end
+
+
+
+

1.3 转换

如果一个类定义了 persisted?id 方法,可以在那个类中引入 ActiveModel::Conversion 模块,这样便能在类的对象上调用 Rails 提供的转换方法。

+
+class Person
+  include ActiveModel::Conversion
+
+  def persisted?
+    false
+  end
+
+  def id
+    nil
+  end
+end
+
+person = Person.new
+person.to_model == person  # => true
+person.to_key              # => nil
+person.to_param            # => nil
+
+
+
+

1.4 弄脏

如果修改了对象的一个或多个属性,但是没有保存,此时就把对象弄脏了。ActiveModel::Dirty 模块提供检查对象是否被修改的功能。它还提供了基于属性的存取方法。假如有个 Person 类,它有两个属性,first_namelast_name

+
+class Person
+  include ActiveModel::Dirty
+  define_attribute_methods :first_name, :last_name
+
+  def first_name
+    @first_name
+  end
+
+  def first_name=(value)
+    first_name_will_change!
+    @first_name = value
+  end
+
+  def last_name
+    @last_name
+  end
+
+  def last_name=(value)
+    last_name_will_change!
+    @last_name = value
+  end
+
+  def save
+    # 执行保存操作……
+    changes_applied
+  end
+end
+
+
+
+
1.4.1 直接查询对象,获取所有被修改的属性列表
+
+person = Person.new
+person.changed? # => false
+
+person.first_name = "First Name"
+person.first_name # => "First Name"
+
+# 如果修改属性后未保存,返回 true,否则返回 false
+person.changed? # => true
+
+# 返回修改之后没有保存的属性列表
+person.changed # => ["first_name"]
+
+# 返回一个属性散列,指明原来的值
+person.changed_attributes # => {"first_name"=>nil}
+
+# 返回一个散列,键为修改的属性名,值是一个数组,包含旧值和新值
+person.changes # => {"first_name"=>[nil, "First Name"]}
+
+
+
+
1.4.2 基于属性的存取方法

判断具体的属性是否被修改了:

+
+# attr_name_changed?
+person.first_name # => "First Name"
+person.first_name_changed? # => true
+
+
+
+

查看属性之前的值:

+
+person.first_name_was # => nil
+
+
+
+

查看属性修改前后的值。如果修改了,返回一个数组,否则返回 nil

+
+person.first_name_change # => [nil, "First Name"]
+person.last_name_change # => nil
+
+
+
+

1.5 数据验证

ActiveModel::Validations 模块提供数据验证功能,这与 Active Record 中的类似。

+
+class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name, :email, :token
+
+  validates :name, presence: true
+  validates_format_of :email, with: /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i
+  validates! :token, presence: true
+end
+
+person = Person.new
+person.token = "2b1f325"
+person.valid?                        # => false
+person.name = 'vishnu'
+person.email = 'me'
+person.valid?                        # => false
+person.email = 'me@vishnuatrai.com'
+person.valid?                        # => true
+person.token = nil
+person.valid?                        # => raises ActiveModel::StrictValidationFailed
+
+
+
+

1.6 命名

ActiveModel::Naming 添加一些类方法,便于管理命名和路由。这个模块定义了 model_name 类方法,它使用 ActiveSupport::Inflector 中的一些方法定义一些存取方法。

+
+class Person
+  extend ActiveModel::Naming
+end
+
+Person.model_name.name                # => "Person"
+Person.model_name.singular            # => "person"
+Person.model_name.plural              # => "people"
+Person.model_name.element             # => "person"
+Person.model_name.human               # => "Person"
+Person.model_name.collection          # => "people"
+Person.model_name.param_key           # => "person"
+Person.model_name.i18n_key            # => :person
+Person.model_name.route_key           # => "people"
+Person.model_name.singular_route_key  # => "person"
+
+
+
+

1.7 模型

ActiveModel::Model 模块能让一个类立即能与 Action Pack 和 Action View 集成。

+
+class EmailContact
+  include ActiveModel::Model
+
+  attr_accessor :name, :email, :message
+  validates :name, :email, :message, presence: true
+
+  def deliver
+    if valid?
+      # 发送电子邮件
+    end
+  end
+end
+
+
+
+

引入 ActiveModel::Model 后,将获得以下功能:

+
    +
  • 模型名称内省

  • +
  • 转换

  • +
  • 翻译

  • +
  • 数据验证

  • +
+

还能像 Active Record 对象那样使用散列指定属性,初始化对象。

+
+email_contact = EmailContact.new(name: 'David',
+                                 email: 'david@example.com',
+                                 message: 'Hello World')
+email_contact.name       # => 'David'
+email_contact.email      # => 'david@example.com'
+email_contact.valid?     # => true
+email_contact.persisted? # => false
+
+
+
+

只要一个类引入了 ActiveModel::Model,它就能像 Active Record 对象那样使用 form_forrender 和任何 Action View 辅助方法。

1.8 序列化

ActiveModel::Serialization 模块为对象提供基本的序列化支持。你要定义一个属性散列,包含想序列化的属性。属性名必须使用字符串,不能使用符号。

+
+class Person
+  include ActiveModel::Serialization
+
+  attr_accessor :name
+
+  def attributes
+    {'name' => nil}
+  end
+end
+
+
+
+

这样就可以使用 serializable_hash 方法访问对象的序列化散列:

+
+person = Person.new
+person.serializable_hash   # => {"name"=>nil}
+person.name = "Bob"
+person.serializable_hash   # => {"name"=>"Bob"}
+
+
+
+
1.8.1 ActiveModel::Serializers +

Rails 提供了 ActiveModel::Serializers::JSON 序列化程序。这个模块自动引入 ActiveModel::Serialization

1.8.1.1 ActiveModel::Serializers::JSON +

若想使用 ActiveModel::Serializers::JSON,只需把 ActiveModel::Serialization 换成 ActiveModel::Serializers::JSON

+
+class Person
+  include ActiveModel::Serializers::JSON
+
+  attr_accessor :name
+
+  def attributes
+    {'name' => nil}
+  end
+end
+
+
+
+

调用 as_json 方法即可访问模型的散列表示形式。

+
+person = Person.new
+person.as_json # => {"name"=>nil}
+person.name = "Bob"
+person.as_json # => {"name"=>"Bob"}
+
+
+
+

若想使用 JSON 字符串定义模型的属性,要在类中定义 attributes= 方法:

+
+class Person
+  include ActiveModel::Serializers::JSON
+
+  attr_accessor :name
+
+  def attributes=(hash)
+    hash.each do |key, value|
+      send("#{key}=", value)
+    end
+  end
+
+  def attributes
+    {'name' => nil}
+  end
+end
+
+
+
+

现在,可以使用 from_json 方法创建 Person 实例,并且设定属性:

+
+json = { name: 'Bob' }.to_json
+person = Person.new
+person.from_json(json) # => #<Person:0x00000100c773f0 @name="Bob">
+person.name            # => "Bob"
+
+
+
+

1.9 翻译

ActiveModel::Translation 模块把对象与 Rails 国际化(i18n)框架集成起来。

+
+class Person
+  extend ActiveModel::Translation
+end
+
+
+
+

使用 human_attribute_name 方法可以把属性名称变成对人类友好的格式。对人类友好的格式在本地化文件中定义。

+
    +
  • +

    config/locales/app.pt-BR.yml

    +
    +
    +pt-BR:
    +  activemodel:
    +    attributes:
    +      person:
    +        name: 'Nome'
    +
    +
    +
    +
  • +
+
+
+Person.human_attribute_name('name') # => "Nome"
+
+
+
+

1.10 lint 测试

ActiveModel::Lint::Tests 模块测试对象是否符合 Active Model API。

+
    +
  • +

    app/models/person.rb

    +
    +
    +class Person
    +  include ActiveModel::Model
    +end
    +
    +
    +
    +
  • +
  • +

    test/models/person_test.rb

    +
    +
    +require 'test_helper'
    +
    +class PersonTest < ActiveSupport::TestCase
    +  include ActiveModel::Lint::Tests
    +
    +  setup do
    +    @model = Person.new
    +  end
    +end
    +
    +
    +
    +
  • +
+
+
+$ rails test
+
+Run options: --seed 14596
+
+# Running:
+
+......
+
+Finished in 0.024899s, 240.9735 runs/s, 1204.8677 assertions/s.
+
+6 runs, 30 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

为了使用 Action Pack,对象无需实现所有 API。这个模块只是提供一种指导,以防你需要全部功能。

1.11 安全密码

ActiveModel::SecurePassword 提供安全加密密码的功能。这个模块提供了 has_secure_password 类方法,它定义了一个名为 password 的存取方法,而且有相应的数据验证。

1.11.1 要求

ActiveModel::SecurePassword 依赖 bcrypt,因此要在 Gemfile 中加入这个 gem,ActiveModel::SecurePassword 才能正确运行。为了使用安全密码,模型中必须定义一个名为 password_digest 的存取方法。has_secure_password 类方法会为 password 存取方法添加下述数据验证:

+
    +
  1. 密码应该存在

  2. +
  3. 密码应该等于密码确认

  4. +
  5. 密码的最大长度为 72(ActiveModel::SecurePassword 依赖的 bcrypt 的要求)

  6. +
+
1.11.2 示例
+
+class Person
+  include ActiveModel::SecurePassword
+  has_secure_password
+  attr_accessor :password_digest
+end
+
+person = Person.new
+
+# 密码为空时
+person.valid? # => false
+
+# 密码确认与密码不匹配时
+person.password = 'aditya'
+person.password_confirmation = 'nomatch'
+person.valid? # => false
+
+# 密码长度超过 72 时
+person.password = person.password_confirmation = 'a' * 100
+person.valid? # => false
+
+# 所有数据验证都通过时
+person.password = person.password_confirmation = 'aditya'
+person.valid? # => true
+
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_record_basics.html b/active_record_basics.html new file mode 100644 index 0000000..d8392cd --- /dev/null +++ b/active_record_basics.html @@ -0,0 +1,498 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Record 基础

本文简介 Active Record。

读完本文后,您将学到:

+
    +
  • 对象关系映射(Object Relational Mapping,ORM)和 Active Record 是什么,以及如何在 Rails 中使用;

  • +
  • Active Record 在 MVC 中的作用;

  • +
  • 如何使用 Active Record 模型处理保存在关系型数据库中的数据;

  • +
  • Active Record 模式(schema)的命名约定;

  • +
  • 数据库迁移,数据验证和回调。

  • +
+

1 Active Record 是什么?

Active Record 是 MVC 中的 M(模型),负责处理数据和业务逻辑。Active Record 负责创建和使用需要持久存入数据库中的数据。Active Record 实现了 Active Record 模式,是一种对象关系映射系统。

1.1 Active Record 模式

Active Record 模式出自 Martin Fowler 写的《企业应用架构模式》一书。在 Active Record 模式中,对象中既有持久存储的数据,也有针对数据的操作。Active Record 模式把数据存取逻辑作为对象的一部分,处理对象的用户知道如何把数据写入数据库,还知道如何从数据库中读出数据。

1.2 对象关系映射

对象关系映射(ORM)是一种技术手段,把应用中的对象和关系型数据库中的数据表连接起来。使用 ORM,应用中对象的属性和对象之间的关系可以通过一种简单的方法从数据库中获取,无需直接编写 SQL 语句,也不过度依赖特定的数据库种类。

1.3 用作 ORM 框架的 Active Record

Active Record 提供了很多功能,其中最重要的几个如下:

+
    +
  • 表示模型和其中的数据;

  • +
  • 表示模型之间的关系;

  • +
  • 通过相关联的模型表示继承层次结构;

  • +
  • 持久存入数据库之前,验证模型;

  • +
  • 以面向对象的方式处理数据库操作。

  • +
+

2 Active Record 中的“多约定少配置”原则

使用其他编程语言或框架开发应用时,可能必须要编写很多配置代码。大多数 ORM 框架都是这样。但是,如果遵循 Rails 的约定,创建 Active Record 模型时不用做多少配置(有时甚至完全不用配置)。Rails 的理念是,如果大多数情况下都要使用相同的方式配置应用,那么就应该把这定为默认的方式。所以,只有约定无法满足要求时,才要额外配置。

2.1 命名约定

默认情况下,Active Record 使用一些命名约定,查找模型和数据库表之间的映射关系。Rails 把模型的类名转换成复数,然后查找对应的数据表。例如,模型类名为 Book,数据表就是 books。Rails 提供的单复数转换功能很强大,常见和不常见的转换方式都能处理。如果类名由多个单词组成,应该按照 Ruby 的约定,使用驼峰式命名法,这时对应的数据库表将使用下划线分隔各单词。因此:

+
    +
  • 数据库表名:复数,下划线分隔单词(例如 book_clubs

  • +
  • 模型类名:单数,每个单词的首字母大写(例如 BookClub

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
模型/类表/模式
Articlearticles
LineItemline_items
Deerdeers
Mousemice
Personpeople
+

2.2 模式约定

根据字段的作用不同,Active Record 对数据库表中的字段命名也做了相应的约定:

+
    +
  • 外键:使用 singularized_table_name_id 形式命名,例如 item_idorder_id。创建模型关联后,Active Record 会查找这个字段;

  • +
  • 主键:默认情况下,Active Record 使用整数字段 id 作为表的主键。使用 Active Record 迁移创建数据库表时,会自动创建这个字段;

  • +
+

还有一些可选的字段,能为 Active Record 实例添加更多的功能:

+
    +
  • created_at:创建记录时,自动设为当前的日期和时间;

  • +
  • updated_at:更新记录时,自动设为当前的日期和时间;

  • +
  • lock_version:在模型中添加乐观锁

  • +
  • type:让模型使用单表继承

  • +
  • (association_name)_type:存储多态关联的类型;

  • +
  • (table_name)_count:缓存所关联对象的数量。比如说,一个 Article 有多个 Comment,那么 comments_count 列存储各篇文章现有的评论数量;

  • +
+

虽然这些字段是可选的,但在 Active Record 中是被保留的。如果想使用相应的功能,就不要把这些保留字段用作其他用途。例如,type 这个保留字段是用来指定数据库表使用单表继承(Single Table Inheritance,STI)的。如果不用单表继承,请使用其他的名称,例如“context”,这也能表明数据的作用。

3 创建 Active Record 模型

创建 Active Record 模型的过程很简单,只要继承 ApplicationRecord 类就行了:

+
+class Product < ApplicationRecord
+end
+
+
+
+

上面的代码会创建 Product 模型,对应于数据库中的 products 表。同时,products 表中的字段也映射到 Product 模型实例的属性上。假如 products 表由下面的 SQL 语句创建:

+
+CREATE TABLE products (
+   id int(11) NOT NULL auto_increment,
+   name varchar(255),
+   PRIMARY KEY  (id)
+);
+
+
+
+

按照这样的数据表结构,可以编写下面的代码:

+
+p = Product.new
+p.name = "Some Book"
+puts p.name # "Some Book"
+
+
+
+

4 覆盖命名约定

如果想使用其他的命名约定,或者在 Rails 应用中使用即有的数据库可以吗?没问题,默认的约定能轻易覆盖。

ApplicationRecord 继承自 ActiveRecord::Base,后者定义了一系列有用的方法。使用 ActiveRecord::Base.table_name= 方法可以指定要使用的表名:

+
+class Product < ApplicationRecord
+  self.table_name = "my_products"
+end
+
+
+
+

如果这么做,还要调用 set_fixture_class 方法,手动指定固件(my_products.yml)的类名:

+
+class ProductTest < ActiveSupport::TestCase
+  set_fixture_class my_products: Product
+  fixtures :my_products
+  ...
+end
+
+
+
+

还可以使用 ActiveRecord::Base.primary_key= 方法指定表的主键:

+
+class Product < ApplicationRecord
+  self.primary_key = "product_id"
+end
+
+
+
+

5 CRUD:读写数据

CURD 是四种数据操作的简称:C 表示创建,R 表示读取,U 表示更新,D 表示删除。Active Record 自动创建了处理数据表中数据的方法。

5.1 创建

Active Record 对象可以使用散列创建,在块中创建,或者创建后手动设置属性。new 方法创建一个新对象,create 方法创建新对象,并将其存入数据库。

例如,User 模型中有两个属性,nameoccupation。调用 create 方法会创建一个新记录,并将其存入数据库:

+
+user = User.create(name: "David", occupation: "Code Artist")
+
+
+
+

new 方法实例化一个新对象,但不保存:

+
+user = User.new
+user.name = "David"
+user.occupation = "Code Artist"
+
+
+
+

调用 user.save 可以把记录存入数据库。

最后,如果在 createnew 方法中使用块,会把新创建的对象拉入块中,初始化对象:

+
+user = User.new do |u|
+  u.name = "David"
+  u.occupation = "Code Artist"
+end
+
+
+
+

5.2 读取

Active Record 为读取数据库中的数据提供了丰富的 API。下面举例说明。

+
+# 返回所有用户组成的集合
+users = User.all
+
+
+
+
+
+# 返回第一个用户
+user = User.first
+
+
+
+
+
+# 返回第一个名为 David 的用户
+david = User.find_by(name: 'David')
+
+
+
+
+
+# 查找所有名为 David,职业为 Code Artists 的用户,而且按照 created_at 反向排列
+users = User.where(name: 'David', occupation: 'Code Artist').order(created_at: :desc)
+
+
+
+

Active Record 查询接口会详细介绍查询 Active Record 模型的方法。

5.3 更新

检索到 Active Record 对象后,可以修改其属性,然后再将其存入数据库。

+
+user = User.find_by(name: 'David')
+user.name = 'Dave'
+user.save
+
+
+
+

还有种使用散列的简写方式,指定属性名和属性值,例如:

+
+user = User.find_by(name: 'David')
+user.update(name: 'Dave')
+
+
+
+

一次更新多个属性时使用这种方法最方便。如果想批量更新多个记录,可以使用类方法 update_all

+
+User.update_all "max_login_attempts = 3, must_change_password = 'true'"
+
+
+
+

5.4 删除

类似地,检索到 Active Record 对象后还可以将其销毁,从数据库中删除。

+
+user = User.find_by(name: 'David')
+user.destroy
+
+
+
+

6 数据验证

在存入数据库之前,Active Record 还可以验证模型。模型验证有很多方法,可以检查属性值是否不为空,是否是唯一的、没有在数据库中出现过,等等。

把数据存入数据库之前进行验证是十分重要的步骤,所以调用 saveupdate 方法时会做数据验证。验证失败时返回 false,此时不会对数据库做任何操作。这两个方法都有对应的爆炸方法(save!update!)。爆炸方法要严格一些,如果验证失败,抛出 ActiveRecord::RecordInvalid 异常。下面举个简单的例子:

+
+class User < ApplicationRecord
+  validates :name, presence: true
+end
+
+user = User.new
+user.save  # => false
+user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
+
+
+
+

Active Record 数据验证会详细介绍数据验证。

7 回调

Active Record 回调用于在模型生命周期的特定事件上绑定代码,相应的事件发生时,执行绑定的代码。例如创建新纪录时、更新记录时、删除记录时,等等。Active Record 回调会详细介绍回调。

8 迁移

Rails 提供了一个 DSL(Domain-Specific Language)用来处理数据库模式,叫做“迁移”。迁移的代码存储在特定的文件中,通过 rails 命令执行,可以用在 Active Record 支持的所有数据库上。下面这个迁移新建一个表:

+
+class CreatePublications < ActiveRecord::Migration[5.0]
+  def change
+    create_table :publications do |t|
+      t.string :title
+      t.text :description
+      t.references :publication_type
+      t.integer :publisher_id
+      t.string :publisher_type
+      t.boolean :single_issue
+
+      t.timestamps
+    end
+    add_index :publications, :publication_type_id
+  end
+end
+
+
+
+

Rails 会跟踪哪些迁移已经应用到数据库上,还提供了回滚功能。为了创建表,要执行 rails db:migrate 命令。如果想回滚,则执行 rails db:rollback 命令。

注意,上面的代码与具体的数据库种类无关,可用于 MySQL、PostgreSQL、Oracle 等数据库。关于迁移的详细介绍,参阅Active Record 迁移

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_record_callbacks.html b/active_record_callbacks.html new file mode 100644 index 0000000..d25c9ec --- /dev/null +++ b/active_record_callbacks.html @@ -0,0 +1,630 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Record 回调

本文介绍如何介入 Active Record 对象的生命周期。

读完本文后,您将学到:

+
    +
  • Active Record 对象的生命周期;

  • +
  • 如何创建用于响应对象生命周期内事件的回调方法;

  • +
  • 如何把常用的回调封装到特殊的类中。

  • +
+

1 对象的生命周期

在 Rails 应用正常运作期间,对象可以被创建、更新或删除。Active Record 为对象的生命周期提供了钩子,使我们可以控制应用及其数据。

回调使我们可以在对象状态更改之前或之后触发逻辑。

2 回调概述

回调是在对象生命周期的某些时刻被调用的方法。通过回调,我们可以编写在创建、保存、更新、删除、验证或从数据库中加载 Active Record 对象时执行的代码。

2.1 注册回调

回调在使用之前需要注册。我们可以先把回调定义为普通方法,然后使用宏式类方法把这些普通方法注册为回调:

+
+class User < ApplicationRecord
+  validates :login, :email, presence: true
+
+  before_validation :ensure_login_has_a_value
+
+  protected
+    def ensure_login_has_a_value
+      if login.nil?
+        self.login = email unless email.blank?
+      end
+    end
+end
+
+
+
+

宏式类方法也接受块。如果块中的代码短到可以放在一行里,可以考虑使用这种编程风格:

+
+class User < ApplicationRecord
+  validates :login, :email, presence: true
+
+  before_create do
+    self.name = login.capitalize if name.blank?
+  end
+end
+
+
+
+

回调也可以注册为仅被某些生命周期事件触发:

+
+class User < ApplicationRecord
+  before_validation :normalize_name, on: :create
+
+  # :on 选项的值也可以是数组
+  after_validation :set_location, on: [ :create, :update ]
+
+  protected
+    def normalize_name
+      self.name = name.downcase.titleize
+    end
+
+    def set_location
+      self.location = LocationService.query(self)
+    end
+end
+
+
+
+

通常应该把回调定义为受保护的方法或私有方法。如果把回调定义为公共方法,就可以从模型外部调用回调,这样做违反了对象封装原则。

3 可用的回调

下面按照回调在 Rails 应用正常运作期间被调用的顺序,列出所有可用的 Active Record 回调。

3.1 创建对象

+
    +
  • before_validation

  • +
  • after_validation

  • +
  • before_save

  • +
  • around_save

  • +
  • before_create

  • +
  • around_create

  • +
  • after_create

  • +
  • after_save

  • +
  • after_commit/after_rollback

  • +
+

3.2 更新对象

+
    +
  • before_validation

  • +
  • after_validation

  • +
  • before_save

  • +
  • around_save

  • +
  • before_update

  • +
  • around_update

  • +
  • after_update

  • +
  • after_save

  • +
  • after_commit/after_rollback

  • +
+

3.3 删除对象

+
    +
  • before_destroy

  • +
  • around_destroy

  • +
  • after_destroy

  • +
  • after_commit/after_rollback

  • +
+

无论按什么顺序注册回调,在创建和更新对象时,after_save 回调总是在更明确的 after_createafter_update 回调之后被调用。

3.4 after_initializeafter_find 回调

当 Active Record 对象被实例化时,不管是通过直接使用 new 方法还是从数据库加载记录,都会调用 after_initialize 回调。使用这个回调可以避免直接覆盖 Active Record 的 initialize 方法。

当 Active Record 从数据库中加载记录时,会调用 after_find 回调。如果同时定义了 after_initializeafter_find 回调,会先调用 after_find 回调。

after_initializeafter_find 回调没有对应的 before_* 回调,这两个回调的注册方式和其他 Active Record 回调一样。

+
+class User < ApplicationRecord
+  after_initialize do |user|
+    puts "You have initialized an object!"
+  end
+
+  after_find do |user|
+    puts "You have found an object!"
+  end
+end
+
+
+
+
+
+>> User.new
+You have initialized an object!
+=> #<User id: nil>
+
+>> User.first
+You have found an object!
+You have initialized an object!
+=> #<User id: 1>
+
+
+
+

3.5 after_touch 回调

当我们在 Active Record 对象上调用 touch 方法时,会调用 after_touch 回调。

+
+class User < ApplicationRecord
+  after_touch do |user|
+    puts "You have touched an object"
+  end
+end
+
+
+
+
+
+>> u = User.create(name: 'Kuldeep')
+=> #<User id: 1, name: "Kuldeep", created_at: "2013-11-25 12:17:49", updated_at: "2013-11-25 12:17:49">
+
+>> u.touch
+You have touched an object
+=> true
+
+
+
+

after_touch 回调可以和 belongs_to 一起使用:

+
+class Employee < ApplicationRecord
+  belongs_to :company, touch: true
+  after_touch do
+    puts 'An Employee was touched'
+  end
+end
+
+class Company < ApplicationRecord
+  has_many :employees
+  after_touch :log_when_employees_or_company_touched
+
+  private
+  def log_when_employees_or_company_touched
+    puts 'Employee/Company was touched'
+  end
+end
+
+
+
+
+
+>> @employee = Employee.last
+=> #<Employee id: 1, company_id: 1, created_at: "2013-11-25 17:04:22", updated_at: "2013-11-25 17:05:05">
+
+# triggers @employee.company.touch
+>> @employee.touch
+Employee/Company was touched
+An Employee was touched
+=> true
+
+
+
+

4 调用回调

下面这些方法会触发回调:

+
    +
  • create

  • +
  • create!

  • +
  • decrement!

  • +
  • destroy

  • +
  • destroy!

  • +
  • destroy_all

  • +
  • increment!

  • +
  • save

  • +
  • save!

  • +
  • save(validate: false)

  • +
  • toggle!

  • +
  • update_attribute

  • +
  • update

  • +
  • update!

  • +
  • valid?

  • +
+

此外,下面这些查找方法会触发 after_find 回调:

+
    +
  • all

  • +
  • first

  • +
  • find

  • +
  • find_by

  • +
  • find_by_*

  • +
  • find_by_*!

  • +
  • find_by_sql

  • +
  • last

  • +
+

每次初始化类的新对象时都会触发 after_initialize 回调。

find_by_*find_by_*! 方法是为每个属性自动生成的动态查找方法。关于动态查找方法的更多介绍,请参阅 动态查找方法

5 跳过回调

和验证一样,我们可以跳过回调。使用下面这些方法可以跳过回调:

+
    +
  • decrement

  • +
  • decrement_counter

  • +
  • delete

  • +
  • delete_all

  • +
  • increment

  • +
  • increment_counter

  • +
  • toggle

  • +
  • touch

  • +
  • update_column

  • +
  • update_columns

  • +
  • update_all

  • +
  • update_counters

  • +
+

请慎重地使用这些方法,因为有些回调包含了重要的业务规则和应用逻辑,在不了解潜在影响的情况下就跳过回调,可能导致无效数据。

6 停止执行

回调在模型中注册后,将被加入队列等待执行。这个队列包含了所有模型的验证、已注册的回调和将要执行的数据库操作。

整个回调链包装在一个事务中。如果任何一个 before 回调方法返回 false 或引发异常,整个回调链就会停止执行,同时发出 ROLLBACK 消息来回滚事务;而 after 回调方法只能通过引发异常来达到相同的效果。

当回调链停止后,Rails 会重新抛出除了 ActiveRecord::RollbackActiveRecord::RecordInvalid 之外的其他异常。这可能导致那些预期 saveupdate_attributes 等方法(通常返回 truefalse )不会引发异常的代码出错。

7 关联回调

回调不仅可以在模型关联中使用,还可以通过模型关联定义。假设有一个用户在博客中发表了多篇文章,现在我们要删除这个用户,那么这个用户的所有文章也应该删除,为此我们通过 Article 模型和 User 模型的关联来给 User 模型添加一个 after_destroy 回调:

+
+class User < ApplicationRecord
+  has_many :articles, dependent: :destroy
+end
+
+class Article < ApplicationRecord
+  after_destroy :log_destroy_action
+
+  def log_destroy_action
+    puts 'Article destroyed'
+  end
+end
+
+
+
+
+
+>> user = User.first
+=> #<User id: 1>
+>> user.articles.create!
+=> #<Article id: 1, user_id: 1>
+>> user.destroy
+Article destroyed
+=> #<User id: 1>
+
+
+
+

8 条件回调

和验证一样,我们可以在满足指定条件时再调用回调方法。为此,我们可以使用 :if:unless 选项,选项的值可以是符号、字符串、Proc 或数组。要想指定在哪些条件下调用回调,可以使用 :if 选项。要想指定在哪些条件下不调用回调,可以使用 :unless 选项。

8.1 使用符号作为 :if:unless 选项的值

可以使用符号作为 :if:unless 选项的值,这个符号用于表示先于回调调用的断言方法。当使用 :if 选项时,如果断言方法返回 false 就不会调用回调;当使用 :unless 选项时,如果断言方法返回 true 就不会调用回调。使用符号作为 :if:unless 选项的值是最常见的方式。在使用这种方式注册回调时,我们可以同时使用几个不同的断言,用于检查是否应该调用回调。

+
+class Order < ApplicationRecord
+  before_save :normalize_card_number, if: :paid_with_card?
+end
+
+
+
+

8.2 使用字符串作为 :if:unless 选项的值

还可以使用字符串作为 :if:unless 选项的值,这个字符串会通过 eval 方法执行,因此必须包含有效的 Ruby 代码。当字符串表示的条件非常短时我们才使用这种方式:

+
+class Order < ApplicationRecord
+  before_save :normalize_card_number, if: "paid_with_card?"
+end
+
+
+
+

8.3 使用 Proc 作为 :if:unless 选项的值

最后,可以使用 Proc 作为 :if:unless 选项的值。在验证方法非常短时最适合使用这种方式,这类验证方法通常只有一行代码:

+
+class Order < ApplicationRecord
+  before_save :normalize_card_number,
+    if: Proc.new { |order| order.paid_with_card? }
+end
+
+
+
+

8.4 在条件回调中使用多个条件

在编写条件回调时,我们可以在同一个回调声明中混合使用 :if:unless 选项:

+
+class Comment < ApplicationRecord
+  after_create :send_email_to_author, if: :author_wants_emails?,
+    unless: Proc.new { |comment| comment.article.ignore_comments? }
+end
+
+
+
+

9 回调类

有时需要在其他模型中重用已有的回调方法,为了解决这个问题,Active Record 允许我们用类来封装回调方法。有了回调类,回调方法的重用就变得非常容易。

在下面的例子中,我们为 PictureFile 模型创建了 PictureFileCallbacks 回调类,在这个回调类中包含了 after_destroy 回调方法:

+
+class PictureFileCallbacks
+  def after_destroy(picture_file)
+    if File.exist?(picture_file.filepath)
+      File.delete(picture_file.filepath)
+    end
+  end
+end
+
+
+
+

在上面的代码中我们可以看到,当在回调类中声明回调方法时,回调方法接受模型对象作为参数。回调类定义之后就可以在模型中使用了:

+
+class PictureFile < ApplicationRecord
+  after_destroy PictureFileCallbacks.new
+end
+
+
+
+

请注意,上面我们把回调声明为实例方法,因此需要实例化新的 PictureFileCallbacks 对象。当回调想要使用实例化的对象的状态时,这种声明方式特别有用。尽管如此,一般我们会把回调声明为类方法:

+
+class PictureFileCallbacks
+  def self.after_destroy(picture_file)
+    if File.exist?(picture_file.filepath)
+      File.delete(picture_file.filepath)
+    end
+  end
+end
+
+
+
+

如果把回调声明为类方法,就不需要实例化新的 PictureFileCallbacks 对象。

+
+class PictureFile < ApplicationRecord
+  after_destroy PictureFileCallbacks
+end
+
+
+
+

我们可以根据需要在回调类中声明任意多个回调。

10 事务回调

after_commitafter_rollback 这两个回调会在数据库事务完成时触发。它们和 after_save 回调非常相似,区别在于它们在数据库变更已经提交或回滚后才会执行,常用于 Active Record 模型需要和数据库事务之外的系统交互的场景。

例如,在前面的例子中,PictureFile 模型中的记录删除后,还要删除相应的文件。如果 after_destroy 回调执行后应用引发异常,事务就会回滚,文件会被删除,模型会保持不一致的状态。例如,假设在下面的代码中,picture_file_2 对象是无效的,那么调用 save! 方法会引发错误:

+
+PictureFile.transaction do
+  picture_file_1.destroy
+  picture_file_2.save!
+end
+
+
+
+

通过使用 after_commit 回调,我们可以解决这个问题:

+
+class PictureFile < ApplicationRecord
+  after_commit :delete_picture_file_from_disk, on: [:destroy]
+
+  def delete_picture_file_from_disk
+    if File.exist?(filepath)
+      File.delete(filepath)
+    end
+  end
+end
+
+
+
+

:on 选项说明什么时候触发回调。如果不提供 :on 选项,那么每个动作都会触发回调。

由于只在执行创建、更新或删除动作时触发 after_commit 回调是很常见的,这些操作都拥有别名:

+
    +
  • after_create_commit

  • +
  • after_update_commit

  • +
  • after_destroy_commit

  • +
+
+
+class PictureFile < ApplicationRecord
+  after_destroy_commit :delete_picture_file_from_disk
+
+  def delete_picture_file_from_disk
+    if File.exist?(filepath)
+      File.delete(filepath)
+    end
+  end
+end
+
+
+
+

对于在事务中创建、更新或删除的模型,after_commitafter_rollback 回调一定会被调用。如果其中有一个回调引发异常,这个异常会被忽略,以避免干扰其他回调。因此,如果回调代码可能引发异常,就需要在回调中救援并进行适当处理。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_record_migrations.html b/active_record_migrations.html new file mode 100644 index 0000000..f3d6fc7 --- /dev/null +++ b/active_record_migrations.html @@ -0,0 +1,912 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Record 迁移

迁移是 Active Record 的一个特性,允许我们按时间顺序管理数据库模式。有了迁移,就不必再用纯 SQL 来修改数据库模式,而是可以使用简单的 Ruby DSL 来描述对数据表的修改。

读完本文后,您将学到:

+
    +
  • 用于创建迁移的生成器;

  • +
  • Active Record 提供的用于操作数据库的方法;

  • +
  • 用于操作迁移和数据库模式的 bin/rails 任务;

  • +
  • 迁移和 schema.rb 文件的关系。

  • +
+

1 迁移概述

迁移是以一致和轻松的方式按时间顺序修改数据库模式的实用方法。它使用 Ruby DSL,因此不必手动编写 SQL,从而实现了数据库无关的数据库模式的创建和修改。

我们可以把迁移看做数据库的新“版本”。数据库模式一开始并不包含任何内容,之后通过一个个迁移来添加或删除数据表、字段和记录。 Active Record 知道如何沿着时间线更新数据库模式,使其从任何历史版本更新为最新版本。Active Record 还会更新 db/schema.rb 文件,以匹配最新的数据库结构。

下面是一个迁移的示例:

+
+class CreateProducts < ActiveRecord::Migration[5.0]
+  def change
+    create_table :products do |t|
+      t.string :name
+      t.text :description
+
+      t.timestamps
+    end
+  end
+end
+
+
+
+

这个迁移用于添加 products 数据表,数据表中包含 name 字符串字段和 description 文本字段。同时隐式添加了 id 主键字段,这是所有 Active Record 模型的默认主键。timestamps 宏添加了 created_atupdated_at 两个字段。后面这几个特殊字段只要存在就都由 Active Record 自动管理。

注意这里定义的对数据库的修改是按时间进行的。在这个迁移运行之前,数据表还不存在。在这个迁移运行之后,数据表就被创建了。Active Record 还知道如何撤销这个迁移:如果我们回滚这个迁移,数据表就会被删除。

对于支持事务并提供了用于修改数据库模式的语句的数据库,迁移被包装在事务中。如果数据库不支持事务,那么当迁移失败时,已成功的那部分操作将无法回滚。这种情况下只能手动完成相应的回滚操作。

某些查询不能在事务内部运行。如果数据库适配器支持 DDL 事务,就可以使用 disable_ddl_transaction! 方法在某个迁移中临时禁用事务。

如果想在迁移中完成一些 Active Record 不知如何撤销的操作,可以使用 reversible 方法:

+
+class ChangeProductsPrice < ActiveRecord::Migration[5.0]
+  def change
+    reversible do |dir|
+      change_table :products do |t|
+        dir.up   { t.change :price, :string }
+        dir.down { t.change :price, :integer }
+      end
+    end
+  end
+end
+
+
+
+

或者用 updown 方法来代替 change 方法:

+
+class ChangeProductsPrice < ActiveRecord::Migration[5.0]
+  def up
+    change_table :products do |t|
+      t.change :price, :string
+    end
+  end
+
+  def down
+    change_table :products do |t|
+      t.change :price, :integer
+    end
+  end
+end
+
+
+
+

2 创建迁移

2.1 创建独立的迁移

迁移文件储存在 db/migrate 文件夹中,一个迁移文件包含一个迁移类。文件名采用 YYYYMMDDHHMMSS_create_products.rb 形式,即 UTC 时间戳加上下划线再加上迁移的名称。迁移类的名称(驼峰式)应该匹配文件名中迁移的名称。例如,在 20080906120000_create_products.rb 文件中应该定义 CreateProducts 类,在 20080906120001_add_details_to_products.rb 文件中应该定义 AddDetailsToProducts 类。Rails 根据文件名的时间戳部分确定要运行的迁移和迁移运行的顺序,因此当需要把迁移文件复制到其他 Rails 应用,或者自己生成迁移文件时,一定要注意迁移运行的顺序。

当然,计算时间戳不是什么有趣的事,因此 Active Record 提供了生成器:

+
+$ bin/rails generate migration AddPartNumberToProducts
+
+
+
+

上面的命令会创建空的迁移,并进行适当命名:

+
+class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
+  def change
+  end
+end
+
+
+
+

如果迁移名称是 AddXXXToYYYRemoveXXXFromYYY 的形式,并且后面跟着字段名和类型列表,那么会生成包含合适的 add_columnremove_column 语句的迁移。

+
+$ bin/rails generate migration AddPartNumberToProducts part_number:string
+
+
+
+

上面的命令会生成:

+
+class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
+  def change
+    add_column :products, :part_number, :string
+  end
+end
+
+
+
+

还可以像下面这样在新建字段上添加索引:

+
+$ bin/rails generate migration AddPartNumberToProducts part_number:string:index
+
+
+
+

上面的命令会生成:

+
+class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
+  def change
+    add_column :products, :part_number, :string
+    add_index :products, :part_number
+  end
+end
+
+
+
+

类似地,还可以生成用于删除字段的迁移:

+
+$ bin/rails generate migration RemovePartNumberFromProducts part_number:string
+
+
+
+

上面的命令会生成:

+
+class RemovePartNumberFromProducts < ActiveRecord::Migration[5.0]
+  def change
+    remove_column :products, :part_number, :string
+  end
+end
+
+
+
+

还可以生成用于添加多个字段的迁移,例如:

+
+$ bin/rails generate migration AddDetailsToProducts part_number:string price:decimal
+
+
+
+

上面的命令会生成:

+
+class AddDetailsToProducts < ActiveRecord::Migration[5.0]
+  def change
+    add_column :products, :part_number, :string
+    add_column :products, :price, :decimal
+  end
+end
+
+
+
+

如果迁移名称是 CreateXXX 的形式,并且后面跟着字段名和类型列表,那么会生成用于创建包含指定字段的 XXX 数据表的迁移。例如:

+
+$ bin/rails generate migration CreateProducts name:string part_number:string
+
+
+
+

上面的命令会生成:

+
+class CreateProducts < ActiveRecord::Migration[5.0]
+  def change
+    create_table :products do |t|
+      t.string :name
+      t.string :part_number
+    end
+  end
+end
+
+
+
+

和往常一样,上面的命令生成的代码只是一个起点,我们可以修改 db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb 文件,根据需要增删代码。

生成器也接受 references 字段类型作为参数(还可使用 belongs_to),例如:

+
+$ bin/rails generate migration AddUserRefToProducts user:references
+
+
+
+

上面的命令会生成:

+
+class AddUserRefToProducts < ActiveRecord::Migration[5.0]
+  def change
+    add_reference :products, :user, index: true, foreign_key: true
+  end
+end
+
+
+
+

这个迁移会创建 user_id 字段并添加索引。关于 add_reference 选项的更多介绍,请参阅 API 文档

如果迁移名称中包含 JoinTable,生成器会创建联结数据表:

+
+$ bin/rails g migration CreateJoinTableCustomerProduct customer product
+
+
+
+

上面的命令会生成:

+
+class CreateJoinTableCustomerProduct < ActiveRecord::Migration[5.0]
+  def change
+    create_join_table :customers, :products do |t|
+      # t.index [:customer_id, :product_id]
+      # t.index [:product_id, :customer_id]
+    end
+  end
+end
+
+
+
+

2.2 模型生成器

模型和脚手架生成器会生成适用于添加新模型的迁移。这些迁移中已经包含用于创建有关数据表的指令。如果我们告诉 Rails 想要哪些字段,那么添加这些字段所需的语句也会被创建。例如,运行下面的命令:

+
+$ bin/rails generate model Product name:string description:text
+
+
+
+

上面的命令会创建下面的迁移:

+
+class CreateProducts < ActiveRecord::Migration[5.0]
+  def change
+    create_table :products do |t|
+      t.string :name
+      t.text :description
+
+      t.timestamps
+    end
+  end
+end
+
+
+
+

我们可以根据需要添加“字段名称/类型”对,没有数量限制。

2.3 传递修饰符

可以直接在命令行中传递常用的类型修饰符。这些类型修饰符用大括号括起来,放在字段类型之后。例如,运行下面的命令:

+
+$ bin/rails generate migration AddDetailsToProducts 'price:decimal{5,2}' supplier:references{polymorphic}
+
+
+
+

上面的命令会创建下面的迁移:

+
+class AddDetailsToProducts < ActiveRecord::Migration[5.0]
+  def change
+    add_column :products, :price, :decimal, precision: 5, scale: 2
+    add_reference :products, :supplier, polymorphic: true, index: true
+  end
+end
+
+
+
+

关于传递修饰符的更多介绍,请参阅生成器的命令行帮助信息。

3 编写迁移

使用生成器创建迁移后,就可以开始写代码了。

3.1 创建数据表

create_table 方法是最基础、最常用的方法,其代码通常是由模型或脚手架生成器生成的。典型的用法像下面这样:

+
+create_table :products do |t|
+  t.string :name
+end
+
+
+
+

上面的命令会创建包含 name 字段的 products 数据表(后面会介绍,数据表还包含自动创建的 id 字段)。

默认情况下,create_table 方法会创建 id 主键。可以用 :primary_key 选项来修改主键名称,还可以传入 id: false 选项以禁用主键。如果需要传递数据库特有的选项,可以在 :options 选项中使用 SQL 代码片段。例如:

+
+create_table :products, options: "ENGINE=BLACKHOLE" do |t|
+  t.string :name, null: false
+end
+
+
+
+

上面的代码会在用于创建数据表的 SQL 语句末尾加上 ENGINE=BLACKHOLE(如果使用 MySQL 或 MarialDB,默认选项是 ENGINE=InnoDB)。

还可以传递带有数据表描述信息的 :comment 选项,这些注释会被储存在数据库中,可以使用 MySQL Workbench、PgAdmin III 等数据库管理工具查看。对于大型数据库,强列推荐在应用的迁移中添加注释。目前只有 MySQL 和 PostgreSQL 适配器支持注释功能。

3.2 创建联结数据表

create_join_table 方法用于创建 HABTM(has and belongs to many)联结数据表。典型的用法像下面这样:

+
+create_join_table :products, :categories
+
+
+
+

上面的代码会创建包含 category_idproduct_id 字段的 categories_products 数据表。这两个字段的 :null 选项默认设置为 false,可以通过 :column_options 选项覆盖这一设置:

+
+create_join_table :products, :categories, column_options: { null: true }
+
+
+
+

联结数据表的名称默认由 create_join_table 方法的前两个参数按字母顺序组合而来。可以传入 :table_name 选项来自定义联结数据表的名称:

+
+create_join_table :products, :categories, table_name: :categorization
+
+
+
+

上面的代码会创建 categorization 数据表。

create_join_table 方法也接受块作为参数,用于添加索引(默认未创建的索引)或附加字段:

+
+create_join_table :products, :categories do |t|
+  t.index :product_id
+  t.index :category_id
+end
+
+
+
+

3.3 修改数据表

change_table 方法和 create_table 非常类似,用于修改现有的数据表。它的用法和 create_table 方法风格类似,但传入块的对象有更多用法。例如:

+
+change_table :products do |t|
+  t.remove :description, :name
+  t.string :part_number
+  t.index :part_number
+  t.rename :upccode, :upc_code
+end
+
+
+
+

上面的代码删除 descriptionname 字段,创建 part_number 字符串字段并添加索引,最后重命名 upccode 字段。

3.4 修改字段

Rails 提供了与 remove_columnadd_column 类似的 change_column 迁移方法。

+
+change_column :products, :part_number, :text
+
+
+
+

上面的代码把 products 数据表的 part_number 字段修改为 :text 字段。请注意 change_column 命令是无法撤销的。

change_column 方法之外,还有 change_column_nullchange_column_default 方法,前者专门用于设置字段可以为空或不可以为空,后者专门用于修改字段的默认值。

+
+change_column_null :products, :name, false
+change_column_default :products, :approved, from: true, to: false
+
+
+
+

上面的代码把 products 数据表的 :name 字段设置为 NOT NULL 字段,把 :approved 字段的默认值由 true 修改为 false

注意:也可以把上面的 change_column_default 迁移写成 change_column_default :products, :approved, false,但这种写法是无法撤销的。

3.5 字段修饰符

字段修饰符可以在创建或修改字段时使用:

+
    +
  • limit 修饰符:设置 string/text/binary/integer 字段的最大长度。

  • +
  • precision 修饰符:定义 decimal 字段的精度,表示数字的总位数。

  • +
  • scale 修饰符:定义 decimal 字段的标度,表示小数点后的位数。

  • +
  • polymorphic 修饰符:为 belongs_to 关联添加 type 字段。

  • +
  • null 修饰符:设置字段能否为 NULL 值。

  • +
  • default 修饰符:设置字段的默认值。请注意,如果使用动态值(如日期)作为默认值,那么默认值只会在第一次使时(如应用迁移的日期)计算一次。

  • +
  • index 修饰符:为字段添加索引。

  • +
  • comment 修饰符:为字段添加注释。

  • +
+

有的适配器可能支持附加选项,更多介绍请参阅相应适配器的 API 文档。

3.6 外键

尽管不是必需的,但有时我们需要使用外键约束以保证引用完整性。

+
+add_foreign_key :articles, :authors
+
+
+
+

上面的代码为 articles 数据表的 author_id 字段添加外键,这个外键会引用 authors 数据表的 id 字段。如果字段名不能从表名称推导出来,我们可以使用 :column:primary_key 选项。

Rails 会为每一个外键生成以 fk_rails_ 开头并且后面紧跟着 10 个字符的外键名,外键名是根据 from_tablecolumn 推导出来的。需要时可以使用 :name 来指定外键名。

Active Record 只支持单字段外键,要想使用复合外键就需要 execute 方法和 structure.sql。更多介绍请参阅 数据库模式转储

删除外键也很容易:

+
+# 让 Active Record 找出列名
+remove_foreign_key :accounts, :branches
+
+# 删除特定列上的外键
+remove_foreign_key :accounts, column: :owner_id
+
+# 通过名称删除外键
+remove_foreign_key :accounts, name: :special_fk_name
+
+
+
+

3.7 如果辅助方法不够用

如果 Active Record 提供的辅助方法不够用,可以使用 excute 方法执行任意 SQL 语句:

+
+Product.connection.execute("UPDATE products SET price = 'free' WHERE 1=1")
+
+
+
+

关于各个方法的更多介绍和例子,请参阅 API 文档。尤其是 ActiveRecord::ConnectionAdapters::SchemaStatements 的文档(在 changeupdown 方法中可以使用的方法)、ActiveRecord::ConnectionAdapters::TableDefinition 的文档(在 create_table 方法的块中可以使用的方法)和 ActiveRecord::ConnectionAdapters::Table 的文档(在 change_table 方法的块中可以使用的方法)。

3.8 使用 change 方法

change 方法是编写迁移时最常用的。在大多数情况下,Active Record 知道如何自动撤销用 change 方法编写的迁移。目前,在 change 方法中只能使用下面这些方法:

+
    +
  • add_column

  • +
  • add_foreign_key

  • +
  • add_index

  • +
  • add_reference

  • +
  • add_timestamps

  • +
  • change_column_default(必须提供 :from:to 选项)

  • +
  • change_column_null

  • +
  • create_join_table

  • +
  • create_table

  • +
  • disable_extension

  • +
  • drop_join_table

  • +
  • drop_table(必须提供块)

  • +
  • enable_extension

  • +
  • remove_column(必须提供字段类型)

  • +
  • remove_foreign_key(必须提供第二个数据表)

  • +
  • remove_index

  • +
  • remove_reference

  • +
  • remove_timestamps

  • +
  • rename_column

  • +
  • rename_index

  • +
  • rename_table

  • +
+

如果在块中不使用 changechange_defaultremove 方法,那么 change_table 方法也是可撤销的。

如果提供了字段类型作为第三个参数,那么 remove_column 是可撤销的。别忘了提供原来字段的选项,否则 Rails 在回滚时就无法准确地重建字段了:

+
+remove_column :posts, :slug, :string, null: false, default: '', index: true
+
+
+
+

如果需要使用其他方法,可以用 reversible 方法或者 updown 方法来代替 change 方法。

3.9 使用 reversible 方法

撤销复杂迁移所需的操作有一些是 Rails 无法自动完成的,这时可以使用 reversible 方法指定运行和撤销迁移所需的操作。例如:

+
+class ExampleMigration < ActiveRecord::Migration[5.0]
+  def change
+    create_table :distributors do |t|
+      t.string :zipcode
+    end
+
+    reversible do |dir|
+      dir.up do
+        # 添加 CHECK 约束
+        execute <<-SQL
+          ALTER TABLE distributors
+            ADD CONSTRAINT zipchk
+              CHECK (char_length(zipcode) = 5) NO INHERIT;
+        SQL
+      end
+      dir.down do
+        execute <<-SQL
+          ALTER TABLE distributors
+            DROP CONSTRAINT zipchk
+        SQL
+      end
+    end
+
+    add_column :users, :home_page_url, :string
+    rename_column :users, :email, :email_address
+  end
+end
+
+
+
+

使用 reversible 方法可以确保指令按正确的顺序执行。在上面的代码中,撤销迁移时,down 块会在删除 home_page_url 字段之后、删除 distributors 数据表之前运行。

有时,迁移执行的操作是无法撤销的,例如删除数据。在这种情况下,我们可以在 down 块中抛出 ActiveRecord::IrreversibleMigration 异常。这样一旦尝试撤销迁移,就会显示无法撤销迁移的出错信息。

3.10 使用 updown 方法

可以使用 updown 方法以传统风格编写迁移而不使用 change 方法。up 方法用于描述对数据库模式所做的改变,down 方法用于撤销 up 方法所做的改变。换句话说,如果调用 up 方法之后紧接着调用 down 方法,数据库模式不会发生任何改变。例如用 up 方法创建数据表,就应该用 down 方法删除这个数据表。在 down 方法中撤销迁移时,明智的做法是按照和 up 方法中操作相反的顺序执行操作。下面的例子和上一节中的例子的功能完全相同:

+
+class ExampleMigration < ActiveRecord::Migration[5.0]
+  def up
+    create_table :distributors do |t|
+      t.string :zipcode
+    end
+
+    # 添加 CHECK 约束
+    execute <<-SQL
+      ALTER TABLE distributors
+        ADD CONSTRAINT zipchk
+        CHECK (char_length(zipcode) = 5);
+    SQL
+
+    add_column :users, :home_page_url, :string
+    rename_column :users, :email, :email_address
+  end
+
+  def down
+    rename_column :users, :email_address, :email
+    remove_column :users, :home_page_url
+
+    execute <<-SQL
+      ALTER TABLE distributors
+        DROP CONSTRAINT zipchk
+    SQL
+
+    drop_table :distributors
+  end
+end
+
+
+
+

对于无法撤销的迁移,应该在 down 方法中抛出 ActiveRecord::IrreversibleMigration 异常。这样一旦尝试撤销迁移,就会显示无法撤销迁移的出错信息。

3.11 撤销之前的迁移

Active Record 提供了 revert 方法用于回滚迁移:

+
+require_relative '20121212123456_example_migration'
+
+class FixupExampleMigration < ActiveRecord::Migration[5.0]
+  def change
+    revert ExampleMigration
+
+    create_table(:apples) do |t|
+      t.string :variety
+    end
+  end
+end
+
+
+
+

revert 方法也接受块,在块中可以定义用于撤销迁移的指令。如果只是想要撤销之前迁移的部分操作,就可以使用块。例如,假设有一个 ExampleMigration 迁移已经执行,但后来发现应该用 ActiveRecord 验证代替 CHECK 约束来验证邮编,那么可以像下面这样编写迁移:

+
+class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration[5.0]
+  def change
+    revert do
+      # 从  ExampleMigration 中复制粘贴代码
+      reversible do |dir|
+        dir.up do
+          # 添加 CHECK 约束
+          execute <<-SQL
+            ALTER TABLE distributors
+              ADD CONSTRAINT zipchk
+                CHECK (char_length(zipcode) = 5);
+          SQL
+        end
+        dir.down do
+          execute <<-SQL
+            ALTER TABLE distributors
+              DROP CONSTRAINT zipchk
+          SQL
+        end
+      end
+
+      # ExampleMigration 中的其他操作无需撤销
+    end
+  end
+end
+
+
+
+

不使用 revert 方法也可以编写出和上面的迁移功能相同的迁移,但需要更多步骤:调换 create_table 方法和 reversible 方法的顺序,用 drop_table 方法代替 create_table 方法,最后对调 updown 方法。换句话说,这么多步骤用一个 revert 方法就可以代替。

要想像上面的例子一样添加 CHECK 约束,必须使用 structure.sql 作为转储方式。请参阅 数据库模式转储

4 运行迁移

Rails 提供了一套用于运行迁移的 bin/rails 任务。其中最常用的是 rails db:migrate 任务,用于调用所有未运行的迁移中的 chagneup 方法。如果没有未运行的迁移,任务会直接退出。调用顺序是根据迁移文件名的时间戳确定的。

请注意,执行 db:migrate 任务时会自动执行 db:schema:dump 任务,这个任务用于更新 db/schema.rb 文件,以匹配数据库结构。

如果指定了目标版本,Active Record 会运行该版本之前的所有迁移(调用其中的 changeupdown 方法),其中版本指的是迁移文件名的数字前缀。例如,下面的命令会运行 20080906120000 版本之前的所有迁移:

+
+$ bin/rails db:migrate VERSION=20080906120000
+
+
+
+

如果版本 20080906120000 高于当前版本(换句话说,是向上迁移),上面的命令会按顺序运行迁移直到运行完 20080906120000 版本,之后的版本都不会运行。如果是向下迁移(即版本 20080906120000 低于当前版本),上面的命令会按顺序运行 20080906120000 版本之前的所有迁移,不包括 20080906120000 版本。

4.1 回滚

另一个常用任务是回滚最后一个迁移。例如,当发现最后一个迁移中有错误需要修正时,就可以执行回滚任务。回滚最后一个迁移不需要指定这个迁移的版本,直接执行下面的命令即可:

+
+$ bin/rails db:rollback
+
+
+
+

上面的命令通过撤销 change 方法或调用 down 方法来回滚最后一个迁移。要想取消多个迁移,可以使用 STEP 参数:

+
+$ bin/rails db:rollback STEP=3
+
+
+
+

上面的命令会撤销最后三个迁移。

db:migrate:redo 任务用于回滚最后一个迁移并再次运行这个迁移。和 db:rollback 任务一样,如果需要重做多个迁移,可以使用 STEP 参数,例如:

+
+$ bin/rails db:migrate:redo STEP=3
+
+
+
+

这些 bin/rails 任务可以完成的操作,通过 db:migrate 也都能完成,区别在于这些任务使用起来更方便,无需显式指定迁移的版本。

4.2 安装数据库

rails db:setup 任务用于创建数据库,加载数据库模式,并使用种子数据初始化数据库。

4.3 重置数据库

rails db:reset 任务用于删除并重新创建数据库,其功能相当于 rails db:drop db:setup

重置数据库和运行所有迁移是不一样的。重置数据库只使用当前的 db/schema.rbdb/structure.sql 文件的内容。如果迁移无法回滚,使用 rails db:reset 任务可能也没用。关于转储数据库模式的更多介绍,请参阅 数据库模式转储

4.4 运行指定迁移

要想运行或撤销指定迁移,可以使用 db:migrate:updb:migrate:down 任务。只需指定版本,对应迁移就会调用它的 changeupdown 方法,例如:

+
+$ bin/rails db:migrate:up VERSION=20080906120000
+
+
+
+

上面的命令会运行 20080906120000 这个迁移,调用它的 changeup 方法。db:migrate:up 任务会检查指定迁移是否已经运行过,如果已经运行过就不会执行任何操作。

4.5 在不同环境中运行迁移

bin/rails db:migrate 任务默认在开发环境中运行迁移。要想在其他环境中运行迁移,可以在执行任务时使用 RAILS_ENV 环境变量说明所需环境。例如,要想在测试环境中运行迁移,可以执行下面的命令:

+
+$ bin/rails db:migrate RAILS_ENV=test
+
+
+
+

4.6 修改迁移运行时的输出

运行迁移时,默认会输出正在进行的操作,以及操作所花费的时间。例如,创建数据表并添加索引的迁移在运行时会生成下面的输出:

+
+==  CreateProducts: migrating =================================================
+-- create_table(:products)
+   -> 0.0028s
+==  CreateProducts: migrated (0.0028s) ========================================
+
+
+
+

在迁移中提供了几种方法,允许我们修改迁移运行时的输出:

+ + + + + + + + + + + + + + + + + + + + + +
方法用途
suppress_messages参数是一个块,抑制块产生的任何输出。
say接受信息文体作为参数并将其输出。方法的第二个参数是布尔值,用于说明输出结果是否缩进。
say_with_time输出信息文本以及执行块所花费的时间。如果块返回整数,这个整数会被当作受块操作影响的记录的条数。
+

例如,下面的迁移:

+
+class CreateProducts < ActiveRecord::Migration[5.0]
+  def change
+    suppress_messages do
+      create_table :products do |t|
+        t.string :name
+        t.text :description
+        t.timestamps
+      end
+    end
+
+    say "Created a table"
+
+    suppress_messages {add_index :products, :name}
+    say "and an index!", true
+
+    say_with_time 'Waiting for a while' do
+      sleep 10
+      250
+    end
+  end
+end
+
+
+
+

会生成下面的输出:

+
+==  CreateProducts: migrating =================================================
+-- Created a table
+   -> and an index!
+-- Waiting for a while
+   -> 10.0013s
+   -> 250 rows
+==  CreateProducts: migrated (10.0054s) =======================================
+
+
+
+

要是不想让 Active Record 生成任何输出,可以使用 rails db:migrate VERBOSE=false

5 修改现有的迁移

在编写迁移时我们偶尔也会犯错误。如果已经运行过存在错误的迁移,那么直接修正迁移中的错误并重新运行这个迁移并不能解决问题:Rails 知道这个迁移已经运行过,因此执行 rails db:migrate 任务时不会执行任何操作。必须先回滚这个迁移(例如通过执行 bin/rails db:rollback 任务),再修正迁移中的错误,然后执行 rails db:migrate 任务来运行这个迁移的正确版本。

通常,直接修改现有的迁移不是个好主意。这样做会给我们和同事带来额外的工作量,如果这个迁移已经在生产服务器上运行过,还可能带来大麻烦。作为替代,可以编写一个新的迁移来执行我们想要的操作。修改还未提交到源代版本码控制系统(或者更一般地,还未传播到开发设备之外)的新生成的迁移是相对无害的。

在编写新的迁移来完全或部分撤销之前的迁移时,可以使用 revert 方法(请参阅前面 撤销之前的迁移)。

6 数据库模式转储

6.1 数据库模式文件有什么用?

迁移尽管很强大,但并非数据库模式的可信来源。Active Record 通过检查数据库生成的 db/schema.rb 文件或 SQL 文件才是数据库模式的可信来源。这两个可信来源不应该被修改,它们仅用于表示数据库的当前状态。

当需要部署 Rails 应用的新实例时,不必把所有迁移重新运行一遍,直接加载当前数据库的模式文件要简单和快速得多。

例如,我们可以这样创建测试数据库:把当前的开发数据库转储为 db/schema.rbdb/structure.sql 文件,然后加载到测试数据库。

数据库模式文件还可以用于快速查看 Active Record 对象具有的属性。这些属性信息不仅在模型代码中找不到,而且经常分散在几个迁移文件中,还好在数据库模式文件中可以很容易地查看这些信息。annotate_models gem 会在每个模型文件的顶部自动添加和更新注释,这些注释是对当前数据库模式的概述,如果需要可以使用这个 gem。

6.2 数据库模式转储的类型

数据库模式转储有两种方式,可以通过 config/application.rb 文件的 config.active_record.schema_format 选项来设置想要采用的方式,即 :sql:ruby

如果选择 :ruby,那么数据库模式会储存在 db/schema.rb 文件中。打开这个文件,会看到内容很多,就像一个巨大的迁移:

+
+ActiveRecord::Schema.define(version: 20080906171750) do
+  create_table "authors", force: true do |t|
+    t.string   "name"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  create_table "products", force: true do |t|
+    t.string   "name"
+    t.text "description"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string "part_number"
+  end
+end
+
+
+
+

在很多情况下,我们看到的数据库模式文件就是上面这个样子。这个文件是通过检查数据库生成的,使用 create_tableadd_index 等方法来表达数据库结构。这个文件是数据库无关的,因此可以加载到 Active Record 支持的任何一种数据库。如果想要分发使用多数据库的 Rails 应用,数据库无关这一特性就非常有用了。

尽管如此,db/schema.rb 在设计上也有所取舍:它不能表达数据库的特定项目,如触发器、存储过程或检查约束。尽管我们可以在迁移中执行定制的 SQL 语句,但是数据库模式转储工具无法从数据库中复原这些语句。如果我们使用了这类特性,就应该把数据库模式的格式设置为 :sql

在把数据库模式转储到 db/structure.sql 文件时,我们不使用数据库模式转储工具,而是使用数据库特有的工具(通过执行 db:structure:dump 任务)。例如,对于 PostgreSQL,使用的是 pg_dump 实用程序。对于 MySQL 和 MariaDB,db/structure.sql 文件将包含各种数据表的 SHOW CREATE TABLE 语句的输出。

加载数据库模式实际上就是执行其中包含的 SQL 语句。根据定义,加载数据库模式会创建数据库结构的完美拷贝。:sql 格式的数据库模式,只能加载到和原有数据库类型相同的数据库,而不能加载到其他类型的数据库。

6.3 数据库模式转储和源码版本控制

数据库模式转储是数据库模式的可信来源,因此强烈建议将其纳入源码版本控制。

db/schema.rb 文件包含数据库的当前版本号,这样可以确保在合并两个包含数据库模式文件的分支时会发生冲突。一旦出现这种情况,就需要手动解决冲突,保留版本较高的那个数据库模式文件。

7 Active Record 和引用完整性

Active Record 在模型而不是数据库中声明关联。因此,像触发器、约束这些依赖数据库的特性没有被大量使用。

验证,如 validates :foreign_key, uniqueness: true,是模型强制数据完整性的一种方式。在关联中设置 :dependent 选项,可以保证父对象删除后,子对象也会被删除。和其他应用层的操作一样,这些操作无法保证引用完整性,因此有些人会在数据库中使用外键约束以加强数据完整性。

尽管 Active Record 并未提供用于直接处理这些特性的工具,但 execute 方法可以用于执行任意 SQL。

8 迁移和种子数据

Rails 迁移特性的主要用途是使用一致的进程调用修改数据库模式的命令。迁移还可以用于添加或修改数据。对于不能删除和重建的数据库,如生产数据库,这些功能非常有用。

+
+class AddInitialProducts < ActiveRecord::Migration[5.0]
+  def up
+    5.times do |i|
+      Product.create(name: "Product ##{i}", description: "A product.")
+    end
+  end
+
+  def down
+    Product.delete_all
+  end
+end
+
+
+
+

使用 Rails 内置的“种子”特性可以快速简便地完成创建数据库后添加初始数据的任务。在开发和测试环境中,经常需要重新加载数据库,这时“种子”特性就更有用了。使用“种子”特性很容易,只要用 Ruby 代码填充 db/seeds.rb 文件,然后执行 rails db:seed 命令即可:

+
+5.times do |i|
+  Product.create(name: "Product ##{i}", description: "A product.")
+end
+
+
+
+

相比之下,这种设置新建应用数据库的方法更加干净利落。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_record_postgresql.html b/active_record_postgresql.html new file mode 100644 index 0000000..84d0f76 --- /dev/null +++ b/active_record_postgresql.html @@ -0,0 +1,747 @@ + + + + + + + +Active Record and PostgreSQL — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Active Record and PostgreSQL

This guide covers PostgreSQL specific usage of Active Record.

After reading this guide, you will know:

+
    +
  • How to use PostgreSQL's datatypes.
  • +
  • How to use UUID primary keys.
  • +
  • How to implement full text search with PostgreSQL.
  • +
  • How to back your Active Record models with database views.
  • +
+ + + + +
+
+ +
+
+
+

In order to use the PostgreSQL adapter you need to have at least version 9.1 +installed. Older versions are not supported.

To get started with PostgreSQL have a look at the +configuring Rails guide. +It describes how to properly setup Active Record for PostgreSQL.

1 Datatypes

PostgreSQL offers a number of specific datatypes. Following is a list of types, +that are supported by the PostgreSQL adapter.

1.1 Bytea

+ +
+
+# db/migrate/20140207133952_create_documents.rb
+create_table :documents do |t|
+  t.binary 'payload'
+end
+
+# app/models/document.rb
+class Document < ApplicationRecord
+end
+
+# Usage
+data = File.read(Rails.root + "tmp/output.pdf")
+Document.create payload: data
+
+
+
+

1.2 Array

+ +
+
+# db/migrate/20140207133952_create_books.rb
+create_table :books do |t|
+  t.string 'title'
+  t.string 'tags', array: true
+  t.integer 'ratings', array: true
+end
+add_index :books, :tags, using: 'gin'
+add_index :books, :ratings, using: 'gin'
+
+# app/models/book.rb
+class Book < ApplicationRecord
+end
+
+# Usage
+Book.create title: "Brave New World",
+            tags: ["fantasy", "fiction"],
+            ratings: [4, 5]
+
+## Books for a single tag
+Book.where("'fantasy' = ANY (tags)")
+
+## Books for multiple tags
+Book.where("tags @> ARRAY[?]::varchar[]", ["fantasy", "fiction"])
+
+## Books with 3 or more ratings
+Book.where("array_length(ratings, 1) >= 3")
+
+
+
+

1.3 Hstore

+ +

You need to enable the hstore extension to use hstore.

+
+# db/migrate/20131009135255_create_profiles.rb
+ActiveRecord::Schema.define do
+  enable_extension 'hstore' unless extension_enabled?('hstore')
+  create_table :profiles do |t|
+    t.hstore 'settings'
+  end
+end
+
+# app/models/profile.rb
+class Profile < ApplicationRecord
+end
+
+# Usage
+Profile.create(settings: { "color" => "blue", "resolution" => "800x600" })
+
+profile = Profile.first
+profile.settings # => {"color"=>"blue", "resolution"=>"800x600"}
+
+profile.settings = {"color" => "yellow", "resolution" => "1280x1024"}
+profile.save!
+
+Profile.where("settings->'color' = ?", "yellow")
+#=> #<ActiveRecord::Relation [#<Profile id: 1, settings: {"color"=>"yellow", "resolution"=>"1280x1024"}>]>
+
+
+
+

1.4 JSON

+ +
+
+# db/migrate/20131220144913_create_events.rb
+create_table :events do |t|
+  t.json 'payload'
+end
+
+# app/models/event.rb
+class Event < ApplicationRecord
+end
+
+# Usage
+Event.create(payload: { kind: "user_renamed", change: ["jack", "john"]})
+
+event = Event.first
+event.payload # => {"kind"=>"user_renamed", "change"=>["jack", "john"]}
+
+## Query based on JSON document
+# The -> operator returns the original JSON type (which might be an object), whereas ->> returns text
+Event.where("payload->>'kind' = ?", "user_renamed")
+
+
+
+

1.5 Range Types

+ +

This type is mapped to Ruby Range objects.

+
+# db/migrate/20130923065404_create_events.rb
+create_table :events do |t|
+  t.daterange 'duration'
+end
+
+# app/models/event.rb
+class Event < ApplicationRecord
+end
+
+# Usage
+Event.create(duration: Date.new(2014, 2, 11)..Date.new(2014, 2, 12))
+
+event = Event.first
+event.duration # => Tue, 11 Feb 2014...Thu, 13 Feb 2014
+
+## All Events on a given date
+Event.where("duration @> ?::date", Date.new(2014, 2, 12))
+
+## Working with range bounds
+event = Event.
+  select("lower(duration) AS starts_at").
+  select("upper(duration) AS ends_at").first
+
+event.starts_at # => Tue, 11 Feb 2014
+event.ends_at # => Thu, 13 Feb 2014
+
+
+
+

1.6 Composite Types

+ +

Currently there is no special support for composite types. They are mapped to +normal text columns:

+
+CREATE TYPE full_address AS
+(
+  city VARCHAR(90),
+  street VARCHAR(90)
+);
+
+
+
+
+
+# db/migrate/20140207133952_create_contacts.rb
+execute <<-SQL
+ CREATE TYPE full_address AS
+ (
+   city VARCHAR(90),
+   street VARCHAR(90)
+ );
+SQL
+create_table :contacts do |t|
+  t.column :address, :full_address
+end
+
+# app/models/contact.rb
+class Contact < ApplicationRecord
+end
+
+# Usage
+Contact.create address: "(Paris,Champs-Élysées)"
+contact = Contact.first
+contact.address # => "(Paris,Champs-Élysées)"
+contact.address = "(Paris,Rue Basse)"
+contact.save!
+
+
+
+

1.7 Enumerated Types

+ +

Currently there is no special support for enumerated types. They are mapped as +normal text columns:

+
+# db/migrate/20131220144913_create_articles.rb
+def up
+  execute <<-SQL
+    CREATE TYPE article_status AS ENUM ('draft', 'published');
+  SQL
+  create_table :articles do |t|
+    t.column :status, :article_status
+  end
+end
+
+# NOTE: It's important to drop table before dropping enum.
+def down
+  drop_table :articles
+
+  execute <<-SQL
+    DROP TYPE article_status;
+  SQL
+end
+
+# app/models/article.rb
+class Article < ApplicationRecord
+end
+
+# Usage
+Article.create status: "draft"
+article = Article.first
+article.status # => "draft"
+
+article.status = "published"
+article.save!
+
+
+
+

To add a new value before/after existing one you should use ALTER TYPE:

+
+# db/migrate/20150720144913_add_new_state_to_articles.rb
+# NOTE: ALTER TYPE ... ADD VALUE cannot be executed inside of a transaction block so here we are using disable_ddl_transaction!
+disable_ddl_transaction!
+
+def up
+  execute <<-SQL
+    ALTER TYPE article_status ADD VALUE IF NOT EXISTS 'archived' AFTER 'published';
+  SQL
+end
+
+
+
+

ENUM values can't be dropped currently. You can read why here.

Hint: to show all the values of the all enums you have, you should call this query in bin/rails db or psql console:

+
+SELECT n.nspname AS enum_schema,
+       t.typname AS enum_name,
+       e.enumlabel AS enum_value
+  FROM pg_type t
+      JOIN pg_enum e ON t.oid = e.enumtypid
+      JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
+
+
+
+

1.8 UUID

+ +

You need to enable the pgcrypto (only PostgreSQL >= 9.4) or uuid-ossp +extension to use uuid.

+
+# db/migrate/20131220144913_create_revisions.rb
+create_table :revisions do |t|
+  t.uuid :identifier
+end
+
+# app/models/revision.rb
+class Revision < ApplicationRecord
+end
+
+# Usage
+Revision.create identifier: "A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11"
+
+revision = Revision.first
+revision.identifier # => "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
+
+
+
+

You can use uuid type to define references in migrations:

+
+# db/migrate/20150418012400_create_blog.rb
+enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
+create_table :posts, id: :uuid, default: 'gen_random_uuid()'
+
+create_table :comments, id: :uuid, default: 'gen_random_uuid()' do |t|
+  # t.belongs_to :post, type: :uuid
+  t.references :post, type: :uuid
+end
+
+# app/models/post.rb
+class Post < ApplicationRecord
+  has_many :comments
+end
+
+# app/models/comment.rb
+class Comment < ApplicationRecord
+  belongs_to :post
+end
+
+
+
+

See this section for more details on using UUIDs as primary key.

1.9 Bit String Types

+ +
+
+# db/migrate/20131220144913_create_users.rb
+create_table :users, force: true do |t|
+  t.column :settings, "bit(8)"
+end
+
+# app/models/device.rb
+class User < ApplicationRecord
+end
+
+# Usage
+User.create settings: "01010011"
+user = User.first
+user.settings # => "01010011"
+user.settings = "0xAF"
+user.settings # => 10101111
+user.save!
+
+
+
+

1.10 Network Address Types

+ +

The types inet and cidr are mapped to Ruby +IPAddr +objects. The macaddr type is mapped to normal text.

+
+# db/migrate/20140508144913_create_devices.rb
+create_table(:devices, force: true) do |t|
+  t.inet 'ip'
+  t.cidr 'network'
+  t.macaddr 'address'
+end
+
+# app/models/device.rb
+class Device < ApplicationRecord
+end
+
+# Usage
+macbook = Device.create(ip: "192.168.1.12",
+                        network: "192.168.2.0/24",
+                        address: "32:01:16:6d:05:ef")
+
+macbook.ip
+# => #<IPAddr: IPv4:192.168.1.12/255.255.255.255>
+
+macbook.network
+# => #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
+
+macbook.address
+# => "32:01:16:6d:05:ef"
+
+
+
+

1.11 Geometric Types

+ +

All geometric types, with the exception of points are mapped to normal text. +A point is casted to an array containing x and y coordinates.

2 UUID Primary Keys

You need to enable the pgcrypto (only PostgreSQL >= 9.4) or uuid-ossp +extension to generate random UUIDs.

+
+# db/migrate/20131220144913_create_devices.rb
+enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
+create_table :devices, id: :uuid, default: 'gen_random_uuid()' do |t|
+  t.string :kind
+end
+
+# app/models/device.rb
+class Device < ApplicationRecord
+end
+
+# Usage
+device = Device.create
+device.id # => "814865cd-5a1d-4771-9306-4268f188fe9e"
+
+
+
+

uuid_generate_v4() (from uuid-ossp) is assumed if no :default option was +passed to create_table.

3 Full Text Search

+
+# db/migrate/20131220144913_create_documents.rb
+create_table :documents do |t|
+  t.string 'title'
+  t.string 'body'
+end
+
+execute "CREATE INDEX documents_idx ON documents USING gin(to_tsvector('english', title || ' ' || body));"
+
+# app/models/document.rb
+class Document < ApplicationRecord
+end
+
+# Usage
+Document.create(title: "Cats and Dogs", body: "are nice!")
+
+## all documents matching 'cat & dog'
+Document.where("to_tsvector('english', title || ' ' || body) @@ to_tsquery(?)",
+                 "cat & dog")
+
+
+
+

4 Database Views

+ +

Imagine you need to work with a legacy database containing the following table:

+
+rails_pg_guide=# \d "TBL_ART"
+                                        Table "public.TBL_ART"
+   Column   |            Type             |                         Modifiers
+------------+-----------------------------+------------------------------------------------------------
+ INT_ID     | integer                     | not null default nextval('"TBL_ART_INT_ID_seq"'::regclass)
+ STR_TITLE  | character varying           |
+ STR_STAT   | character varying           | default 'draft'::character varying
+ DT_PUBL_AT | timestamp without time zone |
+ BL_ARCH    | boolean                     | default false
+Indexes:
+    "TBL_ART_pkey" PRIMARY KEY, btree ("INT_ID")
+
+
+
+

This table does not follow the Rails conventions at all. +Because simple PostgreSQL views are updateable by default, +we can wrap it as follows:

+
+# db/migrate/20131220144913_create_articles_view.rb
+execute <<-SQL
+CREATE VIEW articles AS
+  SELECT "INT_ID" AS id,
+         "STR_TITLE" AS title,
+         "STR_STAT" AS status,
+         "DT_PUBL_AT" AS published_at,
+         "BL_ARCH" AS archived
+  FROM "TBL_ART"
+  WHERE "BL_ARCH" = 'f'
+  SQL
+
+# app/models/article.rb
+class Article < ApplicationRecord
+  self.primary_key = "id"
+  def archive!
+    update_attribute :archived, true
+  end
+end
+
+# Usage
+first = Article.create! title: "Winter is coming",
+                        status: "published",
+                        published_at: 1.year.ago
+second = Article.create! title: "Brace yourself",
+                         status: "draft",
+                         published_at: 1.month.ago
+
+Article.count # => 1
+first.archive!
+Article.count # => 2
+
+
+
+

This application only cares about non-archived Articles. A view also +allows for conditions so we can exclude the archived Articles directly.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_record_querying.html b/active_record_querying.html new file mode 100644 index 0000000..a35b482 --- /dev/null +++ b/active_record_querying.html @@ -0,0 +1,1923 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Record 查询接口

本文介绍使用 Active Record 从数据库中检索数据的不同方法。

读完本文后,您将学到:

+
    +
  • 如何使用各种方法和条件查找记录;

  • +
  • 如何指定所查找记录的排序方式、想要检索的属性、分组方式和其他特性;

  • +
  • 如何使用预先加载以减少数据检索所需的数据库查询的数量;

  • +
  • 如何使用动态查找方法;

  • +
  • 如何通过方法链来连续使用多个 Active Record 方法;

  • +
  • 如何检查某个记录是否存在;

  • +
  • 如何在 Active Record 模型上做各种计算;

  • +
  • 如何在关联上执行 EXPLAIN 命令。

  • +
+

如果你习惯直接使用 SQL 来查找数据库记录,那么你通常会发现 Rails 为执行相同操作提供了更好的方式。在大多数情况下,Active Record 使你无需使用 SQL。

本文中的示例代码会用到下面的一个或多个模型:

除非另有说明,下面所有模型都使用 id 作为主键。

+
+class Client < ApplicationRecord
+  has_one :address
+  has_many :orders
+  has_and_belongs_to_many :roles
+end
+
+
+
+
+
+class Address < ApplicationRecord
+  belongs_to :client
+end
+
+
+
+
+
+class Order < ApplicationRecord
+  belongs_to :client, counter_cache: true
+end
+
+
+
+
+
+class Role < ApplicationRecord
+  has_and_belongs_to_many :clients
+end
+
+
+
+

Active Record 会为你执行数据库查询,它和大多数数据库系统兼容,包括 MySQL、MariaDB、PostgreSQL 和 SQLite。不管使用哪个数据库系统,Active Record 方法的用法总是相同的。

1 从数据库中检索对象

Active Record 提供了几个用于从数据库中检索对象的查找方法。查找方法接受参数并执行指定的数据库查询,使我们无需直接编写 SQL。

下面列出这些查找方法:

+
    +
  • find

  • +
  • create_with

  • +
  • distinct

  • +
  • eager_load

  • +
  • extending

  • +
  • from

  • +
  • group

  • +
  • having

  • +
  • includes

  • +
  • joins

  • +
  • left_outer_joins

  • +
  • limit

  • +
  • lock

  • +
  • none

  • +
  • offset

  • +
  • order

  • +
  • preload

  • +
  • readonly

  • +
  • references

  • +
  • reorder

  • +
  • reverse_order

  • +
  • select

  • +
  • distinct

  • +
  • where

  • +
+

上面的所有方法都会返回 ActiveRecord::Relation 实例。

Model.find(options) 执行的主要操作可以概括为:

+
    +
  • 把提供的选项转换为等价的 SQL 查询。

  • +
  • 触发 SQL 查询并从数据库中检索对应的结果。

  • +
  • 为每个查询结果实例化对应的模型对象。

  • +
  • 当存在回调时,先调用 after_find 回调再调用 after_initialize 回调。

  • +
+

1.1 检索单个对象

Active Record 为检索单个对象提供了几个不同的方法。

1.1.1 find 方法

可以使用 find 方法检索指定主键对应的对象,指定主键时可以使用多个选项。例如:

+
+# 查找主键(ID)为 10 的客户
+client = Client.find(10)
+# => #<Client id: 10, first_name: "Ryan">
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients WHERE (clients.id = 10) LIMIT 1
+
+
+
+

如果没有找到匹配的记录,find 方法抛出 ActiveRecord::RecordNotFound 异常。

还可以使用 find 方法查询多个对象,方法是调用 find 方法并传入主键构成的数组。返回值是包含所提供的主键的所有匹配记录的数组。例如:

+
+# 查找主键为 1 和 10 的客户
+client = Client.find([1, 10]) # Or even Client.find(1, 10)
+# => [#<Client id: 1, first_name: "Lifo">, #<Client id: 10, first_name: "Ryan">]
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients WHERE (clients.id IN (1,10))
+
+
+
+

如果所提供的主键都没有匹配记录,那么 find 方法会抛出 ActiveRecord::RecordNotFound 异常。

1.1.2 take 方法

take 方法检索一条记录而不考虑排序。例如:

+
+client = Client.take
+# => #<Client id: 1, first_name: "Lifo">
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients LIMIT 1
+
+
+
+

如果没有找到记录,take 方法返回 nil,而不抛出异常。

take 方法接受数字作为参数,并返回不超过指定数量的查询结果。例如:

+
+client = Client.take(2)
+# => [
+#   #<Client id: 1, first_name: "Lifo">,
+#   #<Client id: 220, first_name: "Sara">
+# ]
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients LIMIT 2
+
+
+
+

take! 方法的行为和 take 方法类似,区别在于如果没有找到匹配的记录,take! 方法抛出 ActiveRecord::RecordNotFound 异常。

对于不同的数据库引擎,take 方法检索的记录可能不一样。

1.1.3 first 方法

first 方法默认查找按主键排序的第一条记录。例如:

+
+client = Client.first
+# => #<Client id: 1, first_name: "Lifo">
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients ORDER BY clients.id ASC LIMIT 1
+
+
+
+

如果没有找到匹配的记录,first 方法返回 nil,而不抛出异常。

如果默认作用域 (请参阅 应用默认作用域)包含排序方法,first 方法会返回按照这个顺序排序的第一条记录。

first 方法接受数字作为参数,并返回不超过指定数量的查询结果。例如:

+
+client = Client.first(3)
+# => [
+#   #<Client id: 1, first_name: "Lifo">,
+#   #<Client id: 2, first_name: "Fifo">,
+#   #<Client id: 3, first_name: "Filo">
+# ]
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients ORDER BY clients.id ASC LIMIT 3
+
+
+
+

对于使用 order 排序的集合,first 方法返回按照指定属性排序的第一条记录。例如:

+
+client = Client.order(:first_name).first
+# => #<Client id: 2, first_name: "Fifo">
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients ORDER BY clients.first_name ASC LIMIT 1
+
+
+
+

first! 方法的行为和 first 方法类似,区别在于如果没有找到匹配的记录,first! 方法会抛出 ActiveRecord::RecordNotFound 异常。

1.1.4 last 方法

last 方法默认查找按主键排序的最后一条记录。例如:

+
+client = Client.last
+# => #<Client id: 221, first_name: "Russel">
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1
+
+
+
+

如果没有找到匹配的记录,last 方法返回 nil,而不抛出异常。

如果默认作用域 (请参阅 应用默认作用域)包含排序方法,last 方法会返回按照这个顺序排序的最后一条记录。

last 方法接受数字作为参数,并返回不超过指定数量的查询结果。例如:

+
+client = Client.last(3)
+# => [
+#   #<Client id: 219, first_name: "James">,
+#   #<Client id: 220, first_name: "Sara">,
+#   #<Client id: 221, first_name: "Russel">
+# ]
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients ORDER BY clients.id DESC LIMIT 3
+
+
+
+

对于使用 order 排序的集合,last 方法返回按照指定属性排序的最后一条记录。例如:

+
+client = Client.order(:first_name).last
+# => #<Client id: 220, first_name: "Sara">
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients ORDER BY clients.first_name DESC LIMIT 1
+
+
+
+

last! 方法的行为和 last 方法类似,区别在于如果没有找到匹配的记录,last! 方法会抛出 ActiveRecord::RecordNotFound 异常。

1.1.5 find_by 方法

find_by 方法查找匹配指定条件的第一条记录。 例如:

+
+Client.find_by first_name: 'Lifo'
+# => #<Client id: 1, first_name: "Lifo">
+
+Client.find_by first_name: 'Jon'
+# => nil
+
+
+
+

上面的代码等价于:

+
+Client.where(first_name: 'Lifo').take
+
+
+
+

和上面的代码等价的 SQL 是:

+
+SELECT * FROM clients WHERE (clients.first_name = 'Lifo') LIMIT 1
+
+
+
+

find_by! 方法的行为和 find_by 方法类似,区别在于如果没有找到匹配的记录,find_by! 方法会抛出 ActiveRecord::RecordNotFound 异常。例如:

+
+Client.find_by! first_name: 'does not exist'
+# => ActiveRecord::RecordNotFound
+
+
+
+

上面的代码等价于:

+
+Client.where(first_name: 'does not exist').take!
+
+
+
+

1.2 批量检索多个对象

我们常常需要遍历大量记录,例如向大量用户发送时事通讯、导出数据等。

处理这类问题的方法看起来可能很简单:

+
+# 如果 users 表有几千行记录,这样做效率很低
+User.all.each do |user|
+  NewsMailer.weekly(user).deliver_now
+end
+
+
+
+

但随着数据表越来越大,这种方法越来越行不通,因为 User.all.each 会使 Active Record 一次性取回整个数据表,为每条记录创建模型对象,并把整个模型对象数组保存在内存中。事实上,如果我们有大量记录,整个模型对象数组需要占用的空间可能会超过可用的内存容量。

Rails 提供了两种方法来解决这个问题,两种方法都是把整个记录分成多个对内存友好的批处理。第一种方法是通过 find_each 方法每次检索一批记录,然后逐一把每条记录作为模型传入块。第二种方法是通过 find_in_batches 方法每次检索一批记录,然后把这批记录整个作为模型数组传入块。

find_eachfind_in_batches 方法用于大量记录的批处理,这些记录数量很大以至于不适合一次性保存在内存中。如果只需要循环 1000 条记录,那么应该首选常规的 find 方法。

1.2.1 find_each 方法

find_each 方法检索一批记录,然后逐一把每条记录作为模型传入块。在下面的例子中,find_each 方法取回 1000 条记录(find_eachfind_in_batches 方法都默认一次检索 1000 条记录),然后逐一把每条记录作为模型传入块。这一过程会不断重复,直到完成所有记录的处理:

+
+User.find_each do |user|
+  NewsMailer.weekly(user).deliver_now
+end
+
+
+
+

要想为 find_each 操作添加条件,我们可以链接其他 Active Record 方法,例如 where 方法:

+
+User.where(weekly_subscriber: true).find_each do |user|
+  NewsMailer.weekly(user).deliver_now
+end
+
+
+
+
1.2.1.1 find_each 方法的选项

find_each 方法可以使用 find 方法的大多数选项,但 :order:limit 选项例外,它们是 find_each 方法内部使用的保留选项。

find_each 方法还可以使用 :batch_size:start:finish 这三个附加选项。

:batch_size

:batch_size 选项用于指明批量检索记录时一次检索多少条记录。例如,一次检索 5000 条记录:

+
+User.find_each(batch_size: 5000) do |user|
+  NewsMailer.weekly(user).deliver_now
+end
+
+
+
+

:start

记录默认是按主键的升序方式取回的,这里的主键必须是整数。:start 选项用于配置想要取回的记录序列的第一个 ID,比这个 ID 小的记录都不会取回。这个选项有时候很有用,例如当需要恢复之前中断的批处理时,只需从最后一个取回的记录之后开始继续处理即可。

下面的例子把时事通讯发送给主键从 2000 开始的用户,一次检索 5000 条用户记录:

+
+User.find_each(start: 2000, batch_size: 5000) do |user|
+  NewsMailer.weekly(user).deliver_now
+end
+
+
+
+

:finish

:start 选项类似,:finish 选项用于配置想要取回的记录序列的最后一个 ID,比这个 ID 大的记录都不会取回。这个选项有时候很有用,例如可以通过配置 :start:finish 选项指明想要批处理的子记录集。

下面的例子把时事通讯发送给主键从 2000 到 10000 的用户,一次检索 5000 条用户记录:

+
+User.find_each(start: 2000, finish: 10000, batch_size: 5000) do |user|
+  NewsMailer.weekly(user).deliver_now
+end
+
+
+
+

另一个例子是使用多个职程(worker)处理同一个进程队列。通过分别配置 :start:finish 选项可以让每个职程每次都处理 10000 条记录。

1.2.2 find_in_batches 方法

find_in_batches 方法和 find_each 方法类似,两者都是批量检索记录。区别在于,find_in_batches 方法会把一批记录作为模型数组传入块,而不是像 find_each 方法那样逐一把每条记录作为模型传入块。下面的例子每次把 1000 张发票的数组一次性传入块(最后一次传入块的数组中的发票数量可能不到 1000):

+
+# 一次把 1000 张发票组成的数组传给 add_invoices
+Invoice.find_in_batches do |invoices|
+  export.add_invoices(invoices)
+end
+
+
+
+
1.2.2.1 find_in_batches 方法的选项

find_each 方法一样,find_in_batches 方法可以使用 :batch_size:start:finish 选项。

2 条件查询

where 方法用于指明限制返回记录所使用的条件,相当于 SQL 语句的 WHERE 部分。条件可以使用字符串、数组或散列指定。

2.1 纯字符串条件

可以直接用纯字符串为查找添加条件。例如,Client.where("orders_count = '2'") 会查找所有 orders_count 字段的值为 2 的客户记录。

使用纯字符串创建条件存在容易受到 SQL 注入攻击的风险。例如,Client.where("first_name LIKE '%#{params[:first_name]}%'") 是不安全的。在下一节中我们会看到,使用数组创建条件是推荐的做法。

2.2 数组条件

如果 Client.where("orders_count = '2'") 这个例子中的数字是变化的,比如说是从别处传递过来的参数,那么可以像下面这样进行查找:

+
+Client.where("orders_count = ?", params[:orders])
+
+
+
+

Active Record 会把第一个参数作为条件字符串,并用之后的其他参数来替换条件字符串中的问号(?)。

我们还可以指定多个条件:

+
+Client.where("orders_count = ? AND locked = ?", params[:orders], false)
+
+
+
+

在上面的例子中,第一个问号会被替换为 params[:orders] 的值,第二个问号会被替换为 false 在 SQL 中对应的值,这个值是什么取决于所使用的数据库适配器。

强烈推荐使用下面这种写法:

+
+Client.where("orders_count = ?", params[:orders])
+
+
+
+

而不是:

+
+Client.where("orders_count = #{params[:orders]}")
+
+
+
+

原因是出于参数的安全性考虑。把变量直接放入条件字符串会导致变量原封不动地传递给数据库,这意味着即使是恶意用户提交的变量也不会被转义。这样一来,整个数据库就处于风险之中,因为一旦恶意用户发现自己能够滥用数据库,他就可能做任何事情。所以,永远不要把参数直接放入条件字符串。

关于 SQL 注入的危险性的更多介绍,请参阅 安全指南

2.2.1 条件中的占位符

和问号占位符(?)类似,我们还可以在条件字符串中使用符号占位符,并通过散列提供符号对应的值:

+
+Client.where("created_at >= :start_date AND created_at <= :end_date",
+  {start_date: params[:start_date], end_date: params[:end_date]})
+
+
+
+

如果条件中有很多变量,那么上面这种写法的可读性更高。

2.3 散列条件

Active Record 还允许使用散列条件,以提高条件语句的可读性。使用散列条件时,散列的键指明需要限制的字段,键对应的值指明如何进行限制。

在散列条件中,只能进行相等性、范围和子集检查。

2.3.1 相等性条件
+
+Client.where(locked: true)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM clients WHERE (clients.locked = 1)
+
+
+
+

其中字段名也可以是字符串:

+
+Client.where('locked' => true)
+
+
+
+

对于 belongs_to 关联来说,如果使用 Active Record 对象作为值,就可以使用关联键来指定模型。这种方法也适用于多态关联。

+
+Article.where(author: author)
+Author.joins(:articles).where(articles: { author: author })
+
+
+
+

相等性条件中的值不能是符号。例如,Client.where(status: :active) 这种写法是错误的。

2.3.2 范围条件
+
+Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
+
+
+
+

上面的代码会使用 BETWEEN SQL 表达式查找所有昨天创建的客户记录:

+
+SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')
+
+
+
+

这是 数组条件中那个示例代码的更简短的写法。

2.3.3 子集条件

要想用 IN 表达式来查找记录,可以在散列条件中使用数组:

+
+Client.where(orders_count: [1,3,5])
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
+
+
+
+

2.4 NOT 条件

可以用 where.not 创建 NOT SQL 查询:

+
+Client.where.not(locked: true)
+
+
+
+

也就是说,先调用没有参数的 where 方法,然后马上链式调用 not 方法,就可以生成这个查询。上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM clients WHERE (clients.locked != 1)
+
+
+
+

3 排序

要想按特定顺序从数据库中检索记录,可以使用 order 方法。

例如,如果想按 created_at 字段的升序方式取回记录:

+
+Client.order(:created_at)
+# 或
+Client.order("created_at")
+
+
+
+

还可以使用 ASC(升序) 或 DESC(降序) 指定排序方式:

+
+Client.order(created_at: :desc)
+# 或
+Client.order(created_at: :asc)
+# 或
+Client.order("created_at DESC")
+# 或
+Client.order("created_at ASC")
+
+
+
+

或按多个字段排序:

+
+Client.order(orders_count: :asc, created_at: :desc)
+# 或
+Client.order(:orders_count, created_at: :desc)
+# 或
+Client.order("orders_count ASC, created_at DESC")
+# 或
+Client.order("orders_count ASC", "created_at DESC")
+
+
+
+

如果多次调用 order 方法,后续排序会在第一次排序的基础上进行:

+
+Client.order("orders_count ASC").order("created_at DESC")
+# SELECT * FROM clients ORDER BY orders_count ASC, created_at DESC
+
+
+
+

4 选择特定字段

Model.find 默认使用 select * 从结果集中选择所有字段。

可以使用 select 方法从结果集中选择字段的子集。

例如,只选择 viewable_bylocked 字段:

+
+Client.select("viewable_by, locked")
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT viewable_by, locked FROM clients
+
+
+
+

请注意,上面的代码初始化的模型对象只包含了所选择的字段,这时如果访问这个模型对象未包含的字段就会抛出异常:

+
+ActiveModel::MissingAttributeError: missing attribute: <attribute>
+
+
+
+

其中 <attribute> 是我们想要访问的字段。id 方法不会引发 ActiveRecord::MissingAttributeError 异常,因此在使用关联时一定要小心,因为只有当 id 方法正常工作时关联才能正常工作。

在查询时如果想让某个字段的同值记录只出现一次,可以使用 distinct 方法添加唯一性约束:

+
+Client.select(:name).distinct
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT DISTINCT name FROM clients
+
+
+
+

唯一性约束在添加之后还可以删除:

+
+query = Client.select(:name).distinct
+# => 返回无重复的名字
+
+query.distinct(false)
+# => 返回所有名字,即使有重复
+
+
+
+

5 限量和偏移量

要想在 Model.find 生成的 SQL 语句中使用 LIMIT 子句,可以在关联上使用 limitoffset 方法。

limit 方法用于指明想要取回的记录数量,offset 方法用于指明取回记录时在第一条记录之前要跳过多少条记录。例如:

+
+Client.limit(5)
+
+
+
+

上面的代码会返回 5 条客户记录,因为没有使用 offset 方法,所以返回的这 5 条记录就是前 5 条记录。生成的 SQL 语句如下:

+
+SELECT * FROM clients LIMIT 5
+
+
+
+

如果使用 offset 方法:

+
+Client.limit(5).offset(30)
+
+
+
+

这时会返回从第 31 条记录开始的 5 条记录。生成的 SQL 语句如下:

+
+SELECT * FROM clients LIMIT 5 OFFSET 30
+
+
+
+

6 分组

要想在查找方法生成的 SQL 语句中使用 GROUP BY 子句,可以使用 group 方法。

例如,如果我们想根据订单创建日期查找订单记录:

+
+Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")
+
+
+
+

上面的代码会为数据库中同一天创建的订单创建 Order 对象。生成的 SQL 语句如下:

+
+SELECT date(created_at) as ordered_date, sum(price) as total_price
+FROM orders
+GROUP BY date(created_at)
+
+
+
+

6.1 分组项目的总数

要想得到一次查询中分组项目的总数,可以在调用 group 方法后调用 count 方法。

+
+Order.group(:status).count
+# => { 'awaiting_approval' => 7, 'paid' => 12 }
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT COUNT (*) AS count_all, status AS status
+FROM "orders"
+GROUP BY status
+
+
+
+

7 having 方法

SQL 语句用 HAVING 子句指明 GROUP BY 字段的约束条件。要想在 Model.find 生成的 SQL 语句中使用 HAVING 子句,可以使用 having 方法。例如:

+
+Order.select("date(created_at) as ordered_date, sum(price) as total_price").
+  group("date(created_at)").having("sum(price) > ?", 100)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT date(created_at) as ordered_date, sum(price) as total_price
+FROM orders
+GROUP BY date(created_at)
+HAVING sum(price) > 100
+
+
+
+

上面的查询会返回每个 Order 对象的日期和总价,查询结果按日期分组并排序,并且总价必须高于 100。

8 条件覆盖

8.1 unscope 方法

可以使用 unscope 方法删除某些条件。 例如:

+
+Article.where('id > 10').limit(20).order('id asc').unscope(:order)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM articles WHERE id > 10 LIMIT 20
+
+# 没使用 `unscope` 之前的查询
+SELECT * FROM articles WHERE id > 10 ORDER BY id asc LIMIT 20
+
+
+
+

还可以使用 unscope 方法删除 where 方法中的某些条件。例如:

+
+Article.where(id: 10, trashed: false).unscope(where: :id)
+# SELECT "articles".* FROM "articles" WHERE trashed = 0
+
+
+
+

在关联中使用 unscope 方法,会对整个关联造成影响:

+
+Article.order('id asc').merge(Article.unscope(:order))
+# SELECT "articles".* FROM "articles"
+
+
+
+

8.2 only 方法

可以使用 only 方法覆盖某些条件。例如:

+
+Article.where('id > 10').limit(20).order('id desc').only(:order, :where)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM articles WHERE id > 10 ORDER BY id DESC
+
+# 没使用 `only` 之前的查询
+SELECT "articles".* FROM "articles" WHERE (id > 10) ORDER BY id desc LIMIT 20
+
+
+
+

8.3 reorder 方法

可以使用 reorder 方法覆盖默认作用域中的排序方式。例如:

+
+class Article < ApplicationRecord
+  has_many :comments, -> { order('posted_at DESC') }
+end
+
+
+
+
+
+Article.find(10).comments.reorder('name')
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM articles WHERE id = 10
+SELECT * FROM comments WHERE article_id = 10 ORDER BY name
+
+
+
+

如果不使用 reorder 方法,那么会生成下面的 SQL 语句:

+
+SELECT * FROM articles WHERE id = 10
+SELECT * FROM comments WHERE article_id = 10 ORDER BY posted_at DESC
+
+
+
+

8.4 reverse_order 方法

可以使用 reverse_order 方法反转排序条件。

+
+Client.where("orders_count > 10").order(:name).reverse_order
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC
+
+
+
+

如果查询时没有使用 order 方法,那么 reverse_order 方法会使查询结果按主键的降序方式排序。

+
+Client.where("orders_count > 10").reverse_order
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
+
+
+
+

reverse_order 方法不接受任何参数。

8.5 rewhere 方法

可以使用 rewhere 方法覆盖 where 方法中指定的条件。例如:

+
+Article.where(trashed: true).rewhere(trashed: false)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM articles WHERE `trashed` = 0
+
+
+
+

如果不使用 rewhere 方法而是再次使用 where 方法:

+
+Article.where(trashed: true).where(trashed: false)
+
+
+
+

会生成下面的 SQL 语句:

+
+SELECT * FROM articles WHERE `trashed` = 1 AND `trashed` = 0
+
+
+
+

9 空关系

none 方法返回可以在链式调用中使用的、不包含任何记录的空关系。在这个空关系上应用后续条件链,会继续生成空关系。对于可能返回零结果、但又需要在链式调用中使用的方法或作用域,可以使用 none 方法来提供返回值。

+
+Article.none # 返回一个空 Relation 对象,而且不执行查询
+
+
+
+
+
+# 下面的 visible_articles 方法期待返回一个空 Relation 对象
+@articles = current_user.visible_articles.where(name: params[:name])
+
+def visible_articles
+  case role
+  when 'Country Manager'
+    Article.where(country: country)
+  when 'Reviewer'
+    Article.published
+  when 'Bad User'
+    Article.none # => 如果这里返回 [] 或 nil,会导致调用方出错
+  end
+end
+
+
+
+

10 只读对象

在关联中使用 Active Record 提供的 readonly 方法,可以显式禁止修改任何返回对象。如果尝试修改只读对象,不但不会成功,还会抛出 ActiveRecord::ReadOnlyRecord 异常。

+
+client = Client.readonly.first
+client.visits += 1
+client.save
+
+
+
+

在上面的代码中,client 被显式设置为只读对象,因此在更新 client.visits 的值后调用 client.save 会抛出 ActiveRecord::ReadOnlyRecord 异常。

11 在更新时锁定记录

在数据库中,锁定用于避免更新记录时的条件竞争,并确保原子更新。

Active Record 提供了两种锁定机制:

+
    +
  • 乐观锁定

  • +
  • 悲观锁定

  • +
+

11.1 乐观锁定

乐观锁定允许多个用户访问并编辑同一记录,并假设数据发生冲突的可能性最小。其原理是检查读取记录后是否有其他进程尝试更新记录,如果有就抛出 ActiveRecord::StaleObjectError 异常,并忽略该更新。

11.1.1 字段的乐观锁定

为了使用乐观锁定,数据表中需要有一个整数类型的 lock_version 字段。每次更新记录时,Active Record 都会增加 lock_version 字段的值。如果更新请求中 lock_version 字段的值比当前数据库中 lock_version 字段的值小,更新请求就会失败,并抛出 ActiveRecord::StaleObjectError 异常。例如:

+
+c1 = Client.find(1)
+c2 = Client.find(1)
+
+c1.first_name = "Michael"
+c1.save
+
+c2.name = "should fail"
+c2.save # 抛出 ActiveRecord::StaleObjectError
+
+
+
+

抛出异常后,我们需要救援异常并处理冲突,或回滚,或合并,或应用其他业务逻辑来解决冲突。

通过设置 ActiveRecord::Base.lock_optimistically = false 可以关闭乐观锁定。

可以使用 ActiveRecord::Base 提供的 locking_column 类属性来覆盖 lock_version 字段名:

+
+class Client < ApplicationRecord
+  self.locking_column = :lock_client_column
+end
+
+
+
+

11.2 悲观锁定

悲观锁定使用底层数据库提供的锁定机制。在创建关联时使用 lock 方法,会在选定字段上生成互斥锁。使用 lock 方法的关联通常被包装在事务中,以避免发生死锁。例如:

+
+Item.transaction do
+  i = Item.lock.first
+  i.name = 'Jones'
+  i.save!
+end
+
+
+
+

对于 MySQL 后端,上面的会话会生成下面的 SQL 语句:

+
+SQL (0.2ms)   BEGIN
+Item Load (0.3ms)   SELECT * FROM `items` LIMIT 1 FOR UPDATE
+Item Update (0.4ms)   UPDATE `items` SET `updated_at` = '2009-02-07 18:05:56', `name` = 'Jones' WHERE `id` = 1
+SQL (0.8ms)   COMMIT
+
+
+
+

要想支持其他锁定类型,可以直接传递 SQL 给 lock 方法。例如,MySQL 的 LOCK IN SHARE MODE 表达式在锁定记录时允许其他查询读取记录,这个表达式可以用作锁定选项:

+
+Item.transaction do
+  i = Item.lock("LOCK IN SHARE MODE").find(1)
+  i.increment!(:views)
+end
+
+
+
+

对于已有模型实例,可以启动事务并一次性获取锁:

+
+item = Item.first
+item.with_lock do
+  # 这个块在事务中调用
+  # item 已经锁定
+  item.increment!(:views)
+end
+
+
+
+

12 联结表

Active Record 提供了 joinsleft_outer_joins 这两个查找方法,用于指明生成的 SQL 语句中的 JOIN 子句。其中,joins 方法用于 INNER JOIN 查询或定制查询,left_outer_joins 用于 LEFT OUTER JOIN 查询。

12.1 joins 方法

joins 方法有多种用法。

12.1.1 使用字符串 SQL 片段

joins 方法中可以直接用 SQL 指明 JOIN 子句:

+
+Author.joins("INNER JOIN posts ON posts.author_id = author.id AND posts.published = 't'")
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT clients.* FROM clients INNER JOIN posts ON posts.author_id = author.id AND posts.published = 't'
+
+
+
+
12.1.2 使用具名关联数组或散列

使用 joins 方法时,Active Record 允许我们使用在模型上定义的关联的名称,作为指明这些关联的 JOIN 子句的快捷方式。

例如,假设有 CategoryArticleCommentGuestTag 这几个模型:

+
+class Category < ApplicationRecord
+  has_many :articles
+end
+
+class Article < ApplicationRecord
+  belongs_to :category
+  has_many :comments
+  has_many :tags
+end
+
+class Comment < ApplicationRecord
+  belongs_to :article
+  has_one :guest
+end
+
+class Guest < ApplicationRecord
+  belongs_to :comment
+end
+
+class Tag < ApplicationRecord
+  belongs_to :article
+end
+
+
+
+

下面几种用法都会使用 INNER JOIN 生成我们想要的关联查询。

(译者注:原文此处开始出现编号错误,由译者根据内容逻辑关系进行了修正。)

12.1.2.1 单个关联的联结
+
+Category.joins(:articles)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT categories.* FROM categories
+  INNER JOIN articles ON articles.category_id = categories.id
+
+
+
+

这个查询的意思是把所有包含了文章的(非空)分类作为一个 Category 对象返回。请注意,如果多篇文章同属于一个分类,那么这个分类会在 Category 对象中出现多次。要想让每个分类只出现一次,可以使用 Category.joins(:articles).distinct

12.1.2.2 多个关联的联结
+
+Article.joins(:category, :comments)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT articles.* FROM articles
+  INNER JOIN categories ON articles.category_id = categories.id
+  INNER JOIN comments ON comments.article_id = articles.id
+
+
+
+

这个查询的意思是把所有属于某个分类并至少拥有一条评论的文章作为一个 Article 对象返回。同样请注意,拥有多条评论的文章会在 Article 对象中出现多次。

12.1.2.3 单层嵌套关联的联结
+
+Article.joins(comments: :guest)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT articles.* FROM articles
+  INNER JOIN comments ON comments.article_id = articles.id
+  INNER JOIN guests ON guests.comment_id = comments.id
+
+
+
+

这个查询的意思是把所有拥有访客评论的文章作为一个 Article 对象返回。

12.1.2.4 多层嵌套关联的联结
+
+Category.joins(articles: [{ comments: :guest }, :tags])
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT categories.* FROM categories
+  INNER JOIN articles ON articles.category_id = categories.id
+  INNER JOIN comments ON comments.article_id = articles.id
+  INNER JOIN guests ON guests.comment_id = comments.id
+  INNER JOIN tags ON tags.article_id = articles.id
+
+
+
+

这个查询的意思是把所有包含文章的分类作为一个 Category 对象返回,其中这些文章都拥有访客评论并且带有标签。

12.1.3 为联结表指明条件

可以使用普通的数组和字符串条件作为关联数据表的条件。但如果想使用散列条件作为关联数据表的条件,就需要使用特殊语法了:

+
+time_range = (Time.now.midnight - 1.day)..Time.now.midnight
+Client.joins(:orders).where('orders.created_at' => time_range)
+
+
+
+

还有一种更干净的替代语法,即嵌套使用散列条件:

+
+time_range = (Time.now.midnight - 1.day)..Time.now.midnight
+Client.joins(:orders).where(orders: { created_at: time_range })
+
+
+
+

这个查询会查找所有在昨天创建过订单的客户,在生成的 SQL 语句中同样使用了 BETWEEN SQL 表达式。

12.2 left_outer_joins 方法

如果想要选择一组记录,而不管它们是否具有关联记录,可以使用 left_outer_joins 方法。

+
+Author.left_outer_joins(:posts).distinct.select('authors.*, COUNT(posts.*) AS posts_count').group('authors.id')
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT DISTINCT authors.*, COUNT(posts.*) AS posts_count FROM "authors"
+LEFT OUTER JOIN posts ON posts.author_id = authors.id GROUP BY authors.id
+
+
+
+

这个查询的意思是返回所有作者和每位作者的帖子数,而不管这些作者是否发过帖子。

13 及早加载关联

及早加载是一种用于加载 Model.find 返回对象的关联记录的机制,目的是尽可能减少查询次数。

N + 1 查询问题

假设有如下代码,查找 10 条客户记录并打印这些客户的邮编:

+
+clients = Client.limit(10)
+
+clients.each do |client|
+  puts client.address.postcode
+end
+
+
+
+

上面的代码第一眼看起来不错,但实际上存在查询总次数较高的问题。这段代码总共需要执行 1(查找 10 条客户记录)+ 10(每条客户记录都需要加载地址)= 11 次查询。

N + 1 查询问题的解决办法

Active Record 允许我们提前指明需要加载的所有关联,这是通过在调用 Model.find 时指明 includes 方法实现的。通过指明 includes 方法,Active Record 会使用尽可能少的查询来加载所有已指明的关联。

回到之前 N + 1 查询问题的例子,我们重写其中的 Client.limit(10) 来使用及早加载:

+
+clients = Client.includes(:address).limit(10)
+
+clients.each do |client|
+  puts client.address.postcode
+end
+
+
+
+

上面的代码只执行 2 次查询,而不是之前的 11 次查询:

+
+SELECT * FROM clients LIMIT 10
+SELECT addresses.* FROM addresses
+  WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))
+
+
+
+

13.1 及早加载多个关联

通过在 includes 方法中使用数组、散列或嵌套散列,Active Record 允许我们在一次 Model.find 调用中及早加载任意数量的关联。

13.1.1 多个关联的数组
+
+Article.includes(:category, :comments)
+
+
+
+

上面的代码会加载所有文章、所有关联的分类和每篇文章的所有评论。

13.1.2 嵌套关联的散列
+
+Category.includes(articles: [{ comments: :guest }, :tags]).find(1)
+
+
+
+

上面的代码会查找 ID 为 1 的分类,并及早加载所有关联的文章、这些文章关联的标签和评论,以及这些评论关联的访客。

13.2 为关联的及早加载指明条件

尽管 Active Record 允许我们像 joins 方法那样为关联的及早加载指明条件,但推荐的方式是使用联结

尽管如此,在必要时仍然可以用 where 方法来为关联的及早加载指明条件。

+
+Article.includes(:comments).where(comments: { visible: true })
+
+
+
+

上面的代码会生成使用 LEFT OUTER JOIN 子句的 SQL 语句,而 joins 方法会成生使用 INNER JOIN 子句的 SQL 语句。

+
+SELECT "articles"."id" AS t0_r0, ... "comments"."updated_at" AS t1_r5 FROM "articles" LEFT OUTER JOIN "comments" ON "comments"."article_id" = "articles"."id" WHERE (comments.visible = 1)
+
+
+
+

如果上面的代码没有使用 where 方法,就会生成常规的一组两条查询语句。

要想像上面的代码那样使用 where 方法,必须在 where 方法中使用散列。如果想要在 where 方法中使用字符串 SQL 片段,就必须用 references 方法强制使用联结表:

+
+Article.includes(:comments).where("comments.visible = true").references(:comments)
+
+
+
+

通过在 where 方法中使用字符串 SQL 片段并使用 references 方法这种方式,即使一条评论都没有,所有文章仍然会被加载。而在使用 joins 方法(INNER JOIN)时,必须匹配关联条件,否则一条记录都不会返回。

14 作用域

作用域允许我们把常用查询定义为方法,然后通过在关联对象或模型上调用方法来引用这些查询。fotnote:[“作用域”和“作用域方法”在本文中是一个意思。——译者注]在作用域中,我们可以使用之前介绍过的所有方法,如 wherejoinincludes 方法。所有作用域都会返回 ActiveRecord::Relation 对象,这样就可以继续在这个对象上调用其他方法(如其他作用域)。

要想定义简单的作用域,我们可以在类中通过 scope 方法定义作用域,并传入调用这个作用域时执行的查询。

+
+class Article < ApplicationRecord
+  scope :published, -> { where(published: true) }
+end
+
+
+
+

通过上面这种方式定义作用域和通过定义类方法来定义作用域效果完全相同,至于使用哪种方式只是个人喜好问题:

+
+class Article < ApplicationRecord
+  def self.published
+    where(published: true)
+  end
+end
+
+
+
+

在作用域中可以链接其他作用域:

+
+class Article < ApplicationRecord
+  scope :published,               -> { where(published: true) }
+  scope :published_and_commented, -> { published.where("comments_count > 0") }
+end
+
+
+
+

我们可以在模型上调用 published 作用域:

+
+Article.published # => [published articles]
+
+
+
+

或在多个 Article 对象组成的关联对象上调用 published 作用域:

+
+category = Category.first
+category.articles.published # => [published articles belonging to this category]
+
+
+
+

14.1 传入参数

作用域可以接受参数:

+
+class Article < ApplicationRecord
+  scope :created_before, ->(time) { where("created_at < ?", time) }
+end
+
+
+
+

调用作用域和调用类方法一样:

+
+Article.created_before(Time.zone.now)
+
+
+
+

不过这只是复制了本该通过类方法提供给我们的的功能。

+
+class Article < ApplicationRecord
+  def self.created_before(time)
+    where("created_at < ?", time)
+  end
+end
+
+
+
+

当作用域需要接受参数时,推荐改用类方法。使用类方法时,这些方法仍然可以在关联对象上访问:

+
+category.articles.created_before(time)
+
+
+
+

14.2 使用条件

我们可以在作用域中使用条件:

+
+class Article < ApplicationRecord
+  scope :created_before, ->(time) { where("created_at < ?", time) if time.present? }
+end
+
+
+
+

和之前的例子一样,作用域的这一行为也和类方法类似。

+
+class Article < ApplicationRecord
+  def self.created_before(time)
+    where("created_at < ?", time) if time.present?
+  end
+end
+
+
+
+

不过有一点需要特别注意:不管条件的值是 true 还是 false,作用域总是返回 ActiveRecord::Relation 对象,而当条件是 false 时,类方法返回的是 nil。因此,当链接带有条件的类方法时,如果任何一个条件的值是 false,就会引发 NoMethodError 异常。

14.3 应用默认作用域

要想在模型的所有查询中应用作用域,我们可以在这个模型上使用 default_scope 方法。

+
+class Client < ApplicationRecord
+  default_scope { where("removed_at IS NULL") }
+end
+
+
+
+

应用默认作用域后,在这个模型上执行查询,会生成下面这样的 SQL 语句:

+
+SELECT * FROM clients WHERE removed_at IS NULL
+
+
+
+

如果想用默认作用域做更复杂的事情,我们也可以把它定义为类方法:

+
+class Client < ApplicationRecord
+  def self.default_scope
+    # 应该返回一个 ActiveRecord::Relation 对象
+  end
+end
+
+
+
+

默认作用域在创建记录时同样起作用,但在更新记录时不起作用。例如:

+
+class Client < ApplicationRecord
+ default_scope { where(active: true) }
+end
+
+Client.new          # => #<Client id: nil, active: true>
+Client.unscoped.new # => #<Client id: nil, active: nil>
+
+
+
+

14.4 合并作用域

WHERE 子句一样,我们用 AND 来合并作用域。

+
+class User < ApplicationRecord
+  scope :active, -> { where state: 'active' }
+  scope :inactive, -> { where state: 'inactive' }
+end
+
+User.active.inactive
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'inactive'
+
+
+
+

我们可以混合使用 scopewhere 方法,这样最后生成的 SQL 语句会使用 AND 连接所有条件。

+
+User.active.where(state: 'finished')
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'finished'
+
+
+
+

如果使用 Relation#merge 方法,那么在发生条件冲突时总是最后的 WHERE 子句起作用。

+
+User.active.merge(User.inactive)
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
+
+
+
+

有一点需要特别注意,default_scope 总是在所有 scopewhere 之前起作用。

+
+class User < ApplicationRecord
+  default_scope { where state: 'pending' }
+  scope :active, -> { where state: 'active' }
+  scope :inactive, -> { where state: 'inactive' }
+end
+
+User.all
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
+
+User.active
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'active'
+
+User.where(state: 'inactive')
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'inactive'
+
+
+
+

在上面的代码中我们可以看到,在 scope 条件和 where 条件中都合并了 default_scope 条件。

14.5 删除所有作用域

在需要时,可以使用 unscoped 方法删除作用域。如果在模型中定义了默认作用域,但在某次查询中又不想应用默认作用域,这时就可以使用 unscoped 方法。

+
+Client.unscoped.load
+
+
+
+

unscoped 方法会删除所有作用域,仅在数据表上执行常规查询。

+
+Client.unscoped.all
+# SELECT "clients".* FROM "clients"
+
+Client.where(published: false).unscoped.all
+# SELECT "clients".* FROM "clients"
+
+
+
+

unscoped 方法也接受块作为参数。

+
+Client.unscoped {
+  Client.created_before(Time.zone.now)
+}
+
+
+
+

15 动态查找方法

Active Record 为数据表中的每个字段(也称为属性)都提供了查找方法(也就是动态查找方法)。例如,对于 Client 模型的 first_name 字段,Active Record 会自动生成 find_by_first_name 查找方法。对于 Client 模型的 locked 字段,Active Record 会自动生成 find_by_locked 查找方法。

在调用动态查找方法时可以在末尾加上感叹号(!),例如 Client.find_by_name!("Ryan"),这样如果动态查找方法没有返回任何记录,就会抛出 ActiveRecord::RecordNotFound 异常。

如果想同时查询 first_namelocked 字段,可以在动态查找方法中用 and 把这两个字段连起来,例如 Client.find_by_first_name_and_locked("Ryan", true)

16 enum

enum 宏把整数字段映射为一组可能的值。

+
+class Book < ApplicationRecord
+  enum availability: [:available, :unavailable]
+end
+
+
+
+

上面的代码会自动创建用于查询模型的对应作用域,同时会添加用于转换状态和查询当前状态的方法。

+
+# 下面的示例只查询可用的图书
+Book.available
+# 或
+Book.where(availability: :available)
+
+book = Book.new(availability: :available)
+book.available?   # => true
+book.unavailable! # => true
+book.available?   # => false
+
+
+
+

请访问 Rails API 文档,查看 enum 宏的完整文档。

17 理解方法链

Active Record 实现方法链的方式既简单又直接,有了方法链我们就可以同时使用多个 Active Record 方法。

当之前的方法调用返回 ActiveRecord::Relation 对象时,例如 allwherejoins 方法,我们就可以在语句中把方法连接起来。返回单个对象的方法(请参阅 检索单个对象)必须位于语句的末尾。

下面给出了一些例子。本文无法涵盖所有的可能性,这里给出的只是很少的一部分例子。在调用 Active Record 方法时,查询不会立即生成并发送到数据库,这些操作只有在实际需要数据时才会执行。下面的每个例子都会生成一次查询。

17.1 从多个数据表中检索过滤后的数据

+
+Person
+  .select('people.id, people.name, comments.text')
+  .joins(:comments)
+  .where('comments.created_at > ?', 1.week.ago)
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT people.id, people.name, comments.text
+FROM people
+INNER JOIN comments
+  ON comments.person_id = people.id
+WHERE comments.created_at = '2015-01-01'
+
+
+
+

17.2 从多个数据表中检索特定的数据

+
+Person
+  .select('people.id, people.name, companies.name')
+  .joins(:company)
+  .find_by('people.name' => 'John') # this should be the last
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT people.id, people.name, companies.name
+FROM people
+INNER JOIN companies
+  ON companies.person_id = people.id
+WHERE people.name = 'John'
+LIMIT 1
+
+
+
+

请注意,如果查询匹配多条记录,find_by 方法会取回第一条记录并忽略其他记录(如上面的 SQL 语句中的 LIMIT 1)。

18 查找或创建新对象

我们经常需要查找记录并在找不到记录时创建记录,这时我们可以使用 find_or_create_byfind_or_create_by! 方法。

18.1 find_or_create_by 方法

find_or_create_by 方法检查具有指定属性的记录是否存在。如果记录不存在,就调用 create 方法创建记录。让我们看一个例子。

假设我们在查找名为“Andy”的用户记录,但是没找到,因此要创建这条记录。这时我们可以执行下面的代码:

+
+Client.find_or_create_by(first_name: 'Andy')
+# => #<Client id: 1, first_name: "Andy", orders_count: 0, locked: true, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT * FROM clients WHERE (clients.first_name = 'Andy') LIMIT 1
+BEGIN
+INSERT INTO clients (created_at, first_name, locked, orders_count, updated_at) VALUES ('2011-08-30 05:22:57', 'Andy', 1, NULL, '2011-08-30 05:22:57')
+COMMIT
+
+
+
+

find_or_create_by 方法会返回已存在的记录或新建的记录。在本例中,名为“Andy”的客户记录并不存在,因此会创建并返回这条记录。

新建记录不一定会保存到数据库,是否保存取决于验证是否通过(就像 create 方法那样)。

假设我们想在新建记录时把 locked 字段设置为 false,但又不想在查询中进行设置。例如,我们想查找名为“Andy”的客户记录,但这条记录并不存在,因此要创建这条记录并把 locked 字段设置为 false

要完成这一操作有两种方式。第一种方式是使用 create_with 方法:

+
+Client.create_with(locked: false).find_or_create_by(first_name: 'Andy')
+
+
+
+

第二种方式是使用块:

+
+Client.find_or_create_by(first_name: 'Andy') do |c|
+  c.locked = false
+end
+
+
+
+

只有在创建客户记录时才会执行该块。第二次运行这段代码时(此时客户记录已创建),块会被忽略。

18.2 find_or_create_by! 方法

我们也可以使用 find_or_create_by! 方法,这样如果新建记录是无效的就会抛出异常。本文不涉及数据验证,不过这里我们暂且假设已经在 Client 模型中添加了下面的数据验证:

+
+validates :orders_count, presence: true
+
+
+
+

如果我们尝试新建客户记录,但忘了传递 orders_count 字段的值,新建记录就是无效的,因而会抛出下面的异常:

+
+Client.find_or_create_by!(first_name: 'Andy')
+# => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank
+
+
+
+

18.3 find_or_initialize_by 方法

find_or_initialize_by 方法的工作原理和 find_or_create_by 方法类似,区别之处在于前者调用的是 new 方法而不是 create 方法。这意味着新建模型实例在内存中创建,但没有保存到数据库。下面继续使用介绍 find_or_create_by 方法时使用的例子,我们现在想查找名为“Nick”的客户记录:

+
+nick = Client.find_or_initialize_by(first_name: 'Nick')
+# => #<Client id: nil, first_name: "Nick", orders_count: 0, locked: true, created_at: "2011-08-30 06:09:27", updated_at: "2011-08-30 06:09:27">
+
+nick.persisted?
+# => false
+
+nick.new_record?
+# => true
+
+
+
+

出现上面的执行结果是因为 nick 对象还没有保存到数据库。在上面的代码中,find_or_initialize_by 方法会生成下面的 SQL 语句:

+
+SELECT * FROM clients WHERE (clients.first_name = 'Nick') LIMIT 1
+
+
+
+

要想把 nick 对象保存到数据库,只需调用 save 方法:

+
+nick.save
+# => true
+
+
+
+

19 使用 SQL 语句进行查找

要想直接使用 SQL 语句在数据表中查找记录,可以使用 find_by_sql 方法。find_by_sql 方法总是返回对象的数组,即使底层查询只返回了一条记录也是如此。例如,我们可以执行下面的查询:

+
+Client.find_by_sql("SELECT * FROM clients
+  INNER JOIN orders ON clients.id = orders.client_id
+  ORDER BY clients.created_at desc")
+# =>  [
+#   #<Client id: 1, first_name: "Lucas" >,
+#   #<Client id: 2, first_name: "Jan" >,
+#   ...
+# ]
+
+
+
+

find_by_sql 方法提供了对数据库进行定制查询并取回实例化对象的简单方式。

19.1 select_all 方法

find_by_sql 方法有一个名为 connection#select_all 的近亲。和 find_by_sql 方法一样,select_all 方法也会使用定制的 SQL 语句从数据库中检索对象,区别在于 select_all 方法不会对这些对象进行实例化,而是返回一个散列构成的数组,其中每个散列表示一条记录。

+
+Client.connection.select_all("SELECT first_name, created_at FROM clients WHERE id = '1'")
+# => [
+#   {"first_name"=>"Rafael", "created_at"=>"2012-11-10 23:23:45.281189"},
+#   {"first_name"=>"Eileen", "created_at"=>"2013-12-09 11:22:35.221282"}
+# ]
+
+
+
+

19.2 pluck 方法

pluck 方法用于在模型对应的底层数据表中查询单个或多个字段。它接受字段名的列表作为参数,并返回这些字段的值的数组,数组中的每个值都具有对应的数据类型。

+
+Client.where(active: true).pluck(:id)
+# SELECT id FROM clients WHERE active = 1
+# => [1, 2, 3]
+
+Client.distinct.pluck(:role)
+# SELECT DISTINCT role FROM clients
+# => ['admin', 'member', 'guest']
+
+Client.pluck(:id, :name)
+# SELECT clients.id, clients.name FROM clients
+# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
+
+
+
+

使用 pluck 方法,我们可以把下面的代码:

+
+Client.select(:id).map { |c| c.id }
+# 或
+Client.select(:id).map(&:id)
+# 或
+Client.select(:id, :name).map { |c| [c.id, c.name] }
+
+
+
+

替换为:

+
+Client.pluck(:id)
+# 或
+Client.pluck(:id, :name)
+
+
+
+

select 方法不同,pluck 方法把数据库查询结果直接转换为 Ruby 数组,而不是构建 Active Record 对象。这意味着对于大型查询或常用查询,pluck 方法的性能更好。不过对于 pluck 方法,模型方法重载是不可用的。例如:

+
+class Client < ApplicationRecord
+  def name
+    "I am #{super}"
+  end
+end
+
+Client.select(:name).map &:name
+# => ["I am David", "I am Jeremy", "I am Jose"]
+
+Client.pluck(:name)
+# => ["David", "Jeremy", "Jose"]
+
+
+
+

此外,和 select 方法及其他 Relation 作用域不同,pluck 方法会触发即时查询,因此在 pluck 方法之前可以链接作用域,但在 pluck 方法之后不能链接作用域:

+
+Client.pluck(:name).limit(1)
+# => NoMethodError: undefined method `limit' for #<Array:0x007ff34d3ad6d8>
+
+Client.limit(1).pluck(:name)
+# => ["David"]
+
+
+
+

19.3 ids 方法

使用 ids 方法可以获得关联的所有 ID,也就是数据表的主键。

+
+Person.ids
+# SELECT id FROM people
+
+
+
+
+
+class Person < ApplicationRecord
+  self.primary_key = "person_id"
+end
+
+Person.ids
+# SELECT person_id FROM people
+
+
+
+

20 检查对象是否存在

要想检查对象是否存在,可以使用 exists? 方法。exists? 方法查询数据库的工作原理和 find 方法相同,但是 find 方法返回的是对象或对象集合,而 exists? 方法返回的是 truefalse

+
+Client.exists?(1)
+
+
+
+

exists? 方法也接受多个值作为参数,并且只要有一条对应记录存在就会返回 true

+
+Client.exists?(id: [1,2,3])
+# 或
+Client.exists?(name: ['John', 'Sergei'])
+
+
+
+

我们还可以在模型或关联上调用 exists? 方法,这时不需要任何参数。

+
+Client.where(first_name: 'Ryan').exists?
+
+
+
+

只要存在一条名为“Ryan”的客户记录,上面的代码就会返回 true,否则返回 false

+
+Client.exists?
+
+
+
+

如果 clients 数据表是空的,上面的代码返回 false,否则返回 true

我们还可以在模型或关联上调用 any?many? 方法来检查对象是否存在。

+
+# 通过模型
+Article.any?
+Article.many?
+
+# 通过指定的作用域
+Article.recent.any?
+Article.recent.many?
+
+# 通过关系
+Article.where(published: true).any?
+Article.where(published: true).many?
+
+# 通过关联
+Article.first.categories.any?
+Article.first.categories.many?
+
+
+
+

21 计算

在本节的前言中我们以 count 方法为例,例子中提到的所有选项对本节的各小节都适用。

所有用于计算的方法都可以直接在模型上调用:

+
+Client.count
+# SELECT count(*) AS count_all FROM clients
+
+
+
+

或者在关联上调用:

+
+Client.where(first_name: 'Ryan').count
+# SELECT count(*) AS count_all FROM clients WHERE (first_name = 'Ryan')
+
+
+
+

我们还可以在关联上执行各种查找方法来执行复杂的计算:

+
+Client.includes("orders").where(first_name: 'Ryan', orders: { status: 'received' }).count
+
+
+
+

上面的代码会生成下面的 SQL 语句:

+
+SELECT count(DISTINCT clients.id) AS count_all FROM clients
+  LEFT OUTER JOIN orders ON orders.client_id = client.id WHERE
+  (clients.first_name = 'Ryan' AND orders.status = 'received')
+
+
+
+

21.1 count 方法

要想知道模型对应的数据表中有多少条记录,可以使用 Client.count 方法,这个方法的返回值就是记录条数。如果想要知道特定记录的条数,例如具有 age 字段值的所有客户记录的条数,可以使用 Client.count(:age)

关于 count 方法的选项的更多介绍,请参阅 计算

21.2 average 方法

要想知道数据表中某个字段的平均值,可以在数据表对应的类上调用 average 方法。例如:

+
+Client.average("orders_count")
+
+
+
+

上面的代码会返回表示 orders_count 字段平均值的数字(可能是浮点数,如 3.14159265)。

关于 average 方法的选项的更多介绍,请参阅 计算

21.3 minimum 方法

要想查找数据表中某个字段的最小值,可以在数据表对应的类上调用 minimum 方法。例如:

+
+Client.minimum("age")
+
+
+
+

关于 minimum 方法的选项的更多介绍,请参阅 计算

21.4 maximum 方法

要想查找数据表中某个字段的最大值,可以在数据表对应的类上调用 maximum 方法。例如:

+
+Client.maximum("age")
+
+
+
+

关于 maximum 方法的选项的更多介绍,请参阅 计算

21.5 sum 方法

要想知道数据表中某个字段的所有字段值之和,可以在数据表对应的类上调用 sum 方法。例如:

+
+Client.sum("orders_count")
+
+
+
+

关于 sum 方法的选项的更多介绍,请参阅 计算

22 执行 EXPLAIN 命令

我们可以在关联触发的查询上执行 EXPLAIN 命令。例如:

+
+User.where(id: 1).joins(:articles).explain
+
+
+
+

对于 MySQL 和 MariaDB 数据库后端,上面的代码会产生下面的输出结果:

+
+EXPLAIN for: SELECT `users`.* FROM `users` INNER JOIN `articles` ON `articles`.`user_id` = `users`.`id` WHERE `users`.`id` = 1
++----+-------------+----------+-------+---------------+
+| id | select_type | table    | type  | possible_keys |
++----+-------------+----------+-------+---------------+
+|  1 | SIMPLE      | users    | const | PRIMARY       |
+|  1 | SIMPLE      | articles | ALL   | NULL          |
++----+-------------+----------+-------+---------------+
++---------+---------+-------+------+-------------+
+| key     | key_len | ref   | rows | Extra       |
++---------+---------+-------+------+-------------+
+| PRIMARY | 4       | const |    1 |             |
+| NULL    | NULL    | NULL  |    1 | Using where |
++---------+---------+-------+------+-------------+
+
+2 rows in set (0.00 sec)
+
+
+
+

Active Record 会模拟对应数据库的 shell 来打印输出结果。因此对于 PostgreSQL 数据库后端,同样的代码会产生下面的输出结果:

+
+EXPLAIN for: SELECT "users".* FROM "users" INNER JOIN "articles" ON "articles"."user_id" = "users"."id" WHERE "users"."id" = 1
+                                  QUERY PLAN
+------------------------------------------------------------------------------
+ Nested Loop Left Join  (cost=0.00..37.24 rows=8 width=0)
+   Join Filter: (articles.user_id = users.id)
+   ->  Index Scan using users_pkey on users  (cost=0.00..8.27 rows=1 width=4)
+         Index Cond: (id = 1)
+   ->  Seq Scan on articles  (cost=0.00..28.88 rows=8 width=4)
+         Filter: (articles.user_id = 1)
+(6 rows)
+
+
+
+

及早加载在底层可能会触发多次查询,有的查询可能需要使用之前查询的结果。因此,explain 方法实际上先执行了查询,然后询问查询计划。例如:

+
+User.where(id: 1).includes(:articles).explain
+
+
+
+

对于 MySQL 和 MariaDB 数据库后端,上面的代码会产生下面的输出结果:

+
+EXPLAIN for: SELECT `users`.* FROM `users`  WHERE `users`.`id` = 1
++----+-------------+-------+-------+---------------+
+| id | select_type | table | type  | possible_keys |
++----+-------------+-------+-------+---------------+
+|  1 | SIMPLE      | users | const | PRIMARY       |
++----+-------------+-------+-------+---------------+
++---------+---------+-------+------+-------+
+| key     | key_len | ref   | rows | Extra |
++---------+---------+-------+------+-------+
+| PRIMARY | 4       | const |    1 |       |
++---------+---------+-------+------+-------+
+
+1 row in set (0.00 sec)
+
+EXPLAIN for: SELECT `articles`.* FROM `articles`  WHERE `articles`.`user_id` IN (1)
++----+-------------+----------+------+---------------+
+| id | select_type | table    | type | possible_keys |
++----+-------------+----------+------+---------------+
+|  1 | SIMPLE      | articles | ALL  | NULL          |
++----+-------------+----------+------+---------------+
++------+---------+------+------+-------------+
+| key  | key_len | ref  | rows | Extra       |
++------+---------+------+------+-------------+
+| NULL | NULL    | NULL |    1 | Using where |
++------+---------+------+------+-------------+
+
+
+1 row in set (0.00 sec)
+
+
+
+

22.1 对 EXPLAIN 命令输出结果的解释

EXPLAIN 命令输出结果的解释超出了本文的范畴。下面提供了一些有用链接:

+ + + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_record_validations.html b/active_record_validations.html new file mode 100644 index 0000000..103449b --- /dev/null +++ b/active_record_validations.html @@ -0,0 +1,1161 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Record 数据验证

本文介绍如何使用 Active Record 提供的数据验证功能,在数据存入数据库之前验证对象的状态。

读完本文后,您将学到:

+
    +
  • 如何使用 Active Record 内置的数据验证辅助方法;

  • +
  • 如果自定义数据验证方法;

  • +
  • 如何处理验证过程产生的错误消息。

  • +
+

1 数据验证概览

下面是一个非常简单的数据验证:

+
+class Person < ApplicationRecord
+  validates :name, presence: true
+end
+
+Person.create(name: "John Doe").valid? # => true
+Person.create(name: nil).valid? # => false
+
+
+
+

可以看出,如果 Person 没有 name 属性,验证就会将其视为无效对象。第二个 Person 对象不会存入数据库。

在深入探讨之前,我们先来了解数据验证在应用中的作用。

1.1 为什么要做数据验证?

数据验证确保只有有效的数据才能存入数据库。例如,应用可能需要用户提供一个有效的电子邮件地址和邮寄地址。在模型中做验证是最有保障的,只有通过验证的数据才能存入数据库。数据验证和使用的数据库种类无关,终端用户也无法跳过,而且容易测试和维护。在 Rails 中做数据验证很简单,Rails 内置了很多辅助方法,能满足常规的需求,而且还可以编写自定义的验证方法。

在数据存入数据库之前,也有几种验证数据的方法,包括数据库原生的约束、客户端验证和控制器层验证。下面列出这几种验证方法的优缺点:

+
    +
  • 数据库约束和存储过程无法兼容多种数据库,而且难以测试和维护。然而,如果其他应用也要使用这个数据库,最好在数据库层做些约束。此外,数据库层的某些验证(例如在使用量很高的表中做唯一性验证)通过其他方式实现起来有点困难。

  • +
  • 客户端验证很有用,但单独使用时可靠性不高。如果使用 JavaScript 实现,用户在浏览器中禁用 JavaScript 后很容易跳过验证。然而,客户端验证和其他验证方式相结合,可以为用户提供实时反馈。

  • +
  • 控制器层验证很诱人,但一般都不灵便,难以测试和维护。只要可能,就要保证控制器的代码简洁,这样才有利于长远发展。

  • +
+

你可以根据实际需求选择使用合适的验证方式。Rails 团队认为,模型层数据验证最具普适性。

1.2 数据在何时验证?

Active Record 对象分为两种:一种在数据库中有对应的记录,一种没有。新建的对象(例如,使用 new 方法)还不属于数据库。在对象上调用 save 方法后,才会把对象存入相应的数据库表。Active Record 使用实例方法 new_record? 判断对象是否已经存入数据库。假如有下面这个简单的 Active Record 类:

+
+class Person < ApplicationRecord
+end
+
+
+
+

我们可以在 rails console 中看一下到底怎么回事:

+
+$ bin/rails console
+>> p = Person.new(name: "John Doe")
+=> #<Person id: nil, name: "John Doe", created_at: nil, updated_at: nil>
+>> p.new_record?
+=> true
+>> p.save
+=> true
+>> p.new_record?
+=> false
+
+
+
+

新建并保存记录会在数据库中执行 SQL INSERT 操作。更新现有的记录会在数据库中执行 SQL UPDATE 操作。一般情况下,数据验证发生在这些 SQL 操作执行之前。如果验证失败,对象会被标记为无效,Active Record 不会向数据库发送 INSERTUPDATE 指令。这样就可以避免把无效的数据存入数据库。你可以选择在对象创建、保存或更新时执行特定的数据验证。

修改数据库中对象的状态有多种方式。有些方法会触发数据验证,有些则不会。所以,如果不小心处理,还是有可能把无效的数据存入数据库。

下列方法会触发数据验证,如果验证失败就不把对象存入数据库:

+
    +
  • create

  • +
  • create!

  • +
  • save

  • +
  • save!

  • +
  • update

  • +
  • update!

  • +
+

爆炸方法(例如 save!)会在验证失败后抛出异常。验证失败后,非爆炸方法不会抛出异常,saveupdate 返回 falsecreate 返回对象本身。

1.3 跳过验证

下列方法会跳过验证,不管验证是否通过都会把对象存入数据库,使用时要特别留意。

+
    +
  • decrement!

  • +
  • decrement_counter

  • +
  • increment!

  • +
  • increment_counter

  • +
  • toggle!

  • +
  • touch

  • +
  • update_all

  • +
  • update_attribute

  • +
  • update_column

  • +
  • update_columns

  • +
  • update_counters

  • +
+

注意,使用 save 时如果传入 validate: false 参数,也会跳过验证。使用时要特别留意。

+
    +
  • save(validate: false)
  • +
+

1.4 valid?invalid? +

Rails 在保存 Active Record 对象之前验证数据。如果验证过程产生错误,Rails 不会保存对象。

你还可以自己执行数据验证。valid? 方法会触发数据验证,如果对象上没有错误,返回 true,否则返回 false。前面我们已经用过了:

+
+class Person < ApplicationRecord
+  validates :name, presence: true
+end
+
+Person.create(name: "John Doe").valid? # => true
+Person.create(name: nil).valid? # => false
+
+
+
+

Active Record 执行验证后,所有发现的错误都可以通过实例方法 errors.messages 获取。该方法返回一个错误集合。如果数据验证后,这个集合为空,说明对象是有效的。

注意,使用 new 方法初始化对象时,即使无效也不会报错,因为只有保存对象时才会验证数据,例如调用 createsave 方法。

+
+class Person < ApplicationRecord
+  validates :name, presence: true
+end
+
+>> p = Person.new
+# => #<Person id: nil, name: nil>
+>> p.errors.messages
+# => {}
+
+>> p.valid?
+# => false
+>> p.errors.messages
+# => {name:["can't be blank"]}
+
+>> p = Person.create
+# => #<Person id: nil, name: nil>
+>> p.errors.messages
+# => {name:["can't be blank"]}
+
+>> p.save
+# => false
+
+>> p.save!
+# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
+
+>> Person.create!
+# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
+
+
+
+

invalid? 的作用与 valid? 相反,它会触发数据验证,如果找到错误就返回 true,否则返回 false

1.5 errors[] +

若想检查对象的某个属性是否有效,可以使用 errors[:attribute]errors[:attribute] 中包含与 :attribute 有关的所有错误。如果某个属性没有错误,就会返回空数组。

这个方法只在数据验证之后才能使用,因为它只是用来收集错误信息的,并不会触发验证。与前面介绍的 ActiveRecord::Base#invalid? 方法不一样,errors[:attribute] 不会验证整个对象,只检查对象的某个属性是否有错。

+
+class Person < ApplicationRecord
+  validates :name, presence: true
+end
+
+>> Person.new.errors[:name].any? # => false
+>> Person.create.errors[:name].any? # => true
+
+
+
+

我们会在处理验证错误详细说明验证错误。

1.6 errors.details +

若想查看是哪个验证导致属性无效的,可以使用 errors.details[:attribute]。它的返回值是一个由散列组成的数组,:error 键的值是一个符号,指明出错的数据验证。

+
+class Person < ApplicationRecord
+  validates :name, presence: true
+end
+
+>> person = Person.new
+>> person.valid?
+>> person.errors.details[:name] # => [{error: :blank}]
+
+
+
+

处理验证错误会说明如何在自定义的数据验证中使用 details

2 数据验证辅助方法

Active Record 预先定义了很多数据验证辅助方法,可以直接在模型类定义中使用。这些辅助方法提供了常用的验证规则。每次验证失败后,都会向对象的 errors 集合中添加一个消息,而且这些消息与所验证的属性是关联的。

每个辅助方法都可以接受任意个属性名,所以一行代码就能在多个属性上做同一种验证。

所有辅助方法都可指定 :on:message 选项,分别指定何时做验证,以及验证失败后向 errors 集合添加什么消息。:on 选项的可选值是 :create:update。每个辅助函数都有默认的错误消息,如果没有通过 :message 选项指定,则使用默认值。下面分别介绍各个辅助方法。

2.1 acceptance +

这个方法检查表单提交时,用户界面中的复选框是否被选中。这个功能一般用来要求用户接受应用的服务条款、确保用户阅读了一些文本,等等。

+
+class Person < ApplicationRecord
+  validates :terms_of_service, acceptance: true
+end
+
+
+
+

仅当 terms_of_service 不为 nil 时才会执行这个检查。这个辅助方法的默认错误消息是“must be accepted”。通过 message 选项可以传入自定义的消息。

+
+class Person < ApplicationRecord
+  validates :terms_of_service, acceptance: true, message: 'must be abided'
+end
+
+
+
+

这个辅助方法还接受 :accept 选项,指定把哪些值视作“接受”。默认为 ['1', true],不过可以轻易修改:

+
+class Person < ApplicationRecord
+  validates :terms_of_service, acceptance: { accept: 'yes' }
+  validates :eula, acceptance: { accept: ['TRUE', 'accepted'] }
+end
+
+
+
+

这种验证只针对 Web 应用,接受与否无需存入数据库。如果没有对应的字段,该方法会创建一个虚拟属性。如果数据库中有对应的字段,必须把 accept 选项的值设为或包含 true,否则验证不会执行。

2.2 validates_associated +

如果模型和其他模型有关联,而且关联的模型也要验证,要使用这个辅助方法。保存对象时,会在相关联的每个对象上调用 valid? 方法。

+
+class Library < ApplicationRecord
+  has_many :books
+  validates_associated :books
+end
+
+
+
+

这种验证支持所有关联类型。

不要在关联的两端都使用 validates_associated,这样会变成无限循环。

validates_associated 的默认错误消息是“is invalid”。注意,相关联的每个对象都有各自的 errors 集合,错误消息不会都集中在调用该方法的模型对象上。

2.3 confirmation +

如果要检查两个文本字段的值是否完全相同,使用这个辅助方法。例如,确认电子邮件地址或密码。这个验证创建一个虚拟属性,其名字为要验证的属性名后加 _confirmation

+
+class Person < ApplicationRecord
+  validates :email, confirmation: true
+end
+
+
+
+

在视图模板中可以这么写:

+
+<%= text_field :person, :email %>
+<%= text_field :person, :email_confirmation %>
+
+
+
+

只有 email_confirmation 的值不是 nil 时才会检查。所以要为确认属性加上存在性验证(后文会介绍 presence 验证)。

+
+class Person < ApplicationRecord
+  validates :email, confirmation: true
+  validates :email_confirmation, presence: true
+end
+
+
+
+

此外,还可以使用 :case_sensitive 选项指定确认时是否区分大小写。这个选项的默认值是 true

+
+class Person < ApplicationRecord
+  validates :email, confirmation: { case_sensitive: false }
+end
+
+
+
+

这个辅助方法的默认错误消息是“doesn’t match confirmation”。

2.4 exclusion +

这个辅助方法检查属性的值是否不在指定的集合中。集合可以是任何一种可枚举的对象。

+
+class Account < ApplicationRecord
+  validates :subdomain, exclusion: { in: %w(www us ca jp),
+    message: "%{value} is reserved." }
+end
+
+
+
+

exclusion 方法要指定 :in 选项,设置哪些值不能作为属性的值。:in 选项有个别名 :with,作用相同。上面的例子设置了 :message 选项,演示如何获取属性的值。

默认的错误消息是“is reserved”。

2.5 format +

这个辅助方法检查属性的值是否匹配 :with 选项指定的正则表达式。

+
+class Product < ApplicationRecord
+  validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,
+    message: "only allows letters" }
+end
+
+
+
+

或者,使用 :without 选项,指定属性的值不能匹配正则表达式。

默认的错误消息是“is invalid”。

2.6 inclusion +

这个辅助方法检查属性的值是否在指定的集合中。集合可以是任何一种可枚举的对象。

+
+class Coffee < ApplicationRecord
+  validates :size, inclusion: { in: %w(small medium large),
+    message: "%{value} is not a valid size" }
+end
+
+
+
+

inclusion 方法要指定 :in 选项,设置可接受哪些值。:in 选项有个别名 :within,作用相同。上面的例子设置了 :message 选项,演示如何获取属性的值。

该方法的默认错误消息是“is not included in the list”。

2.7 length +

这个辅助方法验证属性值的长度,有多个选项,可以使用不同的方法指定长度约束:

+
+class Person < ApplicationRecord
+  validates :name, length: { minimum: 2 }
+  validates :bio, length: { maximum: 500 }
+  validates :password, length: { in: 6..20 }
+  validates :registration_number, length: { is: 6 }
+end
+
+
+
+

可用的长度约束选项有:

+
    +
  • :minimum:属性的值不能比指定的长度短;

  • +
  • :maximum:属性的值不能比指定的长度长;

  • +
  • :in(或 :within):属性值的长度在指定的范围内。该选项的值必须是一个范围;

  • +
  • :is:属性值的长度必须等于指定值;

  • +
+

默认的错误消息根据长度验证的约束类型而有所不同,不过可以使用 :message 选项定制。定制消息时,可以使用 :wrong_length:too_long:too_short 选项,%{count} 表示长度限制的值。

+
+class Person < ApplicationRecord
+  validates :bio, length: { maximum: 1000,
+    too_long: "%{count} characters is the maximum allowed" }
+end
+
+
+
+

这个辅助方法默认统计字符数,但可以使用 :tokenizer 选项设置其他的统计方式:

注意,默认的错误消息使用复数形式(例如,“is too short (minimum is %{count} characters”),所以如果长度限制是 minimum: 1,就要提供一个定制的消息,或者使用 presence: true 代替。:in:within 的下限值比 1 小时,要提供一个定制的消息,或者在 length 之前调用 presence 方法。

2.8 numericality +

这个辅助方法检查属性的值是否只包含数字。默认情况下,匹配的值是可选的正负符号后加整数或浮点数。如果只接受整数,把 :only_integer 选项设为 true

如果把 :only_integer 的值设为 true,使用下面的正则表达式验证属性的值:

+
+/\A[+-]?\d+\z/
+
+
+
+

否则,会尝试使用 Float 把值转换成数字。

注意,上面的正则表达式允许最后出现换行符。

+
+class Player < ApplicationRecord
+  validates :points, numericality: true
+  validates :games_played, numericality: { only_integer: true }
+end
+
+
+
+

除了 :only_integer 之外,这个方法还可指定以下选项,限制可接受的值:

+
    +
  • :greater_than:属性值必须比指定的值大。该选项默认的错误消息是“must be greater than %{count}”;

  • +
  • :greater_than_or_equal_to:属性值必须大于或等于指定的值。该选项默认的错误消息是“must be greater than or equal to %{count}”;

  • +
  • :equal_to:属性值必须等于指定的值。该选项默认的错误消息是“must be equal to %{count}”;

  • +
  • :less_than:属性值必须比指定的值小。该选项默认的错误消息是“must be less than %{count}”;

  • +
  • :less_than_or_equal_to:属性值必须小于或等于指定的值。该选项默认的错误消息是“must be less than or equal to %{count}”;

  • +
  • :other_than:属性值必须与指定的值不同。该选项默认的错误消息是“must be other than %{count}”。

  • +
  • :odd:如果设为 true,属性值必须是奇数。该选项默认的错误消息是“must be odd”;

  • +
  • :even:如果设为 true,属性值必须是偶数。该选项默认的错误消息是“must be even”;

  • +
+

numericality 默认不接受 nil 值。可以使用 allow_nil: true 选项允许接受 nil

默认的错误消息是“is not a number”。

2.9 presence +

这个辅助方法检查指定的属性是否为非空值。它调用 blank? 方法检查值是否为 nil 或空字符串,即空字符串或只包含空白的字符串。

+
+class Person < ApplicationRecord
+  validates :name, :login, :email, presence: true
+end
+
+
+
+

如果要确保关联对象存在,需要测试关联的对象本身是否存在,而不是用来映射关联的外键。

+
+class LineItem < ApplicationRecord
+  belongs_to :order
+  validates :order, presence: true
+end
+
+
+
+

为了能验证关联的对象是否存在,要在关联中指定 :inverse_of 选项。

+
+class Order < ApplicationRecord
+  has_many :line_items, inverse_of: :order
+end
+
+
+
+

如果验证 has_onehas_many 关联的对象是否存在,会在关联的对象上调用 blank?marked_for_destruction? 方法。

因为 false.blank? 的返回值是 true,所以如果要验证布尔值字段是否存在,要使用下述验证中的一个:

+
+validates :boolean_field_name, inclusion: { in: [true, false] }
+validates :boolean_field_name, exclusion: { in: [nil] }
+
+
+
+

上述验证确保值不是 nil;在多数情况下,即验证不是 NULL

默认的错误消息是“can’t be blank”。

2.10 absence +

这个辅助方法验证指定的属性值是否为空。它使用 present? 方法检测值是否为 nil 或空字符串,即空字符串或只包含空白的字符串。

+
+class Person < ApplicationRecord
+  validates :name, :login, :email, absence: true
+end
+
+
+
+

如果要确保关联对象为空,要测试关联的对象本身是否为空,而不是用来映射关联的外键。

+
+class LineItem < ApplicationRecord
+  belongs_to :order
+  validates :order, absence: true
+end
+
+
+
+

为了能验证关联的对象是否为空,要在关联中指定 :inverse_of 选项。

+
+class Order < ApplicationRecord
+  has_many :line_items, inverse_of: :order
+end
+
+
+
+

如果验证 has_onehas_many 关联的对象是否为空,会在关联的对象上调用 present?marked_for_destruction? 方法。

因为 false.present? 的返回值是 false,所以如果要验证布尔值字段是否为空要使用 validates :field_name, exclusion: { in: [true, false] }

默认的错误消息是“must be blank”。

2.11 uniqueness +

这个辅助方法在保存对象之前验证属性值是否是唯一的。该方法不会在数据库中创建唯一性约束,所以有可能两次数据库连接创建的记录具有相同的字段值。为了避免出现这种问题,必须在数据库的字段上建立唯一性索引。

+
+class Account < ApplicationRecord
+  validates :email, uniqueness: true
+end
+
+
+
+

这个验证会在模型对应的表中执行一个 SQL 查询,检查现有的记录中该字段是否已经出现过相同的值。

:scope 选项用于指定检查唯一性时使用的一个或多个属性:

+
+class Holiday < ApplicationRecord
+  validates :name, uniqueness: { scope: :year,
+    message: "should happen once per year" }
+end
+
+
+
+

如果想确保使用 :scope 选项的唯一性验证严格有效,必须在数据库中为多列创建唯一性索引。多列索引的详情参见 MySQL 手册PostgreSQL 手册中有些示例,说明如何为一组列创建唯一性约束。

还有个 :case_sensitive 选项,指定唯一性验证是否区分大小写,默认值为 true

+
+class Person < ApplicationRecord
+  validates :name, uniqueness: { case_sensitive: false }
+end
+
+
+
+

注意,不管怎样设置,有些数据库查询时始终不区分大小写。

默认的错误消息是“has already been taken”。

2.12 validates_with +

这个辅助方法把记录交给其他类做验证。

+
+class GoodnessValidator < ActiveModel::Validator
+  def validate(record)
+    if record.first_name == "Evil"
+      record.errors[:base] << "This person is evil"
+    end
+  end
+end
+
+class Person < ApplicationRecord
+  validates_with GoodnessValidator
+end
+
+
+
+

record.errors[:base] 中的错误针对整个对象,而不是特定的属性。

validates_with 方法的参数是一个类或一组类,用来做验证。validates_with 方法没有默认的错误消息。在做验证的类中要手动把错误添加到记录的错误集合中。

实现 validate 方法时,必须指定 record 参数,这是要做验证的记录。

与其他验证一样,validates_with 也可指定 :if:unless:on 选项。如果指定了其他选项,会包含在 options 中传递给做验证的类。

+
+class GoodnessValidator < ActiveModel::Validator
+  def validate(record)
+    if options[:fields].any?{|field| record.send(field) == "Evil" }
+      record.errors[:base] << "This person is evil"
+    end
+  end
+end
+
+class Person < ApplicationRecord
+  validates_with GoodnessValidator, fields: [:first_name, :last_name]
+end
+
+
+
+

注意,做验证的类在整个应用的生命周期内只会初始化一次,而不是每次验证时都初始化,所以使用实例变量时要特别小心。

如果做验证的类很复杂,必须要用实例变量,可以用纯粹的 Ruby 对象代替:

+
+class Person < ApplicationRecord
+  validate do |person|
+    GoodnessValidator.new(person).validate
+  end
+end
+
+class GoodnessValidator
+  def initialize(person)
+    @person = person
+  end
+
+  def validate
+    if some_complex_condition_involving_ivars_and_private_methods?
+      @person.errors[:base] << "This person is evil"
+    end
+  end
+
+  # ...
+end
+
+
+
+

2.13 validates_each +

这个辅助方法使用代码块中的代码验证属性。它没有预先定义验证函数,你要在代码块中定义验证方式。要验证的每个属性都会传入块中做验证。在下面的例子中,我们确保名和姓都不能以小写字母开头:

+
+class Person < ApplicationRecord
+  validates_each :name, :surname do |record, attr, value|
+    record.errors.add(attr, 'must start with upper case') if value =~ /\A[[:lower:]]/
+  end
+end
+
+
+
+

代码块的参数是记录、属性名和属性值。在代码块中可以做任何检查,确保数据有效。如果验证失败,应该向模型添加一个错误消息,把数据标记为无效。

3 常用的验证选项

下面介绍常用的验证选项。

3.1 :allow_nil +

指定 :allow_nil 选项后,如果要验证的值为 nil 就跳过验证。

+
+class Coffee < ApplicationRecord
+  validates :size, inclusion: { in: %w(small medium large),
+    message: "%{value} is not a valid size" }, allow_nil: true
+end
+
+
+
+

3.2 :allow_blank +

:allow_blank 选项和 :allow_nil 选项类似。如果要验证的值为空(调用 blank? 方法判断,例如 nil 或空字符串),就跳过验证。

+
+class Topic < ApplicationRecord
+  validates :title, length: { is: 5 }, allow_blank: true
+end
+
+Topic.create(title: "").valid?  # => true
+Topic.create(title: nil).valid? # => true
+
+
+
+

3.3 :message +

前面已经介绍过,如果验证失败,会把 :message 选项指定的字符串添加到 errors 集合中。如果没指定这个选项,Active Record 使用各个验证辅助方法的默认错误消息。:message 选项的值是一个字符串或一个 Proc 对象。

字符串消息中可以包含 %{value}%{attribute}%{model},在验证失败时它们会被替换成具体的值。

Proc 形式的消息有两个参数:验证的对象,以及包含 :model:attribute:value 键值对的散列。

+
+class Person < ApplicationRecord
+  # 直接写消息
+  validates :name, presence: { message: "must be given please" }
+
+  # 带有动态属性值的消息。%{value} 会被替换成属性的值
+  # 此外还可以使用 %{attribute} 和 %{model}
+  validates :age, numericality: { message: "%{value} seems wrong" }
+
+  # Proc
+  validates :username,
+    uniqueness: {
+      # object = 要验证的 person 对象
+      # data = { model: "Person", attribute: "Username", value: <username> }
+      message: ->(object, data) do
+        "Hey #{object.name}!, #{data[:value]} is taken already! Try again #{Time.zone.tomorrow}"
+      end
+    }
+end
+
+
+
+

3.4 :on +

:on 选项指定什么时候验证。所有内置的验证辅助方法默认都在保存时(新建记录或更新记录)验证。如果想修改,可以使用 on: :create,指定只在创建记录时验证;或者使用 on: :update,指定只在更新记录时验证。

+
+class Person < ApplicationRecord
+  # 更新时允许电子邮件地址重复
+  validates :email, uniqueness: true, on: :create
+
+  # 创建记录时允许年龄不是数字
+  validates :age, numericality: true, on: :update
+
+  # 默认行为(创建和更新时都验证)
+  validates :name, presence: true
+end
+
+
+
+

此外,还可以使用 on: 定义自定义的上下文。必须把上下文的名称传给 valid?invalid?save 才能触发自定义的上下文。

+
+class Person < ApplicationRecord
+  validates :email, uniqueness: true, on: :account_setup
+  validates :age, numericality: true, on: :account_setup
+end
+
+person = Person.new
+
+
+
+

person.valid?(:account_setup) 会执行上述两个验证,但不保存记录。person.save(context: :account_setup) 在保存之前在 account_setup 上下文中验证 person。显式触发时,可以只使用某个上下文验证,也可以不使用某个上下文验证。

4 严格验证

数据验证还可以使用严格模式,当对象无效时抛出 ActiveModel::StrictValidationFailed 异常。

+
+class Person < ApplicationRecord
+  validates :name, presence: { strict: true }
+end
+
+Person.new.valid?  # => ActiveModel::StrictValidationFailed: Name can't be blank
+
+
+
+

还可以通过 :strict 选项指定抛出什么异常:

+
+class Person < ApplicationRecord
+  validates :token, presence: true, uniqueness: true, strict: TokenGenerationException
+end
+
+Person.new.valid?  # => TokenGenerationException: Token can't be blank
+
+
+
+

5 条件验证

有时,只有满足特定条件时做验证才说得通。条件可通过 :if:unless 选项指定,这两个选项的值可以是符号、字符串、Proc 或数组。:if 选项指定何时做验证。如果要指定何时不做验证,使用 :unless 选项。

5.1 使用符号

:if:unless 选项的值为符号时,表示要在验证之前执行对应的方法。这是最常用的设置方法。

+
+class Order < ApplicationRecord
+  validates :card_number, presence: true, if: :paid_with_card?
+
+  def paid_with_card?
+    payment_type == "card"
+  end
+end
+
+
+
+

5.2 使用字符串

:if:unless 选项的值还可以是字符串,但必须是有效的 Ruby 代码,传给 eval 方法执行。当字符串表示的条件非常短时才应该使用这种形式。

+
+class Person < ApplicationRecord
+  validates :surname, presence: true, if: "name.nil?"
+end
+
+
+
+

5.3 使用 Proc

:if and :unless 选项的值还可以是 Proc。使用 Proc 对象可以在行间编写条件,不用定义额外的方法。这种形式最适合用在一行代码能表示的条件上。

+
+class Account < ApplicationRecord
+  validates :password, confirmation: true,
+    unless: Proc.new { |a| a.password.blank? }
+end
+
+
+
+

5.4 条件组合

有时,同一个条件会用在多个验证上,这时可以使用 with_options 方法:

+
+class User < ApplicationRecord
+  with_options if: :is_admin? do |admin|
+    admin.validates :password, length: { minimum: 10 }
+    admin.validates :email, presence: true
+  end
+end
+
+
+
+

with_options 代码块中的所有验证都会使用 if: :is_admin? 这个条件。

5.5 联合条件

另一方面,如果是否做某个验证要满足多个条件时,可以使用数组。而且,一个验证可以同时指定 :if:unless 选项。

+
+class Computer < ApplicationRecord
+  validates :mouse, presence: true,
+                    if: ["market.retail?", :desktop?],
+                    unless: Proc.new { |c| c.trackpad.present? }
+end
+
+
+
+

只有当 :if 选项的所有条件都返回 true,且 :unless 选项中的条件返回 false 时才会做验证。

6 自定义验证

如果内置的数据验证辅助方法无法满足需求,可以选择自己定义验证使用的类或方法。

6.1 自定义验证类

自定义的验证类继承自 ActiveModel::Validator,必须实现 validate 方法,其参数是要验证的记录,然后验证这个记录是否有效。自定义的验证类通过 validates_with 方法调用。

+
+class MyValidator < ActiveModel::Validator
+  def validate(record)
+    unless record.name.starts_with? 'X'
+      record.errors[:name] << 'Need a name starting with X please!'
+    end
+  end
+end
+
+class Person
+  include ActiveModel::Validations
+  validates_with MyValidator
+end
+
+
+
+

在自定义的验证类中验证单个属性,最简单的方法是继承 ActiveModel::EachValidator 类。此时,自定义的验证类必须实现 validate_each 方法。这个方法接受三个参数:记录、属性名和属性值。它们分别对应模型实例、要验证的属性及其值。

+
+class EmailValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
+      record.errors[attribute] << (options[:message] || "is not an email")
+    end
+  end
+end
+
+class Person < ApplicationRecord
+  validates :email, presence: true, email: true
+end
+
+
+
+

如上面的代码所示,可以同时使用内置的验证方法和自定义的验证类。

6.2 自定义验证方法

你还可以自定义方法,验证模型的状态,如果验证失败,向 erros 集合添加错误消息。验证方法必须使用类方法 validateAPI)注册,传入自定义验证方法名的符号形式。

这个类方法可以接受多个符号,自定义的验证方法会按照注册的顺序执行。

valid? 方法会验证错误集合是否为空,因此若想让验证失败,自定义的验证方法要把错误添加到那个集合中。

+
+class Invoice < ApplicationRecord
+  validate :expiration_date_cannot_be_in_the_past,
+    :discount_cannot_be_greater_than_total_value
+
+  def expiration_date_cannot_be_in_the_past
+    if expiration_date.present? && expiration_date < Date.today
+      errors.add(:expiration_date, "can't be in the past")
+    end
+  end
+
+  def discount_cannot_be_greater_than_total_value
+    if discount > total_value
+      errors.add(:discount, "can't be greater than total value")
+    end
+  end
+end
+
+
+
+

默认情况下,每次调用 valid? 方法或保存对象时都会执行自定义的验证方法。不过,使用 validate 方法注册自定义验证方法时可以设置 :on 选项,指定什么时候验证。:on 的可选值为 :create:update

+
+class Invoice < ApplicationRecord
+  validate :active_customer, on: :create
+
+  def active_customer
+    errors.add(:customer_id, "is not active") unless customer.active?
+  end
+end
+
+
+
+

7 处理验证错误

除了前面介绍的 valid?invalid? 方法之外,Rails 还提供了很多方法用来处理 errors 集合,以及查询对象的有效性。

下面介绍其中一些最常用的方法。所有可用的方法请查阅 ActiveModel::Errors 的文档。

7.1 errors +

ActiveModel::Errors 的实例包含所有的错误。键是每个属性的名称,值是一个数组,包含错误消息字符串。

+
+class Person < ApplicationRecord
+  validates :name, presence: true, length: { minimum: 3 }
+end
+
+person = Person.new
+person.valid? # => false
+person.errors.messages
+ # => {:name=>["can't be blank", "is too short (minimum is 3 characters)"]}
+
+person = Person.new(name: "John Doe")
+person.valid? # => true
+person.errors.messages # => {}
+
+
+
+

7.2 errors[] +

errors[] 用于获取某个属性上的错误消息,返回结果是一个由该属性所有错误消息字符串组成的数组,每个字符串表示一个错误消息。如果字段上没有错误,则返回空数组。

+
+class Person < ApplicationRecord
+  validates :name, presence: true, length: { minimum: 3 }
+end
+
+person = Person.new(name: "John Doe")
+person.valid? # => true
+person.errors[:name] # => []
+
+person = Person.new(name: "JD")
+person.valid? # => false
+person.errors[:name] # => ["is too short (minimum is 3 characters)"]
+
+person = Person.new
+person.valid? # => false
+person.errors[:name]
+ # => ["can't be blank", "is too short (minimum is 3 characters)"]
+
+
+
+

7.3 errors.add +

add 方法用于手动添加某属性的错误消息,它的参数是属性和错误消息。

使用 errors.full_messages(或等价的 errors.to_a)方法以对用户友好的格式显示错误消息。这些错误消息的前面都会加上属性名(首字母大写),如下述示例所示。

+
+class Person < ApplicationRecord
+  def a_method_used_for_validation_purposes
+    errors.add(:name, "cannot contain the characters !@#%*()_-+=")
+  end
+end
+
+person = Person.create(name: "!@#")
+
+person.errors[:name]
+ # => ["cannot contain the characters !@#%*()_-+="]
+
+person.errors.full_messages
+ # => ["Name cannot contain the characters !@#%*()_-+="]
+
+
+
+

<< 的作用与 errors#add 一样:把一个消息追加到 errors.messages 数组中。

+
+class Person < ApplicationRecord
+  def a_method_used_for_validation_purposes
+    errors.messages[:name] << "cannot contain the characters !@#%*()_-+="
+  end
+end
+
+person = Person.create(name: "!@#")
+
+person.errors[:name]
+ # => ["cannot contain the characters !@#%*()_-+="]
+
+person.errors.to_a
+ # => ["Name cannot contain the characters !@#%*()_-+="]
+
+
+
+

7.4 errors.details +

使用 errors.add 方法可以为返回的错误详情散列指定验证程序类型。

+
+class Person < ApplicationRecord
+  def a_method_used_for_validation_purposes
+    errors.add(:name, :invalid_characters)
+  end
+end
+
+person = Person.create(name: "!@#")
+
+person.errors.details[:name]
+# => [{error: :invalid_characters}]
+
+
+
+

如果想提升错误详情的信息量,可以为 errors.add 方法提供额外的键,指定不允许的字符。

+
+class Person < ApplicationRecord
+  def a_method_used_for_validation_purposes
+    errors.add(:name, :invalid_characters, not_allowed: "!@#%*()_-+=")
+  end
+end
+
+person = Person.create(name: "!@#")
+
+person.errors.details[:name]
+# => [{error: :invalid_characters, not_allowed: "!@#%*()_-+="}]
+
+
+
+

Rails 内置的验证程序生成的错误详情散列都有对应的验证程序类型。

7.5 errors[:base] +

错误消息可以添加到整个对象上,而不是针对某个属性。如果不想管是哪个属性导致对象无效,只想把对象标记为无效状态,就可以使用这个方法。errors[:base] 是个数组,可以添加字符串作为错误消息。

+
+class Person < ApplicationRecord
+  def a_method_used_for_validation_purposes
+    errors[:base] << "This person is invalid because ..."
+  end
+end
+
+
+
+

7.6 errors.clear +

如果想清除 errors 集合中的所有错误消息,可以使用 clear 方法。当然,在无效的对象上调用 errors.clear 方法后,对象还是无效的,虽然 errors 集合为空了,但下次调用 valid? 方法,或调用其他把对象存入数据库的方法时, 会再次进行验证。如果任何一个验证失败了,errors 集合中就再次出现值了。

+
+class Person < ApplicationRecord
+  validates :name, presence: true, length: { minimum: 3 }
+end
+
+person = Person.new
+person.valid? # => false
+person.errors[:name]
+ # => ["can't be blank", "is too short (minimum is 3 characters)"]
+
+person.errors.clear
+person.errors.empty? # => true
+
+person.save # => false
+
+person.errors[:name]
+# => ["can't be blank", "is too short (minimum is 3 characters)"]
+
+
+
+

7.7 errors.size +

size 方法返回对象上错误消息的总数。

+
+class Person < ApplicationRecord
+  validates :name, presence: true, length: { minimum: 3 }
+end
+
+person = Person.new
+person.valid? # => false
+person.errors.size # => 2
+
+person = Person.new(name: "Andrea", email: "andrea@example.com")
+person.valid? # => true
+person.errors.size # => 0
+
+
+
+

8 在视图中显示验证错误

在模型中加入数据验证后,如果在表单中创建模型,出错时,你或许想把错误消息显示出来。

因为每个应用显示错误消息的方式不同,所以 Rails 没有直接提供用于显示错误消息的视图辅助方法。不过,Rails 提供了这么多方法用来处理验证,自己编写一个也不难。使用脚手架时,Rails 会在生成的 _form.html.erb 中加入一些 ERB 代码,显示模型错误消息的完整列表。

假如有个模型对象存储在实例变量 @article 中,视图的代码可以这么写:

+
+<% if @article.errors.any? %>
+  <div id="error_explanation">
+    <h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2>
+
+    <ul>
+    <% @article.errors.full_messages.each do |msg| %>
+      <li><%= msg %></li>
+    <% end %>
+    </ul>
+  </div>
+<% end %>
+
+
+
+

此外,如果使用 Rails 的表单辅助方法生成表单,如果某个表单字段验证失败,会把字段包含在一个 <div> 中:

+
+<div class="field_with_errors">
+  <input id="article_title" name="article[title]" size="30" type="text" value="">
+</div>
+
+
+
+

然后,你可以根据需求为这个 div 添加样式。脚手架默认添加的 CSS 规则如下:

+
+.field_with_errors {
+  padding: 2px;
+  background-color: red;
+  display: table;
+}
+
+
+
+

上述样式把所有出错的表单字段放入一个内边距为 2 像素的红色框内。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_support_core_extensions.html b/active_support_core_extensions.html new file mode 100644 index 0000000..c3cc012 --- /dev/null +++ b/active_support_core_extensions.html @@ -0,0 +1,3346 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + +
+

Chapters

+
    +
  1. +如何加载核心扩展 + + +
  2. +
  3. +所有对象皆可使用的扩展 + + +
  4. +
  5. +Module 的扩展 + + +
  6. +
  7. +Class 的扩展 + + +
  8. +
  9. +String 的扩展 + + +
  10. +
  11. +Numeric 的扩展 + + +
  12. +
  13. +Integer 的扩展 + + +
  14. +
  15. +BigDecimal 的扩展 + + +
  16. +
  17. +Enumerable 的扩展 + + +
  18. +
  19. +Array 的扩展 + + +
  20. +
  21. +Hash 的扩展 + + +
  22. +
  23. +Regexp 的扩展 + + +
  24. +
  25. +Range 的扩展 + + +
  26. +
  27. +Date 的扩展 + + +
  28. +
  29. +DateTime 的扩展 + + +
  30. +
  31. +Time 的扩展 + + +
  32. +
  33. +File 的扩展 + + +
  34. +
  35. +Marshal 的扩展 + + +
  36. +
  37. NameError 的扩展
  38. +
  39. LoadError 的扩展
  40. +
+ +
+ +
+
+ +
+
+
+

Active Support 核心扩展

Active Support 是 Ruby on Rails 的一个组件,扩展了 Ruby 语言,提供了一些实用功能。

Active Support 丰富了 Rails 使用的编程语言,目的是便于开发 Rails 应用以及 Rails 本身。

读完本文后,您将学到:

+
    +
  • 核心扩展是什么;

  • +
  • 如何加载所有扩展;

  • +
  • 如何按需加载想用的扩展;

  • +
  • Active Support 提供了哪些扩展。

  • +
+

1 如何加载核心扩展

1.1 独立的 Active Support

为了减轻应用的负担,默认情况下 Active Support 不会加载任何功能。Active Support 中的各部分功能是相对独立的,可以只加载需要的功能,也可以方便地加载相互联系的功能,或者加载全部功能。

因此,只编写下面这个 require 语句,对象甚至无法响应 blank? 方法:

+
+require 'active_support'
+
+
+
+

我们来看一下到底应该如何加载。

1.1.1 按需加载

获取 blank? 方法最轻便的做法是按需加载其定义所在的文件。

本文为核心扩展中的每个方法都做了说明,告知是在哪个文件中定义的。对 blank? 方法而言,说明如下:

active_support/core_ext/object/blank.rb 文件中定义。

因此 blank? 方法要这么加载:

+
+require 'active_support'
+require 'active_support/core_ext/object/blank'
+
+
+
+

Active Support 的设计方式精良,确保按需加载时真的只加载所需的扩展。

1.1.2 成组加载核心扩展

下一层级是加载 Object 对象的所有扩展。一般来说,对 SomeClass 的扩展都保存在 active_support/core_ext/some_class 文件夹中。

因此,加载 Object 对象的所有扩展(包括 balnk? 方法)可以这么做:

+
+require 'active_support'
+require 'active_support/core_ext/object'
+
+
+
+
1.1.3 加载所有扩展

如果想加载所有核心扩展,可以这么做:

+
+require 'active_support'
+require 'active_support/core_ext'
+
+
+
+
1.1.4 加载 Active Support 提供的所有功能

最后,如果想使用 Active Support 提供的所有功能,可以这么做:

+
+require 'active_support/all'
+
+
+
+

其实,这么做并不会把整个 Active Support 载入内存,有些功能通过 autoload 加载,所以真正使用时才会加载。

1.2 在 Rails 应用中使用 Active Support

除非把 config.active_support.bare 设为 true,否则 Rails 应用不会加载 Active Support 提供的所有功能。即便全部加载,应用也会根据框架的设置按需加载所需功能,而且应用开发者还可以根据需要做更细化的选择,方法如前文所述。

2 所有对象皆可使用的扩展

2.1 blank?present? +

在 Rails 应用中,下面这些值表示空值:

+
    +
  • nilfalse

  • +
  • 只有空白的字符串(注意下面的说明);

  • +
  • 空数组和空散列;

  • +
  • 其他能响应 empty? 方法,而且返回值为 true 的对象;

  • +
+

判断字符串是否为空使用的是能理解 Unicode 字符的 [:space:],所以 U+2029(分段符)会被视为空白。

注意,这里并没有提到数字。特别说明,00.0 不是空值。

例如,ActionController::HttpAuthentication::Token::ControllerMethods 定义的这个方法使用 blank? 检查是否有令牌:

+
+def authenticate(controller, &login_procedure)
+  token, options = token_and_options(controller.request)
+  unless token.blank?
+    login_procedure.call(token, options)
+  end
+end
+
+
+
+

present? 方法等价于 !blank?。下面这个方法摘自 ActionDispatch::Http::Cache::Response

+
+def set_conditional_cache_control!
+  return if self["Cache-Control"].present?
+  ...
+end
+
+
+
+

active_support/core_ext/object/blank.rb 文件中定义。

2.2 presence +

如果 present? 方法返回 truepresence 方法的返回值为调用对象,否则返回 nil。惯用法如下:

+
+host = config[:host].presence || 'localhost'
+
+
+
+

active_support/core_ext/object/blank.rb 文件中定义。

2.3 duplicable? +

Ruby 中很多基本的对象是单例。例如,在应用的整个生命周期内,整数 1 始终表示同一个实例:

+
+1.object_id                 # => 3
+Math.cos(0).to_i.object_id  # => 3
+
+
+
+

因此,这些对象无法通过 dupclone 方法复制:

+
+true.dup  # => TypeError: can't dup TrueClass
+
+
+
+

有些数字虽然不是单例,但也不能复制:

+
+0.0.clone        # => allocator undefined for Float
+(2**1024).clone  # => allocator undefined for Bignum
+
+
+
+

Active Support 提供的 duplicable? 方法用于查询对象是否可以复制:

+
+"foo".duplicable? # => true
+"".duplicable?    # => true
+0.0.duplicable?   # => false
+false.duplicable? # => false
+
+
+
+

按照定义,除了 nilfalsetrue、符号、数字、类、模块和方法对象之外,其他对象都可以复制。

任何类都可以禁止对象复制,只需删除 dupclone 两个方法,或者在这两个方法中抛出异常。因此只能在 rescue 语句中判断对象是否可复制。duplicable? 方法直接检查对象是否在上述列表中,因此比 rescue 的速度快。仅当你知道上述列表能满足需求时才应该使用 duplicable? 方法。

active_support/core_ext/object/duplicable.rb 文件中定义。

2.4 deep_dup +

deep_dup 方法深拷贝指定的对象。一般情况下,复制包含其他对象的对象时,Ruby 不会复制内部对象,这叫做浅拷贝。假如有一个由字符串组成的数组,浅拷贝的行为如下:

+
+array     = ['string']
+duplicate = array.dup
+
+duplicate.push 'another-string'
+
+# 创建了对象副本,因此元素只添加到副本中
+array     # => ['string']
+duplicate # => ['string', 'another-string']
+
+duplicate.first.gsub!('string', 'foo')
+
+# 第一个元素没有副本,因此两个数组都会变
+array     # => ['foo']
+duplicate # => ['foo', 'another-string']
+
+
+
+

如上所示,复制数组后得到了一个新对象,修改新对象后原对象没有变化。但对数组中的元素来说情况就不一样了。因为 dup 方法不是深拷贝,所以数组中的字符串是同一个对象。

如果想深拷贝一个对象,应该使用 deep_dup 方法。举个例子:

+
+array     = ['string']
+duplicate = array.deep_dup
+
+duplicate.first.gsub!('string', 'foo')
+
+array     # => ['string']
+duplicate # => ['foo']
+
+
+
+

如果对象不可复制,deep_dup 方法直接返回对象本身:

+
+number = 1
+duplicate = number.deep_dup
+number.object_id == duplicate.object_id   # => true
+
+
+
+

active_support/core_ext/object/deep_dup.rb 文件中定义。

2.5 try +

如果只想当对象不为 nil 时在其上调用方法,最简单的方式是使用条件语句,但这么做把代码变复杂了。你可以使用 try 方法。try 方法和 Object#send 方法类似,但如果在 nil 上调用,返回值为 nil

举个例子:

+
+# 不使用 try
+unless @number.nil?
+  @number.next
+end
+
+# 使用 try
+@number.try(:next)
+
+
+
+

下面这个例子摘自 ActiveRecord::ConnectionAdapters::AbstractAdapter,实例变量 @logger 有可能为 nil。可以看出,使用 try 方法可以避免不必要的检查。

+
+def log_info(sql, name, ms)
+  if @logger.try(:debug?)
+    name = '%s (%.1fms)' % [name || 'SQL', ms]
+    @logger.debug(format_log_entry(name, sql.squeeze(' ')))
+  end
+end
+
+
+
+

try 方法也可接受代码块,仅当对象不为 nil 时才会执行其中的代码:

+
+@person.try { |p| "#{p.first_name} #{p.last_name}" }
+
+
+
+

注意,try 会吞没没有方法错误,返回 nil。如果想避免此类问题,应该使用 try!

+
+@number.try(:nest)  # => nil
+@number.try!(:nest) # NoMethodError: undefined method `nest' for 1:Integer
+
+
+
+

active_support/core_ext/object/try.rb 文件中定义。

2.6 class_eval(*args, &block) +

使用 class_eval 方法可以在对象的单例类上下文中执行代码:

+
+class Proc
+  def bind(object)
+    block, time = self, Time.current
+    object.class_eval do
+      method_name = "__bind_#{time.to_i}_#{time.usec}"
+      define_method(method_name, &block)
+      method = instance_method(method_name)
+      remove_method(method_name)
+      method
+    end.bind(object)
+  end
+end
+
+
+
+

active_support/core_ext/kernel/singleton_class.rb 文件中定义。

2.7 acts_like?(duck) +

acts_like? 方法检查一个类的行为是否与另一个类相似。比较是基于一个简单的约定:如果在某个类中定义了下面这个方法,就说明其接口与字符串一样。

+
+def acts_like_string?
+end
+
+
+
+

这个方法只是一个标记,其定义体和返回值不影响效果。开发者可使用下面这种方式判断两个类的表现是否类似:

+
+some_klass.acts_like?(:string)
+
+
+
+

Rails 使用这种约定定义了行为与 DateTime 相似的类。

active_support/core_ext/object/acts_like.rb 文件中定义。

2.8 to_param +

Rails 中的所有对象都能响应 to_param 方法。to_param 方法的返回值表示查询字符串的值,或者 URL 片段。

默认情况下,to_param 方法直接调用 to_s 方法:

+
+7.to_param # => "7"
+
+
+
+

to_param 方法的返回值不应该转义:

+
+"Tom & Jerry".to_param # => "Tom & Jerry"
+
+
+
+

Rails 中的很多类都覆盖了这个方法。

例如,niltruefalse 返回自身。Array#to_param 在各个元素上调用 to_param 方法,然后使用 "/" 合并:

+
+[0, true, String].to_param # => "0/true/String"
+
+
+
+

注意,Rails 的路由系统在模型上调用 to_param 方法获取占位符 :id 的值。ActiveRecord::Base#to_param 返回模型的 id,不过可以在模型中重新定义。例如,按照下面的方式重新定义:

+
+class User
+  def to_param
+    "#{id}-#{name.parameterize}"
+  end
+end
+
+
+
+

效果如下:

+
+user_path(@user) # => "/users/357-john-smith"
+
+
+
+

应该让控制器知道重新定义了 to_param 方法,因为接收到上面这种请求后,params[:id] 的值为 "357-john-smith"

active_support/core_ext/object/to_param.rb 文件中定义。

2.9 to_query +

除散列之外,传入未转义的 keyto_query 方法把 to_param 方法的返回值赋值给 key,组成查询字符串。例如,重新定义了 to_param 方法:

+
+class User
+  def to_param
+    "#{id}-#{name.parameterize}"
+  end
+end
+
+
+
+

效果如下:

+
+current_user.to_query('user') # => user=357-john-smith
+
+
+
+

to_query 方法会根据需要转义键和值:

+
+account.to_query('company[name]')
+# => "company%5Bname%5D=Johnson+%26+Johnson"
+
+
+
+

因此得到的值可以作为查询字符串使用。

Array#to_query 方法在各个元素上调用 to_query 方法,键为 _key_[],然后使用 "&" 合并:

+
+[3.4, -45.6].to_query('sample')
+# => "sample%5B%5D=3.4&sample%5B%5D=-45.6"
+
+
+
+

散列也响应 to_query 方法,但处理方式不一样。如果不传入参数,先在各个元素上调用 to_query(key),得到一系列键值对赋值字符串,然后按照键的顺序排列,再使用 "&" 合并:

+
+{c: 3, b: 2, a: 1}.to_query # => "a=1&b=2&c=3"
+
+
+
+

Hash#to_query 方法还有一个可选参数,用于指定键的命名空间:

+
+{id: 89, name: "John Smith"}.to_query('user')
+# => "user%5Bid%5D=89&user%5Bname%5D=John+Smith"
+
+
+
+

active_support/core_ext/object/to_query.rb 文件中定义。

2.10 with_options +

with_options 方法把一系列方法调用中的通用选项提取出来。

使用散列指定通用选项后,with_options 方法会把一个代理对象拽入代码块。在代码块中,代理对象调用的方法会转发给调用者,并合并选项。例如,如下的代码

+
+class Account < ApplicationRecord
+  has_many :customers, dependent: :destroy
+  has_many :products,  dependent: :destroy
+  has_many :invoices,  dependent: :destroy
+  has_many :expenses,  dependent: :destroy
+end
+
+
+
+

其中的重复可以使用 with_options 方法去除:

+
+class Account < ApplicationRecord
+  with_options dependent: :destroy do |assoc|
+    assoc.has_many :customers
+    assoc.has_many :products
+    assoc.has_many :invoices
+    assoc.has_many :expenses
+  end
+end
+
+
+
+

这种用法还可形成一种分组方式。假如想根据用户使用的语言发送不同的电子报,在邮件发送程序中可以根据用户的区域设置分组:

+
+I18n.with_options locale: user.locale, scope: "newsletter" do |i18n|
+  subject i18n.t :subject
+  body    i18n.t :body, user_name: user.name
+end
+
+
+
+

with_options 方法会把方法调用转发给调用者,因此可以嵌套使用。每层嵌套都会合并上一层的选项。

active_support/core_ext/object/with_options.rb 文件中定义。

2.11 对 JSON 的支持

Active Support 实现的 to_json 方法比 json gem 更好用,这是因为 HashOrderedHashProcess::Status 等类转换成 JSON 时要做特别处理。

active_support/core_ext/object/json.rb 文件中定义。

2.12 实例变量

Active Support 提供了很多便于访问实例变量的方法。

2.12.1 instance_values +

instance_values 方法返回一个散列,把实例变量的名称(不含前面的 @ 符号)映射到其值上,键是字符串:

+
+class C
+  def initialize(x, y)
+    @x, @y = x, y
+  end
+end
+
+C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
+
+
+
+

active_support/core_ext/object/instance_variables.rb 文件中定义。

2.12.2 instance_variable_names +

instance_variable_names 方法返回一个数组,实例变量的名称前面包含 @ 符号。

+
+class C
+  def initialize(x, y)
+    @x, @y = x, y
+  end
+end
+
+C.new(0, 1).instance_variable_names # => ["@x", "@y"]
+
+
+
+

active_support/core_ext/object/instance_variables.rb 文件中定义。

2.13 静默警告和异常

silence_warningsenable_warnings 方法修改各自代码块的 $VERBOSE 全局变量,代码块结束后恢复原值:

+
+silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
+
+
+
+

异常消息也可静默,使用 suppress 方法即可。suppress 方法可接受任意个异常类。如果执行代码块的过程中抛出异常,而且异常属于(kind_of?)参数指定的类,suppress 方法会静默该异常类的消息,否则抛出异常:

+
+# 如果用户锁定了,访问次数不增加也没关系
+suppress(ActiveRecord::StaleObjectError) do
+  current_user.increment! :visits
+end
+
+
+
+

active_support/core_ext/kernel/reporting.rb 文件中定义。

2.14 in? +

in? 方法测试某个对象是否在另一个对象中。如果传入的对象不能响应 include? 方法,抛出 ArgumentError 异常。

in? 方法使用举例:

+
+1.in?([1,2])        # => true
+"lo".in?("hello")   # => true
+25.in?(30..50)      # => false
+1.in?(1)            # => ArgumentError
+
+
+
+

active_support/core_ext/object/inclusion.rb 文件中定义。

3 Module 的扩展

3.1 alias_method_chain +

这个方法已经弃用,请使用 Module#prepend

在 Ruby 中,可以把方法包装成其他方法,这叫别名链(alias chain)。

例如,想在功能测试中把参数看做字符串,就像在真正的请求中一样,但希望保留赋值数字等值的便利,可以在文件 test/test_helper.rb 中包装 ActionDispatch::IntegrationTest#process 方法:

+
+ActionDispatch::IntegrationTest.class_eval do
+  # 保存原 process 方法的引用
+  alias_method :original_process, :process
+
+  # 现在重新定义 process,委托给 original_process
+  def process('GET', path, params: nil, headers: nil, env: nil, xhr: false)
+    params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
+    original_process('GET', path, params: params)
+  end
+end
+
+
+
+

getpost 等方法就是委托这个方法实现的。

这种技术有个问题,:original_process 方法可能已经存在了。为了避免方法重名,人们者发明了一种链状结构:

+
+ActionDispatch::IntegrationTest.class_eval do
+  def process_with_stringified_params(...)
+    params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
+    process_without_stringified_params(method, path, params: params)
+  end
+  alias_method :process_without_stringified_params, :process
+  alias_method :process, :process_with_stringified_params
+end
+
+
+
+

alias_method_chain 方法可以简化上述过程:

+
+ActionDispatch::IntegrationTest.class_eval do
+  def process_with_stringified_params(...)
+    params = Hash[*params.map {|k, v| [k, v.to_s]}.flatten]
+    process_without_stringified_params(method, path, params: params)
+  end
+  alias_method_chain :process, :stringified_params
+end
+
+
+
+

active_support/core_ext/module/aliasing.rb 文件中定义。

3.2 属性

3.2.1 alias_attribute +

模型的属性有读值方法、设值方法和判断方法。alias_attribute 方法可以一次性为这三种方法创建别名。和其他创建别名的方法一样,alias_attribute 方法的第一个参数是新属性名,第二个参数是旧属性名(我是这样记的,参数的顺序和赋值语句一样):

+
+class User < ApplicationRecord
+  # 可以使用 login 指代 email 列
+  # 在身份验证代码中可以这样做
+  alias_attribute :login, :email
+end
+
+
+
+

active_support/core_ext/module/aliasing.rb 文件中定义。

3.2.2 内部属性

如果在父类中定义属性,有可能会出现命名冲突。代码库一定要注意这个问题。

Active Support 提供了 attr_internal_readerattr_internal_writerattr_internal_accessor 三个方法,其行为与 Ruby 内置的 attr_* 方法类似,但使用其他方式命名实例变量,从而减少重名的几率。

attr_internal 方法是 attr_internal_accessor 方法的别名:

+
+# 库
+class ThirdPartyLibrary::Crawler
+  attr_internal :log_level
+end
+
+# 客户代码
+class MyCrawler < ThirdPartyLibrary::Crawler
+  attr_accessor :log_level
+end
+
+
+
+

在上面的例子中,:log_level 可能不属于代码库的公开接口,只在开发过程中使用。开发者并不知道潜在的重名风险,创建了子类,并在子类中定义了 :log_level。幸好用了 attr_internal 方法才不会出现命名冲突。

默认情况下,内部变量的名字前面有个下划线,上例中的内部变量名为 @_log_level。不过可使用 Module.attr_internal_naming_format 重新设置,可以传入任何 sprintf 方法能理解的格式,开头加上 @ 符号,并在某处放入 %s(代表原变量名)。默认的设置为 "@_%s"

Rails 的代码很多地方都用到了内部属性,例如,在视图相关的代码中有如下代码:

+
+module ActionView
+  class Base
+    attr_internal :captures
+    attr_internal :request, :layout
+    attr_internal :controller, :template
+  end
+end
+
+
+
+

active_support/core_ext/module/attr_internal.rb 文件中定义。

3.2.3 模块属性

方法 mattr_readermattr_writermattr_accessor 类似于为类定义的 cattr_* 方法。其实 cattr_* 方法就是 mattr_* 方法的别名。参见 类属性

例如,依赖机制就用到了这些方法:

+
+module ActiveSupport
+  module Dependencies
+    mattr_accessor :warnings_on_first_load
+    mattr_accessor :history
+    mattr_accessor :loaded
+    mattr_accessor :mechanism
+    mattr_accessor :load_paths
+    mattr_accessor :load_once_paths
+    mattr_accessor :autoloaded_constants
+    mattr_accessor :explicitly_unloadable_constants
+    mattr_accessor :constant_watch_stack
+    mattr_accessor :constant_watch_stack_mutex
+  end
+end
+
+
+
+

active_support/core_ext/module/attribute_accessors.rb 文件中定义。

3.3 父级

3.3.1 parent +

在嵌套的具名模块上调用 parent 方法,返回包含对应常量的模块:

+
+module X
+  module Y
+    module Z
+    end
+  end
+end
+M = X::Y::Z
+
+X::Y::Z.parent # => X::Y
+M.parent       # => X::Y
+
+
+
+

如果是匿名模块或者位于顶层,parent 方法返回 Object

此时,parent_name 方法返回 nil

active_support/core_ext/module/introspection.rb 文件中定义。

3.3.2 parent_name +

在嵌套的具名模块上调用 parent_name 方法,返回包含对应常量的完全限定模块名:

+
+module X
+  module Y
+    module Z
+    end
+  end
+end
+M = X::Y::Z
+
+X::Y::Z.parent_name # => "X::Y"
+M.parent_name       # => "X::Y"
+
+
+
+

如果是匿名模块或者位于顶层,parent_name 方法返回 nil

注意,此时 parent 方法返回 Object

active_support/core_ext/module/introspection.rb 文件中定义。

3.3.3 parents +

parents 方法在调用者上调用 parent 方法,直至 Object 为止。返回的结果是一个数组,由底而上:

+
+module X
+  module Y
+    module Z
+    end
+  end
+end
+M = X::Y::Z
+
+X::Y::Z.parents # => [X::Y, X, Object]
+M.parents       # => [X::Y, X, Object]
+
+
+
+

active_support/core_ext/module/introspection.rb 文件中定义。

3.3.4 限定的常量名

常规的 const_defined?const_getconst_set 方法接受裸常量名。Active Support 扩展了这个 API,可以传入相对限定的常量名。

新定义的方法是 qualified_const_defined?qualified_const_getqualified_const_set。它们的参数应该是相对接收者的限定常量名:

+
+Object.qualified_const_defined?("Math::PI")       # => true
+Object.qualified_const_get("Math::PI")            # => 3.141592653589793
+Object.qualified_const_set("Math::Phi", 1.618034) # => 1.618034
+
+
+
+

参数也可以是裸常量名:

+
+Math.qualified_const_get("E") # => 2.718281828459045
+
+
+
+

这些方法的行为与内置的对应方法类似。不过,qualified_constant_defined? 方法接受一个可选参数(第二个),指明判断时是否检查祖先树。沿路径检查时,表达式中的每个常量都会考虑这个参数。

例如:

+
+module M
+  X = 1
+end
+
+module N
+  class C
+    include M
+  end
+end
+
+
+
+

此时,qualified_const_defined? 的行为如下:

+
+N.qualified_const_defined?("C::X", false) # => false
+N.qualified_const_defined?("C::X", true)  # => true
+N.qualified_const_defined?("C::X")        # => true
+
+
+
+

如上例所示,第二个参数的默认值为 true,跟 const_defined? 一样。

为了与内置方法保持连贯,只接受相对路径。完全限定常量名,如 ::Math::PI,会抛出 NameError 异常。

active_support/core_ext/module/qualified_const.rb 文件中定义。

3.4 可达性

如果把具名模块存储在相应的常量中,模块是可达的,意即可以通过常量访问模块对象。

通常,模块都是如此。如果有名为“M”的模块,M 常量就存在,指代那个模块:

+
+module M
+end
+
+M.reachable? # => true
+
+
+
+

但是,常量和模块其实是解耦的,因此模块对象也许不可达:

+
+module M
+end
+
+orphan = Object.send(:remove_const, :M)
+
+# 现在模块对象是孤儿,但它仍有名称
+orphan.name # => "M"
+
+# 不能通过常量 M 访问,因为这个常量不存在
+orphan.reachable? # => false
+
+# 再定义一个名为“M”的模块
+module M
+end
+
+# 现在常量 M 存在了,而且存储名为“M”的常量对象
+# 但这是一个新实例
+orphan.reachable? # => false
+
+
+
+

active_support/core_ext/module/reachable.rb 文件中定义。

3.5 匿名

模块可能有也可能没有名称:

+
+module M
+end
+M.name # => "M"
+
+N = Module.new
+N.name # => "N"
+
+Module.new.name # => nil
+
+
+
+

可以使用 anonymous? 方法判断模块有没有名称:

+
+module M
+end
+M.anonymous? # => false
+
+Module.new.anonymous? # => true
+
+
+
+

注意,不可达不意味着就是匿名的:

+
+module M
+end
+
+m = Object.send(:remove_const, :M)
+
+m.reachable? # => false
+m.anonymous? # => false
+
+
+
+

但是按照定义,匿名模块是不可达的。

active_support/core_ext/module/anonymous.rb 文件中定义。

3.6 方法委托

delegate 方法提供一种便利的方法转发方式。

假设在一个应用中,用户的登录信息存储在 User 模型中,而名字和其他数据存储在 Profile 模型中:

+
+class User < ApplicationRecord
+  has_one :profile
+end
+
+
+
+

此时,要通过个人资料获取用户的名字,即 user.profile.name。不过,若能直接访问这些信息更为便利:

+
+class User < ApplicationRecord
+  has_one :profile
+
+  def name
+    profile.name
+  end
+end
+
+
+
+

delegate 方法正是为这种需求而生的:

+
+class User < ApplicationRecord
+  has_one :profile
+
+  delegate :name, to: :profile
+end
+
+
+
+

这样写出的代码更简洁,而且意图更明显。

委托的方法在目标中必须是公开的。

delegate 方法可接受多个参数,委托多个方法:

+
+delegate :name, :age, :address, :twitter, to: :profile
+
+
+
+

内插到字符串中时,:to 选项的值应该能求值为方法委托的对象。通常,使用字符串或符号。这个选项的值在接收者的上下文中求值:

+
+# 委托给 Rails 常量
+delegate :logger, to: :Rails
+
+# 委托给接收者所属的类
+delegate :table_name, to: :class
+
+
+
+

如果 :prefix 选项的值为 true,不能这么做。参见下文。

默认情况下,如果委托导致 NoMethodError 抛出,而且目标是 nil,这个异常会向上冒泡。可以指定 :allow_nil 选项,遇到这种情况时返回 nil

+
+delegate :name, to: :profile, allow_nil: true
+
+
+
+

设定 :allow_nil 选项后,如果用户没有个人资料,user.name 返回 nil

:prefix 选项在生成的方法前面添加一个前缀。如果想起个更好的名称,就可以使用这个选项:

+
+delegate :street, to: :address, prefix: true
+
+
+
+

上述示例生成的方法是 address_street,而不是 street

此时,生成的方法名由目标对象和目标方法的名称构成,因此 :to 选项必须是一个方法名。

此外,还可以自定义前缀:

+
+delegate :size, to: :attachment, prefix: :avatar
+
+
+
+

在这个示例中,生成的方法是 avatar_size,而不是 size

active_support/core_ext/module/delegation.rb 文件中定义。

3.7 重新定义方法

有时需要使用 define_method 定义方法,但却不知道那个方法名是否已经存在。如果存在,而且启用了警告消息,会发出警告。这没什么,但却不够利落。

redefine_method 方法能避免这种警告,如果需要,会把现有的方法删除。

active_support/core_ext/module/remove_method.rb 文件中定义。

4 Class 的扩展

4.1 类属性

4.1.1 class_attribute +

class_attribute 方法声明一个或多个可继承的类属性,它们可以在继承树的任一层级覆盖。

+
+class A
+  class_attribute :x
+end
+
+class B < A; end
+
+class C < B; end
+
+A.x = :a
+B.x # => :a
+C.x # => :a
+
+B.x = :b
+A.x # => :a
+C.x # => :b
+
+C.x = :c
+A.x # => :a
+B.x # => :b
+
+
+
+

例如,ActionMailer::Base 定义了:

+
+class_attribute :default_params
+self.default_params = {
+  mime_version: "1.0",
+  charset: "UTF-8",
+  content_type: "text/plain",
+  parts_order: [ "text/plain", "text/enriched", "text/html" ]
+}.freeze
+
+
+
+

类属性还可以通过实例访问和覆盖:

+
+A.x = 1
+
+a1 = A.new
+a2 = A.new
+a2.x = 2
+
+a1.x # => 1, comes from A
+a2.x # => 2, overridden in a2
+
+
+
+

:instance_writer 选项设为 false,不生成设值实例方法:

+
+module ActiveRecord
+  class Base
+    class_attribute :table_name_prefix, instance_writer: false
+    self.table_name_prefix = ""
+  end
+end
+
+
+
+

模型可以使用这个选项,禁止批量赋值属性。

:instance_reader 选项设为 false,不生成读值实例方法:

+
+class A
+  class_attribute :x, instance_reader: false
+end
+
+A.new.x = 1 # NoMethodError
+
+
+
+

为了方便,class_attribute 还会定义实例判断方法,对实例读值方法的返回值做双重否定。在上例中,判断方法是 x?

如果 :instance_reader 的值是 false,实例判断方法与读值方法一样,返回 NoMethodError

如果不想要实例判断方法,传入 instance_predicate: false,这样就不会定义了。

active_support/core_ext/class/attribute.rb 文件中定义。

4.1.2 cattr_readercattr_writercattr_accessor +

cattr_readercattr_writercattr_accessor 的作用与相应的 attr_* 方法类似,不过是针对类的。它们声明的类属性,初始值为 nil,除非在此之前类属性已经存在,而且会生成相应的访问方法:

+
+class MysqlAdapter < AbstractAdapter
+  # 生成访问 @@emulate_booleans 的类方法
+  cattr_accessor :emulate_booleans
+  self.emulate_booleans = true
+end
+
+
+
+

为了方便,也会生成实例方法,这些实例方法只是类属性的代理。因此,实例可以修改类属性,但是不能覆盖——这与 class_attribute 不同(参见上文)。例如:

+
+module ActionView
+  class Base
+    cattr_accessor :field_error_proc
+    @@field_error_proc = Proc.new{ ... }
+  end
+end
+
+
+
+

这样,我们便可以在视图中访问 field_error_proc

此外,可以把一个块传给 cattr_* 方法,设定属性的默认值:

+
+class MysqlAdapter < AbstractAdapter
+  # 生成访问 @@emulate_booleans 的类方法,其默认值为 true
+  cattr_accessor(:emulate_booleans) { true }
+end
+
+
+
+

:instance_reader 设为 false,不生成实例读值方法,把 :instance_writer 设为 false,不生成实例设值方法,把 :instance_accessor 设为 false,实例读值和设置方法都不生成。此时,这三个选项的值都必须是 false,而不能是假值。

+
+module A
+  class B
+    # 不生成实例读值方法 first_name
+    cattr_accessor :first_name, instance_reader: false
+    # 不生成实例设值方法 last_name=
+    cattr_accessor :last_name, instance_writer: false
+    # 不生成实例读值方法 surname 和实例设值方法 surname=
+    cattr_accessor :surname, instance_accessor: false
+  end
+end
+
+
+
+

在模型中可以把 :instance_accessor 设为 false,防止批量赋值属性。

active_support/core_ext/module/attribute_accessors.rb 文件中定义。

4.2 子类和后代

4.2.1 subclasses +

subclasses 方法返回接收者的子类:

+
+class C; end
+C.subclasses # => []
+
+class B < C; end
+C.subclasses # => [B]
+
+class A < B; end
+C.subclasses # => [B]
+
+class D < C; end
+C.subclasses # => [B, D]
+
+
+
+

返回的子类没有特定顺序。

active_support/core_ext/class/subclasses.rb 文件中定义。

4.2.2 descendants +

descendants 方法返回接收者的后代:

+
+class C; end
+C.descendants # => []
+
+class B < C; end
+C.descendants # => [B]
+
+class A < B; end
+C.descendants # => [B, A]
+
+class D < C; end
+C.descendants # => [B, A, D]
+
+
+
+

返回的后代没有特定顺序。

active_support/core_ext/class/subclasses.rb 文件中定义。

5 String 的扩展

5.1 输出的安全性

5.1.1 引子

把数据插入 HTML 模板要格外小心。例如,不能原封不动地把 @review.title 内插到 HTML 页面中。假如标题是“Flanagan & Matz rules!”,得到的输出格式就不对,因为 & 会转义成“&”。更糟的是,如果应用编写不当,这可能留下严重的安全漏洞,因为用户可以注入恶意的 HTML,设定精心编造的标题。关于这个问题的详情,请阅读 安全指南对跨站脚本的说明。

5.1.2 安全字符串

Active Support 提出了安全字符串(对 HTML 而言)这一概念。安全字符串是对字符串做的一种标记,表示可以原封不动地插入 HTML。这种字符串是可信赖的,不管会不会转义。

默认,字符串被认为是不安全的:

+
+"".html_safe? # => false
+
+
+
+

可以使用 html_safe 方法把指定的字符串标记为安全的:

+
+s = "".html_safe
+s.html_safe? # => true
+
+
+
+

注意,无论如何,html_safe 不会执行转义操作,它的作用只是一种断定:

+
+s = "<script>...</script>".html_safe
+s.html_safe? # => true
+s            # => "<script>...</script>"
+
+
+
+

你要自己确定该不该在某个字符串上调用 html_safe

如果把字符串追加到安全字符串上,不管是就地修改,还是使用 concat/<<+,结果都是一个安全字符串。不安全的字符会转义:

+
+"".html_safe + "<" # => "&lt;"
+
+
+
+

安全的字符直接追加:

+
+"".html_safe + "<".html_safe # => "<"
+
+
+
+

在常规的视图中不应该使用这些方法。不安全的值会自动转义:

+
+<%= @review.title %> <%# 可以这么做,如果需要会转义 %>
+
+
+
+

如果想原封不动地插入值,不能调用 html_safe,而要使用 raw 辅助方法:

+
+<%= raw @cms.current_template %> <%# 原封不动地插入 @cms.current_template %>
+
+
+
+

或者,可以使用等效的 <%==

+
+<%== @cms.current_template %> <%# 原封不动地插入 @cms.current_template %>
+
+
+
+

raw 辅助方法已经调用 html_safe 了:

+
+def raw(stringish)
+  stringish.to_s.html_safe
+end
+
+
+
+

active_support/core_ext/string/output_safety.rb 文件中定义。

5.1.3 转换

通常,修改字符串的方法都返回不安全的字符串,前文所述的拼接除外。例如,downcasegsubstripchompunderscore,等等。

就地转换接收者,如 gsub!,其本身也变成不安全的了。

不管是否修改了自身,安全性都丧失了。

5.1.4 类型转换和强制转换

在安全字符串上调用 to_s,得到的还是安全字符串,但是使用 to_str 强制转换,得到的是不安全的字符串。

5.1.5 复制

在安全字符串上调用 dupclone,得到的还是安全字符串。

5.2 remove +

remove 方法删除匹配模式的所有内容:

+
+"Hello World".remove(/Hello /) # => "World"
+
+
+
+

也有破坏性版本,String#remove!

active_support/core_ext/string/filters.rb 文件中定义。

5.3 squish +

squish 方法把首尾的空白去掉,还会把多个空白压缩成一个:

+
+" \n  foo\n\r \t bar \n".squish # => "foo bar"
+
+
+
+

也有破坏性版本,String#squish!

注意,既能处理 ASCII 空白,也能处理 Unicode 空白。

active_support/core_ext/string/filters.rb 文件中定义。

5.4 truncate +

truncate 方法在指定长度处截断接收者,返回一个副本:

+
+"Oh dear! Oh dear! I shall be late!".truncate(20)
+# => "Oh dear! Oh dear!..."
+
+
+
+

省略号可以使用 :omission 选项自定义:

+
+"Oh dear! Oh dear! I shall be late!".truncate(20, omission: '&hellip;')
+# => "Oh dear! Oh &hellip;"
+
+
+
+

尤其要注意,截断长度包含省略字符串。

设置 :separator 选项,以自然的方式截断:

+
+"Oh dear! Oh dear! I shall be late!".truncate(18)
+# => "Oh dear! Oh dea..."
+"Oh dear! Oh dear! I shall be late!".truncate(18, separator: ' ')
+# => "Oh dear! Oh..."
+
+
+
+

:separator 选项的值可以是一个正则表达式:

+
+"Oh dear! Oh dear! I shall be late!".truncate(18, separator: /\s/)
+# => "Oh dear! Oh..."
+
+
+
+

在上述示例中,本该在“dear”中间截断,但是 :separator 选项进行了阻止。

active_support/core_ext/string/filters.rb 文件中定义。

5.5 truncate_words +

truncate_words 方法在指定个单词处截断接收者,返回一个副本:

+
+"Oh dear! Oh dear! I shall be late!".truncate_words(4)
+# => "Oh dear! Oh dear!..."
+
+
+
+

省略号可以使用 :omission 选项自定义:

+
+"Oh dear! Oh dear! I shall be late!".truncate_words(4, omission: '&hellip;')
+# => "Oh dear! Oh dear!&hellip;"
+
+
+
+

设置 :separator 选项,以自然的方式截断:

+
+"Oh dear! Oh dear! I shall be late!".truncate_words(3, separator: '!')
+# => "Oh dear! Oh dear! I shall be late..."
+
+
+
+

:separator 选项的值可以是一个正则表达式:

+
+"Oh dear! Oh dear! I shall be late!".truncate_words(4, separator: /\s/)
+# => "Oh dear! Oh dear!..."
+
+
+
+

active_support/core_ext/string/filters.rb 文件中定义。

5.6 inquiry +

inquiry 方法把字符串转换成 StringInquirer 对象,这样可以使用漂亮的方式检查相等性:

+
+"production".inquiry.production? # => true
+"active".inquiry.inactive?       # => false
+
+
+
+

5.7 starts_with?ends_with? +

Active Support 为 String#start_with?String#end_with? 定义了第三人称版本:

+
+"foo".starts_with?("f") # => true
+"foo".ends_with?("o")   # => true
+
+
+
+

active_support/core_ext/string/starts_ends_with.rb 文件中定义。

5.8 strip_heredoc +

strip_heredoc 方法去掉 here 文档中的缩进。

例如:

+
+if options[:usage]
+  puts <<-USAGE.strip_heredoc
+    This command does such and such.
+
+    Supported options are:
+      -h         This message
+      ...
+  USAGE
+end
+
+
+
+

用户看到的消息会靠左边对齐。

从技术层面来说,这个方法寻找整个字符串中的最小缩进量,然后删除那么多的前导空白。

active_support/core_ext/string/strip.rb 文件中定义。

5.9 indent +

按指定量缩进接收者:

+
+<<EOS.indent(2)
+def some_method
+  some_code
+end
+EOS
+# =>
+  def some_method
+    some_code
+  end
+
+
+
+

第二个参数,indent_string,指定使用什么字符串缩进。默认值是 nil,让这个方法根据第一个缩进行做猜测,如果第一行没有缩进,则使用空白。

+
+"  foo".indent(2)        # => "    foo"
+"foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
+"foo".indent(2, "\t")    # => "\t\tfoo"
+
+
+
+

indent_string 的值虽然经常设为一个空格或一个制表符,但是可以使用任何字符串。

第三个参数,indent_empty_lines,是个旗标,指明是否缩进空行。默认值是 false

+
+"foo\n\nbar".indent(2)            # => "  foo\n\n  bar"
+"foo\n\nbar".indent(2, nil, true) # => "  foo\n  \n  bar"
+
+
+
+

indent! 方法就地执行缩进。

active_support/core_ext/string/indent.rb 文件中定义。

5.10 访问

5.10.1 at(position) +

返回字符串中 position 位置上的字符:

+
+"hello".at(0)  # => "h"
+"hello".at(4)  # => "o"
+"hello".at(-1) # => "o"
+"hello".at(10) # => nil
+
+
+
+

active_support/core_ext/string/access.rb 文件中定义。

5.10.2 from(position) +

返回子串,从 position 位置开始:

+
+"hello".from(0)  # => "hello"
+"hello".from(2)  # => "llo"
+"hello".from(-2) # => "lo"
+"hello".from(10) # => nil
+
+
+
+

active_support/core_ext/string/access.rb 文件中定义。

5.10.3 to(position) +

返回子串,到 position 位置为止:

+
+"hello".to(0)  # => "h"
+"hello".to(2)  # => "hel"
+"hello".to(-2) # => "hell"
+"hello".to(10) # => "hello"
+
+
+
+

active_support/core_ext/string/access.rb 文件中定义。

5.10.4 first(limit = 1) +

如果 n > 0,str.first(n) 的作用与 str.to(n-1) 一样;如果 n == 0,返回一个空字符串。

active_support/core_ext/string/access.rb 文件中定义。

5.10.5 last(limit = 1) +

如果 n > 0,str.last(n) 的作用与 str.from(-n) 一样;如果 n == 0,返回一个空字符串。

active_support/core_ext/string/access.rb 文件中定义。

5.11 词形变化

5.11.1 pluralize +

pluralize 方法返回接收者的复数形式:

+
+"table".pluralize     # => "tables"
+"ruby".pluralize      # => "rubies"
+"equipment".pluralize # => "equipment"
+
+
+
+

如上例所示,Active Support 知道如何处理不规则的复数形式和不可数名词。内置的规则可以在 config/initializers/inflections.rb 文件中扩展。那个文件是由 rails 命令生成的,里面的注释说明了该怎么做。

pluralize 还可以接受可选的 count 参数。如果 count == 1,返回单数形式。把 count 设为其他值,都会返回复数形式:

+
+"dude".pluralize(0) # => "dudes"
+"dude".pluralize(1) # => "dude"
+"dude".pluralize(2) # => "dudes"
+
+
+
+

Active Record 使用这个方法计算模型对应的默认表名:

+
+# active_record/model_schema.rb
+def undecorated_table_name(class_name = base_class.name)
+  table_name = class_name.to_s.demodulize.underscore
+  pluralize_table_names ? table_name.pluralize : table_name
+end
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.2 singularize +

作用与 pluralize 相反:

+
+"tables".singularize    # => "table"
+"rubies".singularize    # => "ruby"
+"equipment".singularize # => "equipment"
+
+
+
+

关联使用这个方法计算默认的关联类:

+
+# active_record/reflection.rb
+def derive_class_name
+  class_name = name.to_s.camelize
+  class_name = class_name.singularize if collection?
+  class_name
+end
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.3 camelize +

camelize 方法把接收者变成驼峰式:

+
+"product".camelize    # => "Product"
+"admin_user".camelize # => "AdminUser"
+
+
+
+

一般来说,你可以把这个方法的作用想象为把路径转换成 Ruby 类或模块名的方式(使用斜线分隔命名空间):

+
+"backoffice/session".camelize # => "Backoffice::Session"
+
+
+
+

例如,Action Pack 使用这个方法加载提供特定会话存储功能的类:

+
+# action_controller/metal/session_management.rb
+def session_store=(store)
+  @@session_store = store.is_a?(Symbol) ?
+    ActionDispatch::Session.const_get(store.to_s.camelize) :
+    store
+end
+
+
+
+

camelize 接受一个可选的参数,其值可以是 :upper(默认值)或 :lower。设为后者时,第一个字母是小写的:

+
+"visual_effect".camelize(:lower) # => "visualEffect"
+
+
+
+

为使用这种风格的语言计算方法名时可以这么设定,例如 JavaScript。

一般来说,可以把 camelize 视作 underscore 的逆操作,不过也有例外:"SSLError".underscore.camelize 的结果是 "SslError"。为了支持这种情况,Active Support 允许你在 config/initializers/inflections.rb 文件中指定缩略词。

+
+
+
+ActiveSupport::Inflector.inflections do |inflect|
+  inflect.acronym 'SSL'
+end
+
+"SSLError".underscore.camelize # => "SSLError"
+
+
+
+
+

camelcasecamelize 的别名。

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.4 underscore +

underscore 方法的作用相反,把驼峰式变成蛇底式:

+
+"Product".underscore   # => "product"
+"AdminUser".underscore # => "admin_user"
+
+
+
+

还会把 "::" 转换成 "/"

+
+"Backoffice::Session".underscore # => "backoffice/session"
+
+
+
+

也能理解以小写字母开头的字符串:

+
+"visualEffect".underscore # => "visual_effect"
+
+
+
+

不过,underscore 不接受任何参数。

Rails 自动加载类和模块的机制使用 underscore 推断可能定义缺失的常量的文件的相对路径(不带扩展名):

+
+# active_support/dependencies.rb
+def load_missing_constant(from_mod, const_name)
+  ...
+  qualified_name = qualified_name_for from_mod, const_name
+  path_suffix = qualified_name.underscore
+  ...
+end
+
+
+
+

一般来说,可以把 underscore 视作 camelize 的逆操作,不过也有例外。例如,"SSLError".underscore.camelize 的结果是 "SslError"

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.5 titleize +

titleize 方法把接收者中的单词首字母变成大写:

+
+"alice in wonderland".titleize # => "Alice In Wonderland"
+"fermat's enigma".titleize     # => "Fermat's Enigma"
+
+
+
+

titlecasetitleize 的别名。

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.6 dasherize +

dasherize 方法把接收者中的下划线替换成连字符:

+
+"name".dasherize         # => "name"
+"contact_data".dasherize # => "contact-data"
+
+
+
+

模型的 XML 序列化程序使用这个方法处理节点名:

+
+# active_model/serializers/xml.rb
+def reformat_name(name)
+  name = name.camelize if camelize?
+  dasherize? ? name.dasherize : name
+end
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.7 demodulize +

demodulize 方法返回限定常量名的常量名本身,即最右边那一部分:

+
+"Product".demodulize                        # => "Product"
+"Backoffice::UsersController".demodulize    # => "UsersController"
+"Admin::Hotel::ReservationUtils".demodulize # => "ReservationUtils"
+"::Inflections".demodulize                  # => "Inflections"
+"".demodulize                               # => ""
+
+
+
+

例如,Active Record 使用这个方法计算计数器缓存列的名称:

+
+# active_record/reflection.rb
+def counter_cache_column
+  if options[:counter_cache] == true
+    "#{active_record.name.demodulize.underscore.pluralize}_count"
+  elsif options[:counter_cache]
+    options[:counter_cache]
+  end
+end
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.8 deconstantize +

deconstantize 方法去掉限定常量引用表达式的最右侧部分,留下常量的容器:

+
+"Product".deconstantize                        # => ""
+"Backoffice::UsersController".deconstantize    # => "Backoffice"
+"Admin::Hotel::ReservationUtils".deconstantize # => "Admin::Hotel"
+
+
+
+

例如,Active Support 在 Module#qualified_const_set 中使用了这个方法:

+
+def qualified_const_set(path, value)
+  QualifiedConstUtils.raise_if_absolute(path)
+
+  const_name = path.demodulize
+  mod_name = path.deconstantize
+  mod = mod_name.empty? ? self : qualified_const_get(mod_name)
+  mod.const_set(const_name, value)
+end
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.9 parameterize +

parameterize 方法对接收者做整形,以便在精美的 URL 中使用。

+
+"John Smith".parameterize # => "john-smith"
+"Kurt Gödel".parameterize # => "kurt-godel"
+
+
+
+

如果想保留大小写,把 preserve_case 参数设为 true。这个参数的默认值是 false

+
+"John Smith".parameterize(preserve_case: true) # => "John-Smith"
+"Kurt Gödel".parameterize(preserve_case: true) # => "Kurt-Godel"
+
+
+
+

如果想使用自定义的分隔符,覆盖 separator 参数。

+
+"John Smith".parameterize(separator: "_") # => "john\_smith"
+"Kurt Gödel".parameterize(separator: "_") # => "kurt\_godel"
+
+
+
+

其实,得到的字符串包装在 ActiveSupport::Multibyte::Chars 实例中。

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.10 tableize +

tableize 方法相当于先调用 underscore,再调用 pluralize

+
+"Person".tableize      # => "people"
+"Invoice".tableize     # => "invoices"
+"InvoiceLine".tableize # => "invoice_lines"
+
+
+
+

一般来说,tableize 返回简单模型对应的表名。Active Record 真正的实现方式不是只使用 tableize,还会使用 demodulize,再检查一些可能影响返回结果的选项。

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.11 classify +

classify 方法的作用与 tableize 相反,返回表名对应的类名:

+
+"people".classify        # => "Person"
+"invoices".classify      # => "Invoice"
+"invoice_lines".classify # => "InvoiceLine"
+
+
+
+

这个方法能处理限定的表名:

+
+"highrise_production.companies".classify # => "Company"
+
+
+
+

注意,classify 方法返回的类名是字符串。你可以调用 constantize 方法,得到真正的类对象,如下一节所述。

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.12 constantize +

constantize 方法解析接收者中的常量引用表达式:

+
+"Integer".constantize # => Integer
+
+module M
+  X = 1
+end
+"M::X".constantize # => 1
+
+
+
+

如果结果是未知的常量,或者根本不是有效的常量名,constantize 抛出 NameError 异常。

即便开头没有 ::constantize 也始终从顶层的 Object 解析常量名。

+
+X = :in_Object
+module M
+  X = :in_M
+
+  X                 # => :in_M
+  "::X".constantize # => :in_Object
+  "X".constantize   # => :in_Object (!)
+end
+
+
+
+

因此,通常这与 Ruby 的处理方式不同,Ruby 会求值真正的常量。

邮件程序测试用例使用 constantize 方法从测试用例的名称中获取要测试的邮件程序:

+
+# action_mailer/test_case.rb
+def determine_default_mailer(name)
+  name.sub(/Test$/, '').constantize
+rescue NameError => e
+  raise NonInferrableMailerError.new(name)
+end
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.13 humanize +

humanize 方法对属性名做调整,以便显示给终端用户查看。

这个方法所做的转换如下:

+
    +
  • 根据参数做对人类友好的词形变化

  • +
  • 删除前导下划线(如果有)

  • +
  • 删除“_id”后缀(如果有)

  • +
  • 把下划线替换成空格(如果有)

  • +
  • 把所有单词变成小写,缩略词除外

  • +
  • 把第一个单词的首字母变成大写

  • +
+

:capitalize 选项设为 false(默认值为 true)可以禁止把第一个单词的首字母变成大写。

+
+"name".humanize                         # => "Name"
+"author_id".humanize                    # => "Author"
+"author_id".humanize(capitalize: false) # => "author"
+"comments_count".humanize               # => "Comments count"
+"_id".humanize                          # => "Id"
+
+
+
+

如果把“SSL”定义为缩略词:

+
+'ssl_error'.humanize # => "SSL error"
+
+
+
+

full_messages 辅助方法使用 humanize 作为一种后备机制,以便包含属性名:

+
+def full_messages
+  map { |attribute, message| full_message(attribute, message) }
+end
+
+def full_message
+  ...
+  attr_name = attribute.to_s.tr('.', '_').humanize
+  attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
+  ...
+end
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.11.14 foreign_key +

foreign_key 方法根据类名计算外键列的名称。为此,它先调用 demodulize,再调用 underscore,最后加上“_id”:

+
+"User".foreign_key           # => "user_id"
+"InvoiceLine".foreign_key    # => "invoice_line_id"
+"Admin::Session".foreign_key # => "session_id"
+
+
+
+

如果不想添加“_id”中的下划线,传入 false 参数:

+
+"User".foreign_key(false) # => "userid"
+
+
+
+

关联使用这个方法推断外键,例如 has_onehas_many 是这么做的:

+
+# active_record/associations.rb
+foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
+
+
+
+

active_support/core_ext/string/inflections.rb 文件中定义。

5.12 转换

5.12.1 to_dateto_timeto_datetime +

to_dateto_timeto_datetime 是对 Date._parse 的便利包装:

+
+"2010-07-27".to_date              # => Tue, 27 Jul 2010
+"2010-07-27 23:37:00".to_time     # => 2010-07-27 23:37:00 +0200
+"2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
+
+
+
+

to_time 有个可选的参数,值为 :utc:local,指明想使用的时区:

+
+"2010-07-27 23:42:00".to_time(:utc)   # => 2010-07-27 23:42:00 UTC
+"2010-07-27 23:42:00".to_time(:local) # => 2010-07-27 23:42:00 +0200
+
+
+
+

默认值是 :utc

详情参见 Date._parse 的文档。

参数为空时,这三个方法返回 nil

active_support/core_ext/string/conversions.rb 文件中定义。

6 Numeric 的扩展

6.1 字节

所有数字都能响应下述方法:

+
+bytes
+kilobytes
+megabytes
+gigabytes
+terabytes
+petabytes
+exabytes
+
+
+
+

这些方法返回相应的字节数,因子是 1024:

+
+2.kilobytes   # => 2048
+3.megabytes   # => 3145728
+3.5.gigabytes # => 3758096384
+-4.exabytes   # => -4611686018427387904
+
+
+
+

这些方法都有单数别名,因此可以这样用:

+
+1.megabyte # => 1048576
+
+
+
+

active_support/core_ext/numeric/bytes.rb 文件中定义。

6.2 时间

用于计算和声明时间,例如 45.minutes + 2.hours + 4.years

使用 from_nowago 等精确计算日期,以及增减 Time 对象时使用 Time#advance。例如:

+
+# 等价于 Time.current.advance(months: 1)
+1.month.from_now
+
+# 等价于 Time.current.advance(years: 2)
+2.years.from_now
+
+# 等价于 Time.current.advance(months: 4, years: 5)
+(4.months + 5.years).from_now
+
+
+
+

active_support/core_ext/numeric/time.rb 文件中定义。

6.3 格式化

以各种形式格式化数字。

把数字转换成字符串表示形式,表示电话号码:

+
+5551234.to_s(:phone)
+# => 555-1234
+1235551234.to_s(:phone)
+# => 123-555-1234
+1235551234.to_s(:phone, area_code: true)
+# => (123) 555-1234
+1235551234.to_s(:phone, delimiter: " ")
+# => 123 555 1234
+1235551234.to_s(:phone, area_code: true, extension: 555)
+# => (123) 555-1234 x 555
+1235551234.to_s(:phone, country_code: 1)
+# => +1-123-555-1234
+
+
+
+

把数字转换成字符串表示形式,表示货币:

+
+1234567890.50.to_s(:currency)                 # => $1,234,567,890.50
+1234567890.506.to_s(:currency)                # => $1,234,567,890.51
+1234567890.506.to_s(:currency, precision: 3)  # => $1,234,567,890.506
+
+
+
+

把数字转换成字符串表示形式,表示百分比:

+
+100.to_s(:percentage)
+# => 100.000%
+100.to_s(:percentage, precision: 0)
+# => 100%
+1000.to_s(:percentage, delimiter: '.', separator: ',')
+# => 1.000,000%
+302.24398923423.to_s(:percentage, precision: 5)
+# => 302.24399%
+
+
+
+

把数字转换成字符串表示形式,以分隔符分隔:

+
+12345678.to_s(:delimited)                     # => 12,345,678
+12345678.05.to_s(:delimited)                  # => 12,345,678.05
+12345678.to_s(:delimited, delimiter: ".")     # => 12.345.678
+12345678.to_s(:delimited, delimiter: ",")     # => 12,345,678
+12345678.05.to_s(:delimited, separator: " ")  # => 12,345,678 05
+
+
+
+

把数字转换成字符串表示形式,以指定精度四舍五入:

+
+111.2345.to_s(:rounded)                     # => 111.235
+111.2345.to_s(:rounded, precision: 2)       # => 111.23
+13.to_s(:rounded, precision: 5)             # => 13.00000
+389.32314.to_s(:rounded, precision: 0)      # => 389
+111.2345.to_s(:rounded, significant: true)  # => 111
+
+
+
+

把数字转换成字符串表示形式,得到人类可读的字节数:

+
+123.to_s(:human_size)                  # => 123 Bytes
+1234.to_s(:human_size)                 # => 1.21 KB
+12345.to_s(:human_size)                # => 12.1 KB
+1234567.to_s(:human_size)              # => 1.18 MB
+1234567890.to_s(:human_size)           # => 1.15 GB
+1234567890123.to_s(:human_size)        # => 1.12 TB
+1234567890123456.to_s(:human_size)     # => 1.1 PB
+1234567890123456789.to_s(:human_size)  # => 1.07 EB
+
+
+
+

把数字转换成字符串表示形式,得到人类可读的词:

+
+123.to_s(:human)               # => "123"
+1234.to_s(:human)              # => "1.23 Thousand"
+12345.to_s(:human)             # => "12.3 Thousand"
+1234567.to_s(:human)           # => "1.23 Million"
+1234567890.to_s(:human)        # => "1.23 Billion"
+1234567890123.to_s(:human)     # => "1.23 Trillion"
+1234567890123456.to_s(:human)  # => "1.23 Quadrillion"
+
+
+
+

active_support/core_ext/numeric/conversions.rb 文件中定义。

7 Integer 的扩展

7.1 multiple_of? +

multiple_of? 方法测试一个整数是不是参数的倍数:

+
+2.multiple_of?(1) # => true
+1.multiple_of?(2) # => false
+
+
+
+

active_support/core_ext/integer/multiple.rb 文件中定义。

7.2 ordinal +

ordinal 方法返回整数接收者的序数词后缀(字符串):

+
+1.ordinal    # => "st"
+2.ordinal    # => "nd"
+53.ordinal   # => "rd"
+2009.ordinal # => "th"
+-21.ordinal  # => "st"
+-134.ordinal # => "th"
+
+
+
+

active_support/core_ext/integer/inflections.rb 文件中定义。

7.3 ordinalize +

ordinalize 方法返回整数接收者的序数词(字符串)。注意,ordinal 方法只返回后缀。

+
+1.ordinalize    # => "1st"
+2.ordinalize    # => "2nd"
+53.ordinalize   # => "53rd"
+2009.ordinalize # => "2009th"
+-21.ordinalize  # => "-21st"
+-134.ordinalize # => "-134th"
+
+
+
+

active_support/core_ext/integer/inflections.rb 文件中定义。

8 BigDecimal 的扩展

8.1 to_s +

to_s 方法把默认的说明符设为“F”。这意味着,不传入参数时,to_s 返回浮点数表示形式,而不是工程计数法。

+
+BigDecimal.new(5.00, 6).to_s  # => "5.0"
+
+
+
+

说明符也可以使用符号:

+
+BigDecimal.new(5.00, 6).to_s(:db)  # => "5.0"
+
+
+
+

也支持工程计数法:

+
+BigDecimal.new(5.00, 6).to_s("e")  # => "0.5E1"
+
+
+
+

9 Enumerable 的扩展

9.1 sum +

sum 方法计算可枚举对象的元素之和:

+
+[1, 2, 3].sum # => 6
+(1..100).sum  # => 5050
+
+
+
+

只假定元素能响应 +

+
+[[1, 2], [2, 3], [3, 4]].sum    # => [1, 2, 2, 3, 3, 4]
+%w(foo bar baz).sum             # => "foobarbaz"
+{a: 1, b: 2, c: 3}.sum # => [:b, 2, :c, 3, :a, 1]
+
+
+
+

空集合的元素之和默认为零,不过可以自定义:

+
+[].sum    # => 0
+[].sum(1) # => 1
+
+
+
+

如果提供块,sum 变成迭代器,把集合中的元素拽入块中,然后求返回值之和:

+
+(1..5).sum {|n| n * 2 } # => 30
+[2, 4, 6, 8, 10].sum    # => 30
+
+
+
+

空接收者之和也可以使用这种方式自定义:

+
+[].sum(1) {|n| n**3} # => 1
+
+
+
+

active_support/core_ext/enumerable.rb 文件中定义。

9.2 index_by +

index_by 方法生成一个散列,使用某个键索引可枚举对象中的元素。

它迭代集合,把各个元素传入块中。元素使用块的返回值为键:

+
+invoices.index_by(&:number)
+# => {'2009-032' => <Invoice ...>, '2009-008' => <Invoice ...>, ...}
+
+
+
+

键一般是唯一的。如果块为不同的元素返回相同的键,不会使用那个键构建集合。最后一个元素胜出。

active_support/core_ext/enumerable.rb 文件中定义。

9.3 many? +

many? 方法是 collection.size > 1 的简化:

+
+<% if pages.many? %>
+  <%= pagination_links %>
+<% end %>
+
+
+
+

如果提供可选的块,many? 只考虑返回 true 的元素:

+
+@see_more = videos.many? {|video| video.category == params[:category]}
+
+
+
+

active_support/core_ext/enumerable.rb 文件中定义。

9.4 exclude? +

exclude? 方法测试指定对象是否不在集合中。这是内置方法 include? 的逆向判断。

+
+to_visit << node if visited.exclude?(node)
+
+
+
+

active_support/core_ext/enumerable.rb 文件中定义。

9.5 without +

without 从可枚举对象中删除指定的元素,然后返回副本:

+
+["David", "Rafael", "Aaron", "Todd"].without("Aaron", "Todd") # => ["David", "Rafael"]
+
+
+
+

active_support/core_ext/enumerable.rb 文件中定义。

9.6 pluck +

pluck 方法基于指定的键返回一个数组:

+
+[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) # => ["David", "Rafael", "Aaron"]
+
+
+
+

active_support/core_ext/enumerable.rb 文件中定义。

10 Array 的扩展

10.1 访问

为了便于以多种方式访问数组,Active Support 增强了数组的 API。例如,若想获取到指定索引的子数组,可以这么做:

+
+%w(a b c d).to(2) # => %w(a b c)
+[].to(7)          # => []
+
+
+
+

类似地,from 从指定索引一直获取到末尾。如果索引大于数组的长度,返回一个空数组。

+
+%w(a b c d).from(2)  # => %w(c d)
+%w(a b c d).from(10) # => []
+[].from(0)           # => []
+
+
+
+

secondthirdfourthfifth 分别返回对应的元素,second_to_lastthird_to_last 也是(firstlast 是内置的)。得益于公众智慧和积极的建设性建议,还有 forty_two 可用。

+
+%w(a b c d).third # => c
+%w(a b c d).fifth # => nil
+
+
+
+

active_support/core_ext/array/access.rb 文件中定义。

10.2 添加元素

10.2.1 prepend +

这个方法是 Array#unshift 的别名。

+
+%w(a b c d).prepend('e')  # => ["e", "a", "b", "c", "d"]
+[].prepend(10)            # => [10]
+
+
+
+

active_support/core_ext/array/prepend_and_append.rb 文件中定义。

10.2.2 append +

这个方法是 Array#<< 的别名。

+
+%w(a b c d).append('e')  # => ["a", "b", "c", "d", "e"]
+[].append([1,2])         # => [[1, 2]]
+
+
+
+

active_support/core_ext/array/prepend_and_append.rb 文件中定义。

10.3 选项提取

如果方法调用的最后一个参数(不含 &block 参数)是散列,Ruby 允许省略花括号:

+
+User.exists?(email: params[:email])
+
+
+
+

Rails 大量使用这种语法糖,以此避免编写大量位置参数,用于模仿具名参数。Rails 经常在最后一个散列选项上使用这种惯用法。

然而,如果方法期待任意个参数,在声明中使用 *,那么选项散列就会变成数组中一个元素,失去了应有的作用。

此时,可以使用 extract_options! 特殊处理选项散列。这个方法检查数组最后一个元素的类型,如果是散列,把它提取出来,并返回;否则,返回一个空散列。

下面以控制器的 caches_action 方法的定义为例:

+
+def caches_action(*actions)
+  return unless cache_configured?
+  options = actions.extract_options!
+  ...
+end
+
+
+
+

这个方法接收任意个动作名,最后一个参数是选项散列。extract_options! 方法获取选项散列,把它从 actions 参数中删除,这样简单便利。

active_support/core_ext/array/extract_options.rb 文件中定义。

10.4 转换

10.4.1 to_sentence +

to_sentence 方法枚举元素,把数组变成一个句子(字符串):

+
+%w().to_sentence                # => ""
+%w(Earth).to_sentence           # => "Earth"
+%w(Earth Wind).to_sentence      # => "Earth and Wind"
+%w(Earth Wind Fire).to_sentence # => "Earth, Wind, and Fire"
+
+
+
+

这个方法接受三个选项:

+
    +
  • :two_words_connector:数组长度为 2 时使用什么词。默认为“ and”。

  • +
  • :words_connector:数组元素数量为 3 个以上(含)时,使用什么连接除最后两个元素之外的元素。默认为“, ”。

  • +
  • :last_word_connector:数组元素数量为 3 个以上(含)时,使用什么连接最后两个元素。默认为“, and”。

  • +
+

这些选项的默认值可以本地化,相应的键为:

+ + + + + + + + + + + + + + + + + + + + + +
选项i18n 键
:two_words_connectorsupport.array.two_words_connector
:words_connectorsupport.array.words_connector
:last_word_connectorsupport.array.last_word_connector
+

active_support/core_ext/array/conversions.rb 文件中定义。

10.4.2 to_formatted_s +

默认情况下,to_formatted_s 的行为与 to_s 一样。

然而,如果数组中的元素能响应 id 方法,可以传入参数 :db。处理 Active Record 对象集合时经常如此。返回的字符串如下:

+
+[].to_formatted_s(:db)            # => "null"
+[user].to_formatted_s(:db)        # => "8456"
+invoice.lines.to_formatted_s(:db) # => "23,567,556,12"
+
+
+
+

在上述示例中,整数是在元素上调用 id 得到的。

active_support/core_ext/array/conversions.rb 文件中定义。

10.4.3 to_xml +

to_xml 方法返回接收者的 XML 表述:

+
+Contributor.limit(2).order(:rank).to_xml
+# =>
+# <?xml version="1.0" encoding="UTF-8"?>
+# <contributors type="array">
+#   <contributor>
+#     <id type="integer">4356</id>
+#     <name>Jeremy Kemper</name>
+#     <rank type="integer">1</rank>
+#     <url-id>jeremy-kemper</url-id>
+#   </contributor>
+#   <contributor>
+#     <id type="integer">4404</id>
+#     <name>David Heinemeier Hansson</name>
+#     <rank type="integer">2</rank>
+#     <url-id>david-heinemeier-hansson</url-id>
+#   </contributor>
+# </contributors>
+
+
+
+

为此,它把 to_xml 分别发送给每个元素,然后收集结果,放在一个根节点中。所有元素都必须能响应 to_xml,否则抛出异常。

默认情况下,根元素的名称是第一个元素的类名的复数形式经过 underscoredasherize 处理后得到的值——前提是余下的元素属于那个类型(使用 is_a? 检查),而且不是散列。在上例中,根元素是“contributors”。

只要有不属于那个类型的元素,根元素就使用“objects”:

+
+[Contributor.first, Commit.first].to_xml
+# =>
+# <?xml version="1.0" encoding="UTF-8"?>
+# <objects type="array">
+#   <object>
+#     <id type="integer">4583</id>
+#     <name>Aaron Batalion</name>
+#     <rank type="integer">53</rank>
+#     <url-id>aaron-batalion</url-id>
+#   </object>
+#   <object>
+#     <author>Joshua Peek</author>
+#     <authored-timestamp type="datetime">2009-09-02T16:44:36Z</authored-timestamp>
+#     <branch>origin/master</branch>
+#     <committed-timestamp type="datetime">2009-09-02T16:44:36Z</committed-timestamp>
+#     <committer>Joshua Peek</committer>
+#     <git-show nil="true"></git-show>
+#     <id type="integer">190316</id>
+#     <imported-from-svn type="boolean">false</imported-from-svn>
+#     <message>Kill AMo observing wrap_with_notifications since ARes was only using it</message>
+#     <sha1>723a47bfb3708f968821bc969a9a3fc873a3ed58</sha1>
+#   </object>
+# </objects>
+
+
+
+

如果接收者是由散列组成的数组,根元素默认也是“objects”:

+
+[{a: 1, b: 2}, {c: 3}].to_xml
+# =>
+# <?xml version="1.0" encoding="UTF-8"?>
+# <objects type="array">
+#   <object>
+#     <b type="integer">2</b>
+#     <a type="integer">1</a>
+#   </object>
+#   <object>
+#     <c type="integer">3</c>
+#   </object>
+# </objects>
+
+
+
+

如果集合为空,根元素默认为“nil-classes”。例如上述示例中的贡献者列表,如果集合为空,根元素不是“contributors”,而是“nil-classes”。可以使用 :root 选项确保根元素始终一致。

子节点的名称默认为根节点的单数形式。在前面几个例子中,我们见到的是“contributor”和“object”。可以使用 :children 选项设定子节点的名称。

默认的 XML 构建程序是一个新的 Builder::XmlMarkup 实例。可以使用 :builder 选项指定构建程序。这个方法还接受 :dasherize 等方法,它们会被转发给构建程序。

+
+Contributor.limit(2).order(:rank).to_xml(skip_types: true)
+# =>
+# <?xml version="1.0" encoding="UTF-8"?>
+# <contributors>
+#   <contributor>
+#     <id>4356</id>
+#     <name>Jeremy Kemper</name>
+#     <rank>1</rank>
+#     <url-id>jeremy-kemper</url-id>
+#   </contributor>
+#   <contributor>
+#     <id>4404</id>
+#     <name>David Heinemeier Hansson</name>
+#     <rank>2</rank>
+#     <url-id>david-heinemeier-hansson</url-id>
+#   </contributor>
+# </contributors>
+
+
+
+

active_support/core_ext/array/conversions.rb 文件中定义。

10.5 包装

Array.wrap 方法把参数包装成一个数组,除非参数已经是数组(或与数组类似的结构)。

具体而言:

+
    +
  • 如果参数是 nil,返回一个空数组。

  • +
  • 否则,如果参数响应 to_ary 方法,调用之;如果 to_ary 返回值不是 nil,返回之。

  • +
  • 否则,把参数作为数组的唯一元素,返回之。

  • +
+
+
+Array.wrap(nil)       # => []
+Array.wrap([1, 2, 3]) # => [1, 2, 3]
+Array.wrap(0)         # => [0]
+
+
+
+

这个方法的作用与 Kernel#Array 类似,不过二者之间有些区别:

+
    +
  • 如果参数响应 to_ary,调用之。如果 to_ary 的返回值是 nilKernel#Array 接着调用 to_a,而 Array.wrap 把参数作为数组的唯一元素,返回之。

  • +
  • 如果 to_ary 的返回值既不是 nil,也不是 Array 对象,Kernel#Array 抛出异常,而 Array.wrap 不会,它返回那个值。

  • +
  • 如果参数不响应 to_aryArray.wrap 不在参数上调用 to_a,而是把参数作为数组的唯一元素,返回之。

  • +
+

对某些可枚举对象来说,最后一点尤为重要:

+
+Array.wrap(foo: :bar) # => [{:foo=>:bar}]
+Array(foo: :bar)      # => [[:foo, :bar]]
+
+
+
+

还有一种惯用法是使用星号运算符:

+
+[*object]
+
+
+
+

在 Ruby 1.8 中,如果参数是 nil,返回 [nil],否则调用 Array(object)。(如果你知道在 Ruby 1.9 中的行为,请联系 fxn。)

因此,参数为 nil 时二者的行为不同,前文对 Kernel#Array 的说明适用于其他对象。

active_support/core_ext/array/wrap.rb 文件中定义。

10.6 复制

Array#deep_dup 方法使用 Active Support 提供的 Object#deep_dup 方法复制数组自身和里面的对象。其工作方式相当于通过 Array#mapdeep_dup 方法发给里面的各个对象。

+
+array = [1, [2, 3]]
+dup = array.deep_dup
+dup[1][2] = 4
+array[1][2] == nil   # => true
+
+
+
+

active_support/core_ext/object/deep_dup.rb 文件中定义。

10.7 分组

10.7.1 in_groups_of(number, fill_with = nil) +

in_groups_of 方法把数组拆分成特定长度的连续分组,返回由各分组构成的数组:

+
+[1, 2, 3].in_groups_of(2) # => [[1, 2], [3, nil]]
+
+
+
+

如果有块,把各分组拽入块中:

+
+<% sample.in_groups_of(3) do |a, b, c| %>
+  <tr>
+    <td><%= a %></td>
+    <td><%= b %></td>
+    <td><%= c %></td>
+  </tr>
+<% end %>
+
+
+
+

第一个示例说明 in_groups_of 会使用 nil 元素填充最后一组,得到指定大小的分组。可以使用第二个参数(可选的)修改填充值:

+
+[1, 2, 3].in_groups_of(2, 0) # => [[1, 2], [3, 0]]
+
+
+
+

如果传入 false,不填充最后一组:

+
+[1, 2, 3].in_groups_of(2, false) # => [[1, 2], [3]]
+
+
+
+

因此,false 不能作为填充值使用。

active_support/core_ext/array/grouping.rb 文件中定义。

10.7.2 in_groups(number, fill_with = nil) +

in_groups 方法把数组分成特定个分组。这个方法返回由分组构成的数组:

+
+%w(1 2 3 4 5 6 7).in_groups(3)
+# => [["1", "2", "3"], ["4", "5", nil], ["6", "7", nil]]
+
+
+
+

如果有块,把分组拽入块中:

+
+%w(1 2 3 4 5 6 7).in_groups(3) {|group| p group}
+["1", "2", "3"]
+["4", "5", nil]
+["6", "7", nil]
+
+
+
+

在上述示例中,in_groups 使用 nil 填充尾部的分组。一个分组至多有一个填充值,而且是最后一个元素。有填充值的始终是最后几个分组。

可以使用第二个参数(可选的)修改填充值:

+
+%w(1 2 3 4 5 6 7).in_groups(3, "0")
+# => [["1", "2", "3"], ["4", "5", "0"], ["6", "7", "0"]]
+
+
+
+

如果传入 false,不填充较短的分组:

+
+%w(1 2 3 4 5 6 7).in_groups(3, false)
+# => [["1", "2", "3"], ["4", "5"], ["6", "7"]]
+
+
+
+

因此,false 不能作为填充值使用。

active_support/core_ext/array/grouping.rb 文件中定义。

10.7.3 split(value = nil) +

split 方法在指定的分隔符处拆分数组,返回得到的片段。

如果有块,使用块中表达式返回 true 的元素作为分隔符:

+
+(-5..5).to_a.split { |i| i.multiple_of?(4) }
+# => [[-5], [-3, -2, -1], [1, 2, 3], [5]]
+
+
+
+

否则,使用指定的参数(默认为 nil)作为分隔符:

+
+[0, 1, -5, 1, 1, "foo", "bar"].split(1)
+# => [[0], [-5], [], ["foo", "bar"]]
+
+
+
+

仔细观察上例,出现连续的分隔符时,得到的是空数组。

active_support/core_ext/array/grouping.rb 文件中定义。

11 Hash 的扩展

11.1 转换

11.1.1 to_xml +

to_xml 方法返回接收者的 XML 表述(字符串):

+
+{"foo" => 1, "bar" => 2}.to_xml
+# =>
+# <?xml version="1.0" encoding="UTF-8"?>
+# <hash>
+#   <foo type="integer">1</foo>
+#   <bar type="integer">2</bar>
+# </hash>
+
+
+
+

为此,这个方法迭代各个键值对,根据值构建节点。假如键值对是 key, value

+
    +
  • 如果 value 是一个散列,递归调用,此时 key 作为 :root

  • +
  • 如果 value 是一个数组,递归调用,此时 key 作为 :rootkey 的单数形式作为 :children

  • +
  • 如果 value 是可调用对象,必须能接受一个或两个参数。根据参数的数量,传给可调用对象的第一个参数是 options 散列,key 作为 :rootkey 的单数形式作为第二个参数。它的返回值作为新节点。

  • +
  • 如果 value 响应 to_xml,调用这个方法时把 key 作为 :root

  • +
  • +

    否则,使用 key 为标签创建一个节点,value 的字符串表示形式为文本作为节点的文本。如果 valuenil,添加“nil”属性,值为“true”。除非有 :skip_type 选项,而且值为 true,否则还会根据下述对应关系添加“type”属性:

    +
    +
    +XML_TYPE_NAMES = {
    +  "Symbol"     => "symbol",
    +  "Integer"    => "integer",
    +  "BigDecimal" => "decimal",
    +  "Float"      => "float",
    +  "TrueClass"  => "boolean",
    +  "FalseClass" => "boolean",
    +  "Date"       => "date",
    +  "DateTime"   => "datetime",
    +  "Time"       => "datetime"
    +}
    +
    +
    +
    +
  • +
+

默认情况下,根节点是“hash”,不过可以通过 :root 选项配置。

默认的 XML 构建程序是一个新的 Builder::XmlMarkup 实例。可以使用 :builder 选项配置构建程序。这个方法还接受 :dasherize 等选项,它们会被转发给构建程序。

active_support/core_ext/hash/conversions.rb 文件中定义。

11.2 合并

Ruby 有个内置的方法,Hash#merge,用于合并两个散列:

+
+{a: 1, b: 1}.merge(a: 0, c: 2)
+# => {:a=>0, :b=>1, :c=>2}
+
+
+
+

为了方便,Active Support 定义了几个用于合并散列的方法。

11.2.1 reverse_mergereverse_merge! +

如果键有冲突,merge 方法的参数中的键胜出。通常利用这一点为选项散列提供默认值:

+
+options = {length: 30, omission: "..."}.merge(options)
+
+
+
+

Active Support 定义了 reverse_merge 方法,以防你想使用相反的合并方式:

+
+options = options.reverse_merge(length: 30, omission: "...")
+
+
+
+

还有一个爆炸版本,reverse_merge!,就地执行合并:

+
+options.reverse_merge!(length: 30, omission: "...")
+
+
+
+

reverse_merge! 方法会就地修改调用方,这可能不是个好主意。

active_support/core_ext/hash/reverse_merge.rb 文件中定义。

11.2.2 reverse_update +

reverse_update 方法是 reverse_merge! 的别名,作用参见前文。

注意,reverse_update 方法的名称中没有感叹号。

active_support/core_ext/hash/reverse_merge.rb 文件中定义。

11.2.3 deep_mergedeep_merge! +

如前面的示例所示,如果两个散列中有相同的键,参数中的散列胜出。

Active Support 定义了 Hash#deep_merge 方法。在深度合并中,如果两个散列中有相同的键,而且它们的值都是散列,那么在得到的散列中,那个键的值是合并后的结果:

+
+{a: {b: 1}}.deep_merge(a: {c: 2})
+# => {:a=>{:b=>1, :c=>2}}
+
+
+
+

deep_merge! 方法就地执行深度合并。

active_support/core_ext/hash/deep_merge.rb 文件中定义。

11.3 深度复制

Hash#deep_dup 方法使用 Active Support 提供的 Object#deep_dup 方法复制散列自身及里面的键值对。其工作方式相当于通过 Enumerator#each_with_objectdeep_dup 方法发给各个键值对。

+
+hash = { a: 1, b: { c: 2, d: [3, 4] } }
+
+dup = hash.deep_dup
+dup[:b][:e] = 5
+dup[:b][:d] << 5
+
+hash[:b][:e] == nil      # => true
+hash[:b][:d] == [3, 4]   # => true
+
+
+
+

active_support/core_ext/object/deep_dup.rb 文件中定义。

11.4 处理键

11.4.1 exceptexcept! +

except 方法返回一个散列,从接收者中把参数中列出的键删除(如果有的话):

+
+{a: 1, b: 2}.except(:a) # => {:b=>2}
+
+
+
+

如果接收者响应 convert_key 方法,会在各个参数上调用它。这样 except 能更好地处理不区分键类型的散列,例如:

+
+{a: 1}.with_indifferent_access.except(:a)  # => {}
+{a: 1}.with_indifferent_access.except("a") # => {}
+
+
+
+

还有爆炸版本,except!,就地从接收者中删除键。

active_support/core_ext/hash/except.rb 文件中定义。

11.4.2 transform_keystransform_keys! +

transform_keys 方法接受一个块,使用块中的代码处理接收者的键:

+
+{nil => nil, 1 => 1, a: :a}.transform_keys { |key| key.to_s.upcase }
+# => {"" => nil, "A" => :a, "1" => 1}
+
+
+
+

遇到冲突的键时,只会从中选择一个。选择哪个值并不确定。

+
+{"a" => 1, a: 2}.transform_keys { |key| key.to_s.upcase }
+# 结果可能是
+# => {"A"=>2}
+# 也可能是
+# => {"A"=>1}
+
+
+
+

这个方法可以用于构建特殊的转换方式。例如,stringify_keyssymbolize_keys 使用 transform_keys 转换键:

+
+def stringify_keys
+  transform_keys { |key| key.to_s }
+end
+...
+def symbolize_keys
+  transform_keys { |key| key.to_sym rescue key }
+end
+
+
+
+

还有爆炸版本,transform_keys!,就地使用块中的代码处理接收者的键。

此外,可以使用 deep_transform_keysdeep_transform_keys! 把块应用到指定散列及其嵌套的散列的所有键上。例如:

+
+{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_transform_keys { |key| key.to_s.upcase }
+# => {""=>nil, "1"=>1, "NESTED"=>{"A"=>3, "5"=>5}}
+
+
+
+

active_support/core_ext/hash/keys.rb 文件中定义。

11.4.3 stringify_keysstringify_keys! +

stringify_keys 把接收者中的键都变成字符串,然后返回一个散列。为此,它在键上调用 to_s

+
+{nil => nil, 1 => 1, a: :a}.stringify_keys
+# => {"" => nil, "a" => :a, "1" => 1}
+
+
+
+

遇到冲突的键时,只会从中选择一个。选择哪个值并不确定。

+
+{"a" => 1, a: 2}.stringify_keys
+# 结果可能是
+# => {"a"=>2}
+# 也可能是
+# => {"a"=>1}
+
+
+
+

使用这个方法,选项既可以是符号,也可以是字符串。例如 ActionView::Helpers::FormHelper 定义的这个方法:

+
+def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0")
+  options = options.stringify_keys
+  options["type"] = "checkbox"
+  ...
+end
+
+
+
+

因为有第二行,所以用户可以传入 :type"type"

也有爆炸版本,stringify_keys!,直接把接收者的键变成字符串。

此外,可以使用 deep_stringify_keysdeep_stringify_keys! 把指定散列及其中嵌套的散列的键全都转换成字符串。例如:

+
+{nil => nil, 1 => 1, nested: {a: 3, 5 => 5}}.deep_stringify_keys
+# => {""=>nil, "1"=>1, "nested"=>{"a"=>3, "5"=>5}}
+
+
+
+

active_support/core_ext/hash/keys.rb 文件中定义。

11.4.4 symbolize_keyssymbolize_keys! +

symbolize_keys 方法把接收者中的键尽量变成符号。为此,它在键上调用 to_sym

+
+{nil => nil, 1 => 1, "a" => "a"}.symbolize_keys
+# => {1=>1, nil=>nil, :a=>"a"}
+
+
+
+

注意,在上例中,只有键变成了符号。

遇到冲突的键时,只会从中选择一个。选择哪个值并不确定。

+
+{"a" => 1, a: 2}.symbolize_keys
+# 结果可能是
+# => {:a=>2}
+# 也可能是
+# => {:a=>1}
+
+
+
+

使用这个方法,选项既可以是符号,也可以是字符串。例如 ActionController::UrlRewriter 定义的这个方法:

+
+def rewrite_path(options)
+  options = options.symbolize_keys
+  options.update(options[:params].symbolize_keys) if options[:params]
+  ...
+end
+
+
+
+

因为有第二行,所以用户可以传入 :params"params"

也有爆炸版本,symbolize_keys!,直接把接收者的键变成符号。

此外,可以使用 deep_symbolize_keysdeep_symbolize_keys! 把指定散列及其中嵌套的散列的键全都转换成符号。例如:

+
+{nil => nil, 1 => 1, "nested" => {"a" => 3, 5 => 5}}.deep_symbolize_keys
+# => {nil=>nil, 1=>1, nested:{a:3, 5=>5}}
+
+
+
+

active_support/core_ext/hash/keys.rb 文件中定义。

11.4.5 to_optionsto_options! +

to_optionsto_options! 分别是 symbolize_keys and symbolize_keys! 的别名。

active_support/core_ext/hash/keys.rb 文件中定义。

11.4.6 assert_valid_keys +

assert_valid_keys 方法的参数数量不定,检查接收者的键是否在白名单之外。如果是,抛出 ArgumentError 异常。

+
+{a: 1}.assert_valid_keys(:a)  # passes
+{a: 1}.assert_valid_keys("a") # ArgumentError
+
+
+
+

例如,Active Record 构建关联时不接受未知的选项。这个功能就是通过 assert_valid_keys 实现的。

active_support/core_ext/hash/keys.rb 文件中定义。

11.5 处理值

11.5.1 transform_valuestransform_values! +

transform_values 的参数是一个块,使用块中的代码处理接收者中的各个值。

+
+{ nil => nil, 1 => 1, :x => :a }.transform_values { |value| value.to_s.upcase }
+# => {nil=>"", 1=>"1", :x=>"A"}
+
+
+
+

也有爆炸版本,transform_values!,就地处理接收者的值。

active_support/core_ext/hash/transform_values.rb 文件中定义。

11.6 切片

Ruby 原生支持从字符串和数组中提取切片。Active Support 为散列增加了这个功能:

+
+{a: 1, b: 2, c: 3}.slice(:a, :c)
+# => {:c=>3, :a=>1}
+
+{a: 1, b: 2, c: 3}.slice(:b, :X)
+# => {:b=>2} # 不存在的键会被忽略
+
+
+
+

如果接收者响应 convert_key,会使用它对键做整形:

+
+{a: 1, b: 2}.with_indifferent_access.slice("a")
+# => {:a=>1}
+
+
+
+

可以通过切片使用键白名单净化选项散列。

也有 slice!,它就地执行切片,返回被删除的键值对:

+
+hash = {a: 1, b: 2}
+rest = hash.slice!(:a) # => {:b=>2}
+hash                   # => {:a=>1}
+
+
+
+

active_support/core_ext/hash/slice.rb 文件中定义。

11.7 提取

extract! 方法删除并返回匹配指定键的键值对。

+
+hash = {a: 1, b: 2}
+rest = hash.extract!(:a) # => {:a=>1}
+hash                     # => {:b=>2}
+
+
+
+

extract! 方法的返回值类型与接收者一样,是 Hash 或其子类。

+
+hash = {a: 1, b: 2}.with_indifferent_access
+rest = hash.extract!(:a).class
+# => ActiveSupport::HashWithIndifferentAccess
+
+
+
+

active_support/core_ext/hash/slice.rb 文件中定义。

11.8 无差别访问

with_indifferent_access 方法把接收者转换成 ActiveSupport::HashWithIndifferentAccess 实例:

+
+{a: 1}.with_indifferent_access["a"] # => 1
+
+
+
+

active_support/core_ext/hash/indifferent_access.rb 文件中定义。

11.9 压缩

compactcompact! 方法返回没有 nil 值的散列:

+
+{a: 1, b: 2, c: nil}.compact # => {a: 1, b: 2}
+
+
+
+

active_support/core_ext/hash/compact.rb 文件中定义。

12 Regexp 的扩展

12.1 multiline? +

multiline? 方法判断正则表达式有没有设定 /m 旗标,即点号是否匹配换行符。

+
+%r{.}.multiline?  # => false
+%r{.}m.multiline? # => true
+
+Regexp.new('.').multiline?                    # => false
+Regexp.new('.', Regexp::MULTILINE).multiline? # => true
+
+
+
+

Rails 只在一处用到了这个方法,也在路由代码中。路由的条件不允许使用多行正则表达式,这个方法简化了这一约束的实施。

+
+def assign_route_options(segments, defaults, requirements)
+  ...
+  if requirement.multiline?
+    raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
+  end
+  ...
+end
+
+
+
+

active_support/core_ext/regexp.rb 文件中定义。

13 Range 的扩展

13.1 to_s +

Active Support 扩展了 Range#to_s 方法,让它接受一个可选的格式参数。目前,唯一支持的非默认格式是 :db

+
+(Date.today..Date.tomorrow).to_s
+# => "2009-10-25..2009-10-26"
+
+(Date.today..Date.tomorrow).to_s(:db)
+# => "BETWEEN '2009-10-25' AND '2009-10-26'"
+
+
+
+

如上例所示,:db 格式生成一个 BETWEEN SQL 子句。Active Record 使用它支持范围值条件。

active_support/core_ext/range/conversions.rb 文件中定义。

13.2 include? +

Range#include?Range#=== 方法判断值是否在值域的范围内:

+
+(2..3).include?(Math::E) # => true
+
+
+
+

Active Support 扩展了这两个方法,允许参数为另一个值域。此时,测试参数指定的值域是否在接收者的范围内:

+
+(1..10).include?(3..7)  # => true
+(1..10).include?(0..7)  # => false
+(1..10).include?(3..11) # => false
+(1...9).include?(3..9)  # => false
+
+(1..10) === (3..7)  # => true
+(1..10) === (0..7)  # => false
+(1..10) === (3..11) # => false
+(1...9) === (3..9)  # => false
+
+
+
+

active_support/core_ext/range/include_range.rb 文件中定义。

13.3 overlaps? +

Range#overlaps? 方法测试两个值域是否有交集:

+
+(1..10).overlaps?(7..11)  # => true
+(1..10).overlaps?(0..7)   # => true
+(1..10).overlaps?(11..27) # => false
+
+
+
+

active_support/core_ext/range/overlaps.rb 文件中定义。

14 Date 的扩展

14.1 计算

这一节的方法都在 active_support/core_ext/date/calculations.rb 文件中定义。

下述计算方法在 1582 年 10 月有边缘情况,因为 5..14 日不存在。简单起见,本文没有说明这些日子的行为,不过可以说,其行为与预期是相符的。即,Date.new(1582, 10, 4).tomorrow 返回 Date.new(1582, 10, 15),等等。预期的行为参见 test/core_ext/date_ext_test.rb 中的 Active Support 测试组件。

14.1.1 Date.current +

Active Support 定义的 Date.current 方法表示当前时区中的今天。其作用类似于 Date.today,不过会考虑用户设定的时区(如果定义了时区的话)。Active Support 还定义了 Date.yesterdayDate.tomorrow,以及实例判断方法 past?today?future?on_weekday?on_weekend?,这些方法都与 Date.current 相关。

比较日期时,如果要考虑用户设定的时区,应该使用 Date.current,而不是 Date.today。与系统的时区(Date.today 默认采用)相比,用户设定的时区可能超前,这意味着,Date.today 可能等于 Date.yesterday

14.1.2 具名日期
14.1.2.1 prev_yearnext_year +

在 Ruby 1.9 中,prev_yearnext_year 方法返回前一年和下一年中的相同月和日:

+
+d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
+d.prev_year              # => Fri, 08 May 2009
+d.next_year              # => Sun, 08 May 2011
+
+
+
+

如果是润年的 2 月 29 日,得到的是 28 日:

+
+d = Date.new(2000, 2, 29) # => Tue, 29 Feb 2000
+d.prev_year               # => Sun, 28 Feb 1999
+d.next_year               # => Wed, 28 Feb 2001
+
+
+
+

last_yearprev_year 的别名。

14.1.2.2 prev_monthnext_month +

在 Ruby 1.9 中,prev_monthnext_month 方法分别返回前一个月和后一个月中的相同日:

+
+d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
+d.prev_month             # => Thu, 08 Apr 2010
+d.next_month             # => Tue, 08 Jun 2010
+
+
+
+

如果日不存在,返回前一月中的最后一天:

+
+Date.new(2000, 5, 31).prev_month # => Sun, 30 Apr 2000
+Date.new(2000, 3, 31).prev_month # => Tue, 29 Feb 2000
+Date.new(2000, 5, 31).next_month # => Fri, 30 Jun 2000
+Date.new(2000, 1, 31).next_month # => Tue, 29 Feb 2000
+
+
+
+

last_monthprev_month 的别名。

14.1.2.3 prev_quarternext_quarter +

类似于 prev_monthnext_month,返回前一季度和下一季度中的相同日:

+
+t = Time.local(2010, 5, 8) # => Sat, 08 May 2010
+t.prev_quarter             # => Mon, 08 Feb 2010
+t.next_quarter             # => Sun, 08 Aug 2010
+
+
+
+

如果日不存在,返回前一月中的最后一天:

+
+Time.local(2000, 7, 31).prev_quarter  # => Sun, 30 Apr 2000
+Time.local(2000, 5, 31).prev_quarter  # => Tue, 29 Feb 2000
+Time.local(2000, 10, 31).prev_quarter # => Mon, 30 Oct 2000
+Time.local(2000, 11, 31).next_quarter # => Wed, 28 Feb 2001
+
+
+
+

last_quarterprev_quarter 的别名。

14.1.2.4 beginning_of_weekend_of_week +

beginning_of_weekend_of_week 方法分别返回某一周的第一天和最后一天的日期。一周假定从周一开始,不过这是可以修改的,方法是在线程中设定 Date.beginning_of_weekconfig.beginning_of_week

+
+d = Date.new(2010, 5, 8)     # => Sat, 08 May 2010
+d.beginning_of_week          # => Mon, 03 May 2010
+d.beginning_of_week(:sunday) # => Sun, 02 May 2010
+d.end_of_week                # => Sun, 09 May 2010
+d.end_of_week(:sunday)       # => Sat, 08 May 2010
+
+
+
+

at_beginning_of_weekbeginning_of_week 的别名,at_end_of_weekend_of_week 的别名。

14.1.2.5 mondaysunday +

mondaysunday 方法分别返回前一个周一和下一个周日的日期:

+
+d = Date.new(2010, 5, 8)     # => Sat, 08 May 2010
+d.monday                     # => Mon, 03 May 2010
+d.sunday                     # => Sun, 09 May 2010
+
+d = Date.new(2012, 9, 10)    # => Mon, 10 Sep 2012
+d.monday                     # => Mon, 10 Sep 2012
+
+d = Date.new(2012, 9, 16)    # => Sun, 16 Sep 2012
+d.sunday                     # => Sun, 16 Sep 2012
+
+
+
+
14.1.2.6 prev_weeknext_week +

next_week 的参数是一个符号,指定周几的英文名称(默认为线程中的 Date.beginning_of_weekconfig.beginning_of_week,或者 :monday),返回那一天的日期。

+
+d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
+d.next_week              # => Mon, 10 May 2010
+d.next_week(:saturday)   # => Sat, 15 May 2010
+
+
+
+

prev_week 的作用类似:

+
+d.prev_week              # => Mon, 26 Apr 2010
+d.prev_week(:saturday)   # => Sat, 01 May 2010
+d.prev_week(:friday)     # => Fri, 30 Apr 2010
+
+
+
+

last_weekprev_week 的别名。

设定 Date.beginning_of_weekconfig.beginning_of_week 之后,next_weekprev_week 能按预期工作。

14.1.2.7 beginning_of_monthend_of_month +

beginning_of_monthend_of_month 方法分别返回某个月的第一天和最后一天的日期:

+
+d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
+d.beginning_of_month     # => Sat, 01 May 2010
+d.end_of_month           # => Mon, 31 May 2010
+
+
+
+

at_beginning_of_monthbeginning_of_month 的别名,at_end_of_monthend_of_month 的别名。

14.1.2.8 beginning_of_quarterend_of_quarter +

beginning_of_quarterend_of_quarter 分别返回接收者日历年的季度第一天和最后一天的日期:

+
+d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
+d.beginning_of_quarter   # => Thu, 01 Apr 2010
+d.end_of_quarter         # => Wed, 30 Jun 2010
+
+
+
+

at_beginning_of_quarterbeginning_of_quarter 的别名,at_end_of_quarterend_of_quarter 的别名。

14.1.2.9 beginning_of_yearend_of_year +

beginning_of_yearend_of_year 方法分别返回一年的第一天和最后一天的日期:

+
+d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
+d.beginning_of_year      # => Fri, 01 Jan 2010
+d.end_of_year            # => Fri, 31 Dec 2010
+
+
+
+

at_beginning_of_yearbeginning_of_year 的别名,at_end_of_yearend_of_year 的别名。

14.1.3 其他日期计算方法
14.1.3.1 years_agoyears_since +

years_ago 方法的参数是一个数字,返回那么多年以前同一天的日期:

+
+date = Date.new(2010, 6, 7)
+date.years_ago(10) # => Wed, 07 Jun 2000
+
+
+
+

years_since 方法向前移动时间:

+
+date = Date.new(2010, 6, 7)
+date.years_since(10) # => Sun, 07 Jun 2020
+
+
+
+

如果那一天不存在,返回前一个月的最后一天:

+
+Date.new(2012, 2, 29).years_ago(3)     # => Sat, 28 Feb 2009
+Date.new(2012, 2, 29).years_since(3)   # => Sat, 28 Feb 2015
+
+
+
+
14.1.3.2 months_agomonths_since +

months_agomonths_since 方法的作用类似,不过是针对月的:

+
+Date.new(2010, 4, 30).months_ago(2)   # => Sun, 28 Feb 2010
+Date.new(2010, 4, 30).months_since(2) # => Wed, 30 Jun 2010
+
+
+
+

如果那一天不存在,返回前一个月的最后一天:

+
+Date.new(2010, 4, 30).months_ago(2)    # => Sun, 28 Feb 2010
+Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
+
+
+
+
14.1.3.3 weeks_ago +

weeks_ago 方法的作用类似,不过是针对周的:

+
+Date.new(2010, 5, 24).weeks_ago(1)    # => Mon, 17 May 2010
+Date.new(2010, 5, 24).weeks_ago(2)    # => Mon, 10 May 2010
+
+
+
+
14.1.3.4 advance +

跳到另一天最普适的方法是 advance。这个方法的参数是一个散列,包含 :years:months:weeks:days 键,返回移动相应量之后的日期。

+
+date = Date.new(2010, 6, 6)
+date.advance(years: 1, weeks: 2)  # => Mon, 20 Jun 2011
+date.advance(months: 2, days: -2) # => Wed, 04 Aug 2010
+
+
+
+

如上例所示,增量可以是负数。

这个方法做计算时,先增加年,然后是月和周,最后是日。这个顺序是重要的,向一个月的末尾流动。假如我们在 2010 年 2 月的最后一天,我们想向前移动一个月和一天。

此时,advance 先向前移动一个月,然后移动一天,结果是:

+
+Date.new(2010, 2, 28).advance(months: 1, days: 1)
+# => Sun, 29 Mar 2010
+
+
+
+

如果以其他方式移动,得到的结果就不同了:

+
+Date.new(2010, 2, 28).advance(days: 1).advance(months: 1)
+# => Thu, 01 Apr 2010
+
+
+
+
14.1.4 修改日期组成部分

change 方法在接收者的基础上修改日期,修改的值由参数指定:

+
+Date.new(2010, 12, 23).change(year: 2011, month: 11)
+# => Wed, 23 Nov 2011
+
+
+
+

这个方法无法容错不存在的日期,如果修改无效,抛出 ArgumentError 异常:

+
+Date.new(2010, 1, 31).change(month: 2)
+# => ArgumentError: invalid date
+
+
+
+
14.1.5 时间跨度

可以为日期增加或减去时间跨度:

+
+d = Date.current
+# => Mon, 09 Aug 2010
+d + 1.year
+# => Tue, 09 Aug 2011
+d - 3.hours
+# => Sun, 08 Aug 2010 21:00:00 UTC +00:00
+
+
+
+

增加跨度会调用 sinceadvance。例如,跳跃时能正确考虑历法改革:

+
+Date.new(1582, 10, 4) + 1.day
+# => Fri, 15 Oct 1582
+
+
+
+
14.1.6 时间戳

如果可能,下述方法返回 Time 对象,否则返回 DateTime 对象。如果用户设定了时区,会将其考虑在内。

14.1.6.1 beginning_of_dayend_of_day +

beginning_of_day 方法返回一天的起始时间戳(00:00:00):

+
+date = Date.new(2010, 6, 7)
+date.beginning_of_day # => Mon Jun 07 00:00:00 +0200 2010
+
+
+
+

end_of_day 方法返回一天的结束时间戳(23:59:59):

+
+date = Date.new(2010, 6, 7)
+date.end_of_day # => Mon Jun 07 23:59:59 +0200 2010
+
+
+
+

at_beginning_of_daymidnightat_midnightbeginning_of_day 的别名,

14.1.6.2 beginning_of_hourend_of_hour +

beginning_of_hour 返回一小时的起始时间戳(hh:00:00):

+
+date = DateTime.new(2010, 6, 7, 19, 55, 25)
+date.beginning_of_hour # => Mon Jun 07 19:00:00 +0200 2010
+
+
+
+

end_of_hour 方法返回一小时的结束时间戳(hh:59:59):

+
+date = DateTime.new(2010, 6, 7, 19, 55, 25)
+date.end_of_hour # => Mon Jun 07 19:59:59 +0200 2010
+
+
+
+

at_beginning_of_hourbeginning_of_hour 的别名。

14.1.6.3 beginning_of_minuteend_of_minute +

beginning_of_minute 方法返回一分钟的起始时间戳(hh:mm:00):

+
+date = DateTime.new(2010, 6, 7, 19, 55, 25)
+date.beginning_of_minute # => Mon Jun 07 19:55:00 +0200 2010
+
+
+
+

end_of_minute 方法返回一分钟的结束时间戳(hh:mm:59):

+
+date = DateTime.new(2010, 6, 7, 19, 55, 25)
+date.end_of_minute # => Mon Jun 07 19:55:59 +0200 2010
+
+
+
+

at_beginning_of_minutebeginning_of_minute 的别名。

TimeDateTime 实现了 beginning_of_hourend_of_hourbeginning_of_minuteend_of_minute 方法,但是 Date 没有实现,因为在 Date 实例上请求小时和分钟的起始和结束时间戳没有意义。

14.1.6.4 agosince +

ago 的参数是秒数,返回自午夜起那么多秒之后的时间戳:

+
+date = Date.current # => Fri, 11 Jun 2010
+date.ago(1)         # => Thu, 10 Jun 2010 23:59:59 EDT -04:00
+
+
+
+

类似的,since 向前移动:

+
+date = Date.current # => Fri, 11 Jun 2010
+date.since(1)       # => Fri, 11 Jun 2010 00:00:01 EDT -04:00
+
+
+
+

15 DateTime 的扩展

DateTime 不理解夏令时规则,因此如果正处于夏令时,这些方法可能有边缘情况。例如,在夏令时中,seconds_since_midnight 可能无法返回真实的量。

15.1 计算

本节的方法都在 active_support/core_ext/date_time/calculations.rb 文件中定义。

DateTime 类是 Date 的子类,因此加载 active_support/core_ext/date/calculations.rb 时也就继承了下述方法及其别名,只不过,此时都返回 DateTime 对象:

+
+yesterday
+tomorrow
+beginning_of_week (at_beginning_of_week)
+end_of_week (at_end_of_week)
+monday
+sunday
+weeks_ago
+prev_week (last_week)
+next_week
+months_ago
+months_since
+beginning_of_month (at_beginning_of_month)
+end_of_month (at_end_of_month)
+prev_month (last_month)
+next_month
+beginning_of_quarter (at_beginning_of_quarter)
+end_of_quarter (at_end_of_quarter)
+beginning_of_year (at_beginning_of_year)
+end_of_year (at_end_of_year)
+years_ago
+years_since
+prev_year (last_year)
+next_year
+on_weekday?
+on_weekend?
+
+
+
+

下述方法重新实现了,因此使用它们时无需加载 active_support/core_ext/date/calculations.rb

+
+beginning_of_day (midnight, at_midnight, at_beginning_of_day)
+end_of_day
+ago
+since (in)
+
+
+
+

此外,还定义了 advancechange 方法,而且支持更多选项。参见下文。

下述方法只在 active_support/core_ext/date_time/calculations.rb 中实现,因为它们只对 DateTime 实例有意义:

+
+beginning_of_hour (at_beginning_of_hour)
+end_of_hour
+
+
+
+
15.1.1 具名日期时间
15.1.1.1 DateTime.current +

Active Support 定义的 DateTime.current 方法类似于 Time.now.to_datetime,不过会考虑用户设定的时区(如果定义了时区的话)。Active Support 还定义了 DateTime.yesterdayDateTime.tomorrow,以及与 DateTime.current 相关的判断方法 past?future?

15.1.2 其他扩展
15.1.2.1 seconds_since_midnight +

seconds_since_midnight 方法返回自午夜起的秒数:

+
+now = DateTime.current     # => Mon, 07 Jun 2010 20:26:36 +0000
+now.seconds_since_midnight # => 73596
+
+
+
+
15.1.2.2 utc +

utc 返回的日期时间与接收者一样,不过使用 UTC 表示。

+
+now = DateTime.current # => Mon, 07 Jun 2010 19:27:52 -0400
+now.utc                # => Mon, 07 Jun 2010 23:27:52 +0000
+
+
+
+

这个方法有个别名,getutc

15.1.2.3 utc? +

utc? 判断接收者的时区是不是 UTC:

+
+now = DateTime.now # => Mon, 07 Jun 2010 19:30:47 -0400
+now.utc?           # => false
+now.utc.utc?       # => true
+
+
+
+
15.1.2.4 advance +

跳到其他日期时间最普适的方法是 advance。这个方法的参数是一个散列,包含 :years:months:weeks:days:hours:minutes:seconds 等键,返回移动相应量之后的日期时间。

+
+d = DateTime.current
+# => Thu, 05 Aug 2010 11:33:31 +0000
+d.advance(years: 1, months: 1, days: 1, hours: 1, minutes: 1, seconds: 1)
+# => Tue, 06 Sep 2011 12:34:32 +0000
+
+
+
+

这个方法计算目标日期时,把 :years:months:weeks:days 传给 Date#advance,然后调用 since 处理时间,前进相应的秒数。这个顺序是重要的,如若不然,在某些边缘情况下可能得到不同的日期时间。讲解 Date#advance 时所举的例子在这里也适用,我们可以扩展一下,显示处理时间的顺序。

如果先移动日期部分(如前文所述,处理日期的顺序也很重要),然后再计算时间,得到的结果如下:

+
+d = DateTime.new(2010, 2, 28, 23, 59, 59)
+# => Sun, 28 Feb 2010 23:59:59 +0000
+d.advance(months: 1, seconds: 1)
+# => Mon, 29 Mar 2010 00:00:00 +0000
+
+
+
+

但是如果以其他方式计算,结果就不同了:

+
+d.advance(seconds: 1).advance(months: 1)
+# => Thu, 01 Apr 2010 00:00:00 +0000
+
+
+
+

因为 DateTime 不支持夏令时,所以可能得到不存在的时间点,而且没有提醒或报错。

15.1.3 修改日期时间组成部分

change 方法在接收者的基础上修改日期时间,修改的值由选项指定,可以包括 :year:month:day:hour:min:sec:offset:start

+
+now = DateTime.current
+# => Tue, 08 Jun 2010 01:56:22 +0000
+now.change(year: 2011, offset: Rational(-6, 24))
+# => Wed, 08 Jun 2011 01:56:22 -0600
+
+
+
+

如果小时归零了,分钟和秒也归零(除非指定了值):

+
+now.change(hour: 0)
+# => Tue, 08 Jun 2010 00:00:00 +0000
+
+
+
+

类似地,如果分钟归零了,秒也归零(除非指定了值):

+
+now.change(min: 0)
+# => Tue, 08 Jun 2010 01:00:00 +0000
+
+
+
+

这个方法无法容错不存在的日期,如果修改无效,抛出 ArgumentError 异常:

+
+DateTime.current.change(month: 2, day: 30)
+# => ArgumentError: invalid date
+
+
+
+
15.1.4 时间跨度

可以为日期时间增加或减去时间跨度:

+
+now = DateTime.current
+# => Mon, 09 Aug 2010 23:15:17 +0000
+now + 1.year
+# => Tue, 09 Aug 2011 23:15:17 +0000
+now - 1.week
+# => Mon, 02 Aug 2010 23:15:17 +0000
+
+
+
+

增加跨度会调用 sinceadvance。例如,跳跃时能正确考虑历法改革:

+
+DateTime.new(1582, 10, 4, 23) + 1.hour
+# => Fri, 15 Oct 1582 00:00:00 +0000
+
+
+
+

16 Time 的扩展

16.1 计算

本节的方法都在 active_support/core_ext/time/calculations.rb 文件中定义。

Active Support 为 Time 添加了 DateTime 的很多方法:

+
+past?
+today?
+future?
+yesterday
+tomorrow
+seconds_since_midnight
+change
+advance
+ago
+since (in)
+beginning_of_day (midnight, at_midnight, at_beginning_of_day)
+end_of_day
+beginning_of_hour (at_beginning_of_hour)
+end_of_hour
+beginning_of_week (at_beginning_of_week)
+end_of_week (at_end_of_week)
+monday
+sunday
+weeks_ago
+prev_week (last_week)
+next_week
+months_ago
+months_since
+beginning_of_month (at_beginning_of_month)
+end_of_month (at_end_of_month)
+prev_month (last_month)
+next_month
+beginning_of_quarter (at_beginning_of_quarter)
+end_of_quarter (at_end_of_quarter)
+beginning_of_year (at_beginning_of_year)
+end_of_year (at_end_of_year)
+years_ago
+years_since
+prev_year (last_year)
+next_year
+on_weekday?
+on_weekend?
+
+
+
+

它们的作用与之前类似。详情参见前文,不过要知道下述区别:

+
    +
  • change 额外接受 :usec 选项。

  • +
  • +

    Time 支持夏令时,因此能正确计算夏令时。

    +
    +
    +Time.zone_default
    +# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
    +
    +# 因为采用夏令时,在巴塞罗那,2010/03/28 02:00 +0100 变成 2010/03/28 03:00 +0200
    +t = Time.local(2010, 3, 28, 1, 59, 59)
    +# => Sun Mar 28 01:59:59 +0100 2010
    +t.advance(seconds: 1)
    +# => Sun Mar 28 03:00:00 +0200 2010
    +
    +
    +
    +
  • +
  • 如果 sinceago 的目标时间无法使用 Time 对象表示,返回一个 DateTime 对象。

  • +
+
16.1.1 Time.current +

Active Support 定义的 Time.current 方法表示当前时区中的今天。其作用类似于 Time.now,不过会考虑用户设定的时区(如果定义了时区的话)。Active Support 还定义了与 Time.current 有关的实例判断方法 past?today?future?

比较时间时,如果要考虑用户设定的时区,应该使用 Time.current,而不是 Time.now。与系统的时区(Time.now 默认采用)相比,用户设定的时区可能超前,这意味着,Time.now.to_date 可能等于 Date.yesterday

16.1.2 all_dayall_weekall_monthall_quarterall_year +

all_day 方法返回一个值域,表示当前时间的一整天。

+
+now = Time.current
+# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
+now.all_day
+# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00
+
+
+
+

类似地,all_weekall_monthall_quarterall_year 分别生成相应的时间值域。

+
+now = Time.current
+# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
+now.all_week
+# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00
+now.all_week(:sunday)
+# => Sun, 16 Sep 2012 00:00:00 UTC +00:00..Sat, 22 Sep 2012 23:59:59 UTC +00:00
+now.all_month
+# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00
+now.all_quarter
+# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00
+now.all_year
+# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00
+
+
+
+

16.2 时间构造方法

Active Support 定义的 Time.current 方法,在用户设定了时区时,等价于 Time.zone.now,否则回落到 Time.now

+
+Time.zone_default
+# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
+Time.current
+# => Fri, 06 Aug 2010 17:11:58 CEST +02:00
+
+
+
+

DateTime 一样,判断方法 past?future?Time.current 相关。

如果要构造的时间超出了运行时平台对 Time 的支持范围,微秒会被丢掉,然后返回 DateTime 对象。

16.2.1 时间跨度

可以为时间增加或减去时间跨度:

+
+now = Time.current
+# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
+now + 1.year
+#  => Tue, 09 Aug 2011 23:21:11 UTC +00:00
+now - 1.week
+# => Mon, 02 Aug 2010 23:21:11 UTC +00:00
+
+
+
+

增加跨度会调用 sinceadvance。例如,跳跃时能正确考虑历法改革:

+
+Time.utc(1582, 10, 3) + 5.days
+# => Mon Oct 18 00:00:00 UTC 1582
+
+
+
+

17 File 的扩展

17.1 atomic_write +

使用类方法 File.atomic_write 写文件时,可以避免在写到一半时读取内容。

这个方法的参数是文件名,它会产出一个文件句柄,把文件打开供写入。块执行完毕后,atomic_write 会关闭文件句柄,完成工作。

例如,Action Pack 使用这个方法写静态资源缓存文件,如 all.css

+
+File.atomic_write(joined_asset_path) do |cache|
+  cache.write(join_asset_file_contents(asset_paths))
+end
+
+
+
+

为此,atomic_write 会创建一个临时文件。块中的代码其实是向这个临时文件写入。写完之后,重命名临时文件,这在 POSIX 系统中是原子操作。如果目标文件存在,atomic_write 将其覆盖,并且保留属主和权限。不过,有时 atomic_write 无法修改文件的归属或权限。这个错误会被捕获并跳过,从而确保需要它的进程能访问它。

atomic_write 会执行 chmod 操作,因此如果目标文件设定了 ACL,atomic_write 会重新计算或修改 ACL。

注意,不能使用 atomic_write 追加内容。

临时文件在存储临时文件的标准目录中,但是可以传入第二个参数指定一个目录。

active_support/core_ext/file/atomic.rb 文件中定义。

18 Marshal 的扩展

18.1 load +

Active Support 为 load 增加了常量自动加载功能。

例如,文件缓存存储像这样反序列化:

+
+File.open(file_name) { |f| Marshal.load(f) }
+
+
+
+

如果缓存的数据指代那一刻未知的常量,自动加载机制会被触发,如果成功加载,会再次尝试反序列化。

如果参数是 IO 对象,要能响应 rewind 方法才会重试。常规的文件响应 rewind 方法。

active_support/core_ext/marshal.rb 文件中定义。

19 NameError 的扩展

Active Support 为 NameError 增加了 missing_name? 方法,测试异常是不是由于参数的名称引起的。

参数的名称可以使用符号或字符串指定。指定符号时,使用裸常量名测试;指定字符串时,使用完全限定常量名测试。

符号可以表示完全限定常量名,例如 :"ActiveRecord::Base",因此这里符号的行为是为了便利而特别定义的,不是说在技术上只能如此。

例如,调用 ArticlesController 的动作时,Rails 会乐观地使用 ArticlesHelper。如果那个模块不存在也没关系,因此,由那个常量名引起的异常要静默。不过,可能是由于确实是未知的常量名而由 articles_helper.rb 抛出的 NameError 异常。此时,异常应该抛出。missing_name? 方法能区分这两种情况:

+
+def default_helper_module!
+  module_name = name.sub(/Controller$/, '')
+  module_path = module_name.underscore
+  helper module_path
+rescue LoadError => e
+  raise e unless e.is_missing? "helpers/#{module_path}_helper"
+rescue NameError => e
+  raise e unless e.missing_name? "#{module_name}Helper"
+end
+
+
+
+

active_support/core_ext/name_error.rb 文件中定义。

20 LoadError 的扩展

Active Support 为 LoadError 增加了 is_missing? 方法。

is_missing? 方法判断异常是不是由指定路径名(不含“.rb”扩展名)引起的。

例如,调用 ArticlesController 的动作时,Rails 会尝试加载 articles_helper.rb,但是那个文件可能不存在。这没关系,辅助模块不是必须的,因此 Rails 会静默加载错误。但是,有可能是辅助模块存在,而它引用的其他库不存在。此时,Rails 必须抛出异常。is_missing? 方法能区分这两种情况:

+
+def default_helper_module!
+  module_name = name.sub(/Controller$/, '')
+  module_path = module_name.underscore
+  helper module_path
+rescue LoadError => e
+  raise e unless e.is_missing? "helpers/#{module_path}_helper"
+rescue NameError => e
+  raise e unless e.missing_name? "#{module_name}Helper"
+end
+
+
+
+

active_support/core_ext/load_error.rb 文件中定义。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/active_support_instrumentation.html b/active_support_instrumentation.html new file mode 100644 index 0000000..a046e58 --- /dev/null +++ b/active_support_instrumentation.html @@ -0,0 +1,1237 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Support 监测程序

Active Support 是 Rails 核心的一部分,提供 Ruby 语言扩展、实用方法等。其中包括一份监测 API,在应用中可以用它测度 Ruby 代码(如 Rails 应用或框架自身)中的特定操作。不过,这个 API 不限于只能在 Rails 中使用,如果愿意,也可以在其他 Ruby 脚本中使用。

本文教你如何使用 Active Support 中的监测 API 测度 Rails 和其他 Ruby 代码中的事件。

读完本文后,您将学到:

+
    +
  • 使用监测程序能做什么;

  • +
  • Rails 框架为监测提供的钩子;

  • +
  • 订阅钩子;

  • +
  • 自定义监测点。

  • +
+

本文原文尚未完工!

1 监测程序简介

Active Support 提供的监测 API 允许开发者提供钩子,供其他开发者订阅。在 Rails 框架中,有很多。通过这个 API,开发者可以选择在应用或其他 Ruby 代码中发生特定事件时接收通知。

例如,Active Record 中有一个钩子,在每次使用 SQL 查询数据库时调用。开发者可以订阅这个钩子,记录特定操作执行的查询次数。还有一个钩子在控制器的动作执行前后调用,记录动作的执行时间。

在应用中甚至还可以自己创建事件,然后订阅。

2 Rails 框架中的钩子

Ruby on Rails 框架为很多常见的事件提供了钩子。下面详述。

3 Action Controller

3.1 write_fragment.action_controller

+ + + + + + + + + + + + + +
:key完整的键
+
+
+{
+  key: 'posts/1-dashboard-view'
+}
+
+
+
+

3.2 read_fragment.action_controller

+ + + + + + + + + + + + + +
:key完整的键
+
+
+{
+  key: 'posts/1-dashboard-view'
+}
+
+
+
+

3.3 expire_fragment.action_controller

+ + + + + + + + + + + + + +
:key完整的键
+
+
+{
+  key: 'posts/1-dashboard-view'
+}
+
+
+
+

3.4 exist_fragment?.action_controller

+ + + + + + + + + + + + + +
:key完整的键
+
+
+{
+  key: 'posts/1-dashboard-view'
+}
+
+
+
+

3.5 write_page.action_controller

+ + + + + + + + + + + + + +
:path完整的路径
+
+
+{
+  path: '/users/1'
+}
+
+
+
+

3.6 expire_page.action_controller

+ + + + + + + + + + + + + +
:path完整的路径
+
+
+{
+  path: '/users/1'
+}
+
+
+
+

3.7 start_processing.action_controller

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:controller控制器名
:action动作名
:params请求参数散列,不过滤
:headers请求首部
:formathtml、js、json、xml 等
:methodHTTP 请求方法
:path请求路径
+
+
+{
+  controller: "PostsController",
+  action: "new",
+  params: { "action" => "new", "controller" => "posts" },
+  headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
+  format: :html,
+  method: "GET",
+  path: "/posts/new"
+}
+
+
+
+

3.8 process_action.action_controller

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:controller控制器名
:action动作名
:params请求参数散列,不过滤
:headers请求首部
:formathtml、js、json、xml 等
:methodHTTP 请求方法
:path请求路径
:statusHTTP 状态码
:view_runtime花在视图上的时间量(ms)
:db_runtime执行数据库查询的时间量(ms)
+
+
+{
+  controller: "PostsController",
+  action: "index",
+  params: {"action" => "index", "controller" => "posts"},
+  headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
+  format: :html,
+  method: "GET",
+  path: "/posts",
+  status: 200,
+  view_runtime: 46.848,
+  db_runtime: 0.157
+}
+
+
+
+

3.9 send_file.action_controller

+ + + + + + + + + + + + + +
:path文件的完整路径
+

调用方可以添加额外的键。

3.10 send_data.action_controller

ActionController 在载荷(payload)中没有任何特定的信息。所有选项都传到载荷中。

3.11 redirect_to.action_controller

+ + + + + + + + + + + + + + + + + +
:statusHTTP 响应码
:location重定向的 URL
+
+
+{
+  status: 302,
+  location: "http://localhost:3000/posts/new"
+}
+
+
+
+

3.12 halted_callback.action_controller

+ + + + + + + + + + + + + +
:filter过滤暂停的动作
+
+
+{
+  filter: ":halting_filter"
+}
+
+
+
+

4 Action View

4.1 render_template.action_view

+ + + + + + + + + + + + + + + + + +
:identifier模板的完整路径
:layout使用的布局
+
+
+{
+  identifier: "/Users/adam/projects/notifications/app/views/posts/index.html.erb",
+  layout: "layouts/application"
+}
+
+
+
+

4.2 render-partial-action-view

+ + + + + + + + + + + + + +
:identifier模板的完整路径
+
+
+{
+  identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"
+}
+
+
+
+

4.3 render_collection.action_view

+ + + + + + + + + + + + + + + + + + + + + +
:identifier模板的完整路径
:count集合的大小
:cache_hits从缓存中获取的局部视图数量
+

仅当渲染集合时设定了 cached: true 选项,才有 :cache_hits 键。

+
+{
+  identifier: "/Users/adam/projects/notifications/app/views/posts/_post.html.erb",
+  count: 3,
+  cache_hits: 0
+}
+
+
+
+

5 Active Record

5.1 sql.active_record

+ + + + + + + + + + + + + + + + + + + + + + + + + +
:sqlSQL 语句
:name操作的名称
:connection_idself.object_id
:binds绑定的参数
+

适配器也会添加数据。

+
+{
+  sql: "SELECT \"posts\".* FROM \"posts\" ",
+  name: "Post Load",
+  connection_id: 70307250813140,
+  binds: []
+}
+
+
+
+

5.2 instantiation.active_record

+ + + + + + + + + + + + + + + + + +
:record_count实例化记录的数量
:class_name记录所属的类
+
+
+{
+  record_count: 1,
+  class_name: "User"
+}
+
+
+
+

6 Action Mailer

6.1 receive.action_mailer

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:mailer邮件程序类的名称
:message_id邮件的 ID,由 Mail gem 生成
:subject邮件的主题
:to邮件的收件地址
:from邮件的发件地址
:bcc邮件的密送地址
:cc邮件的抄送地址
:date发送邮件的日期
:mail邮件的编码形式
+
+
+{
+  mailer: "Notification",
+  message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",
+  subject: "Rails Guides",
+  to: ["users@rails.com", "ddh@rails.com"],
+  from: ["me@rails.com"],
+  date: Sat, 10 Mar 2012 14:18:09 +0100,
+  mail: "..." # 为了节省空间,省略
+}
+
+
+
+

6.2 deliver.action_mailer

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:mailer邮件程序类的名称
:message_id邮件的 ID,由 Mail gem 生成
:subject邮件的主题
:to邮件的收件地址
:from邮件的发件地址
:bcc邮件的密送地址
:cc邮件的抄送地址
:date发送邮件的日期
:mail邮件的编码形式
+
+
+{
+  mailer: "Notification",
+  message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",
+  subject: "Rails Guides",
+  to: ["users@rails.com", "ddh@rails.com"],
+  from: ["me@rails.com"],
+  date: Sat, 10 Mar 2012 14:18:09 +0100,
+  mail: "..." # 为了节省空间,省略
+}
+
+
+
+

7 Active Support

7.1 cache_read.active_support

+ + + + + + + + + + + + + + + + + + + + + +
:key存储器中使用的键
:hit是否读取了缓存
:super_operation如果使用 #fetch 读取了,添加 :fetch
+

7.2 cache_generate.active_support

仅当使用块调用 #fetch 时使用这个事件。

+ + + + + + + + + + + + + +
:key存储器中使用的键
+

写入存储器时,传给 fetch 的选项会合并到载荷中。

+
+{
+  key: 'name-of-complicated-computation'
+}
+
+
+
+

7.3 cache_fetch_hit.active_support

仅当使用块调用 #fetch 时使用这个事件。

+ + + + + + + + + + + + + +
:key存储器中使用的键
+

传给 fetch 的选项会合并到载荷中。

+
+{
+  key: 'name-of-complicated-computation'
+}
+
+
+
+

7.4 cache_write.active_support

+ + + + + + + + + + + + + +
:key存储器中使用的键
+

缓存存储器可能会添加其他键。

+
+{
+  key: 'name-of-complicated-computation'
+}
+
+
+
+

7.5 cache_delete.active_support

+ + + + + + + + + + + + + +
:key存储器中使用的键
+
+
+{
+  key: 'name-of-complicated-computation'
+}
+
+
+
+

7.6 cache_exist?.active_support

+ + + + + + + + + + + + + +
:key存储器中使用的键
+
+
+{
+  key: 'name-of-complicated-computation'
+}
+
+
+
+

8 Active Job

8.1 enqueue_at.active_job

+ + + + + + + + + + + + + + + + + +
:adapter处理作业的 QueueAdapter 对象
:job作业对象
+

8.2 enqueue.active_job

+ + + + + + + + + + + + + + + + + +
:adapter处理作业的 QueueAdapter 对象
:job作业对象
+

8.3 perform_start.active_job

+ + + + + + + + + + + + + + + + + +
:adapter处理作业的 QueueAdapter 对象
:job作业对象
+

8.4 perform.active_job

+ + + + + + + + + + + + + + + + + +
:adapter处理作业的 QueueAdapter 对象
:job作业对象
+

9 Railties

9.1 load_config_initializer.railties

+ + + + + + + + + + + + + +
:initializer从 config/initializers 中加载的初始化脚本的路径
+

10 Rails

10.1 deprecation.rails

+ + + + + + + + + + + + + + + + + +
:message弃用提醒
:callstack弃用的位置
+

11 订阅事件

订阅事件是件简单的事,在 ActiveSupport::Notifications.subscribe 的块中监听通知即可。

这个块接收下述参数:

+
    +
  • 事件的名称

  • +
  • 开始时间

  • +
  • 结束时间

  • +
  • 事件的唯一 ID

  • +
  • 载荷(参见前述各节)

  • +
+
+
+ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, data|
+  # 自己编写的其他代码
+  Rails.logger.info "#{name} Received!"
+end
+
+
+
+

每次都定义这些块参数很麻烦,我们可以使用 ActiveSupport::Notifications::Event 创建块参数,如下:

+
+ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
+  event = ActiveSupport::Notifications::Event.new *args
+
+  event.name      # => "process_action.action_controller"
+  event.duration  # => 10 (in milliseconds)
+  event.payload   # => {:extra=>information}
+
+  Rails.logger.info "#{event} Received!"
+end
+
+
+
+

多数时候,我们只关注数据本身。下面是只获取数据的简洁方式:

+
+ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
+  data = args.extract_options!
+  data # { extra: :information }
+end
+
+
+
+

此外,还可以订阅匹配正则表达式的事件。这样可以一次订阅多个事件。下面是订阅 ActionController 中所有事件的方式:

+
+ActiveSupport::Notifications.subscribe /action_controller/ do |*args|
+  # 审查所有 ActionController 事件
+end
+
+
+
+

12 自定义事件

自己添加事件也很简单,繁重的工作都由 ActiveSupport::Notifications 代劳,我们只需调用 instrument,并传入 namepayload 和一个块。通知在块返回后发送。ActiveSupport 会生成起始时间和唯一的 ID。传给 instrument 调用的所有数据都会放入载荷中。

下面举个例子:

+
+ActiveSupport::Notifications.instrument "my.custom.event", this: :data do
+  # 自己编写的其他代码
+end
+
+
+
+

然后可以使用下述代码监听这个事件:

+
+ActiveSupport::Notifications.subscribe "my.custom.event" do |name, started, finished, unique_id, data|
+  puts data.inspect # {:this=>:data}
+end
+
+
+
+

自己定义事件时,应该遵守 Rails 的约定。事件名称的格式是 event.library。如果应用发送推文,应该把事件命名为 tweet.twitter

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/api_app.html b/api_app.html new file mode 100644 index 0000000..df92ed0 --- /dev/null +++ b/api_app.html @@ -0,0 +1,476 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

使用 Rails 开发只提供 API 的应用

在本文中您将学到:

+
    +
  • Rails 对只提供 API 的应用的支持;

  • +
  • 如何配置 Rails,不使用任何针对浏览器的功能;

  • +
  • 如何决定使用哪些中间件;

  • +
  • 如何决定在控制器中使用哪些模块。

  • +
+

1 什么是 API 应用?

人们说把 Rails 用作“API”,通常指的是在 Web 应用之外提供一份可通过编程方式访问的 API。例如,GitHub 提供了 API,供你在自己的客户端中使用。

随着客户端框架的出现,越来越多的开发者使用 Rails 构建后端,在 Web 应用和其他原生应用之间共享。

例如,Twitter 使用自己的公开 API 构建 Web 应用,而文档网站是一个静态网站,消费 JSON 资源。

很多人不再使用 Rails 生成 HTML,通过表单和链接与服务器通信,而是把 Web 应用当做 API 客户端,分发包含 JavaScript 的 HTML,消费 JSON API。

本文说明如何构建伺服 JSON 资源的 Rails 应用,供 API 客户端(包括客户端框架)使用。

2 为什么使用 Rails 构建 JSON API?

提到使用 Rails 构建 JSON API,多数人想到的第一个问题是:“使用 Rails 生成 JSON 是不是有点大材小用了?使用 Sinatra 这样的框架是不是更好?”

对特别简单的 API 来说,确实如此。然而,对大量使用 HTML 的应用来说,应用的逻辑大都在视图层之外。

多数人使用 Rails 的原因是,Rails 提供了一系列默认值,开发者能快速上手,而不用做些琐碎的决定。

下面是 Rails 提供的一些开箱即用的功能,这些功能在 API 应用中也适用。

在中间件层处理的功能:

+
    +
  • 重新加载:Rails 应用支持简单明了的重新加载机制。即使应用变大,每次请求都重启服务器变得不切实际,这一机制依然适用。

  • +
  • 开发模式:Rails 应用自带智能的开发默认值,使得开发过程很愉快,而且不会破坏生产环境的效率。

  • +
  • 测试模式:同开发模式。

  • +
  • 日志:Rails 应用会在日志中记录每次请求,而且为不同环境设定了合适的详细等级。在开发环境中,Rails 记录的信息包括请求环境、数据库查询和基本的性能信息。

  • +
  • 安全性:Rails 能检测并防范 IP 欺骗攻击,还能处理时序攻击中的加密签名。不知道 IP 欺骗攻击和时序攻击是什么?这就对了。

  • +
  • 参数解析:想以 JSON 的形式指定参数,而不是 URL 编码字符串形式?没问题。Rails 会代为解码 JSON,存入 params 中。想使用嵌套的 URL 编码参数?也没问题。

  • +
  • 条件 GET 请求:Rails 能处理条件 GET 请求相关的首部(ETagLast-Modified),然后返回正确的响应首部和状态码。你只需在控制器中使用 stale? 做检查,剩下的 HTTP 细节都由 Rails 处理。

  • +
  • HEAD 请求:Rails 会把 HEAD 请求转换成 GET 请求,只返回首部。这样 HEAD 请求在所有 Rails API 中都可靠。

  • +
+

虽然这些功能可以使用 Rack 中间件实现,但是上述列表的目的是说明 Rails 默认提供的中间件栈提供了大量有价值的功能,即便“只是生成 JSON”也用得到。

在 Action Pack 层处理的功能:

+
    +
  • 资源式路由:如果构建的是 REST 式 JSON API,你会想用 Rails 路由器的。按照约定以简明的方式把 HTTP 映射到控制器上能节省很多时间,不用再从 HTTP 方面思考如何建模 API。

  • +
  • URL 生成:路由的另一面是 URL 生成。基于 HTTP 的优秀 API 包含 URL(比如 GitHub Gist API)。

  • +
  • 首部和重定向响应:head :no_contentredirect_to user_url(http://github.com/current_user) 用着很方便。当然,你可以自己动手添加相应的响应首部,但是为什么要费这事呢?

  • +
  • 缓存:Rails 提供了页面缓存、动作缓存和片段缓存。构建嵌套的 JSON 对象时,片段缓存特别有用。

  • +
  • 基本身份验证、摘要身份验证和令牌身份验证:Rails 默认支持三种 HTTP 身份验证。

  • +
  • 监测程序:Rails 提供了监测 API,在众多事件发生时触发注册的处理程序,例如处理动作、发送文件或数据、重定向和数据库查询。各个事件的载荷中包含相关的信息(对动作处理事件来说,载荷中包括控制器、动作、参数、请求格式、请求方法和完整的请求路径)。

  • +
  • 生成器:通常生成一个资源就能把模型、控制器、测试桩件和路由在一个命令中通通创建出来,然后再做调整。迁移等也有生成器。

  • +
  • 插件:有很多第三方库支持 Rails,这样不必或很少需要花时间设置及把库与 Web 框架连接起来。插件可以重写默认的生成器、添加 Rake 任务,而且继续使用 Rails 选择的处理方式(如日志记录器和缓存后端)。

  • +
+

当然,Rails 启动过程还是要把各个注册的组件连接起来。例如,Rails 启动时会使用 config/database.yml 文件配置 Active Record。

简单来说,你可能没有想过去掉视图层之后要把 Rails 的哪些部分保留下来,不过答案是,多数都要保留。

3 基本配置

如果你构建的 Rails 应用主要用作 API,可以从较小的 Rails 子集开始,然后再根据需要添加功能。

3.1 新建应用

生成 Rails API 应用使用下述命令:

+
+$ rails new my_api --api
+
+
+
+

这个命令主要做三件事:

+
    +
  • 配置应用,使用有限的中间件(比常规应用少)。具体而言,不含默认主要针对浏览器应用的中间件(如提供 cookie 支持的中间件)。

  • +
  • ApplicationController 继承 ActionController::API,而不继承 ActionController::Base。与中间件一样,这样做是为了去除主要针对浏览器应用的 Action Controller 模块。

  • +
  • 配置生成器,生成资源时不生成视图、辅助方法和静态资源。

  • +
+

3.2 修改现有应用

如果你想把现有的应用改成 API 应用,请阅读下述步骤。

config/application.rb 文件中,把下面这行代码添加到 Application 类定义的顶部:

+
+config.api_only = true
+
+
+
+

config/environments/development.rb 文件中,设定 config.debug_exception_response_format 选项,配置在开发环境中出现错误时响应使用的格式。

如果想使用 HTML 页面渲染调试信息,把值设为 :default

+
+config.debug_exception_response_format = :default
+
+
+
+

如果想使用响应所用的格式渲染调试信息,把值设为 :api

+
+config.debug_exception_response_format = :api
+
+
+
+

默认情况下,config.api_only 的值为 true 时,config.debug_exception_response_format 的值是 :api

最后,在 app/controllers/application_controller.rb 文件中,把下述代码

+
+class ApplicationController < ActionController::Base
+end
+
+
+
+

改为

+
+class ApplicationController < ActionController::API
+end
+
+
+
+

4 选择中间件

API 应用默认包含下述中间件:

+
    +
  • Rack::Sendfile

  • +
  • ActionDispatch::Static

  • +
  • ActionDispatch::Executor

  • +
  • ActiveSupport::Cache::Strategy::LocalCache::Middleware

  • +
  • Rack::Runtime

  • +
  • ActionDispatch::RequestId

  • +
  • Rails::Rack::Logger

  • +
  • ActionDispatch::ShowExceptions

  • +
  • ActionDispatch::DebugExceptions

  • +
  • ActionDispatch::RemoteIp

  • +
  • ActionDispatch::Reloader

  • +
  • ActionDispatch::Callbacks

  • +
  • Rack::Head

  • +
  • Rack::ConditionalGet

  • +
  • Rack::ETag

  • +
+

各个中间件的作用参见 内部中间件栈

其他插件,包括 Active Record,可能会添加额外的中间件。一般来说,这些中间件对要构建的应用类型一无所知,可以在只提供 API 的 Rails 应用中使用。

可以通过下述命令列出应用中的所有中间件:

+
+$ rails middleware
+
+
+
+

4.1 使用缓存中间件

默认情况下,Rails 会根据应用的配置提供一个缓存存储器(默认为 memcache)。因此,内置的 HTTP 缓存依靠这个中间件。

例如,使用 stale? 方法:

+
+def show
+  @post = Post.find(params[:id])
+
+  if stale?(last_modified: @post.updated_at)
+    render json: @post
+  end
+end
+
+
+
+

上述 stale? 调用比较请求中的 If-Modified-Since 首部和 @post.updated_at。如果首部的值比最后修改时间晚,这个动作返回“304 未修改”响应;否则,渲染响应,并且设定 Last-Modified 首部。

通常,这个机制会区分客户端。缓存中间件支持跨客户端共享这种缓存机制。跨客户端缓存可以在调用 stale? 时启用:

+
+def show
+  @post = Post.find(params[:id])
+
+  if stale?(last_modified: @post.updated_at, public: true)
+    render json: @post
+  end
+end
+
+
+
+

这表明,缓存中间件会在 Rails 缓存中存储 URL 的 Last-Modified 值,而且为后续对同一个 URL 的入站请求添加 If-Modified-Since 首部。

可以把这种机制理解为使用 HTTP 语义的页面缓存。

4.2 使用 Rack::Sendfile

在 Rails 控制器中使用 send_file 方法时,它会设定 X-Sendfile 首部。Rack::Sendfile 负责发送文件。

如果前端服务器支持加速发送文件,Rack::Sendfile 会把文件交给前端服务器发送。

此时,可以在环境的配置文件中设定 config.action_dispatch.x_sendfile_header 选项,为前端服务器指定首部的名称。

关于如何在流行的前端服务器中使用 Rack::Sendfile,参见 Rack::Sendfile 的文档

下面是两个流行的服务器的配置。这样配置之后,就能支持加速文件发送功能了。

+
+# Apache 和 lighttpd
+config.action_dispatch.x_sendfile_header = "X-Sendfile"
+
+# Nginx
+config.action_dispatch.x_sendfile_header = "X-Accel-Redirect"
+
+
+
+

请按照 Rack::Sendfile 文档中的说明配置你的服务器。

4.3 使用 ActionDispatch::Request

ActionDispatch::Request#params 获取客户端发来的 JSON 格式参数,将其存入 params,可在控制器中访问。

为此,客户端要发送 JSON 编码的参数,并把 Content-Type 设为 application/json

下面以 jQuery 为例:

+
+jQuery.ajax({
+  type: 'POST',
+  url: '/people',
+  dataType: 'json',
+  contentType: 'application/json',
+  data: JSON.stringify({ person: { firstName: "Yehuda", lastName: "Katz" } }),
+  success: function(json) { }
+});
+
+
+
+

ActionDispatch::Request 检查 Content-Type 后,把参数转换成:

+
+{ :person => { :firstName => "Yehuda", :lastName => "Katz" } }
+
+
+
+

4.4 其他中间件

Rails 自带的其他中间件在 API 应用中可能也会用到,尤其是 API 客户端包含浏览器时:

+
    +
  • Rack::MethodOverride

  • +
  • ActionDispatch::Cookies

  • +
  • ActionDispatch::Flash

  • +
  • +

    管理会话

    +
      +
    • ActionDispatch::Session::CacheStore +
    • +
    • ActionDispatch::Session::CookieStore +
    • +
    • ActionDispatch::Session::MemCacheStore +
    • +
    +
  • +
+

这些中间件可通过下述方式添加:

+
+config.middleware.use Rack::MethodOverride
+
+
+
+

4.5 删除中间件

如果默认的 API 中间件中有不需要使用的,可以通过下述方式将其删除:

+
+config.middleware.delete ::Rack::Sendfile
+
+
+
+

注意,删除中间件后 Action Controller 的特定功能就不可用了。

5 选择控制器模块

API 应用(使用 ActionController::API)默认有下述控制器模块:

+
    +
  • ActionController::UrlFor:提供 url_for 等辅助方法。

  • +
  • ActionController::Redirecting:提供 redirect_to

  • +
  • AbstractController::RenderingActionController::ApiRendering:提供基本的渲染支持。

  • +
  • ActionController::Renderers::All:提供 render :json 等。

  • +
  • ActionController::ConditionalGet:提供 stale?

  • +
  • ActionController::BasicImplicitRender:如果没有显式响应,确保返回一个空响应。

  • +
  • ActionController::StrongParameters:结合 Active Model 批量赋值,提供参数白名单过滤功能。

  • +
  • ActionController::ForceSSL:提供 force_ssl

  • +
  • ActionController::DataStreaming:提供 send_filesend_data

  • +
  • AbstractController::Callbacks:提供 before_action 等方法。

  • +
  • ActionController::Rescue:提供 rescue_from

  • +
  • ActionController::Instrumentation:提供 Action Controller 定义的监测钩子(详情参见 Active Support 监测程序)。

  • +
  • ActionController::ParamsWrapper:把参数散列放到一个嵌套散列中,这样在发送 POST 请求时无需指定根元素。

  • +
+

其他插件可能会添加额外的模块。ActionController::API 引入的模块可以在 Rails 控制台中列出:

+
+$ bin/rails c
+>> ActionController::API.ancestors - ActionController::Metal.ancestors
+
+
+
+

5.1 添加其他模块

所有 Action Controller 模块都知道它们所依赖的模块,因此在控制器中可以放心引入任何模块,所有依赖都会自动引入。

可能想添加的常见模块有:

+
    +
  • AbstractController::Translation:提供本地化和翻译方法 lt

  • +
  • ActionController::HttpAuthentication::Basic(或 DigestToken):提供基本、摘要或令牌 HTTP 身份验证。

  • +
  • ActionView::Layouts:渲染时支持使用布局。

  • +
  • ActionController::MimeResponds:提供 respond_to

  • +
  • ActionController::Cookies:提供 cookies,包括签名和加密 cookie。需要 cookies 中间件支持。

  • +
+

模块最好添加到 ApplicationController 中,不过也可以在各个控制器中添加。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/api_documentation_guidelines.html b/api_documentation_guidelines.html new file mode 100644 index 0000000..943acc4 --- /dev/null +++ b/api_documentation_guidelines.html @@ -0,0 +1,482 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

API 文档指导方针

本文说明 Ruby on Rails 的 API 文档指导方针。

读完本文后,您将学到:

+
    +
  • 如何编写有效的文档;

  • +
  • 为不同 Ruby 代码编写文档的风格指导方针。

  • +
+

1 RDoc

Rails API 文档使用 RDoc 生成。如果想生成 API 文档,要在 Rails 根目录中执行 bundle install,然后再执行:

+
+$ bundle exec rake rdoc
+
+
+
+

得到的 HTML 文件在 ./doc/rdoc 目录中。

RDoc 的标记额外的指令参见文档。

2 用词

使用简单的陈述句。简短更好,要说到点子上。

使用现在时:“Returns a hash that…​”,而非“Returned a hash that…​”或“Will return a hash that…​”。

注释的第一个字母大写,后续内容遵守常规的标点符号规则:

+
+# Declares an attribute reader backed by an internally-named
+# instance variable.
+def attr_internal_reader(*attrs)
+  ...
+end
+
+
+
+

使用通行的方式与读者交流,可以直言,也可以隐晦。使用当下推荐的习语。如有必要,调整内容的顺序,强调推荐的方式。文档应该说明最佳实践和现代的权威 Rails 用法。

文档应该简洁全面,要指明边缘情况。如果模块是匿名的呢?如果集合是空的呢?如果参数是 nil 呢?

Rails 组件的名称在单词之间有个空格,如“Active Support”。ActiveRecord 是一个 Ruby 模块,而 Active Record 是一个 ORM。所有 Rails 文档都应该始终使用正确的名称引用 Rails 组件。如果你在下一篇博客文章或演示文稿中这么做,人们会觉得你很正规。

拼写要正确:Arel、Test::Unit、RSpec、HTML、MySQL、JavaScript、ERB。如果不确定,请查看一些权威资料,如各自的官方文档。

“SQL”前面使用不定冠词“an”,如“an SQL statement”和“an SQLite database”。

避免使用“you”和“your”。例如,较之

+
+If you need to use `return` statements in your callbacks, it is recommended that you explicitly define them as methods.
+
+
+
+

这样写更好:

+
+If `return` is needed it is recommended to explicitly define a method.
+
+
+
+

不过,使用代词指代虚构的人时,例如“有会话 cookie 的用户”,应该使用中性代词(they/their/them)。

+
    +
  • 不用 he 或 she,用 they

  • +
  • 不用 him 或 her,用 them

  • +
  • 不用 his 或 her,用 their

  • +
  • 不用 his 或 hers,用 theirs

  • +
  • 不用 himself 或 herself,用 themselves

  • +
+

3 英语

请使用美式英语(color、center、modularize,等等)。美式英语与英式英语之间的拼写差异参见这里

4 牛津式逗号

请使用牛津式逗号(“red, white, and blue”,而非“red, white and blue”)。

5 示例代码

选择有意义的示例,说明基本用法和有趣的点或坑。

代码使用两个空格缩进,即根据标记在左外边距的基础上增加两个空格。示例应该遵守 Rails 编程约定

简短的文档无需明确使用“Examples”标注引入代码片段,直接跟在段后即可:

+
+# Converts a collection of elements into a formatted string by
+# calling +to_s+ on all elements and joining them.
+#
+#   Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
+
+
+
+

但是大段文档可以单独有个“Examples”部分:

+
+# ==== Examples
+#
+#   Person.exists?(5)
+#   Person.exists?('5')
+#   Person.exists?(name: "David")
+#   Person.exists?(['name LIKE ?', "%#{query}%"])
+
+
+
+

表达式的结果在表达式之后,使用 “# => ”给出,而且要纵向对齐:

+
+# For checking if an integer is even or odd.
+#
+#   1.even? # => false
+#   1.odd?  # => true
+#   2.even? # => true
+#   2.odd?  # => false
+
+
+
+

如果一行太长,结果可以放在下一行:

+
+#   label(:article, :title)
+#   # => <label for="article_title">Title</label>
+#
+#   label(:article, :title, "A short title")
+#   # => <label for="article_title">A short title</label>
+#
+#   label(:article, :title, "A short title", class: "title_label")
+#   # => <label for="article_title" class="title_label">A short title</label>
+
+
+
+

不要使用打印方法,如 putsp 给出结果。

常规的注释不使用箭头:

+
+#   polymorphic_url(http://github.com/record)  # same as comment_url(http://github.com/record)
+
+
+
+

6 布尔值

在判断方法或旗标中,尽量使用布尔语义,不要用具体的值。

如果所用的“true”或“false”与 Ruby 定义的一样,使用常规字体。truefalse 两个单例要使用等宽字体。请不要使用“truthy”,Ruby 语言定义了什么是真什么是假,“true”和“false”就能表达技术意义,无需使用其他词代替。

通常,如非绝对必要,不要为单例编写文档。这样能阻止智能的结构,如 !! 或三元运算符,便于重构,而且代码不依赖方法返回的具体值。

例如:

+
+`config.action_mailer.perform_deliveries` specifies whether mail will actually be delivered and is true by default
+
+
+
+

用户无需知道旗标具体的默认值,因此我们只说明它的布尔语义。

下面是一个判断方法的文档示例:

+
+# Returns true if the collection is empty.
+#
+# If the collection has been loaded
+# it is equivalent to <tt>collection.size.zero?</tt>. If the
+# collection has not been loaded, it is equivalent to
+# <tt>collection.exists?</tt>. If the collection has not already been
+# loaded and you are going to fetch the records anyway it is better to
+# check <tt>collection.length.zero?</tt>.
+def empty?
+  if loaded?
+    size.zero?
+  else
+    @target.blank? && !scope.exists?
+  end
+end
+
+
+
+

这个 API 没有提到任何具体的值,知道它具有判断功能就够了。

7 文件名

通常,文件名相对于应用的根目录:

+
+config/routes.rb            # YES
+routes.rb                   # NO
+RAILS_ROOT/config/routes.rb # NO
+
+
+
+

8 字体

8.1 等宽字体

使用等宽字体编写:

+
    +
  • 常量,尤其是类名和模块名

  • +
  • 方法名

  • +
  • 字面量,如 nilfalsetrueself

  • +
  • 符号

  • +
  • 方法的参数

  • +
  • 文件名

  • +
+
+
+class Array
+  # Calls +to_param+ on all its elements and joins the result with
+  # slashes. This is used by +url_for+ in Action Pack.
+  def to_param
+    collect { |e| e.to_param }.join '/'
+  end
+end
+
+
+
+

只有简单的内容才能使用 +...+ 标记使用等宽字体,如常规的方法名、符号、路径(含有正斜线),等等。其他内容应该使用 <tt>…​</tt>,尤其是带有命名空间的类名或模块名,如 <tt>ActiveRecord::Base</tt>

可以使用下述命令测试 RDoc 的输出:

+
+$ echo "+:to_param+" | rdoc --pipe
+# => <p><code>:to_param</code></p>
+
+
+
+

8.2 常规字体

“true”和“false”是英语单词而不是 Ruby 关键字时,使用常规字体:

+
+# Runs all the validations within the specified context.
+# Returns true if no errors are found, false otherwise.
+#
+# If the argument is false (default is +nil+), the context is
+# set to <tt>:create</tt> if <tt>new_record?</tt> is true,
+# and to <tt>:update</tt> if it is not.
+#
+# Validations with no <tt>:on</tt> option will run no
+# matter the context. Validations with # some <tt>:on</tt>
+# option will only run in the specified context.
+def valid?(context = nil)
+  ...
+end
+
+
+
+

9 描述列表

在选项、参数等列表中,在项目和描述之间使用一个连字符(而不是一个冒号,因为选项一般是符号):

+
+# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
+
+
+
+

描述开头是大写字母,结尾有一个句号——这是标准的英语。

10 动态生成的方法

使用 (module|class)_eval(STRING) 创建的方法在旁边有个注释,举例说明生成的代码。这种注释与模板之间相距两个空格。

+
+for severity in Severity.constants
+  class_eval <<-EOT, __FILE__, __LINE__
+    def #{severity.downcase}(message = nil, progname = nil, &block)  # def debug(message = nil, progname = nil, &block)
+      add(#{severity}, message, progname, &block)                    #   add(DEBUG, message, progname, &block)
+    end                                                              # end
+                                                                     #
+    def #{severity.downcase}?                                        # def debug?
+      #{severity} >= @level                                          #   DEBUG >= @level
+    end                                                              # end
+  EOT
+end
+
+
+
+

如果这样得到的行太长,比如说有 200 多列,把注释放在上方:

+
+# def self.find_by_login_and_activated(*args)
+#   options = args.extract_options!
+#   ...
+# end
+self.class_eval %{
+  def self.#{method_id}(*args)
+    options = args.extract_options!
+    ...
+  end
+}
+
+
+
+

11 方法可见性

为 Rails 编写文档时,要区分公开 API 和内部 API。

与多数库一样,Rails 使用 Ruby 提供的 private 关键字定义内部 API。然而,公开 API 遵照的约定稍有不同。不是所有公开方法都旨在供用户使用,Rails 使用 :nodoc: 指令注解内部 API 方法。

因此,在 Rails 中有些可见性为 public 的方法不是供用户使用的。

ActiveRecord::Core::ClassMethods#arel_table 就是一例:

+
+module ActiveRecord::Core::ClassMethods
+  def arel_table #:nodoc:
+    # do some magic..
+  end
+end
+
+
+
+

你可能想,“这是 ActiveRecord::Core 的一个公开类方法”,没错,但是 Rails 团队不希望用户使用这个方法。因此,他们把它标记为 :nodoc:,不包含在公开文档中。这样做,开发团队可以根据内部需要在发布新版本时修改这个方法。方法的名称可能会变,或者返回值有变化,也可能是整个类都不复存在——有太多不确定性,因此不应该在你的插件或应用中使用这个 API。如若不然,升级新版 Rails 时,你的应用或 gem 可能遭到破坏。

为 Rails 做贡献时一定要考虑清楚 API 是否供最终用户使用。未经完整的弃用循环之前,Rails 团队不会轻易对公开 API 做大的改动。如果没有定义为私有的(默认是内部 API),建议你使用 :nodoc: 标记所有内部的方法和类。API 稳定之后,可见性可以修改,但是为了向后兼容,公开 API 往往不宜修改。

使用 :nodoc: 标记一个类或模块表示里面的所有方法都是内部 API,不应该直接使用。

如果遇到 :nodoc:,一定要小心。在删除这一标记之前可以询问核心团队成员或者代码的作者。这种操作基本上都通过拉取请求处理,不能在 docrails 项目中删除。

:nodoc: 不是为了标记方法或类缺少文档。内部的公开方法可能没有 :nodoc: 标记,这只是例外,可能是因为方法由私有变成公开时忘记了。遇到这种情况时应该通过一个拉取请求讨论,而且要具体情况具体分析,绝对不能直接在 docrails 中修改。

综上,Rails 团队使用 :nodoc: 标记供内部使用的可见性为公开的方法和类,对 API 可见性的修改要谨慎,必须先通过一个拉取请求讨论。

12 考虑 Rails 栈

为 Rails API 编写文档时,一定要记住所有内容都身处 Rails 栈中。

这意味着,方法或类的行为在不同的作用域或上下文中可能有所不同。

把整个栈考虑进来之后,行为在不同的地方可能有变。ActionView::Helpers::AssetTagHelper#image_tag 就是一例:

+
+# image_tag("icon.png")
+#   # => <img alt="Icon" src="http://github.com/assets/icon.png" />
+
+
+
+

虽然 #image_tag 的默认行为是返回 /images/icon.png,但是把整个 Rails 栈(包括 Asset Pipeline)考虑进来之后,可能会得到上述结果。

我们只关注考虑整个 Rails 默认栈的行为。

因此,我们要说明的是框架的行为,而不是单个方法。

如果你对 Rails 团队处理某个 API 的方式有疑问,别迟疑,在问题追踪系统中发一个工单,或者提交补丁。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/asset_pipeline.html b/asset_pipeline.html new file mode 100644 index 0000000..e939177 --- /dev/null +++ b/asset_pipeline.html @@ -0,0 +1,232 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+

Asset Pipeline

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/association_basics.html b/association_basics.html new file mode 100644 index 0000000..fed6476 --- /dev/null +++ b/association_basics.html @@ -0,0 +1,2155 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Active Record 关联

本文介绍 Active Record 的关联功能。

读完本文后,您将学到:

+
    +
  • 如何声明 Active Record 模型间的关联;

  • +
  • 怎么理解不同的 Active Record 关联类型;

  • +
  • 如何使用关联为模型添加的方法。

  • +
+

1 为什么使用关联

在 Rails 中,关联在两个 Active Record 模型之间建立联系。模型之间为什么要有关联?因为关联能让常规操作变得更简单。例如,在一个简单的 Rails 应用中,有一个作者模型和一个图书模型。每位作者可以著有多本图书。不用关联的话,模型可以像下面这样定义:

+
+class Author < ApplicationRecord
+end
+
+class Book < ApplicationRecord
+end
+
+
+
+

现在,假如我们想为一位现有作者添加一本书,得这么做:

+
+@book = Book.create(published_at: Time.now, author_id: @author.id)
+
+
+
+

假如要删除一位作者的话,也要把属于他的书都删除:

+
+@books = Book.where(author_id: @author.id)
+@books.each do |book|
+  book.destroy
+end
+@author.destroy
+
+
+
+

使用 Active Record 关联,Rails 知道两个模型之间有联系,上述操作(以及其他操作)可以得到简化。下面使用关联重新定义作者和图书模型:

+
+class Author < ApplicationRecord
+  has_many :books, dependent: :destroy
+end
+
+class Book < ApplicationRecord
+  belongs_to :author
+end
+
+
+
+

这么修改之后,为某位作者添加新书就简单了:

+
+@book = @author.books.create(published_at: Time.now)
+
+
+
+

删除作者及其所有图书也更容易:

+
+@author.destroy
+
+
+
+

请阅读下一节,进一步学习不同的关联类型。后面还会介绍一些使用关联时的小技巧,然后列出关联添加的所有方法和选项。

2 关联的类型

Rails 支持六种关联:

+
    +
  • belongs_to

  • +
  • has_one

  • +
  • has_many

  • +
  • has_many :through

  • +
  • has_one :through

  • +
  • has_and_belongs_to_many

  • +
+

关联使用宏式调用实现,用声明的形式为模型添加功能。例如,声明一个模型属于(belongs_to)另一个模型后,Rails 会维护两个模型之间的“主键-外键”关系,而且还会向模型中添加很多实用的方法。

在下面几小节中,你会学到如何声明并使用这些关联。首先来看一下各种关联适用的场景。

2.1 belongs_to 关联

belongs_to 关联创建两个模型之间一对一的关系,声明所在的模型实例属于另一个模型的实例。例如,如果应用中有作者和图书两个模型,而且每本书只能指定给一位作者,就要这么声明图书模型:

+
+class Book < ApplicationRecord
+  belongs_to :author
+end
+
+
+
+

belongs to

belongs_to 关联声明中必须使用单数形式。如果在上面的代码中使用复数形式定义 author 关联,应用会报错,提示“uninitialized constant Book::Authors”。这是因为 Rails 自动使用关联名推导类名。如果关联名错误地使用复数,推导出的类名也就变成了复数。

相应的迁移如下:

+
+class CreateBooks < ActiveRecord::Migration[5.0]
+  def change
+    create_table :authors do |t|
+      t.string :name
+      t.timestamps
+    end
+
+    create_table :books do |t|
+      t.belongs_to :author, index: true
+      t.datetime :published_at
+      t.timestamps
+    end
+  end
+end
+
+
+
+

2.2 has_one 关联

has_one 关联也建立两个模型之间的一对一关系,但语义和结果有点不一样。这种关联表示模型的实例包含或拥有另一个模型的实例。例如,应用中每个供应商只有一个账户,可以这么定义供应商模型:

+
+class Supplier < ApplicationRecord
+  has_one :account
+end
+
+
+
+

has one

相应的迁移如下:

+
+class CreateSuppliers < ActiveRecord::Migration[5.0]
+  def change
+    create_table :suppliers do |t|
+      t.string :name
+      t.timestamps
+    end
+
+    create_table :accounts do |t|
+      t.belongs_to :supplier, index: true
+      t.string :account_number
+      t.timestamps
+    end
+  end
+end
+
+
+
+

根据使用需要,可能还要为 accounts 表中的 supplier 列创建唯一性索引和(或)外键约束。这里,我们像下面这样定义这一列:

+
+create_table :accounts do |t|
+  t.belongs_to :supplier, index: true, unique: true, foreign_key: true
+  # ...
+end
+
+
+
+

2.3 has_many 关联

has_many 关联建立两个模型之间的一对多关系。在 belongs_to 关联的另一端经常会使用这个关联。has_many 关联表示模型的实例有零个或多个另一模型的实例。例如,对应用中的作者和图书模型来说,作者模型可以这样声明:

+
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

声明 has_many 关联时,另一个模型使用复数形式。

has many

相应的迁移如下:

+
+class CreateAuthors < ActiveRecord::Migration[5.0]
+  def change
+    create_table :authors do |t|
+      t.string :name
+      t.timestamps
+    end
+
+    create_table :books do |t|
+      t.belongs_to :author, index: true
+      t.datetime :published_at
+      t.timestamps
+    end
+  end
+end
+
+
+
+

2.4 has_many :through 关联

has_many :through 关联经常用于建立两个模型之间的多对多关联。这种关联表示一个模型的实例可以借由第三个模型,拥有零个和多个另一模型的实例。例如,在医疗锻炼中,病人要和医生约定练习时间。这中间的关联声明如下:

+
+class Physician < ApplicationRecord
+  has_many :appointments
+  has_many :patients, through: :appointments
+end
+
+class Appointment < ApplicationRecord
+  belongs_to :physician
+  belongs_to :patient
+end
+
+class Patient < ApplicationRecord
+  has_many :appointments
+  has_many :physicians, through: :appointments
+end
+
+
+
+

has many through

相应的迁移如下:

+
+class CreateAppointments < ActiveRecord::Migration[5.0]
+  def change
+    create_table :physicians do |t|
+      t.string :name
+      t.timestamps
+    end
+
+    create_table :patients do |t|
+      t.string :name
+      t.timestamps
+    end
+
+    create_table :appointments do |t|
+      t.belongs_to :physician, index: true
+      t.belongs_to :patient, index: true
+      t.datetime :appointment_date
+      t.timestamps
+    end
+  end
+end
+
+
+
+

联结模型可以使用 has_many 关联方法管理。例如:

+
+physician.patients = patients
+
+
+
+

会为新建立的关联对象创建联结模型实例。如果其中一个对象删除了,相应的联结记录也会删除。

自动删除联结模型的操作直接执行,不会触发 *_destroy 回调。

has_many :through 还能简化嵌套的 has_many 关联。例如,一个文档分为多个部分,每一部分又有多个段落,如果想使用简单的方式获取文档中的所有段落,可以这么做:

+
+class Document < ApplicationRecord
+  has_many :sections
+  has_many :paragraphs, through: :sections
+end
+
+class Section < ApplicationRecord
+  belongs_to :document
+  has_many :paragraphs
+end
+
+class Paragraph < ApplicationRecord
+  belongs_to :section
+end
+
+
+
+

加上 through: :sections 后,Rails 就能理解这段代码:

+
+@document.paragraphs
+
+
+
+

2.5 has_one :through 关联

has_one :through 关联建立两个模型之间的一对一关系。这种关联表示一个模型通过第三个模型拥有另一模型的实例。例如,每个供应商只有一个账户,而且每个账户都有一个账户历史,那么可以这么定义模型:

+
+class Supplier < ApplicationRecord
+  has_one :account
+  has_one :account_history, through: :account
+end
+
+class Account < ApplicationRecord
+  belongs_to :supplier
+  has_one :account_history
+end
+
+class AccountHistory < ApplicationRecord
+  belongs_to :account
+end
+
+
+
+

相应的迁移如下:

+
+class CreateAccountHistories < ActiveRecord::Migration[5.0]
+  def change
+    create_table :suppliers do |t|
+      t.string :name
+      t.timestamps
+    end
+
+    create_table :accounts do |t|
+      t.belongs_to :supplier, index: true
+      t.string :account_number
+      t.timestamps
+    end
+
+    create_table :account_histories do |t|
+      t.belongs_to :account, index: true
+      t.integer :credit_rating
+      t.timestamps
+    end
+  end
+end
+
+
+
+

has one through

2.6 has_and_belongs_to_many 关联

has_and_belongs_to_many 关联直接建立两个模型之间的多对多关系,不借由第三个模型。例如,应用中有装配体和零件两个模型,每个装配体有多个零件,每个零件又可用于多个装配体,这时可以按照下面的方式定义模型:

+
+class Assembly < ApplicationRecord
+  has_and_belongs_to_many :parts
+end
+
+class Part < ApplicationRecord
+  has_and_belongs_to_many :assemblies
+end
+
+
+
+

habtm

相应的迁移如下:

+
+class CreateAssembliesAndParts < ActiveRecord::Migration[5.0]
+  def change
+    create_table :assemblies do |t|
+      t.string :name
+      t.timestamps
+    end
+
+    create_table :parts do |t|
+      t.string :part_number
+      t.timestamps
+    end
+
+    create_table :assemblies_parts, id: false do |t|
+      t.belongs_to :assembly, index: true
+      t.belongs_to :part, index: true
+    end
+  end
+end
+
+
+
+

2.7 在 belongs_tohas_one 之间选择

如果想建立两个模型之间的一对一关系,要在一个模型中添加 belongs_to,在另一模型中添加 has_one。但是怎么知道在哪个模型中添加哪个呢?

二者之间的区别是在哪里放置外键(外键在 belongs_to 关联所在模型对应的表中),不过也要考虑数据的语义。has_one 的意思是某样东西属于我,即哪个东西指向你。例如,说供应商有一个账户,比账户拥有供应商更合理,所以正确的关联应该这么声明:

+
+class Supplier < ApplicationRecord
+  has_one :account
+end
+
+class Account < ApplicationRecord
+  belongs_to :supplier
+end
+
+
+
+

相应的迁移如下:

+
+class CreateSuppliers < ActiveRecord::Migration[5.0]
+  def change
+    create_table :suppliers do |t|
+      t.string  :name
+      t.timestamps
+    end
+
+    create_table :accounts do |t|
+      t.integer :supplier_id
+      t.string  :account_number
+      t.timestamps
+    end
+
+    add_index :accounts, :supplier_id
+  end
+end
+
+
+
+

t.integer :supplier_id 更明确地表明了外键的名称。在目前的 Rails 版本中,可以抽象实现的细节,使用 t.references :supplier 代替。

2.8 在 has_many :throughhas_and_belongs_to_many 之间选择

Rails 提供了两种建立模型之间多对多关系的方式。其中比较简单的是 has_and_belongs_to_many,可以直接建立关联:

+
+class Assembly < ApplicationRecord
+  has_and_belongs_to_many :parts
+end
+
+class Part < ApplicationRecord
+  has_and_belongs_to_many :assemblies
+end
+
+
+
+

第二种方式是使用 has_many :through,通过联结模型间接建立关联:

+
+class Assembly < ApplicationRecord
+  has_many :manifests
+  has_many :parts, through: :manifests
+end
+
+class Manifest < ApplicationRecord
+  belongs_to :assembly
+  belongs_to :part
+end
+
+class Part < ApplicationRecord
+  has_many :manifests
+  has_many :assemblies, through: :manifests
+end
+
+
+
+

根据经验,如果想把关联模型当做独立实体使用,要用 has_many :through 关联;如果不需要使用关联模型,建立 has_and_belongs_to_many 关联更简单(不过要记得在数据库中创建联结表)。

如果要对联结模型做数据验证、调用回调,或者使用其他属性,要使用 has_many :through 关联。

2.9 多态关联

关联还有一种高级形式——多态关联(polymorphic association)。在多态关联中,在同一个关联中,一个模型可以属于多个模型。例如,图片模型可以属于雇员模型或者产品模型,模型的定义如下:

+
+class Picture < ApplicationRecord
+  belongs_to :imageable, polymorphic: true
+end
+
+class Employee < ApplicationRecord
+  has_many :pictures, as: :imageable
+end
+
+class Product < ApplicationRecord
+  has_many :pictures, as: :imageable
+end
+
+
+
+

belongs_to 中指定使用多态,可以理解成创建了一个接口,可供任何一个模型使用。在 Employee 模型实例上,可以使用 @employee.pictures 获取图片集合。

类似地,可使用 @product.pictures 获取产品的图片。

Picture 模型的实例上,可以使用 @picture.imageable 获取父对象。不过事先要在声明多态接口的模型中创建外键字段和类型字段:

+
+class CreatePictures < ActiveRecord::Migration[5.0]
+  def change
+    create_table :pictures do |t|
+      t.string  :name
+      t.integer :imageable_id
+      t.string  :imageable_type
+      t.timestamps
+    end
+
+    add_index :pictures, [:imageable_type, :imageable_id]
+  end
+end
+
+
+
+

上面的迁移可以使用 t.references 简化:

+
+class CreatePictures < ActiveRecord::Migration[5.0]
+  def change
+    create_table :pictures do |t|
+      t.string :name
+      t.references :imageable, polymorphic: true, index: true
+      t.timestamps
+    end
+  end
+end
+
+
+
+

polymorphic

2.10 自联结

设计数据模型时,模型有时要和自己建立关系。例如,在一个数据库表中保存所有雇员的信息,但要建立经理和下属之间的关系。这种情况可以使用自联结关联解决:

+
+class Employee < ApplicationRecord
+  has_many :subordinates, class_name: "Employee",
+                          foreign_key: "manager_id"
+
+  belongs_to :manager, class_name: "Employee"
+end
+
+
+
+

这样定义模型后,可以使用 @employee.subordinates@employee.manager 检索了。

在迁移(模式)中,要添加一个引用字段,指向模型自身:

+
+class CreateEmployees < ActiveRecord::Migration[5.0]
+  def change
+    create_table :employees do |t|
+      t.references :manager, index: true
+      t.timestamps
+    end
+  end
+end
+
+
+
+

3 小技巧和注意事项

为了在 Rails 应用中有效使用 Active Record 关联,要了解以下几点:

+
    +
  • 控制缓存

  • +
  • 避免命名冲突

  • +
  • 更新模式

  • +
  • 控制关联的作用域

  • +
  • 双向关联

  • +
+

3.1 控制缓存

关联添加的方法都会使用缓存,记录最近一次查询的结果,以备后用。缓存还会在方法之间共享。例如:

+
+author.books           # 从数据库中检索图书
+author.books.size      # 使用缓存的图书副本
+author.books.empty?    # 使用缓存的图书副本
+
+
+
+

应用的其他部分可能会修改数据,那么应该怎么重载缓存呢?在关联上调用 reload 即可:

+
+author.books                 # 从数据库中检索图书
+author.books.size            # 使用缓存的图书副本
+author.books.reload.empty?   # 丢掉缓存的图书副本
+                             # 重新从数据库中检索
+
+
+
+

3.2 避免命名冲突

关联的名称并不能随意使用。因为创建关联时,会向模型添加同名方法,所以关联的名字不能和 ActiveRecord::Base 中的实例方法同名。如果同名,关联方法会覆盖 ActiveRecord::Base 中的实例方法,导致错误。例如,关联的名字不能为 attributesconnection

3.3 更新模式

关联非常有用,但没什么魔法。关联对应的数据库模式需要你自己编写。不同的关联类型,要做的事也不同。对 belongs_to 关联来说,要创建外键;对 has_and_belongs_to_many 关联来说,要创建相应的联结表。

3.3.1 创建 belongs_to 关联所需的外键

声明 belongs_to 关联后,要创建相应的外键。例如,有下面这个模型:

+
+class Book < ApplicationRecord
+  belongs_to :author
+end
+
+
+
+

上述关联需要在 books 表中创建相应的外键:

+
+class CreateBooks < ActiveRecord::Migration[5.0]
+  def change
+    create_table :books do |t|
+      t.datetime :published_at
+      t.string   :book_number
+      t.integer  :author_id
+    end
+
+    add_index :books, :author_id
+  end
+end
+
+
+
+

如果声明关联之前已经定义了模型,则要在迁移中使用 add_column 创建外键。

3.3.2 创建 has_and_belongs_to_many 关联所需的联结表

创建 has_and_belongs_to_many 关联后,必须手动创建联结表。除非使用 :join_table 选项指定了联结表的名称,否则 Active Record 会按照类名出现在字典中的顺序为表起名。因此,作者和图书模型使用的联结表默认名为“authors_books”,因为在字典中,“a”在“b”前面。

模型名的顺序使用字符串的 <=> 运算符确定。所以,如果两个字符串的长度不同,比较最短长度时,两个字符串是相等的,那么长字符串的排序比短字符串靠前。例如,你可能以为“paper_boxes”和“papers”这两个表生成的联结表名为“papers_paper_boxes”,因为“paper_boxes”比“papers”长,但其实生成的联结表名为“paper_boxes_papers”,因为在一般的编码方式中,“_”比“s”靠前。

不管名称是什么,你都要在迁移中手动创建联结表。例如下面的关联:

+
+class Assembly < ApplicationRecord
+  has_and_belongs_to_many :parts
+end
+
+class Part < ApplicationRecord
+  has_and_belongs_to_many :assemblies
+end
+
+
+
+

上述关联需要在迁移中创建 assemblies_parts 表,而且该表无主键:

+
+class CreateAssembliesPartsJoinTable < ActiveRecord::Migration[5.0]
+  def change
+    create_table :assemblies_parts, id: false do |t|
+      t.integer :assembly_id
+      t.integer :part_id
+    end
+
+    add_index :assemblies_parts, :assembly_id
+    add_index :assemblies_parts, :part_id
+  end
+end
+
+
+
+

我们把 id: false 选项传给 create_table 方法,因为这个表不对应模型。只有这样,关联才能正常建立。如果在使用 has_and_belongs_to_many 关联时遇到奇怪的行为,例如提示模型 ID 损坏,或 ID 冲突,有可能就是因为创建了主键。

联结表还可以使用 create_join_table 方法创建:

+
+class CreateAssembliesPartsJoinTable < ActiveRecord::Migration[5.0]
+  def change
+    create_join_table :assemblies, :parts do |t|
+      t.index :assembly_id
+      t.index :part_id
+    end
+  end
+end
+
+
+
+

3.4 控制关联的作用域

默认情况下,关联只会查找当前模块作用域中的对象。如果在模块中定义 Active Record 模型,知道这一点很重要。例如:

+
+module MyApplication
+  module Business
+    class Supplier < ApplicationRecord
+       has_one :account
+    end
+
+    class Account < ApplicationRecord
+       belongs_to :supplier
+    end
+  end
+end
+
+
+
+

上面的代码能正常运行,因为 SupplierAccount 在同一个作用域中。但下面这段代码就不行了,因为 SupplierAccount 在不同的作用域中:

+
+module MyApplication
+  module Business
+    class Supplier < ApplicationRecord
+       has_one :account
+    end
+  end
+
+  module Billing
+    class Account < ApplicationRecord
+       belongs_to :supplier
+    end
+  end
+end
+
+
+
+

要想让处在不同命名空间中的模型正常建立关联,声明关联时要指定完整的类名:

+
+module MyApplication
+  module Business
+    class Supplier < ApplicationRecord
+       has_one :account,
+        class_name: "MyApplication::Billing::Account"
+    end
+  end
+
+  module Billing
+    class Account < ApplicationRecord
+       belongs_to :supplier,
+        class_name: "MyApplication::Business::Supplier"
+    end
+  end
+end
+
+
+
+

3.5 双向关联

一般情况下,都要求能在关联的两端进行操作,即在两个模型中都要声明关联。

+
+class Author < ApplicationRecord
+  has_many :books
+end
+
+class Book < ApplicationRecord
+  belongs_to :author
+end
+
+
+
+

默认情况下,Active Record 并不知道关联中两个模型之间的联系。这可能导致同一对象的两个副本不同步:

+
+a = Author.first
+b = a.books.first
+a.first_name == b.author.first_name # => true
+a.first_name = 'Manny'
+a.first_name == b.author.first_name # => false
+
+
+
+

之所以会发生这种情况,是因为 ab.author 在内存中是同一数据的两种表述,修改其中一个并不会自动刷新另一个。Active Record 提供了 :inverse_of 选项,可以告知 Rails 两者之间的关系:

+
+class Author < ApplicationRecord
+  has_many :books, inverse_of: :author
+end
+
+class Book < ApplicationRecord
+  belongs_to :author, inverse_of: :books
+end
+
+
+
+

这么修改之后,Active Record 只会加载一个作者对象,从而避免数据的不一致性,提高应用的执行效率:

+
+a = Author.first
+b = a.books.first
+a.first_name == b.author.first_name # => true
+a.first_name = 'Manny'
+a.first_name == b.author.first_name # => true
+
+
+
+

inverse_of 有些限制:

+
    +
  • 不支持 :through 关联;

  • +
  • 不支持 :polymorphic 关联;

  • +
  • 不支持 :as 选项;

  • +
  • belongs_to 关联会忽略 has_many 关联的 inverse_of 选项;

  • +
+

每种关联都会尝试自动找到关联的另一端,并且设置 :inverse_of 选项(根据关联的名称)。使用标准名称的关联都有这种功能。但是,如果在关联中设置了下面这些选项,将无法自动设置 :inverse_of

+
    +
  • :conditions

  • +
  • :through

  • +
  • :polymorphic

  • +
  • :foreign_key

  • +
+

4 关联详解

下面几小节详细说明各种关联,包括添加的方法和声明关联时可以使用的选项。

4.1 belongs_to 关联详解

belongs_to 关联创建一个模型与另一个模型之间的一对一关系。用数据库术语来说,就是这个类中包含外键。如果外键在另一个类中,应该使用 has_one 关联。

4.1.1 belongs_to 关联添加的方法

声明 belongs_to 关联后,所在的类自动获得了五个和关联相关的方法:

+
    +
  • association

  • +
  • association=(associate)

  • +
  • build_association(attributes = {})

  • +
  • create_association(attributes = {})

  • +
  • create_association!(attributes = {})

  • +
+

这五个方法中的 association 要替换成传给 belongs_to 方法的第一个参数。对下述声明来说:

+
+class Book < ApplicationRecord
+  belongs_to :author
+end
+
+
+
+

Book 模型的每个实例都获得了这些方法:

+
+author
+author=
+build_author
+create_author
+create_author!
+
+
+
+

has_onebelongs_to 关联中,必须使用 build_* 方法构建关联对象。association.build 方法是在 has_manyhas_and_belongs_to_many 关联中使用的。创建关联对象要使用 create_* 方法。

4.1.1.1 association +

如果关联的对象存在,association 方法会返回关联的对象。如果找不到关联的对象,返回 nil

+
+@author = @book.author
+
+
+
+

如果关联的对象之前已经取回,会返回缓存版本。如果不想使用缓存版本(强制读取数据库)在父对象上调用 #reload 方法。

+
+@author = @book.reload.author
+
+
+
+
4.1.1.2 association=(associate) +

association= 方法用于赋值关联的对象。这个方法的底层操作是,从关联对象上读取主键,然后把值赋给该主键对应的对象。

+
+@book.author = @author
+
+
+
+
4.1.1.3 build_association(attributes = {}) +

build_association 方法返回该关联类型的一个新对象。这个对象使用传入的属性初始化,对象的外键会自动设置,但关联对象不会存入数据库。

+
+@author = @book.build_author(author_number: 123,
+                             author_name: "John Doe")
+
+
+
+
4.1.1.4 create_association(attributes = {}) +

create_association 方法返回该关联类型的一个新对象。这个对象使用传入的属性初始化,对象的外键会自动设置,只要能通过所有数据验证,就会把关联对象存入数据库。

+
+@author = @book.create_author(author_number: 123,
+                                   author_name: "John Doe")
+
+
+
+
4.1.1.5 create_association!(attributes = {}) +

create_association 方法作用相同,但是如果记录无效,会抛出 ActiveRecord::RecordInvalid 异常。

4.1.2 belongs_to 方法的选项

Rails 的默认设置足够智能,能满足多数需求。但有时还是需要定制 belongs_to 关联的行为。定制的方法很简单,声明关联时传入选项或者使用代码块即可。例如,下面的关联使用了两个选项:

+
+class Book < ApplicationRecord
+  belongs_to :author, dependent: :destroy,
+    counter_cache: true
+end
+
+
+
+

belongs_to 关联支持下列选项:

+
    +
  • :autosave

  • +
  • :class_name

  • +
  • :counter_cache

  • +
  • :dependent

  • +
  • :foreign_key

  • +
  • :primary_key

  • +
  • :inverse_of

  • +
  • :polymorphic

  • +
  • :touch

  • +
  • :validate

  • +
  • :optional

  • +
+
4.1.2.1 :autosave +

如果把 :autosave 选项设为 true,保存父对象时,会自动保存所有子对象,并把标记为析构的子对象销毁。

4.1.2.2 :class_name +

如果另一个模型无法从关联的名称获取,可以使用 :class_name 选项指定模型名。例如,如果一本书属于一位作者,但是表示作者的模型是 Patron,就可以这样声明关联:

+
+class Book < ApplicationRecord
+  belongs_to :author, class_name: "Patron"
+end
+
+
+
+
4.1.2.3 :counter_cache +

:counter_cache 选项可以提高统计所属对象数量操作的效率。以下述模型为例:

+
+class Book < ApplicationRecord
+  belongs_to :author
+end
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

这样声明关联后,如果想知道 @author.books.size 的结果,要在数据库中执行 COUNT(*) 查询。如果不想执行这个查询,可以在声明 belongs_to 关联的模型中加入计数缓存功能:

+
+class Book < ApplicationRecord
+  belongs_to :author, counter_cache: true
+end
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

这样声明关联后,Rails 会及时更新缓存,调用 size 方法时会返回缓存中的值。

虽然 :counter_cache 选项在声明 belongs_to 关联的模型中设置,但实际使用的字段要添加到所关联的模型中(has_many 那一方)。针对上面的例子,要把 books_count 字段加入 Author 模型。

这个字段的名称也是可以设置的,把 counter_cache 选项的值换成列名即可。例如,不使用 books_count,而是使用 count_of_books

+
+class Book < ApplicationRecord
+  belongs_to :author, counter_cache: :count_of_books
+end
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

只需在关联的 belongs_to 一侧指定 :counter_cache 选项。

计数缓存字段通过 attr_readonly 方法加入关联模型的只读属性列表中。

4.1.2.4 :dependent +

:dependent 选项控制属主销毁后怎么处理关联的对象:

+
    +
  • :destroy:也销毁关联的对象

  • +
  • :delete_all:直接从数据库中删除关联的对象(不执行回调)

  • +
  • :nullify:把外键设为 NULL(不执行回调)

  • +
  • :restrict_with_exception:如果有关联的记录,抛出异常

  • +
  • :restrict_with_error:如果有关联的对象,为属主添加一个错误

  • +
+

belongs_to 关联和 has_many 关联配对时,不应该设置这个选项,否则会导致数据库中出现无主记录。

4.1.2.5 :foreign_key +

按照约定,用来存储外键的字段名是关联名后加 _id:foreign_key 选项可以设置要使用的外键名:

+
+class Book < ApplicationRecord
+  belongs_to :author, class_name: "Patron",
+                      foreign_key: "patron_id"
+end
+
+
+
+

不管怎样,Rails 都不会自动创建外键字段,你要自己在迁移中创建。

4.1.2.6 :primary_key +

按照约定,Rails 假定使用表中的 id 列保存主键。使用 :primary_key 选项可以指定使用其他列。

假如有个 users 表使用 guid 列存储主键,todos 想在 guid 列中存储用户的 ID,那么可以使用 primary_key 选项设置:

+
+class User < ApplicationRecord
+  self.primary_key = 'guid' # 主键是 guid,不是 id
+end
+
+class Todo < ApplicationRecord
+  belongs_to :user, primary_key: 'guid'
+end
+
+
+
+

执行 @user.todos.create 时,@todo 记录的用户 ID 是 @userguid 值。

4.1.2.7 :inverse_of +

:inverse_of 选项指定 belongs_to 关联另一端的 has_manyhas_one 关联名。不能和 :polymorphic 选项一起使用。

+
+class Author < ApplicationRecord
+  has_many :books, inverse_of: :author
+end
+
+class Book < ApplicationRecord
+  belongs_to :author, inverse_of: :books
+end
+
+
+
+
4.1.2.8 :polymorphic +

:polymorphic 选项为 true 时,表明这是个多态关联。多态关联已经详细介绍过多态关联。

4.1.2.9 :touch +

如果把 :touch 选项设为 true,保存或销毁对象时,关联对象的 updated_atupdated_on 字段会自动设为当前时间。

+
+class Book < ApplicationRecord
+  belongs_to :author, touch: true
+end
+
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

在这个例子中,保存或销毁一本书后,会更新关联的作者的时间戳。还可指定要更新哪个时间戳字段:

+
+class Book < ApplicationRecord
+  belongs_to :author, touch: :books_updated_at
+end
+
+
+
+
4.1.2.10 :validate +

如果把 :validate 选项设为 true,保存对象时,会同时验证关联的对象。该选项的默认值是 false,保存对象时不验证关联的对象。

4.1.2.11 :optional +

如果把 :optional 选项设为 true,不会验证关联的对象是否存在。该选项的默认值是 false

4.1.3 belongs_to 的作用域

有时可能需要定制 belongs_to 关联使用的查询,定制的查询可在作用域代码块中指定。例如:

+
+class Book < ApplicationRecord
+  belongs_to :author, -> { where active: true },
+                      dependent: :destroy
+end
+
+
+
+

在作用域代码块中可以使用任何一个标准的查询方法。下面分别介绍这几个:

+
    +
  • where

  • +
  • includes

  • +
  • readonly

  • +
  • select

  • +
+
4.1.3.1 where +

where 方法指定关联对象必须满足的条件。

+
+class book < ApplicationRecord
+  belongs_to :author, -> { where active: true }
+end
+
+
+
+
4.1.3.2 includes +

includes 方法指定使用关联时要及早加载的间接关联。例如,有如下的模型:

+
+class LineItem < ApplicationRecord
+  belongs_to :book
+end
+
+class Book < ApplicationRecord
+  belongs_to :author
+  has_many :line_items
+end
+
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

如果经常要直接从商品上获取作者对象(@line_item.book.author),就可以在关联中把作者从商品引入图书中:

+
+class LineItem < ApplicationRecord
+  belongs_to :book, -> { includes :author }
+end
+
+class Book < ApplicationRecord
+  belongs_to :author
+  has_many :line_items
+end
+
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

直接关联没必要使用 includes。如果 Book belongs_to :author,那么需要使用时会自动及早加载作者。

4.1.3.3 readonly +

如果使用 readonly,通过关联获取的对象是只读的。

4.1.3.4 select +

select 方法用于覆盖检索关联对象使用的 SQL SELECT 子句。默认情况下,Rails 检索所有字段。

如果在 belongs_to 关联中使用 select 方法,应该同时设置 :foreign_key 选项,确保返回的结果正确。

4.1.4 什么时候保存对象

把对象赋值给 belongs_to 关联不会自动保存对象,也不会保存关联的对象。

4.2 has_one 关联详解

has_one 关联建立两个模型之间的一对一关系。用数据库术语来说,这种关联的意思是外键在另一个类中。如果外键在这个类中,应该使用 belongs_to 关联。

4.2.1 has_one 关联添加的方法

声明 has_one 关联后,声明所在的类自动获得了五个关联相关的方法:

+
    +
  • association

  • +
  • association=(associate)

  • +
  • build_association(attributes = {})

  • +
  • create_association(attributes = {})

  • +
  • create_association!(attributes = {})

  • +
+

这五个方法中的 association 要替换成传给 has_one 方法的第一个参数。对如下的声明来说:

+
+class Supplier < ApplicationRecord
+  has_one :account
+end
+
+
+
+

每个 Supplier 模型实例都获得了这些方法:

+
+account
+account=
+build_account
+create_account
+create_account!
+
+
+
+

has_onebelongs_to 关联中,必须使用 build_* 方法构建关联对象。association.build 方法是在 has_manyhas_and_belongs_to_many 关联中使用的。创建关联对象要使用 create_* 方法。

4.2.1.1 association +

如果关联的对象存在,association 方法会返回关联的对象。如果找不到关联的对象,返回 nil

+
+@account = @supplier.account
+
+
+
+

如果关联的对象之前已经取回,会返回缓存版本。如果不想使用缓存版本,而是强制重新从数据库中读取,在父对象上调用 #reload 方法。

+
+@account = @supplier.reload.account
+
+
+
+
4.2.1.2 association=(associate) +

association= 方法用于赋值关联的对象。这个方法的底层操作是,从对象上读取主键,然后把关联的对象的外键设为那个值。

+
+@supplier.account = @account
+
+
+
+
4.2.1.3 build_association(attributes = {}) +

build_association 方法返回该关联类型的一个新对象。这个对象使用传入的属性初始化,和对象链接的外键会自动设置,但关联对象不会存入数据库。

+
+@account = @supplier.build_account(terms: "Net 30")
+
+
+
+
4.2.1.4 create_association(attributes = {}) +

create_association 方法返回该关联类型的一个新对象。这个对象使用传入的属性初始化,和对象链接的外键会自动设置,只要能通过所有数据验证,就会把关联对象存入数据库。

+
+@account = @supplier.create_account(terms: "Net 30")
+
+
+
+
4.2.1.5 create_association!(attributes = {}) +

create_association 方法作用相同,但是如果记录无效,会抛出 ActiveRecord::RecordInvalid 异常。

4.2.2 has_one 方法的选项

Rails 的默认设置足够智能,能满足多数需求。但有时还是需要定制 has_one 关联的行为。定制的方法很简单,声明关联时传入选项即可。例如,下面的关联使用了两个选项:

+
+class Supplier < ApplicationRecord
+  has_one :account, class_name: "Billing", dependent: :nullify
+end
+
+
+
+

has_one 关联支持下列选项:

+
    +
  • :as

  • +
  • :autosave

  • +
  • :class_name

  • +
  • :dependent

  • +
  • :foreign_key

  • +
  • :inverse_of

  • +
  • :primary_key

  • +
  • :source

  • +
  • :source_type

  • +
  • :through

  • +
  • :validate

  • +
+
4.2.2.1 :as +

:as 选项表明这是多态关联。前文已经详细介绍过多态关联。

4.2.2.2 :autosave +

如果把 :autosave 选项设为 true,保存父对象时,会自动保存所有子对象,并把标记为析构的子对象销毁。

4.2.2.3 :class_name +

如果另一个模型无法从关联的名称获取,可以使用 :class_name 选项指定模型名。例如,供应商有一个账户,但表示账户的模型是 Billing,那么就可以这样声明关联:

+
+class Supplier < ApplicationRecord
+  has_one :account, class_name: "Billing"
+end
+
+
+
+
4.2.2.4 :dependent +

控制属主销毁后怎么处理关联的对象:

+
    +
  • :destroy:也销毁关联的对象;

  • +
  • :delete:直接把关联的对象从数据库中删除(不执行回调);

  • +
  • :nullify:把外键设为 NULL,不执行回调;

  • +
  • :restrict_with_exception:有关联的对象时抛出异常;

  • +
  • :restrict_with_error:有关联的对象时,向属主添加一个错误;

  • +
+

如果在数据库层设置了 NOT NULL 约束,就不能使用 :nullify 选项。如果 :dependent 选项没有销毁关联,就无法修改关联的对象,因为关联的对象的外键设置为不接受 NULL

4.2.2.5 :foreign_key +

按照约定,在另一个模型中用来存储外键的字段名是模型名后加 _id:foreign_key 选项用于设置要使用的外键名:

+
+class Supplier < ApplicationRecord
+  has_one :account, foreign_key: "supp_id"
+end
+
+
+
+

不管怎样,Rails 都不会自动创建外键字段,你要自己在迁移中创建。

4.2.2.6 :inverse_of +

:inverse_of 选项指定 has_one 关联另一端的 belongs_to 关联名。不能和 :through:as 选项一起使用。

+
+class Supplier < ApplicationRecord
+  has_one :account, inverse_of: :supplier
+end
+
+class Account < ApplicationRecord
+  belongs_to :supplier, inverse_of: :account
+end
+
+
+
+
4.2.2.7 :primary_key +

按照约定,用来存储该模型主键的字段名 id:primary_key 选项用于设置要使用的主键名。

4.2.2.8 :source +

:source 选项指定 has_one :through 关联的源关联名称。

4.2.2.9 :source_type +

:source_type 选项指定通过多态关联处理 has_one :through 关联的源关联类型。

4.2.2.10 :through +

:through 选项指定用于执行查询的联结模型。前文详细介绍过 has_one :through 关联。

4.2.2.11 :validate +

如果把 :validate 选项设为 true,保存对象时,会同时验证关联的对象。该选项的默认值是 false,即保存对象时不验证关联的对象。

4.2.3 has_one 的作用域

有时可能需要定制 has_one 关联使用的查询。定制的查询在作用域代码块中指定。例如:

+
+class Supplier < ApplicationRecord
+  has_one :account, -> { where active: true }
+end
+
+
+
+

在作用域代码块中可以使用任何一个标准的查询方法。下面介绍其中几个:

+
    +
  • where

  • +
  • includes

  • +
  • readonly

  • +
  • select

  • +
+
4.2.3.1 where +

where 方法指定关联的对象必须满足的条件。

+
+class Supplier < ApplicationRecord
+  has_one :account, -> { where "confirmed = 1" }
+end
+
+
+
+
4.2.3.2 includes +

includes 方法指定使用关联时要及早加载的间接关联。例如,有如下的模型:

+
+class Supplier < ApplicationRecord
+  has_one :account
+end
+
+class Account < ApplicationRecord
+  belongs_to :supplier
+  belongs_to :representative
+end
+
+class Representative < ApplicationRecord
+  has_many :accounts
+end
+
+
+
+

如果经常直接获取供应商代表(@supplier.account.representative),可以把代表引入供应商和账户的关联中:

+
+class Supplier < ApplicationRecord
+  has_one :account, -> { includes :representative }
+end
+
+class Account < ApplicationRecord
+  belongs_to :supplier
+  belongs_to :representative
+end
+
+class Representative < ApplicationRecord
+  has_many :accounts
+end
+
+
+
+
4.2.3.3 readonly +

如果使用 readonly,通过关联获取的对象是只读的。

4.2.3.4 select +

select 方法会覆盖获取关联对象使用的 SQL SELECT 子句。默认情况下,Rails 检索所有列。

4.2.4 检查关联的对象是否存在

检查关联的对象是否存在可以使用 association.nil? 方法:

+
+if @supplier.account.nil?
+  @msg = "No account found for this supplier"
+end
+
+
+
+
4.2.5 什么时候保存对象

把对象赋值给 has_one 关联时,那个对象会自动保存(因为要更新外键)。而且所有被替换的对象也会自动保存,因为外键也变了。

如果由于无法通过验证而导致上述保存失败,赋值语句返回 false,赋值操作会取消。

如果父对象(has_one 关联声明所在的模型)没保存(new_record? 方法返回 true),那么子对象也不会保存。只有保存了父对象,才会保存子对象。

如果赋值给 has_one 关联时不想保存对象,使用 association.build 方法。

4.3 has_many 关联详解

has_many 关联建立两个模型之间的一对多关系。用数据库术语来说,这种关联的意思是外键在另一个类中,指向这个类的实例。

4.3.1 has_many 关联添加的方法

声明 has_many 关联后,声明所在的类自动获得了 16 个关联相关的方法:

+
    +
  • collection

  • +
  • collection<<(object, …​)

  • +
  • collection.delete(object, …​)

  • +
  • collection.destroy(object, …​)

  • +
  • collection=(objects)

  • +
  • collection_singular_ids

  • +
  • collection_singular_ids=(ids)

  • +
  • collection.clear

  • +
  • collection.empty?

  • +
  • collection.size

  • +
  • collection.find(…​)

  • +
  • collection.where(…​)

  • +
  • collection.exists?(…​)

  • +
  • collection.build(attributes = {}, …​)

  • +
  • collection.create(attributes = {})

  • +
  • collection.create!(attributes = {})

  • +
+

这些个方法中的 collection 要替换成传给 has_many 方法的第一个参数。collection_singular 要替换成第一个参数的单数形式。对如下的声明来说:

+
+class Author < ApplicationRecord
+  has_many :books
+end
+
+
+
+

每个 Author 模型实例都获得了这些方法:

+
+books
+books<<(object, ...)
+books.delete(object, ...)
+books.destroy(object, ...)
+books=(objects)
+book_ids
+book_ids=(ids)
+books.clear
+books.empty?
+books.size
+books.find(...)
+books.where(...)
+books.exists?(...)
+books.build(attributes = {}, ...)
+books.create(attributes = {})
+books.create!(attributes = {})
+
+
+
+
4.3.1.1 collection +

collection 方法返回一个数组,包含所有关联的对象。如果没有关联的对象,则返回空数组。

+
+@books = @author.books
+
+
+
+
4.3.1.2 collection<<(object, …​) +

collection<< 方法向关联对象数组中添加一个或多个对象,并把各个所加对象的外键设为调用此方法的模型的主键。

+
+@author.books << @book1
+
+
+
+
4.3.1.3 collection.delete(object, …​) +

collection.delete 方法从关联对象数组中删除一个或多个对象,并把删除的对象外键设为 NULL

+
+@author.books.delete(@book1)
+
+
+
+

如果关联设置了 dependent: :destroy,还会销毁关联的对象;如果关联设置了 dependent: :delete_all,还会删除关联的对象。

4.3.1.4 collection.destroy(object, …​) +

collection.destroy 方法在关联对象上调用 destroy 方法,从关联对象数组中删除一个或多个对象。

+
+@author.books.destroy(@book1)
+
+
+
+

对象始终会从数据库中删除,忽略 :dependent 选项。

4.3.1.5 collection=(objects) +

collection= 方法让关联对象数组只包含指定的对象,根据需求会添加或删除对象。

4.3.1.6 collection_singular_ids +

collection_singular_ids 方法返回一个数组,包含关联对象数组中各对象的 ID。

+
+@book_ids = @author.book_ids
+
+
+
+
4.3.1.7 collection_singular_ids=(ids) +

collection_singular_ids= 方法让关联对象数组中只包含指定的主键,根据需要会增删 ID。

4.3.1.8 collection.clear +

collection.clear 方法根据 dependent 选项指定的策略删除集合中的所有对象。如果没有指定这个选项,使用默认策略。has_many :through 关联的默认策略是 delete_allhas_many 关联的默认策略是,把外键设为 NULL

+
+@author.books.clear
+
+
+
+

如果设为 dependent: :destroy,对象会被删除,这与 dependent: :delete_all 一样。

4.3.1.9 collection.empty? +

如果集合中没有关联的对象,collection.empty? 方法返回 true

+
+<% if @author.books.empty? %>
+  No Books Found
+<% end %>
+
+
+
+
4.3.1.10 collection.size +

collection.size 返回集合中的对象数量。

+
+@book_count = @author.books.size
+
+
+
+
4.3.1.11 collection.find(…​) +

collection.find 方法在集合中查找对象,使用的句法和选项跟 ActiveRecord::Base.find 方法一样。

+
+@available_books = @author.books.find(1)
+
+
+
+
4.3.2 collection.where(…​) +

collection.where 方法根据指定的条件在集合中查找对象,但对象是惰性加载的,即访问对象时才会查询数据库。

+
+@available_books = @author.books.where(available: true) # 尚未查询
+@available_book = @available_books.first # 现在查询数据库
+
+
+
+
4.3.2.1 collection.exists?(…​) +

collection.exists? 方法根据指定的条件检查集合中是否有符合条件的对象,使用的句法和选项跟 ActiveRecord::Base.exists? 方法一样。

4.3.2.2 collection.build(attributes = {}, …​) +

collection.build 方法返回一个或多个此种关联类型的新对象。这些对象会使用传入的属性初始化,还会创建对应的外键,但不会保存关联的对象。

+
+@book = @author.books.build(published_at: Time.now,
+                            book_number: "A12345")
+
+@books = @author.books.build([
+  { published_at: Time.now, book_number: "A12346" },
+  { published_at: Time.now, book_number: "A12347" }
+])
+
+
+
+
4.3.2.3 collection.create(attributes = {}) +

collection.create 方法返回一个或多个此种关联类型的新对象。这些对象会使用传入的属性初始化,还会创建对应的外键,只要能通过所有数据验证,就会保存关联的对象。

+
+@book = @author.books.create(published_at: Time.now,
+                             book_number: "A12345")
+
+@books = @author.books.create([
+  { published_at: Time.now, book_number: "A12346" },
+  { published_at: Time.now, book_number: "A12347" }
+])
+
+
+
+
4.3.3 collection.create!(attributes = {}) +

作用与 collection.create 相同,但如果记录无效,会抛出 ActiveRecord::RecordInvalid 异常。

4.3.4 has_many 方法的选项

Rails 的默认设置足够智能,能满足多数需求。但有时还是需要定制 has_many 关联的行为。定制的方法很简单,声明关联时传入选项即可。例如,下面的关联使用了两个选项:

+
+class Author < ApplicationRecord
+  has_many :books, dependent: :delete_all, validate: false
+end
+
+
+
+

has_many 关联支持以下选项:

+
    +
  • :as

  • +
  • :autosave

  • +
  • :class_name

  • +
  • :counter_cache

  • +
  • :dependent

  • +
  • :foreign_key

  • +
  • :inverse_of

  • +
  • :primary_key

  • +
  • :source

  • +
  • :source_type

  • +
  • :through

  • +
  • :validate

  • +
+
4.3.4.1 :as +

:as 选项表明这是多态关联。前文已经详细介绍过多态关联。

4.3.4.2 :autosave +

如果把 :autosave 选项设为 true,保存父对象时,会自动保存所有子对象,并把标记为析构的子对象销毁。

4.3.4.3 :class_name +

如果另一个模型无法从关联的名称获取,可以使用 :class_name 选项指定模型名。例如,一位作者有多本图书,但表示图书的模型是 Transaction,那么可以这样声明关联:

+
+class Author < ApplicationRecord
+  has_many :books, class_name: "Transaction"
+end
+
+
+
+
4.3.4.4 :counter_cache +

这个选项用于定制计数缓存列的名称。仅当定制了 belongs_to 关联的 :counter_cache 选项时才需要设定这个选项。

4.3.4.5 :dependent +

设置销毁属主时怎么处理关联的对象:

+
    +
  • :destroy:也销毁所有关联的对象;

  • +
  • :delete_all:直接把所有关联的对象从数据库中删除(不执行回调);

  • +
  • :nullify:把外键设为 NULL,不执行回调;

  • +
  • :restrict_with_exception:有关联的对象时抛出异常;

  • +
  • :restrict_with_error:有关联的对象时,向属主添加一个错误;

  • +
+
4.3.4.6 :foreign_key +

按照约定,另一个模型中用来存储外键的字段名是模型名后加 _id:foreign_key 选项用于设置要使用的外键名:

+
+class Author < ApplicationRecord
+  has_many :books, foreign_key: "cust_id"
+end
+
+
+
+

不管怎样,Rails 都不会自动创建外键字段,你要自己在迁移中创建。

4.3.4.7 :inverse_of +

:inverse_of 选项指定 has_many 关联另一端的 belongs_to 关联名。不能和 :through:as 选项一起使用。

+
+class Author < ApplicationRecord
+  has_many :books, inverse_of: :author
+end
+
+class Book < ApplicationRecord
+  belongs_to :author, inverse_of: :books
+end
+
+
+
+
4.3.4.8 :primary_key +

按照约定,用来存储该模型主键的字段名为 id:primary_key 选项用于设置要使用的主键名。

假设 users 表的主键是 id,但还有一个 guid 列。根据要求,todos 表中应该使用 guid 列作为外键,而不是 id 列。这种需求可以这么实现:

+
+class User < ApplicationRecord
+  has_many :todos, primary_key: :guid
+end
+
+
+
+

如果执行 @todo = @user.todos.create 创建新的待办事项,那么 @todo.user_id 就是 @user 记录中 guid 字段的值。

4.3.4.9 :source +

:source 选项指定 has_many :through 关联的源关联名称。只有无法从关联名中解出源关联的名称时才需要设置这个选项。

4.3.4.10 :source_type +

:source_type 选项指定通过多态关联处理 has_many :through 关联的源关联类型。

4.3.4.11 :through +

:through 选项指定一个联结模型,查询通过它执行。前文说过,has_many :through 关联是实现多对多关联的方式之一。

4.3.4.12 :validate +

如果把 :validate 选项设为 false,保存对象时,不验证关联的对象。该选项的默认值是 true,即保存对象时验证关联的对象。

4.3.5 has_many 的作用域

有时可能需要定制 has_many 关联使用的查询。定制的查询在作用域代码块中指定。例如:

+
+class Author < ApplicationRecord
+  has_many :books, -> { where processed: true }
+end
+
+
+
+

在作用域代码块中可以使用任何一个标准的查询方法。下面介绍其中几个:

+
    +
  • where

  • +
  • extending

  • +
  • group

  • +
  • includes

  • +
  • limit

  • +
  • offset

  • +
  • order

  • +
  • readonly

  • +
  • select

  • +
  • distinct

  • +
+
4.3.5.1 where +

where 方法指定关联的对象必须满足的条件。

+
+class Author < ApplicationRecord
+  has_many :confirmed_books, -> { where "confirmed = 1" },
+                             class_name: "Book"
+end
+
+
+
+

条件还可以使用散列指定:

+
+class Author < ApplicationRecord
+  has_many :confirmed_books, -> { where confirmed: true },
+                             class_name: "Book"
+end
+
+
+
+

如果 where 使用散列形式,通过这个关联创建的记录会自动使用散列中的作用域。针对上面的例子,使用 @author.confirmed_books.create@author.confirmed_books.build 创建图书时,会自动把 confirmed 列的值设为 true

4.3.5.2 extending +

extending 方法指定一个模块名,用于扩展关联代理。后文会详细介绍关联扩展。

4.3.5.3 group +

group 方法指定一个属性名,用在 SQL GROUP BY 子句中,分组查询结果。

+
+class Author < ApplicationRecord
+  has_many :line_items, -> { group 'books.id' },
+                        through: :books
+end
+
+
+
+
4.3.5.4 includes +

includes 方法指定使用关联时要及早加载的间接关联。例如,有如下的模型:

+
+class Author < ApplicationRecord
+  has_many :books
+end
+
+class Book < ApplicationRecord
+  belongs_to :author
+  has_many :line_items
+end
+
+class LineItem < ApplicationRecord
+  belongs_to :book
+end
+
+
+
+

如果经常要直接获取作者购买的商品(@author.books.line_items),可以把商品引入作者和图书的关联中:

+
+class Author < ApplicationRecord
+  has_many :books, -> { includes :line_items }
+end
+
+class Book < ApplicationRecord
+  belongs_to :author
+  has_many :line_items
+end
+
+class LineItem < ApplicationRecord
+  belongs_to :book
+end
+
+
+
+
4.3.5.5 limit +

limit 方法限制通过关联获取的对象数量。

+
+class Author < ApplicationRecord
+  has_many :recent_books,
+    -> { order('published_at desc').limit(100) },
+    class_name: "Book",
+end
+
+
+
+
4.3.5.6 offset +

offset 方法指定通过关联获取对象时的偏移量。例如,-> { offset(11) } 会跳过前 11 个记录。

4.3.5.7 order +

order 方法指定获取关联对象时使用的排序方式,用在 SQL ORDER BY 子句中。

+
+class Author < ApplicationRecord
+  has_many :books, -> { order "date_confirmed DESC" }
+end
+
+
+
+
4.3.5.8 readonly +

如果使用 readonly,通过关联获取的对象是只读的。

4.3.5.9 select +

select 方法用于覆盖检索关联对象数据的 SQL SELECT 子句。默认情况下,Rails 会检索所有列。

如果设置 select 选项,记得要包含主键和关联模型的外键。否则,Rails 会抛出异常。

4.3.5.10 distinct +

使用 distinct 方法可以确保集合中没有重复的对象。与 :through 选项一起使用最有用。

+
+class Person < ApplicationRecord
+  has_many :readings
+  has_many :articles, through: :readings
+end
+
+person = Person.create(name: 'John')
+article   = Article.create(name: 'a1')
+person.articles << article
+person.articles << article
+person.articles.inspect # => [#<Article id: 5, name: "a1">, #<Article id: 5, name: "a1">]
+Reading.all.inspect  # => [#<Reading id: 12, person_id: 5, article_id: 5>, #<Reading id: 13, person_id: 5, article_id: 5>]
+
+
+
+

在上面的代码中,读者读了两篇文章,即使是同一篇文章,person.articles 也会返回两个对象。

下面加入 distinct 方法:

+
+class Person
+  has_many :readings
+  has_many :articles, -> { distinct }, through: :readings
+end
+
+person = Person.create(name: 'Honda')
+article   = Article.create(name: 'a1')
+person.articles << article
+person.articles << article
+person.articles.inspect # => [#<Article id: 7, name: "a1">]
+Reading.all.inspect  # => [#<Reading id: 16, person_id: 7, article_id: 7>, #<Reading id: 17, person_id: 7, article_id: 7>]
+
+
+
+

在这段代码中,读者还是读了两篇文章,但 person.articles 只返回一个对象,因为加载的集合已经去除了重复元素。

如果要确保只把不重复的记录写入关联模型的数据表(这样就不会从数据库中获取重复记录了),需要在数据表上添加唯一性索引。例如,数据表名为 readings,我们要保证其中所有的文章都没重复,可以在迁移中加入以下代码:

+
+add_index :readings, [:person_id, :article_id], unique: true
+
+
+
+

添加唯一性索引之后,尝试为同一个人添加两篇相同的文章会抛出 ActiveRecord::RecordNotUnique 异常:

+
+person = Person.create(name: 'Honda')
+article = Article.create(name: 'a1')
+person.articles << article
+person.articles << article # => ActiveRecord::RecordNotUnique
+
+
+
+

注意,使用 include? 等方法检查唯一性可能导致条件竞争。不要使用 include? 确保关联的唯一性。还是以前面的文章模型为例,下面的代码会导致条件竞争,因为多个用户可能会同时执行这一操作:

+
+person.articles << article unless person.articles.include?(article)
+
+
+
+
4.3.6 什么时候保存对象

把对象赋值给 has_many 关联时,会自动保存对象(因为要更新外键)。如果一次赋值多个对象,所有对象都会自动保存。

如果由于无法通过验证而导致保存失败,赋值语句返回 false,赋值操作会取消。

如果父对象(has_many 关联声明所在的模型)没保存(new_record? 方法返回 true),那么子对象也不会保存。只有保存了父对象,才会保存子对象。

如果赋值给 has_many 关联时不想保存对象,使用 collection.build 方法。

4.4 has_and_belongs_to_many 关联详解

has_and_belongs_to_many 关联建立两个模型之间的多对多关系。用数据库术语来说,这种关联的意思是有个联结表包含指向这两个类的外键。

4.4.1 has_and_belongs_to_many 关联添加的方法

声明 has_and_belongs_to_many 关联后,声明所在的类自动获得了 16 个关联相关的方法:

+
    +
  • collection

  • +
  • collection<<(object, …​)

  • +
  • collection.delete(object, …​)

  • +
  • collection.destroy(object, …​)

  • +
  • collection=(objects)

  • +
  • collection_singular_ids

  • +
  • collection_singular_ids=(ids)

  • +
  • collection.clear

  • +
  • collection.empty?

  • +
  • collection.size

  • +
  • collection.find(…​)

  • +
  • collection.where(…​)

  • +
  • collection.exists?(…​)

  • +
  • collection.build(attributes = {})

  • +
  • collection.create(attributes = {})

  • +
  • collection.create!(attributes = {})

  • +
+

这些个方法中的 collection 要替换成传给 has_and_belongs_to_many 方法的第一个参数。collection_singular 要替换成第一个参数的单数形式。对如下的声明来说:

+
+class Part < ApplicationRecord
+  has_and_belongs_to_many :assemblies
+end
+
+
+
+

每个 Part 模型实例都获得了这些方法:

+
+assemblies
+assemblies<<(object, ...)
+assemblies.delete(object, ...)
+assemblies.destroy(object, ...)
+assemblies=(objects)
+assembly_ids
+assembly_ids=(ids)
+assemblies.clear
+assemblies.empty?
+assemblies.size
+assemblies.find(...)
+assemblies.where(...)
+assemblies.exists?(...)
+assemblies.build(attributes = {}, ...)
+assemblies.create(attributes = {})
+assemblies.create!(attributes = {})
+
+
+
+
4.4.1.1 额外的列方法

如果 has_and_belongs_to_many 关联使用的联结表中,除了两个外键之外还有其他列,通过关联获取的记录中会包含这些列,但是只读的,因为 Rails 不知道如何保存对这些列的改动。

has_and_belongs_to_many 关联的联结表中使用其他字段的功能已经废弃。如果在多对多关联中需要使用这么复杂的数据表,应该用 has_many :through 关联代替 has_and_belongs_to_many 关联。

4.4.1.2 collection +

collection 方法返回一个数组,包含所有关联的对象。如果没有关联的对象,则返回空数组。

+
+@assemblies = @part.assemblies
+
+
+
+
4.4.1.3 collection<<(object, …​) +

collection<< 方法向集合中添加一个或多个对象,并在联结表中创建相应的记录。

+
+@part.assemblies << @assembly1
+
+
+
+

这个方法是 collection.concatcollection.push 的别名。

4.4.1.4 collection.delete(object, …​) +

collection.delete 方法从集合中删除一个或多个对象,并删除联结表中相应的记录,但是不会销毁对象。

+
+@part.assemblies.delete(@assembly1)
+
+
+
+

这个方法不会触发联结记录上的回调。

4.4.1.5 collection.destroy(object, …​) +

collection.destroy 方法在联结表中的记录上调用 destroy 方法,从集合中删除一个或多个对象,还会触发回调。这个方法不会销毁对象本身。

+
+@part.assemblies.destroy(@assembly1)
+
+
+
+
4.4.1.6 collection=(objects) +

collection= 方法让集合只包含指定的对象,根据需求会添加或删除对象。

4.4.1.7 collection_singular_ids +

collection_singular_ids 方法返回一个数组,包含集合中各对象的 ID。

+
+@assembly_ids = @part.assembly_ids
+
+
+
+
4.4.1.8 collection_singular_ids=(ids) +

collection_singular_ids= 方法让集合中只包含指定的主键,根据需要会增删 ID。

4.4.1.9 collection.clear +

collection.clear 方法删除集合中的所有对象,并把联结表中的相应记录删除。这个方法不会销毁关联的对象。

4.4.1.10 collection.empty? +

如果集合中没有任何关联的对象,collection.empty? 方法返回 true

+
+<% if @part.assemblies.empty? %>
+  This part is not used in any assemblies
+<% end %>
+
+
+
+
4.4.1.11 collection.size +

collection.size 方法返回集合中的对象数量。

+
+@assembly_count = @part.assemblies.size
+
+
+
+
4.4.1.12 collection.find(…​) +

collection.find 方法在集合中查找对象,使用的句法和选项跟 ActiveRecord::Base.find 方法一样。此外还限制对象必须在集合中。

+
+@assembly = @part.assemblies.find(1)
+
+
+
+
4.4.1.13 collection.where(…​) +

collection.where 方法根据指定的条件在集合中查找对象,但对象是惰性加载的,访问对象时才执行查询。此外还限制对象必须在集合中。

+
+@new_assemblies = @part.assemblies.where("created_at > ?", 2.days.ago)
+
+
+
+
4.4.1.14 collection.exists?(…​) +

collection.exists? 方法根据指定的条件检查集合中是否有符合条件的对象,使用的句法和选项跟 ActiveRecord::Base.exists? 方法一样。

4.4.1.15 collection.build(attributes = {}) +

collection.build 方法返回一个此种关联类型的新对象。这个对象会使用传入的属性初始化,还会在联结表中创建对应的记录,但不会保存关联的对象。

+
+@assembly = @part.assemblies.build({assembly_name: "Transmission housing"})
+
+
+
+
4.4.1.16 collection.create(attributes = {}) +

collection.create 方法返回一个此种关联类型的新对象。这个对象会使用传入的属性初始化,还会在联结表中创建对应的记录,只要能通过所有数据验证,就保存关联对象。

+
+@assembly = @part.assemblies.create({assembly_name: "Transmission housing"})
+
+
+
+
4.4.1.17 collection.create!(attributes = {}) +

作用和 collection.create 相同,但如果记录无效,会抛出 ActiveRecord::RecordInvalid 异常。

4.4.2 has_and_belongs_to_many 方法的选项

Rails 的默认设置足够智能,能满足多数需求。但有时还是需要定制 has_and_belongs_to_many 关联的行为。定制的方法很简单,声明关联时传入选项即可。例如,下面的关联使用了两个选项:

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies, -> { readonly },
+                                       autosave: true
+end
+
+
+
+

has_and_belongs_to_many 关联支持以下选项:

+
    +
  • :association_foreign_key

  • +
  • :autosave

  • +
  • :class_name

  • +
  • :foreign_key

  • +
  • :join_table

  • +
  • :validate

  • +
+
4.4.2.1 :association_foreign_key +

按照约定,在联结表中用来指向另一个模型的外键名是模型名后加 _id:association_foreign_key 选项用于设置要使用的外键名:

:foreign_key:association_foreign_key 这两个选项在设置多对多自联结时很有用。例如:

+
+
+
+class User < ApplicationRecord
+  has_and_belongs_to_many :friends,
+      class_name: "User",
+      foreign_key: "this_user_id",
+      association_foreign_key: "other_user_id"
+end
+
+
+
+
+
4.4.2.2 :autosave +

如果把 :autosave 选项设为 true,保存父对象时,会自动保存所有子对象,并把标记为析构的子对象销毁。

4.4.2.3 :class_name +

如果另一个模型无法从关联的名称获取,可以使用 :class_name 选项指定。例如,一个部件由多个装配件组成,但表示装配件的模型是 Gadget,那么可以这样声明关联:

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies, class_name: "Gadget"
+end
+
+
+
+
4.4.2.4 :foreign_key +

按照约定,在联结表中用来指向模型的外键名是模型名后加 _id:foreign_key 选项用于设置要使用的外键名:

+
+class User < ApplicationRecord
+  has_and_belongs_to_many :friends,
+      class_name: "User",
+      foreign_key: "this_user_id",
+      association_foreign_key: "other_user_id"
+end
+
+
+
+
4.4.2.5 :join_table +

如果默认按照字典顺序生成的联结表名不能满足要求,可以使用 :join_table 选项指定。

4.4.2.6 :validate +

如果把 :validate 选项设为 false,保存对象时,不会验证关联的对象。该选项的默认值是 true,即保存对象时验证关联的对象。

4.4.3 has_and_belongs_to_many 的作用域

有时可能需要定制 has_and_belongs_to_many 关联使用的查询。定制的查询在作用域代码块中指定。例如:

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies, -> { where active: true }
+end
+
+
+
+

在作用域代码块中可以使用任何一个标准的查询方法。下面分别介绍其中几个:

+
    +
  • where

  • +
  • extending

  • +
  • group

  • +
  • includes

  • +
  • limit

  • +
  • offset

  • +
  • order

  • +
  • readonly

  • +
  • select

  • +
  • distinct

  • +
+
4.4.3.1 where +

where 方法指定关联的对象必须满足的条件。

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies,
+    -> { where "factory = 'Seattle'" }
+end
+
+
+
+

条件还可以使用散列指定:

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies,
+    -> { where factory: 'Seattle' }
+end
+
+
+
+

如果 where 使用散列形式,通过这个关联创建的记录会自动使用散列中的作用域。针对上面的例子,使用 @parts.assemblies.create@parts.assemblies.build 创建订单时,会自动把 factory 字段的值设为 "Seattle"

4.4.3.2 extending +

extending 方法指定一个模块名,用来扩展关联代理。后文会详细介绍关联扩展。

4.4.3.3 group +

group 方法指定一个属性名,用在 SQL GROUP BY 子句中,分组查询结果。

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies, -> { group "factory" }
+end
+
+
+
+
4.4.3.4 includes +

includes 方法指定使用关联时要及早加载的间接关联。

4.4.3.5 limit +

limit 方法限制通过关联获取的对象数量。

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies,
+    -> { order("created_at DESC").limit(50) }
+end
+
+
+
+
4.4.3.6 offset +

offset 方法指定通过关联获取对象时的偏移量。例如,-> { offset(11) } 会跳过前 11 个记录。

4.4.3.7 order +

order 方法指定获取关联对象时使用的排序方式,用在 SQL ORDER BY 子句中。

+
+class Parts < ApplicationRecord
+  has_and_belongs_to_many :assemblies,
+    -> { order "assembly_name ASC" }
+end
+
+
+
+
4.4.3.8 readonly +

如果使用 readonly,通过关联获取的对象是只读的。

4.4.3.9 select +

select 方法用于覆盖检索关联对象数据的 SQL SELECT 子句。默认情况下,Rails 检索所有列。

4.4.3.10 distinct +

distinct 方法用于删除集合中重复的对象。

4.4.4 什么时候保存对象

把对象赋值给 has_and_belongs_to_many 关联时,会自动保存对象(因为要更新外键)。如果一次赋值多个对象,所有对象都会自动保存。

如果由于无法通过验证而导致保存失败,赋值语句返回 false,赋值操作会取消。

如果父对象(has_and_belongs_to_many 关联声明所在的模型)没保存(new_record? 方法返回 true),那么子对象也不会保存。只有保存了父对象,才会保存子对象。

如果赋值给 has_and_belongs_to_many 关联时不想保存对象,使用 collection.build 方法。

4.5 关联回调

普通回调会介入 Active Record 对象的生命周期,在多个时刻处理对象。例如,可以使用 :before_save 回调在保存对象之前处理对象。

关联回调和普通回调差不多,只不过由集合生命周期中的事件触发。关联回调有四种:

+
    +
  • before_add

  • +
  • after_add

  • +
  • before_remove

  • +
  • after_remove

  • +
+

关联回调在声明关联时定义。例如:

+
+class Author < ApplicationRecord
+  has_many :books, before_add: :check_credit_limit
+
+  def check_credit_limit(book)
+    ...
+  end
+end
+
+
+
+

Rails 会把要添加或删除的对象传入回调。

同一事件可以触发多个回调,多个回调使用数组指定:

+
+class Author < ApplicationRecord
+  has_many :books,
+    before_add: [:check_credit_limit, :calculate_shipping_charges]
+
+  def check_credit_limit(book)
+    ...
+  end
+
+  def calculate_shipping_charges(book)
+    ...
+  end
+end
+
+
+
+

如果 before_add 回调抛出异常,不会把对象添加到集合中。类似地,如果 before_remove 抛出异常,对象不会从集合中删除。

4.6 关联扩展

Rails 基于关联代理对象自动创建的功能是死的,可以通过匿名模块、新的查找方法、创建对象的方法等进行扩展。例如:

+
+class Author < ApplicationRecord
+  has_many :books do
+    def find_by_book_prefix(book_number)
+      find_by(category_id: book_number[0..2])
+    end
+  end
+end
+
+
+
+

如果扩展要在多个关联中使用,可以将其写入具名扩展模块。例如:

+
+module FindRecentExtension
+  def find_recent
+    where("created_at > ?", 5.days.ago)
+  end
+end
+
+class Author < ApplicationRecord
+  has_many :books, -> { extending FindRecentExtension }
+end
+
+class Supplier < ApplicationRecord
+  has_many :deliveries, -> { extending FindRecentExtension }
+end
+
+
+
+

在扩展中可以使用如下 proxy_association 方法的三个属性获取关联代理的内部信息:

+
    +
  • proxy_association.owner:返回关联所属的对象;

  • +
  • proxy_association.reflection:返回描述关联的反射对象;

  • +
  • proxy_association.target:返回 belongs_tohas_one 关联的关联对象,或者 has_manyhas_and_belongs_to_many 关联的关联对象集合;

  • +
+

5 单表继承

有时可能想在不同的模型中共用相同的字段和行为。假如有 Car、Motorcycle 和 Bicycle 三个模型,我们想在它们中共用 colorprice 字段,但是各自的具体行为不同,而且使用不同的控制器。

在 Rails 中实现这一需求非常简单。首先,生成基模型 Vehicle:

+
+$ rails generate model vehicle type:string color:string price:decimal{10.2}
+
+
+
+

注意到了吗,我们添加了一个“type”字段?既然所有模型都保存在这一个数据库表中,Rails 会把保存的模型名存储在这一列中。对这个例子来说,“type”字段的值可能是“Car”、“Motorcycle”或“Bicycle”。如果表中没有“type”字段,单表继承无法工作。

然后,生成三个模型,都继承自 Vehicle。为此,可以使用 parent=PARENT 选项。这样,生成的模型继承指定的父模型,而且不生成对应的迁移(因为表已经存在)。

例如,生成 Car 模型的命令是:

+
+$ rails generate model car --parent=Vehicle
+
+
+
+

生成的模型如下:

+
+class Car < Vehicle
+end
+
+
+
+

这意味着,添加到 Vehicle 中的所有行为在 Car 中都可用,例如关联、公开方法,等等。

创建一辆汽车,相应的记录保存在 vehicles 表中,而且 type 字段的值是“Car”:

+
+Car.create(color: 'Red', price: 10000)
+
+
+
+

对应的 SQL 如下:

+
+INSERT INTO "vehicles" ("type", "color", "price") VALUES ('Car', 'Red', 10000)
+
+
+
+

查询汽车记录时只会搜索此类车辆:

+
+Car.all
+
+
+
+

执行的查询如下:

+
+SELECT "vehicles".* FROM "vehicles" WHERE "vehicles"."type" IN ('Car')
+
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/autoloading_and_reloading_constants.html b/autoloading_and_reloading_constants.html new file mode 100644 index 0000000..a6087eb --- /dev/null +++ b/autoloading_and_reloading_constants.html @@ -0,0 +1,1000 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

自动加载和重新加载常量

本文说明常量自动加载和重新加载机制。

读完本文后,您将学到:

+
    +
  • Ruby 常量的关键知识;

  • +
  • autoload_paths 是什么;

  • +
  • 常量是如何自动加载的;

  • +
  • require_dependency 是什么;

  • +
  • 常量是如何重新加载的;

  • +
  • 自动加载常见问题的解决方案。

  • +
+

1 简介

编写 Ruby on Rails 应用时,代码会预加载。

在常规的 Ruby 程序中,类需要加载依赖:

+
+require 'application_controller'
+require 'post'
+
+class PostsController < ApplicationController
+  def index
+    @posts = Post.all
+  end
+end
+
+
+
+

Ruby 程序员的直觉立即就能发现这样做有冗余:如果类定义所在的文件与类名一致,难道不能通过某种方式自动加载吗?我们无需扫描文件寻找依赖,这样不可靠。

而且,Kernel#require 只加载文件一次,如果修改后无需重启服务器,那么开发的过程就更为平顺。如果能在开发环境中使用 Kernel#load,而在生产环境使用 Kernel#require,那该多好。

其实,Ruby on Rails 就有这样的功能,我们刚才已经用到了:

+
+class PostsController < ApplicationController
+  def index
+    @posts = Post.all
+  end
+end
+
+
+
+

本文说明这一机制的运作原理。

2 常量刷新程序

在多数编程语言中,常量不是那么重要,但在 Ruby 中却是一个内容丰富的话题。

本文不会详解 Ruby 常量,但是会重点说明关键的概念。掌握以下几小节的内容对理解常量自动加载和重新加载有所帮助。

2.1 嵌套

类和模块定义可以嵌套,从而创建命名空间:

+
+module XML
+  class SAXParser
+    # (1)
+  end
+end
+
+
+
+

类和模块的嵌套由内向外展开。嵌套可以通过 Module.nesting 方法审查。例如,在上述示例中,(1) 处的嵌套是

+
+[XML::SAXParser, XML]
+
+
+
+

注意,组成嵌套的是类和模块“对象”,而不是访问它们的常量,与它们的名称也没有关系。

例如,对下面的定义来说

+
+class XML::SAXParser
+  # (2)
+end
+
+
+
+

虽然作用跟前一个示例类似,但是 (2) 处的嵌套是

+
+[XML::SAXParser]
+
+
+
+

不含“XML”。

从这个示例可以看出,嵌套中的类或模块的名称与所在的命名空间没有必然联系。

事实上,二者毫无关系。比如说:

+
+module X
+  module Y
+  end
+end
+
+module A
+  module B
+  end
+end
+
+module X::Y
+  module A::B
+    # (3)
+  end
+end
+
+
+
+

(3) 处的嵌套包含两个模块对象:

+
+[A::B, X::Y]
+
+
+
+

可以看出,嵌套的最后不是“A”,甚至不含“A”,但是包含 X::Y,而且它与 A::B 无关。

嵌套是解释器维护的一个内部堆栈,根据下述规则修改:

+
    +
  • 执行 class 关键字后面的定义体时,类对象入栈;执行完毕后出栈。

  • +
  • 执行 module 关键字后面的定义体时,模块对象入栈;执行完毕后出栈。

  • +
  • 执行 class << object 打开的单例类时,类对象入栈;执行完毕后出栈。

  • +
  • 调用 instance_eval 时如果传入字符串参数,接收者的单例类入栈求值的代码所在的嵌套层次。调用 class_evalmodule_eval 时如果传入字符串参数,接收者入栈求值的代码所在的嵌套层次.

  • +
  • 顶层代码中由 Kernel#load 解释嵌套是空的,除非调用 load 时把第二个参数设为真值;如果是这样,Ruby 会创建一个匿名模块,将其入栈。

  • +
+

注意,块不会修改嵌套堆栈。尤其要注意的是,传给 Class.newModule.new 的块不会导致定义的类或模块入栈嵌套堆栈。由此可见,以不同的方式定义类和模块,达到的效果是有区别的。

2.2 定义类和模块是为常量赋值

假设下面的代码片段是定义一个类(而不是打开类):

+
+class C
+end
+
+
+
+

Ruby 在 Object 中创建一个变量 C,并将一个类对象存储在 C 常量中。这个类实例的名称是“C”,一个字符串,跟常量名一样。

如下的代码:

+
+class Project < ApplicationRecord
+end
+
+
+
+

这段代码执行的操作等效于下述常量赋值:

+
+Project = Class.new(ApplicationRecord)
+
+
+
+

而且有个副作用——设定类的名称:

+
+Project.name # => "Project"
+
+
+
+

这得益于常量赋值的一条特殊规则:如果被赋值的对象是匿名类或模块,Ruby 会把对象的名称设为常量的名称。

自此之后常量和实例发生的事情无关紧要。例如,可以把常量删除,类对象可以赋值给其他常量,或者不再存储于常量中,等等。名称一旦设定就不会再变。

类似地,模块使用 module 关键字创建,如下所示:

+
+module Admin
+end
+
+
+
+

这段代码执行的操作等效于下述常量赋值:

+
+Admin = Module.new
+
+
+
+

而且有个副作用——设定模块的名称:

+
+Admin.name # => "Admin"
+
+
+
+

传给 Class.newModule.new 的块与 classmodule 关键字的定义体不在完全相同的上下文中执行。但是两种方式得到的结果都是为常量赋值。

因此,当人们说“String 类”的时候,真正指的是 Object 常量中存储的一个类对象,它存储着常量“String”中存储的一个类对象。而 String 是一个普通的 Ruby 常量,与常量有关的一切,例如解析算法,在 String 常量上都适用。

同样地,在下述控制器中

+
+class PostsController < ApplicationController
+  def index
+    @posts = Post.all
+  end
+end
+
+
+
+

Post 不是调用类的句法,而是一个常规的 Ruby 常量。如果一切正常,这个常量的求值结果是一个能响应 all 方法的对象。

因此,我们讨论的话题才是“常量”自动加载。Rails 提供了自动加载常量的功能。

2.3 常量存储在模块中

按字面意义理解,常量属于模块。类和模块有常量表,你可以将其理解为哈希表。

下面通过一个示例来理解。通常我们都说“String 类”,这样方面,下面的阐述只是为了讲解原理。

我们来看看下述模块定义:

+
+module Colors
+  RED = '0xff0000'
+end
+
+
+
+

首先,处理 module 关键字时,解释器会在 Object 常量存储的类对象的常量表中新建一个条目。这个条目把“Colors”与一个新建的模块对象关联起来。而且,解释器把那个新建的模块对象的名称设为字符串“Colors”。

随后,解释模块的定义体时,会在 Colors 常量中存储的模块对象的常量表中新建一个条目。那个条目把“RED”映射到字符串“0xff0000”上。

注意,Colors::RED 与其他类或模块对象中的 RED 常量完全没有关系。如果存在这样一个常量,它在相应的常量表中,是不同的条目。

在前述各段中,尤其要注意类和模块对象、常量名称,以及常量表中与之关联的值对象之间的区别。

2.4 解析算法

2.4.1 相对常量的解析算法

在代码中的特定位置,假如使用 cref 表示嵌套中的第一个元素,如果没有嵌套,则表示 Object

简单来说,相对常量(relative constant)引用的解析算法如下:

+
    +
  1. 如果嵌套不为空,在嵌套中按元素顺序查找常量。元素的祖先忽略不计。

  2. +
  3. 如果未找到,算法向上,进入 cref 的祖先链。

  4. +
  5. 如果未找到,而且 cref 是个模块,在 Object 中查找常量。

  6. +
  7. 如果未找到,在 cref 上调用 const_missing 方法。这个方法的默认行为是抛出 NameError 异常,不过可以覆盖。

  8. +
+

Rails 的自动加载机制没有仿照这个算法,查找的起点是要自动加载的常量名称,即 cref。详情参见 相对引用

2.4.2 限定常量的解析算法

限定常量(qualified constant)指下面这种:

+
+Billing::Invoice
+
+
+
+

Billing::Invoice 由两个常量组成,其中 Billing 是相对常量,使用前一节所属的算法解析。

在开头加上两个冒号可以把第一部分的相对常量变成绝对常量,例如 ::Billing::Invoice。此时,Billing 作为顶层常量查找。

InvoiceBilling 限定,下面说明它是如何解析的。假定 parent 是限定的类或模块对象,即上例中的 Billing。限定常量的解析算法如下:

+
    +
  1. 在 parent 及其祖先中查找常量。

  2. +
  3. 如果未找到,调用 parent 的 const_missing 方法。这个方法的默认行为是抛出 NameError 异常,不过可以覆盖。

  4. +
+

可以看出,这个算法比相对常量的解析算法简单。毕竟这里不涉及嵌套,而且模块也不是特殊情况,如果二者及其祖先中都找不到常量,不会再查看 Object

Rails 的自动加载机制没有仿照这个算法,查找的起点是要自动加载的常量名称和 parent。详情参见 限定引用

3 词汇表

3.1 父级命名空间

给定常量路径字符串,父级命名空间是把最右边那一部分去掉后余下的字符串。

例如,字符串“A::B::C”的父级命名空间是字符串“A::B”,“A::B”的父级命名空间是“A”,“A”的父级命名空间是“”(空)。

不过涉及类和模块的父级命名空间解释有点复杂。假设有个名为“A::B”的模块 M:

+
    +
  • 父级命名空间 “A” 在给定位置可能反应不出嵌套。

  • +
  • 某处代码可能把常量 AObject 中删除了,导致常量 A 不存在。

  • +
  • 如果 A 存在,A 中原来有的类或模块可能不再存在。例如,把一个常量删除后再赋值另一个常量,那么存在的可能就不是同一个对象。

  • +
  • 这种情形中,重新赋值的 A 可能是一个名为“A”的新类或模块。

  • +
  • 在上述情况下,无法再通过 A::B 访问 M,但是模块对象本身可以继续存活于某处,而且名称依然是“A::B”。

  • +
+

父级命名空间这个概念是自动加载算法的核心,有助于以直观的方式解释和理解算法,但是并不严谨。由于有边缘情况,本文所说的“父级命名空间”真正指的是具体的字符串来源。

3.2 加载机制

如果 config.cache_classes 的值是 false(开发环境的默认值),Rails 使用 Kernel#load 自动加载文件,否则使用 Kernel#require 自动加载文件(生产环境的默认值)。

如果启用了常量重新加载,Rails 通过 Kernel#load 多次执行相同的文件。

本文使用的“加载”是指解释指定的文件,但是具体使用 Kernel#load 还是 Kernel#require,取决于配置。

4 自动加载可用性

只要环境允许,Rails 始终会自动加载。例如,runner 命令会自动加载:

+
+$ bin/rails runner 'p User.column_names'
+["id", "email", "created_at", "updated_at"]
+
+
+
+

控制台会自动加载,测试组件会自动加载,当然,应用也会自动加载。

默认情况下,在生产环境中,Rails 启动时会及早加载应用文件,因此开发环境中的多数自动加载行为不会发生。但是在及早加载的过程中仍然可能会触发自动加载。

例如:

+
+class BeachHouse < House
+end
+
+
+
+

如果及早加载 app/models/beach_house.rb 文件之后,House 尚不可知,Rails 会自动加载它。

5 autoload_paths +

或许你已经知道,使用 require 引入相对文件名时,例如

+
+require 'erb'
+
+
+
+

Ruby 在 $LOAD_PATH 中列出的目录里寻找文件。即,Ruby 迭代那些目录,检查其中有没有名为“erb.rb”“erb.so”“erb.o”或“erb.dll”的文件。如果在某个目录中找到了,解释器加载那个文件,搜索结束。否则,继续在后面的目录中寻找。如果最后没有找到,抛出 LoadError 异常。

后面会详述常量自动加载机制,不过整体思路是,遇到未知的常量时,如 Post,假如 app/models 目录中存在 post.rb 文件,Rails 会找到它,执行它,从而定义 Post 常量。

好吧,其实 Rails 会在一系列目录中查找 post.rb,有点类似于 $LOAD_PATH。那一系列目录叫做 autoload_paths,默认包含:

+
    +
  • 应用和启动时存在的引擎的 app 目录中的全部子目录。例如,app/controllers。这些子目录不一定是默认的,可以是任何自定义的目录,如 app/workersapp 目录中的全部子目录都自动纳入 autoload_paths

  • +
  • 应用和引擎中名为 app/*/concerns 的二级目录。

  • +
  • test/mailers/previews 目录。

  • +
+

此外,这些目录可以使用 config.autoload_paths 配置。例如,以前 lib 在这一系列目录中,但是现在不在了。应用可以在 config/application.rb 文件中添加下述配置,将其纳入其中:

+
+config.autoload_paths << "#{Rails.root}/lib"
+
+
+
+

在各个环境的配置文件中不能配置 config.autoload_paths

autoload_paths 的值可以审查。在新创建的应用中,它的值是(经过编辑):

+
+$ bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths'
+.../app/assets
+.../app/controllers
+.../app/helpers
+.../app/mailers
+.../app/models
+.../app/controllers/concerns
+.../app/models/concerns
+.../test/mailers/previews
+
+
+
+

autoload_paths 在初始化过程中计算并缓存。目录结构发生变化时,要重启服务器。

6 自动加载算法

6.1 相对引用

相对常量引用可在多处出现,例如:

+
+class PostsController < ApplicationController
+  def index
+    @posts = Post.all
+  end
+end
+
+
+
+

这里的三个常量都是相对引用。

6.1.1 classmodule 关键字后面的常量

Ruby 程序会查找 classmodule 关键字后面的常量,因为要知道是定义类或模块,还是再次打开。

如果常量不被认为是缺失的,不会定义常量,也不会触发自动加载。

因此,在上述示例中,解释那个文件时,如果 PostsController 未定义,Rails 不会触发自动加载机制,而是由 Ruby 定义那个控制器。

6.1.2 顶层常量

相对地,如果 ApplicationController 是未知的,会被认为是缺失的,Rails 会尝试自动加载。

为了加载 ApplicationController,Rails 会迭代 autoload_paths。首先,检查 app/assets/application_controller.rb 文件是否存在,如果不存在(通常如此),再检查 app/controllers/application_controller.rb 是否存在。

如果那个文件定义了 ApplicationController 常量,那就没事,否则抛出 LoadError 异常:

+
+unable to autoload constant ApplicationController, expected
+<full path to application_controller.rb> to define it (LoadError)
+
+
+
+

Rails 不要求自动加载的常量是类或模块对象。假如在 app/models/max_clients.rb 文件中定义了 MAX_CLIENTS = 100,Rails 也能自动加载 MAX_CLIENTS

6.1.3 命名空间

自动加载 ApplicationController 时直接检查 autoload_paths 里的目录,因为它没有嵌套。Post 就不同了,那一行的嵌套是 [PostsController],此时就会使用涉及命名空间的算法。

对下述代码来说:

+
+module Admin
+  class BaseController < ApplicationController
+    @@all_roles = Role.all
+  end
+end
+
+
+
+

为了自动加载 Role,要分别检查当前或父级命名空间中有没有定义 Role。因此,从概念上讲,要按顺序尝试自动加载下述常量:

+
+Admin::BaseController::Role
+Admin::Role
+Role
+
+
+
+

为此,Rails 在 autoload_paths 中分别查找下述文件名:

+
+admin/base_controller/role.rb
+admin/role.rb
+role.rb
+
+
+
+

此外还会查找一些其他目录,稍后说明。

不含扩展名的相对文件路径通过 'Constant::Name'.underscore 得到,其中 Constant::Name 是已定义的常量。

假设 app/models/post.rb 文件中定义了 Post 模型,下面说明 Rails 是如何自动加载 PostsController 中的 Post 常量的。

首先,在 autoload_paths 中查找 posts_controller/post.rb

+
+app/assets/posts_controller/post.rb
+app/controllers/posts_controller/post.rb
+app/helpers/posts_controller/post.rb
+...
+test/mailers/previews/posts_controller/post.rb
+
+
+
+

最后并未找到,因此会寻找一个类似的目录,下一节说明原因:

+
+app/assets/posts_controller/post
+app/controllers/posts_controller/post
+app/helpers/posts_controller/post
+...
+test/mailers/previews/posts_controller/post
+
+
+
+

如果也未找到这样一个目录,Rails 会在父级命名空间中再次查找。对 Post 来说,只剩下顶层命名空间了:

+
+app/assets/post.rb
+app/controllers/post.rb
+app/helpers/post.rb
+app/mailers/post.rb
+app/models/post.rb
+
+
+
+

这一次找到了 app/models/post.rb 文件。查找停止,加载那个文件。如果那个文件中定义了 Post,那就没问题,否则抛出 LoadError 异常。

6.2 限定引用

如果缺失限定常量,Rails 不会在父级命名空间中查找。但是有一点要留意:缺失常量时,Rails 不知道它是相对引用还是限定引用。

例如:

+
+module Admin
+  User
+end
+
+
+
+

+
+Admin::User
+
+
+
+

如果 User 缺失,在上述两种情况中 Rails 只知道缺失的是“Admin”模块中一个名为“User”的常量。

如果 User 是顶层常量,对前者来说,Ruby 会解析,但是后者不会。一般来说,Rails 解析常量的算法与 Ruby 不同,但是此时,Rails 尝试使用下述方式处理:

+
+

如果类或模块的父级命名空间中没有缺失的常量,Rails 假定引用的是相对常量。否则是限定常量。

+
+

例如,如果下述代码触发自动加载

+
+Admin::User
+
+
+
+

那么,Object 中已经存在 User 常量。但是下述代码不会触发自动加载

+
+module Admin
+  User
+end
+
+
+
+

如若不然,Ruby 就能解析出 User,也就无需自动加载了。因此,Rails 假定它是限定引用,只会在 admin/user.rb 文件和 admin/user 目录中查找。

其实,只要嵌套匹配全部父级命名空间,而且彼时适用这一规则的常量已知,这种机制便能良好运行。

然而,自动加载是按需执行的。如果碰巧顶层 User 尚未加载,那么 Rails 就假定它是相对引用。

在实际使用中,这种命名冲突很少发生。如果发生,require_dependency 提供了解决方案:确保做前述引文中的试探时,在有冲突的地方定义了常量。

6.3 自动模块

把模块作为命名空间使用时,Rails 不要求应用为之定义一个文件,有匹配命名空间的目录就够了。

假设应用有个后台,相关的控制器存储在 app/controllers/admin 目录中。遇到 Admin::UsersController 时,如果 Admin 模块尚未加载,Rails 要先自动加载 Admin 常量。

如果 autoload_paths 中有个名为 admin.rb 的文件,Rails 会加载那个文件。如果没有这么一个文件,而且存在名为 admin 的目录,Rails 会创建一个空模块,自动将其赋值给 Admin 常量。

6.4 一般步骤

相对引用在 cref 中报告缺失,限定引用在 parent 中报告缺失(cref 的指代参见 相对常量的解析算法开头,parent 的指代参见 限定常量的解析算法开头)。

在任意的情况下,自动加载常量 C 的步骤如下:

+
+if the class or module in which C is missing is Object
+  let ns = ''
+else
+  let M = the class or module in which C is missing
+
+  if M is anonymous
+    let ns = ''
+  else
+    let ns = M.name
+  end
+end
+
+loop do
+  # 查找特定的文件
+  for dir in autoload_paths
+    if the file "#{dir}/#{ns.underscore}/c.rb" exists
+      load/require "#{dir}/#{ns.underscore}/c.rb"
+
+      if C is now defined
+        return
+      else
+        raise LoadError
+      end
+    end
+  end
+
+  # 查找自动模块
+  for dir in autoload_paths
+    if the directory "#{dir}/#{ns.underscore}/c" exists
+      if ns is an empty string
+        let C = Module.new in Object and return
+      else
+        let C = Module.new in ns.constantize and return
+      end
+    end
+  end
+
+  if ns is empty
+    # 到顶层了,还未找到常量
+    raise NameError
+  else
+    if C exists in any of the parent namespaces
+      # 以限定常量试探
+      raise NameError
+    else
+      # 在父级命名空间中再试一次
+      let ns = the parent namespace of ns and retry
+    end
+  end
+end
+
+
+
+

7 require_dependency +

常量自动加载按需触发,因此使用特定常量的代码可能已经定义了常量,或者触发自动加载。具体情况取决于执行路径,二者之间可能有较大差异。

然而,有时执行到某部分代码时想确保特定常量是已知的。require_dependency 为此提供了一种方式。它使用目前的加载机制加载文件,而且会记录文件中定义的常量,就像是自动加载的一样,而且会按需重新加载。

require_dependency 很少需要使用,不过 自动加载和 STI常量未缺失有几个用例。

与自动加载不同,require_dependency 不期望文件中定义任何特定的常量。但是利用这种行为不好,文件和常量路径应该匹配。

8 常量重新加载

config.cache_classes 设为 false 时,Rails 会重新自动加载常量。

例如,在控制台会话中编辑文件之后,可以使用 reload! 命令重新加载代码:

+
+> reload!
+
+
+
+

在应用运行的过程中,如果相关的逻辑有变,会重新加载代码。为此,Rails 会监控下述文件:

+
    +
  • config/routes.rb

  • +
  • 本地化文件

  • +
  • autoload_paths 中的 Ruby 文件

  • +
  • db/schema.rbdb/structure.sql

  • +
+

如果这些文件中的内容有变,有个中间件会发现,然后重新加载代码。

自动加载机制会记录自动加载的常量。重新加载机制使用 Module#remove_const 方法把它们从相应的类和模块中删除。这样,运行代码时那些常量就变成未知了,从而按需重新加载文件。

这是一个极端操作,Rails 重新加载的不只是那些有变化的代码,因为类之间的依赖极难处理。相反,Rails 重新加载一切。

9 Module#autoload 不涉其中

Module#autoload 提供的是惰性加载常量方式,深置于 Ruby 的常量查找算法、动态常量 API,等等。这一机制相当简单。

Rails 内部在加载过程中大量采用这种方式,尽量减少工作量。但是,Rails 的常量自动加载机制不是使用 Module#autoload 实现的。

如果基于 Module#autoload 实现,可以遍历应用树,调用 autoload 把文件名和常规的常量名对应起来。

Rails 不采用这种实现方式有几个原因。

例如,Module#autoload 只能使用 require 加载文件,因此无法重新加载。不仅如此,它使用的是 require 关键字,而不是 Kernel#require 方法。

因此,删除文件后,它无法移除声明。如果使用 Module#remove_const 把常量删除了,不会触发 Module#autoload。此外,它不支持限定名称,因此有命名空间的文件要在遍历树时解析,这样才能调用相应的 autoload 方法,但是那些文件中可能有尚未配置的常量引用。

基于 Module#autoload 的实现很棒,但是如你所见,目前还不可能。Rails 的常量自动加载机制使用 Module#const_missing 实现,因此才有本文所述的独特算法。

10 常见问题

10.1 嵌套和限定常量

假如有下述代码

+
+module Admin
+  class UsersController < ApplicationController
+    def index
+      @users = User.all
+    end
+  end
+end
+
+
+
+

+
+class Admin::UsersController < ApplicationController
+  def index
+    @users = User.all
+  end
+end
+
+
+
+

为了解析 User,对前者来说,Ruby 会检查 Admin,但是后者不会,因为它不在嵌套中(参见 嵌套解析算法)。

可惜,在缺失常量的地方,Rails 自动加载机制不知道嵌套,因此行为与 Ruby 不同。具体而言,在两种情况下,Admin::User 都能自动加载。

尽管严格来说某些情况下 classmodule 关键字后面的限定常量可以自动加载,但是最好使用相对常量:

+
+module Admin
+  class UsersController < ApplicationController
+    def index
+      @users = User.all
+    end
+  end
+end
+
+
+
+

10.2 自动加载和 STI

单表继承(Single Table Inheritance,STI)是 Active Record 的一个功能,作用是在一个数据库表中存储具有层次结构的多个模型。这种模型的 API 知道层次结构的存在,而且封装了一些常用的需求。例如,对下面的类来说:

+
+# app/models/polygon.rb
+class Polygon < ApplicationRecord
+end
+
+# app/models/triangle.rb
+class Triangle < Polygon
+end
+
+# app/models/rectangle.rb
+class Rectangle < Polygon
+end
+
+
+
+

Triangle.create 在表中创建一行,表示一个三角形,而 Rectangle.create 创建一行,表示一个长方形。如果 id 是某个现有记录的 ID,Polygon.find(id) 返回的是正确类型的对象。

操作集合的方法也知道层次结构。例如,Polygon.all 返回表中的全部记录,因为所有长方形和三角形都是多边形。Active Record 负责为结果集合中的各个实例设定正确的类。

类型会按需自动加载。例如,如果 Polygon.first 是一个长方形,而 Rectangle 尚未加载,Active Record 会自动加载它,然后正确实例化记录。

目前一切顺利,但是如果在根类上执行查询,需要处理子类,这时情况就复杂了。

处理 Polygon 时,无需知道全部子代,因为表中的所有记录都是多边形。但是处理子类时, Active Record 需要枚举类型,找到所需的那个。下面看一个例子。

Rectangle.all 在查询中添加一个类型约束,只加载长方形:

+
+SELECT "polygons".* FROM "polygons"
+WHERE "polygons"."type" IN ("Rectangle")
+
+
+
+

下面定义一个 Rectangle 的子类:

+
+# app/models/square.rb
+class Square < Rectangle
+end
+
+
+
+

现在,Rectangle.all 返回的结果应该既有长方形,也有正方形:

+
+SELECT "polygons".* FROM "polygons"
+WHERE "polygons"."type" IN ("Rectangle", "Square")
+
+
+
+

但是这里有个问题:Active Record 怎么知道存在 Square 类呢?

如果 app/models/square.rb 文件存在,而且定义了 Square 类,但是没有代码使用它,Rectangle.all 执行的查询是

+
+SELECT "polygons".* FROM "polygons"
+WHERE "polygons"."type" IN ("Rectangle")
+
+
+
+

这不是缺陷,查询包含了所有已知的 Rectangle 子代。

为了确保能正确处理,而不管代码的执行顺序,可以在定义根类的文件底部手动加载子代:

+
+# app/models/polygon.rb
+class Polygon < ApplicationRecord
+end
+require_dependency 'square'
+
+
+
+

只有最小辈的子代需要以这种方式加载。直接子类无需预加载。如果层次结构较深,中间类会自底向上递归自动加载,因为相应的常量作为超类出现在类定义中。

10.3 自动加载和 require +

通过自动加载机制加载的定义常量的文件一定不能使用 require 引入:

+
+require 'user' # 千万别这么做
+
+class UsersController < ApplicationController
+  ...
+end
+
+
+
+

如果这么做,在开发环境中会导致两个问题:

+
    +
  1. 如果在执行 require 之前自动加载了 Userapp/models/user.rb 会再次运行,因为 load 不会更新 $LOADED_FEATURES

  2. +
  3. 如果 require 先执行了,Rails 不会把 User 标记为自动加载的常量,因此 app/models/user.rb 文件中的改动不会重新加载。

  4. +
+

我们应该始终遵守规则,使用常量自动加载机制,一定不能混用自动加载和 require。底线是,如果一定要加载特定的文件,使用 require_dependency,这样能正确利用常量自动加载机制。不过,实际上很少需要这么做。

当然,在自动加载的文件中使用 require 加载第三方库没问题,Rails 会做区分,不把第三方库里的常量标记为自动加载的。

10.4 自动加载和初始化脚本

假设 config/initializers/set_auth_service.rb 文件中有下述赋值语句:

+
+AUTH_SERVICE = if Rails.env.production?
+  RealAuthService
+else
+  MockedAuthService
+end
+
+
+
+

这么做的目的是根据所在环境为 AUTH_SERVICE 赋予不同的值。在开发环境中,运行这个初始化脚本时,自动加载 MockedAuthService。假如我们发送了几个请求,修改了实现,然后再次运行应用,奇怪的是,改动没有生效。这是为什么呢?

从前文得知,Rails 会删除自动加载的常量,但是 AUTH_SERVICE 存储的还是原来那个类对象。原来那个常量不存在了,但是功能完全不受影响。

下述代码概述了这种情况:

+
+class C
+  def quack
+    'quack!'
+  end
+end
+
+X = C
+Object.instance_eval { remove_const(:C) }
+X.new.quack # => quack!
+X.name      # => C
+C           # => uninitialized constant C (NameError)
+
+
+
+

鉴于此,不建议在应用初始化过程中自动加载常量。

对上述示例来说,我们可以实现一个动态接入点:

+
+# app/models/auth_service.rb
+class AuthService
+  if Rails.env.production?
+    def self.instance
+      RealAuthService
+    end
+  else
+    def self.instance
+      MockedAuthService
+    end
+  end
+end
+
+
+
+

然后在应用中使用 AuthService.instance。这样,AuthService 会按需加载,而且能顺利自动加载。

10.5 require_dependency 和初始化脚本

前面说过,require_dependency 加载的文件能顺利自动加载。但是,一般来说不应该在初始化脚本中使用。

有人可能觉得在初始化脚本中调用 require_dependency 能确保提前加载特定的常量,例如用于解决 STI 问题

问题是,在开发环境中,如果文件系统中有相关的改动,自动加载的常量会被抹除。这样就与使用初始化脚本的初衷背道而驰了。

require_dependency 调用应该写在能自动加载的地方。

10.6 常量未缺失

10.6.1 相对引用

以一个飞行模拟器为例。应用中有个默认的飞行模型:

+
+# app/models/flight_model.rb
+class FlightModel
+end
+
+
+
+

每架飞机都可以将其覆盖,例如:

+
+# app/models/bell_x1/flight_model.rb
+module BellX1
+  class FlightModel < FlightModel
+  end
+end
+
+# app/models/bell_x1/aircraft.rb
+module BellX1
+  class Aircraft
+    def initialize
+      @flight_model = FlightModel.new
+    end
+  end
+end
+
+
+
+

初始化脚本想创建一个 BellX1::FlightModel 对象,而且嵌套中有 BellX1,看起来这没什么问题。但是,如果默认飞行模型加载了,但是 Bell-X1 模型没有,解释器能解析顶层的 FlightModel,因此 BellX1::FlightModel 不会触发自动加载机制。

这种代码取决于执行路径。

这种歧义通常可以通过限定常量解决:

+
+module BellX1
+  class Plane
+    def flight_model
+      @flight_model ||= BellX1::FlightModel.new
+    end
+  end
+end
+
+
+
+

此外,使用 require_dependency 也能解决:

+
+require_dependency 'bell_x1/flight_model'
+
+module BellX1
+  class Plane
+    def flight_model
+      @flight_model ||= FlightModel.new
+    end
+  end
+end
+
+
+
+
10.6.2 限定引用

对下述代码来说

+
+# app/models/hotel.rb
+class Hotel
+end
+
+# app/models/image.rb
+class Image
+end
+
+# app/models/hotel/image.rb
+class Hotel
+  class Image < Image
+  end
+end
+
+
+
+

Hotel::Image 这个表达式有歧义,因为它取决于执行路径。

从前文得知,Ruby 会在 Hotel 及其祖先中查找常量。如果加载了 app/models/image.rb 文件,但是没有加载 app/models/hotel/image.rb,Ruby 在 Hotel 中找不到 Image,而在 Object 中能找到:

+
+$ bin/rails r 'Image; p Hotel::Image' 2>/dev/null
+Image # 不是 Hotel::Image!
+
+
+
+

若想得到 Hotel::Image,要确保 app/models/hotel/image.rb 文件已经加载——或许是使用 require_dependency 加载的。

不过,在这些情况下,解释器会发出提醒:

+
+warning: toplevel constant Image referenced by Hotel::Image
+
+
+
+

任何限定的类都能发现这种奇怪的常量解析行为:

+
+2.1.5 :001 > String::Array
+(irb):1: warning: toplevel constant Array referenced by String::Array
+ => Array
+
+
+
+

为了发现这种问题,限定命名空间必须是类。Object 不是模块的祖先。

10.7 单例类中的自动加载

假如有下述类定义:

+
+# app/models/hotel/services.rb
+module Hotel
+  class Services
+  end
+end
+
+# app/models/hotel/geo_location.rb
+module Hotel
+  class GeoLocation
+    class << self
+      Services
+    end
+  end
+end
+
+
+
+

如果加载 app/models/hotel/geo_location.rb 文件时 Hotel::Services 是已知的,Services 由 Ruby 解析,因为打开 Hotel::GeoLocation 的单例类时,Hotel 在嵌套中。

但是,如果 Hotel::Services 是未知的,Rails 无法自动加载它,应用会抛出 NameError 异常。

这是因为单例类(匿名的)会触发自动加载,从前文得知,在这种边缘情况下,Rails 只检查顶层命名空间。

这个问题的简单解决方案是使用限定常量:

+
+module Hotel
+  class GeoLocation
+    class << self
+      Hotel::Services
+    end
+  end
+end
+
+
+
+

10.8 BasicObject 中的自动加载

BasicObject 的直接子代的祖先中没有 Object,因此无法解析顶层常量:

+
+class C < BasicObject
+  String # NameError: uninitialized constant C::String
+end
+
+
+
+

如果涉及自动加载,情况稍微复杂一些。对下述代码来说

+
+class C < BasicObject
+  def user
+    User # 错误
+  end
+end
+
+
+
+

因为 Rails 会检查顶层命名空间,所以第一次调用 user 方法时,User 能自动加载。但是,如果 User 是已知的,尤其是第二次调用 user 方法时,情况就不同了:

+
+c = C.new
+c.user # 奇怪的是能正常运行,返回 User
+c.user # NameError: uninitialized constant C::User
+
+
+
+

因为此时发现父级命名空间中已经有那个常量了(参见 限定引用)。

在纯 Ruby 代码中,在 BasicObject 的直接子代的定义体中应该始终使用绝对常量路径:

+
+class C < BasicObject
+  ::String # 正确
+
+  def user
+    ::User # 正确
+  end
+end
+
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/caching_with_rails.html b/caching_with_rails.html new file mode 100644 index 0000000..4aff309 --- /dev/null +++ b/caching_with_rails.html @@ -0,0 +1,576 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Rails 缓存概览

本文简述如何使用缓存提升 Rails 应用的速度。

缓存是指存储请求-响应循环中生成的内容,在类似请求的响应中复用。

通常,缓存是提升应用性能最有效的方式。通过缓存,在单个服务器中使用单个数据库的网站可以承受数千个用户并发访问。

Rails 自带了一些缓存功能。本文说明它们的适用范围和作用。掌握这些技术之后,你的 Rails 应用能承受大量访问,而不必花大量时间生成响应,或者支付高昂的服务器账单。

读完本文后,您将学到:

+
    +
  • 片段缓存和俄罗斯套娃缓存;

  • +
  • 如何管理缓存依赖;

  • +
  • 不同的缓存存储器;

  • +
  • 对条件 GET 请求的支持。

  • +
+

1 基本缓存

本节简介三种缓存技术:页面缓存(page caching)、动作缓存(action caching)和片段缓存(fragment caching)。Rails 默认提供了片段缓存。如果想使用页面缓存或动作缓存,要把 actionpack-page_cachingactionpack-action_caching 添加到 Gemfile 中。

默认情况下,缓存只在生产环境启用。如果想在本地启用缓存,要在相应的 config/environments/*.rb 文件中把 config.action_controller.perform_caching 设为 true

+
+config.action_controller.perform_caching = true
+
+
+
+

修改 config.action_controller.perform_caching 的值只对 Action Controller 组件提供的缓存有影响。例如,对低层缓存没影响,下文详述

1.1 页面缓存

页面缓存时 Rails 提供的一种缓存机制,让 Web 服务器(如 Apache 和 NGINX)直接伺服生成的页面,而不经由 Rails 栈处理。虽然这种缓存的速度超快,但是不适用于所有情况(例如需要验证身份的页面)。此外,因为 Web 服务器直接从文件系统中伺服文件,所以你要自行实现缓存失效机制。

Rails 4 删除了页面缓存。参见 actionpack-page_caching gem

1.2 动作缓存

有前置过滤器的动作不能使用页面缓存,例如需要验证身份的页面。此时,应该使用动作缓存。动作缓存的工作原理与页面缓存类似,不过入站请求会经过 Rails 栈处理,以便运行前置过滤器,然后再伺服缓存。这样,可以做身份验证和其他限制,同时还能从缓存的副本中伺服结果。

Rails 4 删除了动作缓存。参见 actionpack-action_caching gem。最新推荐的做法参见 DHH 写的“How key-based cache expiration works”一文。

1.3 片段缓存

动态 Web 应用一般使用不同的组件构建页面,不是所有组件都能使用同一种缓存机制。如果页面的不同部分需要使用不同的缓存机制,在不同的条件下失效,可以使用片段缓存。

片段缓存把视图逻辑的一部分放在 cache 块中,下次请求使用缓存存储器中的副本伺服。

例如,如果想缓存页面中的各个商品,可以使用下述代码:

+
+<% @products.each do |product| %>
+  <% cache product do %>
+    <%= render product %>
+  <% end %>
+<% end %>
+
+
+
+

首次访问这个页面时,Rails 会创建一个具有唯一键的缓存条目。缓存键类似下面这种:

+
+views/products/1-201505056193031061005000/bea67108094918eeba42cd4a6e786901
+
+
+
+

中间的数字是 product_id 加上商品记录的 updated_at 属性中存储的时间戳。Rails 使用时间戳确保不伺服过期的数据。如果 updated_at 的值变了,Rails 会生成一个新键,然后在那个键上写入一个新缓存,旧键上的旧缓存不再使用。这叫基于键的失效方式。

视图片段有变化时(例如视图的 HTML 有变),缓存的片段也失效。缓存键末尾那个字符串是模板树摘要,是基于缓存的视图片段的内容计算的 MD5 哈希值。如果视图片段有变化,MD5 哈希值就变了,因此现有文件失效。

Memcached 等缓存存储器会自动删除旧的缓存文件。

如果想在特定条件下缓存一个片段,可以使用 cache_ifcache_unless

+
+<% cache_if admin?, product do %>
+  <%= render product %>
+<% end %>
+
+
+
+
1.3.1 集合缓存

render 辅助方法还能缓存渲染集合的单个模板。这甚至比使用 each 的前述示例更好,因为是一次性读取所有缓存模板的,而不是一次读取一个。若想缓存集合,渲染集合时传入 cached: true 选项:

+
+<%= render partial: 'products/product', collection: @products, cached: true %>
+
+
+
+

上述代码中所有的缓存模板一次性获取,速度更快。此外,尚未缓存的模板也会写入缓存,在下次渲染时获取。

1.4 俄罗斯套娃缓存

有时,可能想把缓存的片段嵌套在其他缓存的片段里。这叫俄罗斯套娃缓存(Russian doll caching)。

俄罗斯套娃缓存的优点是,更新单个商品后,重新生成外层片段时,其他内存片段可以复用。

前一节说过,如果缓存的文件对应的记录的 updated_at 属性值变了,缓存的文件失效。但是,内层嵌套的片段不失效。

对下面的视图来说:

+
+<% cache product do %>
+  <%= render product.games %>
+<% end %>
+
+
+
+

而它渲染这个视图:

+
+<% cache game do %>
+  <%= render game %>
+<% end %>
+
+
+
+

如果游戏的任何一个属性变了,updated_at 的值会设为当前时间,因此缓存失效。然而,商品对象的 updated_at 属性不变,因此它的缓存不失效,从而导致应用伺服过期的数据。为了解决这个问题,可以使用 touch 方法把模型绑在一起:

+
+class Product < ApplicationRecord
+  has_many :games
+end
+
+class Game < ApplicationRecord
+  belongs_to :product, touch: true
+end
+
+
+
+

touch 设为 true 后,导致游戏的 updated_at 变化的操作,也会修改关联的商品的 updated_at 属性,从而让缓存失效。

1.5 管理依赖

为了正确地让缓存失效,要正确地定义缓存依赖。Rails 足够智能,能处理常见的情况,无需自己指定。但是有时需要处理自定义的辅助方法(以此为例),因此要自行定义。

1.5.1 隐式依赖

多数模板依赖可以从模板中的 render 调用中推导出来。下面举例说明 ActionView::Digestor 知道如何解码的 render 调用:

+
+render partial: "comments/comment", collection: commentable.comments
+render "comments/comments"
+render 'comments/comments'
+render('comments/comments')
+
+render "header" => render("comments/header")
+
+render(@topic)         => render("topics/topic")
+render(topics)         => render("topics/topic")
+render(message.topics) => render("topics/topic")
+
+
+
+

而另一方面,有些调用要做修改方能让缓存正确工作。例如,如果传入自定义的集合,要把下述代码:

+
+render @project.documents.where(published: true)
+
+
+
+

改为:

+
+render partial: "documents/document", collection: @project.documents.where(published: true)
+
+
+
+
1.5.2 显式依赖

有时,模板依赖推导不出来。在辅助方法中渲染时经常是这样。下面举个例子:

+
+<%= render_sortable_todolists @project.todolists %>
+
+
+
+

此时,要使用一种特殊的注释格式:

+
+<%# Template Dependency: todolists/todolist %>
+<%= render_sortable_todolists @project.todolists %>
+
+
+
+

某些情况下,例如设置单表继承,可能要显式定义一堆依赖。此时无需写出每个模板,可以使用通配符匹配一个目录中的全部模板:

+
+<%# Template Dependency: events/* %>
+<%= render_categorizable_events @person.events %>
+
+
+
+

对集合缓存来说,如果局部模板不是以干净的缓存调用开头,依然可以使用集合缓存,不过要在模板中的任意位置添加一种格式特殊的注释,如下所示:

+
+<%# Template Collection: notification %>
+<% my_helper_that_calls_cache(some_arg, notification) do %>
+  <%= notification.name %>
+<% end %>
+
+
+
+
1.5.3 外部依赖

如果在缓存的块中使用辅助方法,而后更新了辅助方法,还要更新缓存。具体方法不限,只要能改变模板文件的 MD5 值就行。推荐的方法之一是添加一个注释,如下所示:

+
+<%# Helper Dependency Updated: Jul 28, 2015 at 7pm %>
+<%= some_helper_method(person) %>
+
+
+
+

1.6 低层缓存

有时需要缓存特定的值或查询结果,而不是缓存视图片段。Rails 的缓存机制能存储任何类型的信息。

实现低层缓存最有效的方式是使用 Rails.cache.fetch 方法。这个方法既能读取也能写入缓存。传入单个参数时,获取指定的键,返回缓存中的值。传入块时,在指定键上缓存块的结果,并返回结果。

下面举个例子。应用中有个 Product 模型,它有个实例方法,在竞争网站中查找商品的价格。这个方法返回的数据特别适合使用低层缓存:

+
+class Product < ApplicationRecord
+  def competing_price
+    Rails.cache.fetch("#{cache_key}/competing_price", expires_in: 12.hours) do
+      Competitor::API.find_price(id)
+    end
+  end
+end
+
+
+
+

注意,这个示例使用了 cache_key 方法,因此得到的缓存键类似这种:products/233-20140225082222765838000/competing_pricecache_key 方法根据模型的 idupdated_at 属性生成一个字符串。这是常见的约定,有个好处是,商品更新后缓存自动失效。一般来说,使用低层缓存缓存实例层信息时,需要生成缓存键。

1.7 SQL 缓存

查询缓存是 Rails 提供的一个功能,把各个查询的结果集缓存起来。如果在同一个请求中遇到了相同的查询,Rails 会使用缓存的结果集,而不再次到数据库中运行查询。

例如:

+
+class ProductsController < ApplicationController
+
+  def index
+    # 运行查找查询
+    @products = Product.all
+
+    ...
+
+    # 再次运行相同的查询
+    @products = Product.all
+  end
+
+end
+
+
+
+

再次运行相同的查询时,根本不会发给数据库。首次运行查询得到的结果存储在查询缓存中(内存里),第二次查询从内存中获取。

然而要知道,查询缓存在动作开头创建,到动作末尾销毁,只在动作的存续时间内存在。如果想持久化存储查询结果,使用低层缓存也能实现。

2 缓存存储器

Rails 为存储缓存数据(SQL 缓存和页面缓存除外)提供了不同的存储器。

2.1 配置

config.cache_store 配置选项用于设定应用的默认缓存存储器。可以设定其他参数,传给缓存存储器的构造方法:

+
+config.cache_store = :memory_store, { size: 64.megabytes }
+
+
+
+

此外,还可以在配置块外部调用 ActionController::Base.cache_store

缓存存储器通过 Rails.cache 访问。

2.2 ActiveSupport::Cache::Store +

这个类是在 Rails 中与缓存交互的基础。这是个抽象类,不能直接使用。你必须根据存储器引擎具体实现这个类。Rails 提供了几个实现,说明如下。

主要调用的方法有 readwritedeleteexist?fetchfetch 方法接受一个块,返回缓存中现有的值,或者把新值写入缓存。

所有缓存实现有些共用的选项,可以传给构造方法,或者传给与缓存条目交互的各个方法。

+
    +
  • :namespace:在缓存存储器中创建命名空间。如果与其他应用共用同一个缓存存储器,这个选项特别有用。

  • +
  • :compress:指定压缩缓存。通过缓慢的网络传输大量缓存时用得着。

  • +
  • :compress_threshold:与 :compress 选项搭配使用,指定一个阈值,未达到时不压缩缓存。默认为 16 千字节。

  • +
  • :expires_in:为缓存条目设定失效时间(秒数),失效后自动从缓存中删除。

  • +
  • :race_condition_ttl:与 :expires_in 选项搭配使用。避免多个进程同时重新生成相同的缓存条目(也叫 dog pile effect),防止让缓存条目过期时出现条件竞争。这个选项设定在重新生成新值时失效的条目还可以继续使用多久(秒数)。如果使用 :expires_in 选项, 最好也设定这个选项。

  • +
+
2.2.1 自定义缓存存储器

缓存存储器可以自己定义,只需扩展 ActiveSupport::Cache::Store 类,实现相应的方法。这样,你可以把任何缓存技术带到你的 Rails 应用中。

若想使用自定义的缓存存储器,只需把 cache_store 设为自定义类的实例:

+
+config.cache_store = MyCacheStore.new
+
+
+
+

2.3 ActiveSupport::Cache::MemoryStore +

这个缓存存储器把缓存条目放在内存中,与 Ruby 进程放在一起。可以把 :size 选项传给构造方法,指定缓存的大小限制(默认为 32Mb)。超过分配的大小后,会清理缓存,把最不常用的条目删除。

+
+config.cache_store = :memory_store, { size: 64.megabytes }
+
+
+
+

如果运行多个 Ruby on Rails 服务器进程(例如使用 mongrel_cluster 或 Phusion Passenger),各个实例之间无法共享缓存数据。这个缓存存储器不适合大型应用使用。不过,适合只有几个服务器进程的低流量小型应用使用,也适合在开发环境和测试环境中使用。

2.4 ActiveSupport::Cache::FileStore +

这个缓存存储器使用文件系统存储缓存条目。初始化这个存储器时,必须指定存储文件的目录:

+
+config.cache_store = :file_store, "/path/to/cache/directory"
+
+
+
+

使用这个缓存存储器时,在同一台主机中运行的多个服务器进程可以共享缓存。这个缓存存储器适合一到两个主机的中低流量网站使用。运行在不同主机中的多个服务器进程若想共享缓存,可以使用共享的文件系统,但是不建议这么做。

缓存量一直增加,直到填满磁盘,所以建议你定期清理旧缓存条目。

这是默认的缓存存储器。

2.5 ActiveSupport::Cache::MemCacheStore +

这个缓存存储器使用 Danga 的 memcached 服务器为应用提供中心化缓存。Rails 默认使用自带的 dalli gem。这是生产环境的网站目前最常使用的缓存存储器。通过它可以实现单个共享的缓存集群,效率很高,有较好的冗余。

初始化这个缓存存储器时,要指定集群中所有 memcached 服务器的地址。如果不指定,假定 memcached 运行在本地的默认端口上,但是对大型网站来说,这样做并不好。

这个缓存存储器的 writefetch 方法接受两个额外的选项,以便利用 memcached 的独有特性。指定 :raw 时,直接把值发给服务器,不做序列化。值必须是字符串或数字。memcached 的直接操作,如 incrementdecrement,只能用于原始值。还可以指定 :unless_exist 选项,不让 memcached 覆盖现有条目。

+
+config.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"
+
+
+
+

2.6 ActiveSupport::Cache::NullStore +

这个缓存存储器只应该在开发或测试环境中使用,它并不存储任何信息。在开发环境中,如果代码直接与 Rails.cache 交互,但是缓存可能对代码的结果有影响,可以使用这个缓存存储器。在这个缓存存储器上调用 fetchread 方法不返回任何值。

+
+config.cache_store = :null_store
+
+
+
+

3 缓存键

缓存中使用的键可以是能响应 cache_keyto_param 方法的任何对象。如果想定制生成键的方式,可以覆盖 cache_key 方法。Active Record 根据类名和记录 ID 生成缓存键。

缓存键的值可以是散列或数组:

+
+# 这是一个有效的缓存键
+Rails.cache.read(site: "mysite", owners: [owner_1, owner_2])
+
+
+
+

Rails.cache 使用的键与存储引擎使用的并不相同,存储引擎使用的键可能含有命名空间,或者根据后端的限制做调整。这意味着,使用 Rails.cache 存储值时使用的键可能无法用于供 dalli gem 获取缓存条目。然而,你也无需担心会超出 memcached 的大小限制,或者违背句法规则。

4 对条件 GET 请求的支持

条件 GET 请求是 HTTP 规范的一个特性,以此告诉 Web 浏览器,GET 请求的响应自上次请求之后没有变化,可以放心从浏览器的缓存中读取。

为此,要传递 HTTP_IF_NONE_MATCHHTTP_IF_MODIFIED_SINCE 首部,其值分别为唯一的内容标识符和上一次改动时的时间戳。浏览器发送的请求,如果内容标识符(etag)或上一次修改的时间戳与服务器中的版本匹配,那么服务器只需返回一个空响应,把状态设为未修改。

服务器(也就是我们自己)要负责查看最后修改时间戳和 HTTP_IF_NONE_MATCH 首部,判断要不要返回完整的响应。既然 Rails 支持条件 GET 请求,那么这个任务就非常简单:

+
+class ProductsController < ApplicationController
+
+  def show
+    @product = Product.find(params[:id])
+
+    # 如果根据指定的时间戳和 etag 值判断请求的内容过期了
+    # (即需要重新处理)执行这个块
+    if stale?(last_modified: @product.updated_at.utc, etag: @product.cache_key)
+      respond_to do |wants|
+        # ... 正常处理响应
+      end
+    end
+
+    # 如果请求的内容还新鲜(即未修改),无需做任何事
+    # render 默认使用前面 stale? 中的参数做检查,会自动发送 :not_modified 响应
+    # 就这样,工作结束
+  end
+end
+
+
+
+

除了散列,还可以传入模型。Rails 会使用 updated_atcache_key 方法设定 last_modifiedetag

+
+class ProductsController < ApplicationController
+  def show
+    @product = Product.find(params[:id])
+
+    if stale?(@product)
+      respond_to do |wants|
+        # ... 正常处理响应
+      end
+    end
+  end
+end
+
+
+
+

如果无需特殊处理响应,而且使用默认的渲染机制(即不使用 respond_to,或者不自己调用 render),可以使用 fresh_when 简化这个过程:

+
+class ProductsController < ApplicationController
+
+  # 如果请求的内容是新鲜的,自动返回 :not_modified
+  # 否则渲染默认的模板(product.*)
+
+  def show
+    @product = Product.find(params[:id])
+    fresh_when last_modified: @product.published_at.utc, etag: @product
+  end
+end
+
+
+
+

4.1 强 Etag 与弱 Etag

Rails 默认生成弱 ETag。这种 Etag 允许语义等效但主体不完全匹配的响应具有相同的 Etag。如果响应主体有微小改动,而不想重新渲染页面,可以使用这种 Etag。

为了与强 Etag 区别,弱 Etag 前面有 W/

+
+W/"618bbc92e2d35ea1945008b42799b0e7" => 弱 ETag
+"618bbc92e2d35ea1945008b42799b0e7"   => 强 ETag
+
+
+
+

与弱 Etag 不同,强 Etag 要求响应完全一样,不能有一个字节的差异。在大型视频或 PDF 文件内部做 Range 查询时用得到。有些 CDN,如 Akamai,只支持强 Etag。如果确实想生成强 Etag,可以这么做:

+
+class ProductsController < ApplicationController
+  def show
+    @product = Product.find(params[:id])
+    fresh_when last_modified: @product.published_at.utc, strong_etag: @product
+  end
+end
+
+
+
+

也可以直接在响应上设定强 Etag:

+
+response.strong_etag = response.body
+# => "618bbc92e2d35ea1945008b42799b0e7"
+
+
+
+

5 参考资源

+ + + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/command_line.html b/command_line.html new file mode 100644 index 0000000..44ad27c --- /dev/null +++ b/command_line.html @@ -0,0 +1,798 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Rails 命令行

读完本文后,您将学到:

+
    +
  • 如何新建 Rails 应用;

  • +
  • 如何生成模型、控制器、数据库迁移和单元测试;

  • +
  • 如何启动开发服务器;

  • +
  • 如果在交互式 shell 中测试对象;

  • +
+

阅读本文前请阅读getting_started.xml,掌握一些 Rails 基础知识。

1 命令行基础

有些命令在 Rails 开发过程中经常会用到,下面按照使用频率倒序列出:

+
    +
  • rails console

  • +
  • rails server

  • +
  • bin/rails

  • +
  • rails generate

  • +
  • rails dbconsole

  • +
  • rails new app_name

  • +
+

这些命令都可指定 -h--help 选项列出更多信息。

下面我们新建一个 Rails 应用,通过它介绍各个命令的用法。

1.1 rails new +

安装 Rails 后首先要做的就是使用 rails new 命令新建 Rails 应用。

如果还没安装 Rails ,可以执行 gem install rails 命令安装。

+
+$ rails new commandsapp
+     create
+     create  README.md
+     create  Rakefile
+     create  config.ru
+     create  .gitignore
+     create  Gemfile
+     create  app
+     ...
+     create  tmp/cache
+     ...
+        run  bundle install
+
+
+
+

这个简单的命令会生成很多文件,组成一个完整的 Rails 应用目录结构,直接就可运行。

1.2 rails server +

rails server 命令用于启动 Rails 自带的 Puma Web 服务器。若想在浏览器中访问应用,就要执行这个命令。

无需其他操作,执行 rails server 命令后就能运行刚才创建的 Rails 应用:

+
+$ cd commandsapp
+$ bin/rails server
+=> Booting Puma
+=> Rails 5.0.0 application starting in development on http://0.0.0.0:3000
+=> Run `rails server -h` for more startup options
+Puma starting in single mode...
+* Version 3.0.2 (ruby 2.3.0-p0), codename: Plethora of Penguin Pinatas
+* Min threads: 5, max threads: 5
+* Environment: development
+* Listening on tcp://localhost:3000
+Use Ctrl-C to stop
+
+
+
+

只执行了三个命令,我们就启动了一个 Rails 服务器,监听着 3000 端口。打开浏览器,访问 http://localhost:3000,你会看到一个简单的 Rails 应用。

启动服务器的命令还可使用别名“s”:rails s

如果想让服务器监听其他端口,可通过 -p 选项指定。所处的环境(默认为开发环境)可由 -e 选项指定。

+
+$ bin/rails server -e production -p 4000
+
+
+
+

-b 选项把 Rails 绑定到指定的 IP(默认为 localhost)。指定 -d 选项后,服务器会以守护进程的形式运行。

1.3 rails generate +

rails generate 目录使用模板生成很多东西。单独执行 rails generate 命令,会列出可用的生成器:

还可使用别名“g”执行生成器命令:rails g

+
+$ bin/rails generate
+Usage: rails generate GENERATOR [args] [options]
+
+...
+...
+
+Please choose a generator below.
+
+Rails:
+  assets
+  controller
+  generator
+  ...
+  ...
+
+
+
+

使用其他生成器 gem 可以安装更多的生成器,或者使用插件中提供的生成器,甚至还可以自己编写生成器。

使用生成器可以节省大量编写样板代码(即应用运行必须的代码)的时间。

下面我们使用控制器生成器生成一个控制器。不过,应该使用哪个命令呢?我们问一下生成器:

所有 Rails 命令都有帮助信息。和其他 *nix 命令一样,可以在命令后加上 --help-h 选项,例如 rails server --help

+
+$ bin/rails generate controller
+Usage: rails generate controller NAME [action action] [options]
+
+...
+...
+
+Description:
+    ...
+
+    To create a controller within a module, specify the controller name as a path like 'parent_module/controller_name'.
+
+    ...
+
+Example:
+    `rails generate controller CreditCards open debit credit close`
+
+    Credit card controller with URLs like /credit_cards/debit.
+        Controller: app/controllers/credit_cards_controller.rb
+        Test:       test/controllers/credit_cards_controller_test.rb
+        Views:      app/views/credit_cards/debit.html.erb [...]
+        Helper:     app/helpers/credit_cards_helper.rb
+
+
+
+

控制器生成器接受的参数形式是 generate controller ControllerName action1 action2。下面我们来生成 Greetings 控制器,包含一个动作 hello,通过它跟读者打个招呼。

+
+$ bin/rails generate controller Greetings hello
+     create  app/controllers/greetings_controller.rb
+      route  get "greetings/hello"
+     invoke  erb
+     create    app/views/greetings
+     create    app/views/greetings/hello.html.erb
+     invoke  test_unit
+     create    test/controllers/greetings_controller_test.rb
+     invoke  helper
+     create    app/helpers/greetings_helper.rb
+     invoke  assets
+     invoke    coffee
+     create      app/assets/javascripts/greetings.coffee
+     invoke    scss
+     create      app/assets/stylesheets/greetings.scss
+
+
+
+

这个命令生成了什么呢?它在应用中创建了一堆目录,还有控制器文件、视图文件、功能测试文件、视图辅助方法文件、JavaScript 文件和样式表文件。

打开控制器文件(app/controllers/greetings_controller.rb),做些改动:

+
+class GreetingsController < ApplicationController
+  def hello
+    @message = "Hello, how are you today?"
+  end
+end
+
+
+
+

然后修改视图文件(app/views/greetings/hello.html.erb),显示消息:

+
+<h1>A Greeting for You!</h1>
+<p><%= @message %></p>
+
+
+
+

执行 rails server 命令启动服务器:

+
+$ bin/rails server
+=> Booting Puma...
+
+
+
+

要查看的 URL 是 http://localhost:3000/greetings/hello

在常规的 Rails 应用中,URL 的格式是 http://(host)/(controller)/(action),访问 http://(host)/(controller) 这样的 URL 会进入控制器的 index 动作。

Rails 也为数据模型提供了生成器。

+
+$ bin/rails generate model
+Usage:
+  rails generate model NAME [field[:type][:index] field[:type][:index]] [options]
+
+...
+
+Active Record options:
+      [--migration]            # Indicates when to generate migration
+                               # Default: true
+
+...
+
+Description:
+    Create rails files for model generator.
+
+
+
+

全部可用的字段类型,请查看 TableDefinition 类的 API 文档

不过我们暂且不直接生成模型(后文再生成),先来使用脚手架(scaffold)。Rails 中的脚手架会生成资源所需的全部文件,包括模型、模型所用的迁移、处理模型的控制器、查看数据的视图,以及各部分的测试组件。

我们要创建一个名为“HighScore”的资源,记录视频游戏的最高得分。

+
+$ bin/rails generate scaffold HighScore game:string score:integer
+    invoke  active_record
+    create    db/migrate/20130717151933_create_high_scores.rb
+    create    app/models/high_score.rb
+    invoke    test_unit
+    create      test/models/high_score_test.rb
+    create      test/fixtures/high_scores.yml
+    invoke  resource_route
+     route    resources :high_scores
+    invoke  scaffold_controller
+    create    app/controllers/high_scores_controller.rb
+    invoke    erb
+    create      app/views/high_scores
+    create      app/views/high_scores/index.html.erb
+    create      app/views/high_scores/edit.html.erb
+    create      app/views/high_scores/show.html.erb
+    create      app/views/high_scores/new.html.erb
+    create      app/views/high_scores/_form.html.erb
+    invoke    test_unit
+    create      test/controllers/high_scores_controller_test.rb
+    invoke    helper
+    create      app/helpers/high_scores_helper.rb
+    invoke    jbuilder
+    create      app/views/high_scores/index.json.jbuilder
+    create      app/views/high_scores/show.json.jbuilder
+    invoke  assets
+    invoke    coffee
+    create      app/assets/javascripts/high_scores.coffee
+    invoke    scss
+    create      app/assets/stylesheets/high_scores.scss
+    invoke  scss
+   identical    app/assets/stylesheets/scaffolds.scss
+
+
+
+

这个生成器检测到以下各组件对应的目录已经存在:模型、控制器、辅助方法、布局、功能测试、单元测试和样式表。然后创建“HighScore”资源的视图、控制器、模型和数据库迁移(用于创建 high_scores 数据表和字段),并设置好路由,以及测试等。

我们要运行迁移,执行文件 20130717151933_create_high_scores.rb 中的代码,这样才能修改数据库的模式。那么要修改哪个数据库呢?执行 bin/rails db:migrate 命令后会生成 SQLite3 数据库。稍后再详细说明 bin/rails

+
+$ bin/rails db:migrate
+==  CreateHighScores: migrating ===============================================
+-- create_table(:high_scores)
+   -> 0.0017s
+==  CreateHighScores: migrated (0.0019s) ======================================
+
+
+
+

介绍一下单元测试。单元测试是用来测试和做断言的代码。在单元测试中,我们只关注代码的一小部分,例如模型中的一个方法,测试其输入和输出。单元测试是你的好伙伴,你逐渐会意识到,单元测试的程度越高,生活的质量越高。真的。关于单元测试的详情,参阅testing.xml

我们来看一下 Rails 创建的界面。

+
+$ bin/rails server
+
+
+
+

打开浏览器,访问 http://localhost:3000/high_scores,现在可以创建新的最高得分了(太空入侵者得了 55,160 分)。

1.4 rails console +

执行 console 命令后,可以在命令行中与 Rails 应用交互。rails console 使用的是 IRB,所以如果你用过 IRB 的话,操作起来很顺手。在控制台里可以快速测试想法,或者修改服务器端数据,而无需在网站中操作。

这个命令还可以使用别名“c”:rails c

执行 console 命令时可以指定在哪个环境中打开控制台:

+
+$ bin/rails console staging
+
+
+
+

如果你想测试一些代码,但不想改变存储的数据,可以执行 rails console --sandbox 命令。

+
+$ bin/rails console --sandbox
+Loading development environment in sandbox (Rails 5.0.0)
+Any modifications you make will be rolled back on exit
+irb(main):001:0>
+
+
+
+
1.4.1 apphelper 对象

在控制台中可以访问 apphelper 对象。

通过 app 可以访问 URL 和路径辅助方法,还可以发送请求。

+
+>> app.root_path
+=> "/"
+
+>> app.get _
+Started GET "/" for 127.0.0.1 at 2014-06-19 10:41:57 -0300
+...
+
+
+
+

通过 helper 可以访问 Rails 和应用定义的辅助方法。

+
+>> helper.time_ago_in_words 30.days.ago
+=> "about 1 month"
+
+>> helper.my_custom_helper
+=> "my custom helper"
+
+
+
+

1.5 rails dbconsole +

rails dbconsole 能检测到你正在使用的数据库类型(还能理解传入的命令行参数),然后进入该数据库的命令行界面。该命令支持 MySQL(包括 MariaDB)、PostgreSQL 和 SQLite3。

这个命令还可以使用别名“db”:rails db

1.6 rails runner +

runner 能以非交互的方式在 Rails 中运行 Ruby 代码。例如:

+
+$ bin/rails runner "Model.long_running_method"
+
+
+
+

这个命令还可以使用别名“r”:rails r

可以使用 -e 选项指定 runner 命令在哪个环境中运行。

+
+$ bin/rails runner -e staging "Model.long_running_method"
+
+
+
+

甚至还可以执行文件中的 Ruby 代码:

+
+$ bin/rails runner lib/code_to_be_run.rb
+
+
+
+

1.7 rails destroy +

destroy 可以理解成 generate 的逆操作,它能识别生成了什么,然后撤销。

这个命令还可以使用别名“d”:rails d

+
+$ bin/rails generate model Oops
+      invoke  active_record
+      create    db/migrate/20120528062523_create_oops.rb
+      create    app/models/oops.rb
+      invoke    test_unit
+      create      test/models/oops_test.rb
+      create      test/fixtures/oops.yml
+
+
+
+
+
+$ bin/rails destroy model Oops
+      invoke  active_record
+      remove    db/migrate/20120528062523_create_oops.rb
+      remove    app/models/oops.rb
+      invoke    test_unit
+      remove      test/models/oops_test.rb
+      remove      test/fixtures/oops.yml
+
+
+
+

2 bin/rails +

从 Rails 5.0+ 起,rake 命令内建到 rails 可执行文件中了,因此现在应该使用 bin/rails 执行命令。

bin/rails 支持的任务列表可通过 bin/rails --help 查看(可用的任务根据所在的目录有所不同)。每个任务都有描述,应该能帮助你找到所需的那个。

+
+$ bin/rails --help
+Usage: rails COMMAND [ARGS]
+
+The most common rails commands are:
+generate    Generate new code (short-cut alias: "g")
+console     Start the Rails console (short-cut alias: "c")
+server      Start the Rails server (short-cut alias: "s")
+...
+
+All commands can be run with -h (or --help) for more information.
+
+In addition to those commands, there are:
+about                               List versions of all Rails ...
+assets:clean[keep]                  Remove old compiled assets
+assets:clobber                      Remove compiled assets
+assets:environment                  Load asset compile environment
+assets:precompile                   Compile all the assets ...
+...
+db:fixtures:load                    Loads fixtures into the ...
+db:migrate                          Migrate the database ...
+db:migrate:status                   Display status of migrations
+db:rollback                         Rolls the schema back to ...
+db:schema:cache:clear               Clears a db/schema_cache.dump file
+db:schema:cache:dump                Creates a db/schema_cache.dump file
+db:schema:dump                      Creates a db/schema.rb file ...
+db:schema:load                      Loads a schema.rb file ...
+db:seed                             Loads the seed data ...
+db:structure:dump                   Dumps the database structure ...
+db:structure:load                   Recreates the databases ...
+db:version                          Retrieves the current schema ...
+...
+restart                             Restart app by touching ...
+tmp:create
+
+
+
+

还可以使用 bin/rails -T 列出所有任务。

2.1 about +

bin/rails about 输出以下信息:Ruby、RubyGems、Rails 的版本号,Rails 使用的组件,应用所在的文件夹,Rails 当前所处的环境名,应用使用的数据库适配器,以及数据库模式版本号。如果想向他人需求帮助,检查安全补丁对你是否有影响,或者需要查看现有 Rails 应用的状态,就可以使用这个任务。

+
+$ bin/rails about
+About your application's environment
+Rails version             5.0.0
+Ruby version              2.2.2 (x86_64-linux)
+RubyGems version          2.4.6
+Rack version              1.6
+JavaScript Runtime        Node.js (V8)
+Middleware                Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
+Application root          /home/foobar/commandsapp
+Environment               development
+Database adapter          sqlite3
+Database schema version   20110805173523
+
+
+
+

2.2 assets +

bin/rails assets:precompile 用于预编译 app/assets 文件夹中的静态资源文件。bin/rails assets:clean 用于把之前编译好的静态资源文件删除。滚动部署时应该执行 assets:clean,以防仍然链接旧的静态资源文件。

如果想完全清空 public/assets 目录,可以使用 bin/rails assets:clobber

2.3 db +

bin/rails 命名空间 db: 中最常用的任务是 migratecreate,这两个任务会尝试运行所有迁移相关的任务(updownredoreset)。bin/rails db:version 在排查问题时很有用,它会输出数据库的当前版本。

关于数据库迁移的进一步说明,参阅active_record_migrations.xml

2.4 notes +

bin/rails notes 在代码中搜索以 FIXME、OPTIMIZE 或 TODO 开头的注释。搜索的文件类型包括 .builder.rb.rake.yml.yaml.ruby.css.js.erb,搜索的注解包括默认的和自定义的。

+
+$ bin/rails notes
+(in /home/foobar/commandsapp)
+app/controllers/admin/users_controller.rb:
+  * [ 20] [TODO] any other way to do this?
+  * [132] [FIXME] high priority for next deploy
+
+app/models/school.rb:
+  * [ 13] [OPTIMIZE] refactor this code to make it faster
+  * [ 17] [FIXME]
+
+
+
+

可以使用 config.annotations.register_extensions 选项添加新的文件扩展名。这个选项的值是扩展名列表和对应的正则表达式。

+
+config.annotations.register_extensions("scss", "sass", "less") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ }
+
+
+
+

如果想查看特定类型的注解,如 FIXME,可以使用 bin/rails notes:fixme。注意,注解的名称是小写形式。

+
+$ bin/rails notes:fixme
+(in /home/foobar/commandsapp)
+app/controllers/admin/users_controller.rb:
+  * [132] high priority for next deploy
+
+app/models/school.rb:
+  * [ 17]
+
+
+
+

此外,还可以在代码中使用自定义的注解,然后使用 bin/rails notes:custom,并通过 ANNOTATION 环境变量指定注解类型,将其列出。

+
+$ bin/rails notes:custom ANNOTATION=BUG
+(in /home/foobar/commandsapp)
+app/models/article.rb:
+  * [ 23] Have to fix this one before pushing!
+
+
+
+

使用内置的注解或自定义的注解时,注解的名称(FIXME、BUG 等)不会在输出中显示。

默认情况下,rails notesappconfigdblibtest 目录中搜索。如果想搜索其他目录,可以通过 SOURCE_ANNOTATION_DIRECTORIES 环境变量指定,各个目录使用逗号分隔。

+
+$ export SOURCE_ANNOTATION_DIRECTORIES='spec,vendor'
+$ bin/rails notes
+(in /home/foobar/commandsapp)
+app/models/user.rb:
+  * [ 35] [FIXME] User should have a subscription at this point
+spec/models/user_spec.rb:
+  * [122] [TODO] Verify the user that has a subscription works
+
+
+
+

2.5 routes +

rails routes 列出应用中定义的所有路由,可为解决路由问题提供帮助,还可以让你对应用中的所有 URL 有个整体了解。

2.6 test +

Rails 中的单元测试详情,参见testing.xml

Rails 提供了一个名为 Minitest 的测试组件。Rails 的稳定性由测试决定。test: 命名空间中的任务可用于运行各种测试。

2.7 tmp +

Rails.root/tmp 目录和 *nix 系统中的 /tmp 目录作用相同,用于存放临时文件,例如 PID 文件和缓存的动作等。

tmp: 命名空间中的任务可以清理或创建 Rails.root/tmp 目录:

+
    +
  • rails tmp:cache:clear 清空 tmp/cache 目录;

  • +
  • rails tmp:sockets:clear 清空 tmp/sockets 目录;

  • +
  • rails tmp:clear 清空所有缓存和套接字文件;

  • +
  • rails tmp:create 创建缓存、套接字和 PID 所需的临时目录;

  • +
+

2.8 其他任务

+
    +
  • rails stats 用于统计代码状况,显示千行代码数和测试比例等;

  • +
  • rails secret 生成一个伪随机字符串,作为会话的密钥;

  • +
  • rails time:zones:all 列出 Rails 能理解的所有时区;

  • +
+

2.9 自定义 Rake 任务

自定义的 Rake 任务保存在 Rails.root/lib/tasks 目录中,文件的扩展名是 .rake。执行 bin/rails generate task 命令会生成一个新的自定义任务文件。

+
+desc "I am short, but comprehensive description for my cool task"
+task task_name: [:prerequisite_task, :another_task_we_depend_on] do
+  # 在这里定义任务
+  # 可以使用任何有效的 Ruby 代码
+end
+
+
+
+

向自定义的任务传入参数的方式如下:

+
+task :task_name, [:arg_1] => [:prerequisite_1, :prerequisite_2] do |task, args|
+  argument_1 = args.arg_1
+end
+
+
+
+

任务可以分组,放入命名空间:

+
+namespace :db do
+  desc "This task does nothing"
+  task :nothing do
+    # 确实什么也没做
+  end
+end
+
+
+
+

执行任务的方法如下:

+
+$ bin/rails task_name
+$ bin/rails "task_name[value 1]" # 整个参数字符串应该放在引号内
+$ bin/rails db:nothing
+
+
+
+

如果在任务中要与应用的模型交互、查询数据库等,可以使用 environment 任务加载应用代码。

3 Rails 命令行高级用法

Rails 命令行的高级用法就是找到实用的参数,满足特定需求或者工作流程。下面是一些常用的高级命令。

3.1 新建应用时指定数据库和源码管理系统

新建 Rails 应用时,可以设定一些选项指定使用哪种数据库和源码管理系统。这么做可以节省一点时间,减少敲击键盘的次数。

我们来看一下 --git--database=postgresql 选项有什么作用:

+
+$ mkdir gitapp
+$ cd gitapp
+$ git init
+Initialized empty Git repository in .git/
+$ rails new . --git --database=postgresql
+      exists
+      create  app/controllers
+      create  app/helpers
+...
+...
+      create  tmp/cache
+      create  tmp/pids
+      create  Rakefile
+add 'Rakefile'
+      create  README.md
+add 'README.md'
+      create  app/controllers/application_controller.rb
+add 'app/controllers/application_controller.rb'
+      create  app/helpers/application_helper.rb
+...
+      create  log/test.log
+add 'log/test.log'
+
+
+
+

上面的命令先新建 gitapp 文件夹,初始化一个空的 git 仓库,然后再把 Rails 生成的文件纳入仓库。再来看一下它在数据库配置文件中添加了什么:

+
+$ cat config/database.yml
+# PostgreSQL. Versions 9.1 and up are supported.
+#
+# Install the pg driver:
+#   gem install pg
+# On OS X with Homebrew:
+#   gem install pg -- --with-pg-config=/usr/local/bin/pg_config
+# On OS X with MacPorts:
+#   gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
+# On Windows:
+#   gem install pg
+#       Choose the win32 build.
+#       Install PostgreSQL and put its /bin directory on your path.
+#
+# Configure Using Gemfile
+# gem 'pg'
+#
+development:
+  adapter: postgresql
+  encoding: unicode
+  database: gitapp_development
+  pool: 5
+  username: gitapp
+  password:
+...
+...
+
+
+
+

这个命令还根据我们选择的 PostgreSQL 数据库在 database.yml 中添加了一些配置。

指定源码管理系统选项时唯一的不便是,要先新建存放应用的目录,再初始化源码管理系统,然后才能执行 rails new 命令生成应用骨架。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/configuring.html b/configuring.html new file mode 100644 index 0000000..b56dfca --- /dev/null +++ b/configuring.html @@ -0,0 +1,1190 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

配置 Rails 应用

本文涵盖 Rails 应用可用的配置和初始化功能。

读完本文后,您将学到:

+
    +
  • 如何调整 Rails 应用的行为;

  • +
  • 如何增加额外代码,在应用启动时运行。

  • +
+

1 初始化代码的存放位置

Rails 为初始化代码提供了四个标准位置:

+
    +
  • config/application.rb

  • +
  • 针对各环境的配置文件

  • +
  • 初始化脚本

  • +
  • 后置初始化脚本

  • +
+

2 在 Rails 之前运行代码

虽然在加载 Rails 自身之前运行代码很少见,但是如果想这么做,可以把代码添加到 config/application.rb 文件中 require 'rails/all' 的前面。

3 配置 Rails 组件

一般来说,配置 Rails 的意思是配置 Rails 的组件和 Rails 自身。传给各个组件的设置在 config/application.rb 配置文件或者针对各环境的配置文件(如 config/environments/production.rb)中指定。

例如,config/application.rb 文件中有下述设置:

+
+config.time_zone = 'Central Time (US & Canada)'
+
+
+
+

这是针对 Rails 自身的设置。如果想把设置传给某个 Rails 组件,依然是在 config/application.rb 文件中通过 config 对象去做:

+
+config.active_record.schema_format = :ruby
+
+
+
+

Rails 会使用这个设置配置 Active Record。

3.1 Rails 的一般性配置

这些配置方法在 Rails::Railtie 对象上调用,例如 Rails::EngineRails::Application 的子类。

+
    +
  • +

    config.after_initialize 接受一个块,在 Rails 初始化应用之后运行。初始化过程包括初始化框架自身、引擎和 config/initializers 目录中的全部初始化脚本。注意,这个块会被 Rake 任务运行。可用于配置其他初始化脚本设定的值:

    +
    +
    +config.after_initialize do
    +  ActionView::Base.sanitized_allowed_tags.delete 'div'
    +end
    +
    +
    +
    +
  • +
  • config.asset_host 设定静态资源文件的主机名。使用 CDN 贮存静态资源文件,或者想绕开浏览器对同一域名的并发连接数的限制时可以使用这个选项。这是 config.action_controller.asset_host 的简短版本。

  • +
  • config.autoload_once_paths 接受一个路径数组,告诉 Rails 自动加载常量后不在每次请求中都清空。如果 config.cache_classes 的值为 false(开发环境的默认值),这个选项有影响。否则,都只自动加载一次。这个数组的全部元素都要在 autoload_paths 中。默认值为一个空数组。

  • +
  • config.autoload_paths 接受一个路径数组,让 Rails 自动加载里面的常量。默认值是 app 目录中的全部子目录。

  • +
  • config.cache_classes 控制每次请求是否重新加载应用的类和模块。在开发环境中默认为 false,在测试和生产环境中默认为 true

  • +
  • config.action_view.cache_template_loading 控制每次请求是否重新加载模板。默认值为 config.cache_classes 的值。

  • +
  • config.beginning_of_week 设定一周从周几开始。可接受的值是有效的周几符号(如 :monday)。

  • +
  • config.cache_store 配置 Rails 缓存使用哪个存储器。可用的选项有::memory_store:file_store:mem_cache_store:null_store,或者实现了缓存 API 的对象。如果存在 tmp/cache 目录,默认值为 :file_store,否则为 :memory_store

  • +
  • config.colorize_logging 指定在日志中记录信息时是否使用 ANSI 颜色代码。默认值为 true

  • +
  • config.consider_all_requests_local 是一个旗标。如果设为 true,发生任何错误都会把详细的调试信息转储到 HTTP 响应中,而且 Rails::Info 控制器会在 /rails/info/properties 中显示应用的运行时上下文。开发和测试环境中默认为 true,生产环境默认为 false。如果想精细控制,把这个选项设为 false,然后在控制器中实现 local_request? 方法,指定哪些请求应该在出错时显示调试信息。

  • +
  • +

    config.console 设定 rails console 命令所用的控制台类。最好在 console 块中运行:

    +
    +
    +console do
    +  # 这个块只在运行控制台时运行
    +  # 因此可以安全引入 pry
    +  require "pry"
    +  config.console = Pry
    +end
    +
    +
    +
    +
  • +
  • config.eager_load 设为 true 时,及早加载注册的全部 config.eager_load_namespaces。包括应用、引擎、Rails 框架和注册的其他命名空间。

  • +
  • config.eager_load_namespaces 注册命名空间,当 config.eager_loadtrue 时及早加载。这里列出的所有命名空间都必须响应 eager_load! 方法。

  • +
  • config.eager_load_paths 接受一个路径数组,如果启用类缓存,启动 Rails 时会及早加载。默认值为 app 目录中的全部子目录。

  • +
  • config.enable_dependency_loading 设为 true 时,即便应用及早加载了,而且把 config.cache_classes 设为 true,也自动加载。默认值为 false

  • +
  • config.encoding 设定应用全局编码。默认为 UTF-8。

  • +
  • config.exceptions_app 设定出现异常时 ShowException 中间件调用的异常应用。默认为 ActionDispatch::PublicExceptions.new(Rails.public_path)

  • +
  • config.debug_exception_response_format 设定开发环境中出错时响应的格式。只提供 API 的应用默认值为 :api,常规应用的默认值为 :default

  • +
  • config.file_watcher 指定一个类,当 config.reload_classes_only_on_change 设为 true 时用于检测文件系统中文件的变动。Rails 提供了 ActiveSupport::FileUpdateChecker(默认)和 ActiveSupport::EventedFileUpdateChecker(依赖 listen gem)。自定义的类必须符合 ActiveSupport::FileUpdateChecker API。

  • +
  • config.filter_parameters 用于过滤不想记录到日志中的参数,例如密码或信用卡卡号。默认,Rails 把 Rails.application.config.filter_parameters += [:password] 添加到 config/initializers/filter_parameter_logging.rb 文件中,过滤密码。过滤的参数部分匹配正则表达式。

  • +
  • config.force_ssl 强制所有请求经由 ActionDispatch::SSL 中间件处理,即通过 HTTPS 伺服,而且把 config.action_mailer.default_url_options 设为 { protocol: 'https' }。SSL 通过设定 config.ssl_options 选项配置,详情参见 ActionDispatch::SSL 的文档

  • +
  • config.log_formatter 定义 Rails 日志记录器的格式化程序。这个选项的默认值在开发和测试环境中是 ActiveSupport::Logger::SimpleFormatter 的实例,在生产环境中是 Logger::Formatter。如果为 config.logger 设定了值,必须在包装到 ActiveSupport::TaggedLogging 实例中之前手动把格式化程序的值传给日志记录器,Rails 不会为你代劳。

  • +
  • config.log_level 定义 Rails 日志记录器的详细程度。在所有环境中,这个选项的默认值都是 :debug。可用的日志等级有 :debug:info:warn:error:fatal:unknown

  • +
  • config.log_tags 的值可以是一组 request 对象响应的方法,可以是一个接受 request 对象的 Proc,也可以是能响应 to_s 方法的对象。这样便于为包含调试信息的日志行添加标签,例如二级域名和请求 ID——二者对调试多用户应用十分有用。

  • +
  • +

    config.logger 指定 Rails.logger 和与 Rails 有关的其他日志(ActiveRecord::Base.logger)所用的日志记录器。默认值为 ActiveSupport::TaggedLogging 实例,包装 ActiveSupport::Logger 实例,把日志存储在 log/ 目录中。你可以提供自定义的日志记录器,但是为了完全兼容,必须遵照下述指导方针:

    +
      +
    • 为了支持格式化程序,必须手动把 config.log_formatter 指定的格式化程序赋值给日志记录器。
    • +
    • 为了支持日志标签,日志实例必须使用 ActiveSupport::TaggedLogging 包装。
    • +
    • +

      为了支持静默,日志记录器必须引入 LoggerSilenceActiveSupport::LoggerThreadSafeLevel 模块。ActiveSupport::Logger 类已经引入这两个模块。

      +
      +
      +class MyLogger < ::Logger
      +  include ActiveSupport::LoggerThreadSafeLevel
      +  include LoggerSilence
      +end
      +
      +mylogger           = MyLogger.new(STDOUT)
      +mylogger.formatter = config.log_formatter
      +config.logger = ActiveSupport::TaggedLogging.new(mylogger)
      +
      +
      +
      +
    • +
    +
  • +
  • config.middleware 用于配置应用的中间件。详情参见 配置中间件

  • +
  • config.reload_classes_only_on_change 设定仅在跟踪的文件有变化时是否重新加载类。默认跟踪自动加载路径中的一切文件,这个选项的值为 true。如果把 config.cache_classes 设为 true,这个选项将被忽略。

  • +
  • secrets.secret_key_base 用于指定一个密钥,检查应用的会话,防止篡改。secrets.secret_key_base 的值一开始是个随机的字符串,存储在 config/secrets.yml 文件中。

  • +
  • config.public_file_server.enabled 配置 Rails 从 public 目录中伺服静态文件。这个选项的默认值是 false,但在生产环境中设为 false,因为应该使用运行应用的服务器软件(如 NGINX 或 Apache)伺服静态文件。在生产环境中如果使用 WEBrick 运行或测试应用(不建议在生产环境中使用 WEBrick),把这个选项设为 true。否则无法使用页面缓存,也无法请求 public 目录中的文件。

  • +
  • +

    config.session_store 通常在 config/initializers/session_store.rb 文件中设定,用于指定使用哪个类存储会话。可用的值有 :cookie_store(默认值)、:mem_cache_store:disabled。最后一个值告诉 Rails 不处理会话。也可以指定自定义的会话存储器:

    +
    +
    +config.session_store :my_custom_store
    +
    +
    +
    +

    这个自定义的存储器必须定义为 ActionDispatch::Session::MyCustomStore

    +
  • +
  • config.time_zone 设定应用的默认时区,并让 Active Record 知道。

  • +
+

3.2 配置静态资源

+
    +
  • config.assets.enabled 是个旗标,控制是否启用 Asset Pipeline。默认值为 true

  • +
  • config.assets.raise_runtime_errors 设为 true 时启用额外的运行时错误检查。推荐在 config/environments/development.rb 中设定,以免部署到生产环境时遇到意料之外的错误。

  • +
  • config.assets.css_compressor 定义所用的 CSS 压缩程序。默认设为 sass-rails。目前唯一的另一个值是 :yui,使用 yui-compressor gem 压缩。

  • +
  • config.assets.js_compressor 定义所用的 JavaScript 压缩程序。可用的值有 :closure:uglifier:yui,分别使用 closure-compileruglifieryui-compressor gem。

  • +
  • config.assets.gzip 是一个旗标,设定在静态资源的常规版本之外是否创建 gzip 版本。默认为 true

  • +
  • config.assets.paths 包含查找静态资源的路径。在这个配置选项中追加的路径,会在里面寻找静态资源。

  • +
  • config.assets.precompile 设定运行 rake assets:precompile 任务时要预先编译的其他静态资源(除 application.cssapplication.js 之外)。

  • +
  • config.assets.prefix 定义伺服静态资源的前缀。默认为 /assets

  • +
  • config.assets.manifest 定义静态资源预编译器使用的清单文件的完整路径。默认为 public 文件夹中 config.assets.prefix 设定的目录中的 manifest-<random>.json

  • +
  • config.assets.digest 设定是否在静态资源的名称中包含 MD5 指纹。默认为 true

  • +
  • config.assets.debug 禁止拼接和压缩静态文件。在 development.rb 文件中默认设为 true

  • +
  • config.assets.compile 是一个旗标,设定在生产环境中是否启用实时 Sprockets 编译。

  • +
  • config.assets.logger 接受一个符合 Log4r 接口的日志记录器,或者默认的 Ruby Logger 类。默认值与 config.logger 相同。如果设为 false,不记录对静态资源的伺服。

  • +
+

3.3 配置生成器

Rails 允许通过 config.generators 方法调整生成器的行为。这个方法接受一个块:

+
+config.generators do |g|
+  g.orm :active_record
+  g.test_framework :test_unit
+end
+
+
+
+

在这个块中可以使用的全部方法如下:

+
    +
  • assets 指定在生成脚手架时是否创建静态资源。默认为 true

  • +
  • force_plural 指定模型名是否允许使用复数。默认为 false

  • +
  • helper 指定是否生成辅助模块。默认为 true

  • +
  • integration_tool 指定使用哪个集成工具生成集成测试。默认为 :test_unit

  • +
  • javascripts 启用生成器中的 JavaScript 文件钩子。在 Rails 中供 scaffold 生成器使用。默认为 true

  • +
  • javascript_engine 配置生成静态资源时使用的脚本引擎(如 coffee)。默认为 :js

  • +
  • orm 指定使用哪个 ORM。默认为 false,即使用 Active Record。

  • +
  • resource_controller 指定 rails generate resource 使用哪个生成器生成控制器。默认为 :controller

  • +
  • resource_route 指定是否生成资源路由。默认为 true

  • +
  • scaffold_controllerresource_controller 不同,它指定 rails generate scaffold 使用哪个生成器生成脚手架中的控制器。默认为 :scaffold_controller

  • +
  • stylesheets 启用生成器中的样式表钩子。在 Rails 中供 scaffold 生成器使用,不过也可以供其他生成器使用。默认为 true

  • +
  • stylesheet_engine 配置生成静态资源时使用的样式表引擎(如 sass)。默认为 :css

  • +
  • scaffold_stylesheet 生成脚手架中的资源时创建 scaffold.css。默认为 true

  • +
  • test_framework 指定使用哪个测试框架。默认为 false,即使用 Minitest。

  • +
  • template_engine 指定使用哪个模板引擎,例如 ERB 或 Haml。默认为 :erb

  • +
+

3.4 配置中间件

每个 Rails 应用都自带一系列中间件,在开发环境中按下述顺序使用:

+
    +
  • ActionDispatch::SSL 强制使用 HTTPS 伺服每个请求。config.force_ssl 设为 true 时启用。传给这个中间件的选项通过 config.ssl_options 配置。

  • +
  • ActionDispatch::Static 用于伺服静态资源。config.public_file_server.enabled 设为 false 时禁用。如果静态资源目录的索引文件不是 index,使用 config.public_file_server.index_name 指定。例如,请求目录时如果想伺服 main.html,而不是 index.html,把 config.public_file_server.index_name 设为 "main"

  • +
  • ActionDispatch::Executor 以线程安全的方式重新加载代码。onfig.allow_concurrency 设为 false 时禁用,此时加载 Rack::LockRack::Lock 把应用包装在 mutex 中,因此一次只能被一个线程调用。

  • +
  • ActiveSupport::Cache::Strategy::LocalCache 是基本的内存后端缓存。这个缓存对线程不安全,只应该用作单线程的临时内存缓存。

  • +
  • Rack::Runtime 设定 X-Runtime 首部,包含执行请求的时间(单位为秒)。

  • +
  • Rails::Rack::Logger 通知日志请求开始了。请求完成后,清空相关日志。

  • +
  • ActionDispatch::ShowExceptions 拯救应用抛出的任何异常,在本地或者把 config.consider_all_requests_local 设为 true 时渲染精美的异常页面。如果把 config.action_dispatch.show_exceptions 设为 false,异常总是抛出。

  • +
  • ActionDispatch::RequestId 在响应中添加 X-Request-Id 首部,并且启用 ActionDispatch::Request#uuid 方法。

  • +
  • ActionDispatch::RemoteIp 检查 IP 欺骗攻击,从请求首部中获取有效的 client_ip。可通过 config.action_dispatch.ip_spoofing_checkconfig.action_dispatch.trusted_proxies 配置。

  • +
  • Rack::Sendfile 截获从文件中伺服内容的响应,将其替换成服务器专属的 X-Sendfile 首部。可通过 config.action_dispatch.x_sendfile_header 配置。

  • +
  • ActionDispatch::Callbacks 在伺服请求之前运行准备回调。

  • +
  • ActiveRecord::ConnectionAdapters::ConnectionManagement 在每次请求后清理活跃的连接,除非请求环境的 rack.test 键为 true

  • +
  • ActiveRecord::QueryCache 缓存请求中生成的所有 SELECT 查询。如果有 INSERT 或 UPDATE 查询,清空所有缓存。

  • +
  • ActionDispatch::Cookies 为请求设定 cookie。

  • +
  • ActionDispatch::Session::CookieStore 负责把会话存储在 cookie 中。可以把 config.action_controller.session_store 改为其他值,换成其他中间件。此外,可以使用 config.action_controller.session_options 配置传给这个中间件的选项。

  • +
  • ActionDispatch::Flash 设定 flash 键。仅当为 config.action_controller.session_store 设定值时可用。

  • +
  • Rack::MethodOverride 在设定了 params[:_method] 时允许覆盖请求方法。这是支持 PATCH、PUT 和 DELETE HTTP 请求的中间件。

  • +
  • Rack::Head 把 HEAD 请求转换成 GET 请求,然后以 GET 请求伺服。

  • +
+

除了这些常规中间件之外,还可以使用 config.middleware.use 方法添加:

+
+config.middleware.use Magical::Unicorns
+
+
+
+

上述代码把 Magical::Unicorns 中间件添加到栈的末尾。如果想把中间件添加到另一个中间件的前面,可以使用 insert_before

+
+config.middleware.insert_before Rack::Head, Magical::Unicorns
+
+
+
+

此外,还有 insert_after。它把中间件添加到另一个中间件的后面:

+
+config.middleware.insert_after Rack::Head, Magical::Unicorns
+
+
+
+

中间件也可以完全替换掉:

+
+config.middleware.swap ActionController::Failsafe, Lifo::Failsafe
+
+
+
+

还可以从栈中移除:

+
+config.middleware.delete Rack::MethodOverride
+
+
+
+

3.5 配置 i18n

这些配置选项都委托给 I18n 库。

+
    +
  • config.i18n.available_locales 设定应用可用的本地化白名单。默认为在本地化文件中找到的全部本地化键,在新应用中通常只有 :en

  • +
  • config.i18n.default_locale 设定供 i18n 使用的默认本地化。默认为 :en

  • +
  • config.i18n.enforce_available_locales 确保传给 i18n 的本地化必须在 available_locales 声明的列表中,否则抛出 I18n::InvalidLocale 异常。默认为 true。除非有特别的原因,否则不建议禁用这个选项,因为这是一项安全措施,能防止用户输入无效的本地化。

  • +
  • config.i18n.load_path 设定 Rails 寻找本地化文件的路径。默认为 config/locales/*.{yml,rb}

  • +
+

3.6 配置 Active Record

config.active_record 包含众多配置选项:

+
    +
  • config.active_record.logger 接受符合 Log4r 接口的日志记录器,或者默认的 Ruby Logger 类,然后传给新的数据库连接。可以在 Active Record 模型类或实例上调用 logger 方法获取日志记录器。设为 nil 时禁用日志。

  • +
  • +

    config.active_record.primary_key_prefix_type 用于调整主键列的名称。默认情况下,Rails 假定主键列名为 id(无需配置)。此外有两个选择:

    +
      +
    • 设为 :table_name 时,Customer 类的主键为 customerid
    • +
    • 设为 :table_name_with_underscore 时,Customer 类的主键为 customer_id
    • +
    +
  • +
  • config.active_record.table_name_prefix 设定一个全局字符串,放在表名前面。如果设为 northwest_Customer 类对应的表是 northwest_customers。默认为空字符串。

  • +
  • config.active_record.table_name_suffix 设定一个全局字符串,放在表名后面。如果设为 _northwestCustomer 类对应的表是 customers_northwest。默认为空字符串。

  • +
  • config.active_record.schema_migrations_table_name 设定模式迁移表的名称。

  • +
  • config.active_record.pluralize_table_names 指定 Rails 在数据库中寻找单数还是复数表名。如果设为 true(默认),那么 Customer 类使用 customers 表。如果设为 falseCustomer 类使用 customer 表。

  • +
  • config.active_record.default_timezone 设定从数据库中检索日期和时间时使用 Time.local(设为 :local 时)还是 Time.utc(设为 :utc 时)。默认为 :utc

  • +
  • config.active_record.schema_format 控制把数据库模式转储到文件中时使用的格式。可用的值有::ruby(默认),与所用的数据库无关;:sql,转储 SQL 语句(可能与数据库有关)。

  • +
  • config.active_record.error_on_ignored_order_or_limit 指定批量查询时如果忽略顺序或数量限制是否抛出错误。设为 true 时抛出错误,设为 false 时发出提醒。默认为 false

  • +
  • config.active_record.timestamped_migrations 控制迁移使用整数还是时间戳编号。默认为 true,使用时间戳。如果有多个开发者共同开发同一个应用,建议这么设置。

  • +
  • config.active_record.lock_optimistically 控制 Active Record 是否使用乐观锁。默认为 true

  • +
  • config.active_record.cache_timestamp_format 控制缓存键中时间戳的格式。默认为 :nsec

  • +
  • config.active_record.record_timestamps 是个布尔值选项,控制 createupdate 操作是否更新时间戳。默认值为 true

  • +
  • config.active_record.partial_writes 是个布尔值选项,控制是否使用部分写入(partial write,即更新时是否只设定有变化的属性)。注意,使用部分写入时,还应该使用乐观锁(config.active_record.lock_optimistically),因为并发更新可能写入过期的属性。默认值为 true

  • +
  • config.active_record.maintain_test_schema 是个布尔值选项,控制 Active Record 是否应该在运行测试时让测试数据库的模式与 db/schema.rb(或 db/structure.sql)保持一致。默认为 true

  • +
  • config.active_record.dump_schema_after_migration 是个旗标,控制运行迁移后是否转储模式(db/schema.rbdb/structure.sql)。生成 Rails 应用时,config/environments/production.rb 文件中把它设为 false。如果不设定这个选项,默认为 true

  • +
  • config.active_record.dump_schemas 控制运行 db:structure:dump 任务时转储哪些数据库模式。可用的值有::schema_search_path(默认),转储 schema_search_path 列出的全部模式;:all,不考虑 schema_search_path,始终转储全部模式;以逗号分隔的模式字符串。

  • +
  • config.active_record.belongs_to_required_by_default 是个布尔值选项,控制没有 belongs_to 关联时记录的验证是否失败。

  • +
  • config.active_record.warn_on_records_fetched_greater_than 为查询结果的数量设定一个提醒阈值。如果查询返回的记录数量超过这一阈值,在日志中记录一个提醒。可用于标识可能导致内存泛用的查询。

  • +
  • config.active_record.index_nested_attribute_errors 让嵌套的 has_many 关联错误显示索引。默认为 false

  • +
+

MySQL 适配器添加了一个配置选项:

+
    +
  • +ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans 控制 Active Record 是否把 tinyint(1) 类型的列当做布尔值。默认为 true
  • +
+

模式转储程序添加了一个配置选项:

+
    +
  • +ActiveRecord::SchemaDumper.ignore_tables 指定一个表数组,不包含在生成的模式文件中。如果 config.active_record.schema_format 的值不是 :ruby,这个设置会被忽略。
  • +
+

3.7 配置 Action Controller

config.action_controller 包含众多配置选项:

+
    +
  • config.action_controller.asset_host 设定静态资源的主机。不使用应用自身伺服静态资源,而是通过 CDN 伺服时设定。

  • +
  • config.action_controller.perform_caching 配置应用是否使用 Action Controller 组件提供的缓存功能。默认在开发环境中为 false,在生产环境中为 true

  • +
  • config.action_controller.default_static_extension 配置缓存页面的扩展名。默认为 .html

  • +
  • config.action_controller.include_all_helpers 配置视图辅助方法在任何地方都可用,还是只在相应的控制器中可用。如果设为 falseUsersHelper 模块中的方法只在 UsersController 的视图中可用。如果设为 trueUsersHelper 模块中的方法在任何地方都可用。默认的行为(不明确设为 truefalse)是视图辅助方法在每个控制器中都可用。

  • +
  • config.action_controller.logger 接受符合 Log4r 接口的日志记录器,或者默认的 Ruby Logger 类,用于记录 Action Controller 的信息。设为 nil 时禁用日志。

  • +
  • config.action_controller.request_forgery_protection_token 设定请求伪造的令牌参数名称。调用 protect_from_forgery 默认把它设为 :authenticity_token

  • +
  • config.action_controller.allow_forgery_protection 启用或禁用 CSRF 防护。在测试环境中默认为 false,其他环境默认为 true

  • +
  • config.action_controller.forgery_protection_origin_check 配置是否检查 HTTP Origin 首部与网站的源一致,作为一道额外的 CSRF 防线。

  • +
  • config.action_controller.per_form_csrf_tokens 控制 CSRF 令牌是否只在生成它的方法(动作)中有效。

  • +
  • config.action_controller.relative_url_root 用于告诉 Rails 你把应用部署到子目录中。默认值为 ENV['RAILS_RELATIVE_URL_ROOT']

  • +
  • config.action_controller.permit_all_parameters 设定默认允许批量赋值全部参数。默认值为 false

  • +
  • config.action_controller.action_on_unpermitted_parameters 设定在发现没有允许的参数时记录日志还是抛出异常。设为 :log:raise 时启用。开发和测试环境的默认值是 :log,其他环境的默认值是 false

  • +
  • config.action_controller.always_permitted_parameters 设定一个参数白名单列表,默认始终允许。默认值是 ['controller', 'action']

  • +
+

3.8 配置 Action Dispatch

+
    +
  • config.action_dispatch.session_store 设定存储会话数据的存储器。默认为 :cookie_store;其他有效的值包括 :active_record_store:mem_cache_store 或自定义类的名称。

  • +
  • +

    config.action_dispatch.default_headers 的值是一个散列,设定每个响应默认都有的 HTTP 首部。默认定义的首部有:

    +
    +
    +config.action_dispatch.default_headers = {
    +  'X-Frame-Options' => 'SAMEORIGIN',
    +  'X-XSS-Protection' => '1; mode=block',
    +  'X-Content-Type-Options' => 'nosniff'
    +}
    +
    +
    +
    +
  • +
  • config.action_dispatch.default_charset 指定渲染时使用的默认字符集。默认为 nil

  • +
  • config.action_dispatch.tld_length 设定应用的 TLD(top-level domain,顶级域名)长度。默认为 1

  • +
  • config.action_dispatch.http_auth_salt 设定 HTTP Auth 的盐值。默认为 'http authentication'

  • +
  • config.action_dispatch.signed_cookie_salt 设定签名 cookie 的盐值。默认为 'signed cookie'

  • +
  • config.action_dispatch.encrypted_cookie_salt 设定加密 cookie 的盐值。默认为 'encrypted cookie'

  • +
  • config.action_dispatch.encrypted_signed_cookie_salt 设定签名加密 cookie 的盐值。默认为 'signed encrypted cookie'

  • +
  • config.action_dispatch.perform_deep_munge 配置是否在参数上调用 deep_munge 方法。详情参见 安全指南。默认为 true

  • +
  • +

    config.action_dispatch.rescue_responses 设定异常与 HTTP 状态的对应关系。其值为一个散列,指定异常和状态之间的映射。默认的定义如下:

    +
    +
    +config.action_dispatch.rescue_responses = {
    +  'ActionController::RoutingError'              => :not_found,
    +  'AbstractController::ActionNotFound'          => :not_found,
    +  'ActionController::MethodNotAllowed'          => :method_not_allowed,
    +  'ActionController::UnknownHttpMethod'         => :method_not_allowed,
    +  'ActionController::NotImplemented'            => :not_implemented,
    +  'ActionController::UnknownFormat'             => :not_acceptable,
    +  'ActionController::InvalidAuthenticityToken'  => :unprocessable_entity,
    +  'ActionController::InvalidCrossOriginRequest' => :unprocessable_entity,
    +  'ActionDispatch::ParamsParser::ParseError'    => :bad_request,
    +  'ActionController::BadRequest'                => :bad_request,
    +  'ActionController::ParameterMissing'          => :bad_request,
    +  'Rack::QueryParser::ParameterTypeError'       => :bad_request,
    +  'Rack::QueryParser::InvalidParameterError'    => :bad_request,
    +  'ActiveRecord::RecordNotFound'                => :not_found,
    +  'ActiveRecord::StaleObjectError'              => :conflict,
    +  'ActiveRecord::RecordInvalid'                 => :unprocessable_entity,
    +  'ActiveRecord::RecordNotSaved'                => :unprocessable_entity
    +}
    +
    +
    +
    +

    没有配置的异常映射为 500 Internal Server Error。

    +
  • +
  • ActionDispatch::Callbacks.before 接受一个代码块,在请求之前运行。

  • +
  • ActionDispatch::Callbacks.to_prepare 接受一个块,在 ActionDispatch::Callbacks.before 之后、请求之前运行。在开发环境中每个请求都会运行,但在生产环境或 cache_classes 设为 true 的环境中只运行一次。

  • +
  • ActionDispatch::Callbacks.after 接受一个代码块,在请求之后运行。

  • +
+

3.9 配置 Action View

config.action_view 有一些配置选项:

+
    +
  • +

    config.action_view.field_error_proc 提供一个 HTML 生成器,用于显示 Active Model 抛出的错误。默认为:

    +
    +
    +Proc.new do |html_tag, instance|
    +  %Q(<div class="field_with_errors">#{html_tag}</div>).html_safe
    +end
    +
    +
    +
    +
  • +
  • config.action_view.default_form_builder 告诉 Rails 默认使用哪个表单构造器。默认为 ActionView::Helpers::FormBuilder。如果想在初始化之后加载表单构造器类,把值设为一个字符串。

  • +
  • config.action_view.logger 接受符合 Log4r 接口的日志记录器,或者默认的 Ruby Logger 类,用于记录 Action View 的信息。设为 nil 时禁用日志。

  • +
  • config.action_view.erb_trim_mode 让 ERB 使用修剪模式。默认为 '-',使用 <%= -%><%= =%> 时裁掉尾部的空白和换行符。详情参见 Erubis 的文档

  • +
  • config.action_view.embed_authenticity_token_in_remote_forms 设定具有 remote: true 选项的表单中 authenticity_token 的默认行为。默认设为 false,即远程表单不包含 authenticity_token,对表单做片段缓存时可以这么设。远程表单从 meta 标签中获取真伪令牌,因此除非要支持没有 JavaScript 的浏览器,否则不应该内嵌在表单中。如果想支持没有 JavaScript 的浏览器,可以在表单选项中设定 authenticity_token: true,或者把这个配置设为 true

  • +
  • +

    config.action_view.prefix_partial_path_with_controller_namespace 设定渲染嵌套在命名空间中的控制器时是否在子目录中寻找局部视图。例如,Admin::ArticlesController 渲染这个模板:

    +
    +
    +<%= render @article %>
    +
    +
    +
    +

    默认设置是 true,使用局部视图 /admin/articles/_article.erb。设为 false 时,渲染 /articles/_article.erb——这与渲染没有放入命名空间中的控制器一样,例如 ArticlesController

    +
  • +
  • config.action_view.raise_on_missing_translations 设定缺少翻译时是否抛出错误。

  • +
  • config.action_view.automatically_disable_submit_tag 设定点击提交按钮(submit_tag)时是否自动将其禁用。默认为 true

  • +
  • config.action_view.debug_missing_translation 设定是否把缺少的翻译键放在 <span> 标签中。默认为 true

  • +
+

3.10 配置 Action Mailer

config.action_mailer 有一些配置选项:

+
    +
  • config.action_mailer.logger 接受符合 Log4r 接口的日志记录器,或者默认的 Ruby Logger 类,用于记录 Action Mailer 的信息。设为 nil 时禁用日志。

  • +
  • +

    config.action_mailer.smtp_settings 用于详细配置 :smtp 发送方法。值是一个选项散列,包含下述选项:

    +
      +
    • :address:设定远程邮件服务器的地址。默认为 localhost。
    • +
    • :port:如果邮件服务器不在 25 端口上(很少发生),可以修改这个选项。
    • +
    • :domain:如果需要指定 HELO 域名,通过这个选项设定。
    • +
    • :user_name:如果邮件服务器需要验证身份,通过这个选项设定用户名。
    • +
    • :password:如果邮件服务器需要验证身份,通过这个选项设定密码。
    • +
    • :authentication:如果邮件服务器需要验证身份,要通过这个选项设定验证类型。这个选项的值是一个符号,可以是 :plain:login:cram_md5
    • +
    +
  • +
  • +

    config.action_mailer.sendmail_settings 用于详细配置 sendmail 发送方法。值是一个选项散列,包含下述选项:

    +
      +
    • :location:sendmail 可执行文件的位置。默认为 /usr/sbin/sendmail
    • +
    • :arguments:命令行参数。默认为 -i
    • +
    +
  • +
  • config.action_mailer.raise_delivery_errors 指定无法发送电子邮件时是否抛出错误。默认为 true

  • +
  • config.action_mailer.delivery_method 设定发送方法,默认为 :smtp。详情参见 配置 Action Mailer

  • +
  • config.action_mailer.perform_deliveries 指定是否真的发送邮件,默认为 true。测试时建议设为 false

  • +
  • +

    config.action_mailer.default_options 配置 Action Mailer 的默认值。用于为每封邮件设定 fromreply_to 等选项。设定的默认值为:

    +
    +
    +mime_version:  "1.0",
    +charset:       "UTF-8",
    +content_type: "text/plain",
    +parts_order:  ["text/plain", "text/enriched", "text/html"]
    +
    +
    +
    +

    若想设定额外的选项,使用一个散列:

    +
    +
    +config.action_mailer.default_options = {
    +  from: "noreply@example.com"
    +}
    +
    +
    +
    +
  • +
  • +

    config.action_mailer.observers 注册观测器(observer),发送邮件时收到通知。

    +
    +
    +config.action_mailer.observers = ["MailObserver"]
    +
    +
    +
    +
  • +
  • +

    config.action_mailer.interceptors 注册侦听器(interceptor),在发送邮件前调用。

    +
    +
    +config.action_mailer.interceptors = ["MailInterceptor"]
    +
    +
    +
    +
  • +
  • +

    config.action_mailer.preview_path 指定邮件程序预览的位置。

    +
    +
    +config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
    +
    +
    +
    +
  • +
  • +

    config.action_mailer.show_previews 启用或禁用邮件程序预览。开发环境默认为 true

    +
    +
    +config.action_mailer.show_previews = false
    +
    +
    +
    +
  • +
  • config.action_mailer.deliver_later_queue_name 设定邮件程序的队列名称。默认为 mailers

  • +
  • config.action_mailer.perform_caching 指定是否片段缓存邮件模板。在所有环境中默认为 false

  • +
+

3.11 配置 Active Support

Active Support 有一些配置选项:

+
    +
  • config.active_support.bare 指定在启动 Rails 时是否加载 active_support/all。默认为 nil,即加载 active_support/all

  • +
  • config.active_support.test_order 设定执行测试用例的顺序。可用的值是 :random:sorted。对新生成的应用来说,在 config/environments/test.rb 文件中设为 :random。如果应用没指定测试顺序,在 Rails 5.0 之前默认为 :sorted,之后默认为 :random

  • +
  • config.active_support.escape_html_entities_in_json 指定在 JSON 序列化中是否转义 HTML 实体。默认为 true

  • +
  • config.active_support.use_standard_json_time_format 指定是否把日期序列化成 ISO 8601 格式。默认为 true

  • +
  • config.active_support.time_precision 设定 JSON 编码的时间值的精度。默认为 3

  • +
  • ActiveSupport.halt_callback_chains_on_return_false 指定是否可以通过在前置回调中返回 false 停止 Active Record 和 Active Model 回调链。设为 false 时,只能通过 throw(:abort) 停止回调链。设为 true 时,可以通过返回 false 停止回调链(Rails 5 之前版本的行为),但是会发出弃用提醒。在弃用期内默认为 true。新的 Rails 5 应用会生成一个名为 callback_terminator.rb 的初始化文件,把值设为 false。执行 rails app:update 命令时不会添加这个文件,因此把旧应用升级到 Rails 5 后依然可以通过返回 false 停止回调链,不过会显示弃用提醒,提示用户升级代码。

  • +
  • ActiveSupport::Logger.silencer 设为 false 时静默块的日志。默认为 true

  • +
  • ActiveSupport::Cache::Store.logger 指定缓存存储操作使用的日志记录器。

  • +
  • ActiveSupport::Deprecation.behavior 的作用与 config.active_support.deprecation 相同,用于配置 Rails 弃用提醒的行为。

  • +
  • ActiveSupport::Deprecation.silence 接受一个块,块里的所有弃用提醒都静默。

  • +
  • ActiveSupport::Deprecation.silenced 设定是否显示弃用提醒。

  • +
+

3.12 配置 Active Job

config.active_job 提供了下述配置选项:

+
    +
  • +

    config.active_job.queue_adapter 设定队列后端的适配器。默认的适配器是 :async。最新的内置适配器参见 ActiveJob::QueueAdapters 的 API 文档

    +
    +
    +# 要把适配器的 gem 写入 Gemfile
    +# 请参照适配器的具体安装和部署说明
    +config.active_job.queue_adapter = :sidekiq
    +
    +
    +
    +
  • +
  • +

    config.active_job.default_queue_name 用于修改默认的队列名称。默认为 "default"

    +
    +
    +config.active_job.default_queue_name = :medium_priority
    +
    +
    +
    +
  • +
  • +

    config.active_job.queue_name_prefix 用于为所有作业设定队列名称的前缀(可选)。默认为空,不使用前缀。

    +

    做下述配置后,在生产环境中运行时把指定作业放入 production_high_priority 队列中:

    +
    +
    +config.active_job.queue_name_prefix = Rails.env
    +
    +
    +
    +
    +
    +class GuestsCleanupJob < ActiveJob::Base
    +  queue_as :high_priority
    +  #....
    +end
    +
    +
    +
    +
  • +
  • +

    config.active_job.queue_name_delimiter 的默认值是 '_'。如果设定了 queue_name_prefix,使用 queue_name_delimiter 连接前缀和队列名。

    +

    下述配置把指定作业放入 video_server.low_priority 队列中:

    +
    +
    +# 设定了前缀才会使用分隔符
    +config.active_job.queue_name_prefix = 'video_server'
    +config.active_job.queue_name_delimiter = '.'
    +
    +
    +
    +
    +
    +class EncoderJob < ActiveJob::Base
    +  queue_as :low_priority
    +  #....
    +end
    +
    +
    +
    +
  • +
  • config.active_job.logger 接受符合 Log4r 接口的日志记录器,或者默认的 Ruby Logger 类,用于记录 Action Job 的信息。在 Active Job 类或实例上调用 logger 方法可以获取日志记录器。设为 nil 时禁用日志。

  • +
+

3.13 配置 Action Cable

+
    +
  • config.action_cable.url 的值是一个 URL 字符串,指定 Action Cable 服务器的地址。如果 Action Cable 服务器与主应用的服务器不同,可以使用这个选项。

  • +
  • config.action_cable.mount_path 的值是一个字符串,指定把 Action Cable 挂载在哪里,作为主服务器进程的一部分。默认为 /cable。可以设为 nil,不把 Action Cable 挂载为常规 Rails 服务器的一部分。

  • +
+

3.14 配置数据库

几乎所有 Rails 应用都要与数据库交互。可以通过环境变量 ENV['DATABASE_URL']config/database.yml 配置文件中的信息连接数据库。

config/database.yml 文件中可以指定访问数据库所需的全部信息:

+
+development:
+  adapter: postgresql
+  database: blog_development
+  pool: 5
+
+
+
+

此时使用 postgresql 适配器连接名为 blog_development 的数据库。这些信息也可以存储在一个 URL 中,然后通过环境变量提供,如下所示:

+
+> puts ENV['DATABASE_URL']
+postgresql://localhost/blog_development?pool=5
+
+
+
+

config/database.yml 文件分成三部分,分别对应 Rails 默认支持的三个环境:

+
    +
  • development 环境在开发(本地)电脑中使用,手动与应用交互。

  • +
  • test 环境用于运行自动化测试。

  • +
  • production 环境在把应用部署到线上时使用。

  • +
+

如果愿意,可以在 config/database.yml 文件中指定连接 URL:

+
+development:
+  url: postgresql://localhost/blog_development?pool=5
+
+
+
+

config/database.yml 文件中可以包含 ERB 标签 <%= %>。这个标签中的内容作为 Ruby 代码执行。可以使用这个标签从环境变量中获取数据,或者执行计算,生成所需的连接信息。

无需自己动手更新数据库配置。如果查看应用生成器的选项,你会发现其中一个名为 --database。通过这个选项可以从最常使用的关系数据库中选择一个。甚至还可以重复运行这个生成器:cd .. && rails new blog --database=mysql。同意重写 config/database.yml 文件后,应用的配置会针对 MySQL 更新。常见的数据库连接示例参见下文。

3.15 连接配置的优先级

因为有两种配置连接的方式(使用 config/database.yml 文件或者一个环境变量),所以要明白二者之间的关系。

如果 config/database.yml 文件为空,而 ENV['DATABASE_URL'] 有值,那么 Rails 使用环境变量连接数据库:

+
+$ cat config/database.yml
+
+$ echo $DATABASE_URL
+postgresql://localhost/my_database
+
+
+
+

如果在 config/database.yml 文件中做了配置,而 ENV['DATABASE_URL'] 没有值,那么 Rails 使用这个文件中的信息连接数据库:

+
+$ cat config/database.yml
+development:
+  adapter: postgresql
+  database: my_database
+  host: localhost
+
+$ echo $DATABASE_URL
+
+
+
+

如果 config/database.yml 文件中做了配置,而且 ENV['DATABASE_URL'] 有值,Rails 会把二者合并到一起。为了更好地理解,必须看些示例。

如果连接信息有重复,环境变量中的信息优先级高:

+
+$ cat config/database.yml
+development:
+  adapter: sqlite3
+  database: NOT_my_database
+  host: localhost
+
+$ echo $DATABASE_URL
+postgresql://localhost/my_database
+
+$ bin/rails runner 'puts ActiveRecord::Base.configurations'
+{"development"=>{"adapter"=>"postgresql", "host"=>"localhost", "database"=>"my_database"}}
+
+
+
+

可以看出,适配器、主机和数据库与 ENV['DATABASE_URL'] 中的信息匹配。

如果信息无重复,都是唯一的,遇到冲突时还是环境变量中的信息优先级高:

+
+$ cat config/database.yml
+development:
+  adapter: sqlite3
+  pool: 5
+
+$ echo $DATABASE_URL
+postgresql://localhost/my_database
+
+$ bin/rails runner 'puts ActiveRecord::Base.configurations'
+{"development"=>{"adapter"=>"postgresql", "host"=>"localhost", "database"=>"my_database", "pool"=>5}}
+
+
+
+

ENV['DATABASE_URL'] 没有提供连接池数量,因此从文件中获取。而两处都有 adapter,因此 ENV['DATABASE_URL'] 中的连接信息胜出。

如果不想使用 ENV['DATABASE_URL'] 中的连接信息,唯一的方法是使用 "url" 子键指定一个 URL:

+
+$ cat config/database.yml
+development:
+  url: sqlite3:NOT_my_database
+
+$ echo $DATABASE_URL
+postgresql://localhost/my_database
+
+$ bin/rails runner 'puts ActiveRecord::Base.configurations'
+{"development"=>{"adapter"=>"sqlite3", "database"=>"NOT_my_database"}}
+
+
+
+

这里,ENV['DATABASE_URL'] 中的连接信息被忽略了。注意,适配器和数据库名称不同了。

因为在 config/database.yml 文件中可以内嵌 ERB,所以最好明确表明使用 ENV['DATABASE_URL'] 连接数据库。这在生产环境中特别有用,因为不应该把机密信息(如数据库密码)提交到源码控制系统中(如 Git)。

+
+$ cat config/database.yml
+production:
+  url: <%= ENV['DATABASE_URL'] %>
+
+
+
+

现在的行为很明确,只使用 <%= ENV['DATABASE_URL'] %> 中的连接信息。

3.15.1 配置 SQLite3 数据库

Rails 内建支持 SQLite3,这是一个轻量级无服务器数据库应用。SQLite 可能无法负担生产环境,但是在开发和测试环境中用着很好。新建 Rails 项目时,默认使用 SQLite 数据库,不过之后可以随时更换。

下面是默认配置文件(config/database.yml)中开发环境的连接信息:

+
+development:
+  adapter: sqlite3
+  database: db/development.sqlite3
+  pool: 5
+  timeout: 5000
+
+
+
+

Rails 默认使用 SQLite3 存储数据,因为它无需配置,立即就能使用。Rails 还原生支持 MySQL(含 MariaDB)和 PostgreSQL,此外还有针对其他多种数据库系统的插件。在生产环境中使用的数据库,基本上都有相应的 Rails 适配器。

3.15.2 配置 MySQL 或 MariaDB 数据库

如果选择使用 MySQL 或 MariaDB,而不是 SQLite3,config/database.yml 文件的内容稍有不同。下面是开发环境的连接信息:

+
+development:
+  adapter: mysql2
+  encoding: utf8
+  database: blog_development
+  pool: 5
+  username: root
+  password:
+  socket: /tmp/mysql.sock
+
+
+
+

如果开发数据库使用 root 用户,而且没有密码,这样配置就行了。否则,要相应地修改 development 部分的用户名和密码。

3.15.3 配置 PostgreSQL 数据库

如果选择使用 PostgreSQL,config/database.yml 文件会针对 PostgreSQL 数据库定制:

+
+development:
+  adapter: postgresql
+  encoding: unicode
+  database: blog_development
+  pool: 5
+
+
+
+

PostgreSQL 默认启用预处理语句(prepared statement)。若想禁用,把 prepared_statements 设为 false

+
+production:
+  adapter: postgresql
+  prepared_statements: false
+
+
+
+

如果启用,Active Record 默认最多为一个数据库连接创建 1000 个预处理语句。若想修改,可以把 statement_limit 设定为其他值:

+
+production:
+  adapter: postgresql
+  statement_limit: 200
+
+
+
+

预处理语句的数量越多,数据库消耗的内存越多。如果 PostgreSQL 数据库触及内存上限,尝试降低 statement_limit 的值,或者禁用预处理语句。

3.15.4 为 JRuby 平台配置 SQLite3 数据库

如果选择在 JRuby 中使用 SQLite3,config/database.yml 文件的内容稍有不同。下面是 development 部分:

+
+development:
+  adapter: jdbcsqlite3
+  database: db/development.sqlite3
+
+
+
+
3.15.5 为 JRuby 平台配置 MySQL 或 MariaDB 数据库

如果选择在 JRuby 中使用 MySQL 或 MariaDB,config/database.yml 文件的内容稍有不同。下面是 development 部分:

+
+development:
+  adapter: jdbcmysql
+  database: blog_development
+  username: root
+  password:
+
+
+
+
3.15.6 为 JRuby 平台配置 PostgreSQL 数据库

如果选择在 JRuby 中使用 PostgreSQL,config/database.yml 文件的内容稍有不同。下面是 development 部分:

+
+development:
+  adapter: jdbcpostgresql
+  encoding: unicode
+  database: blog_development
+  username: blog
+  password:
+
+
+
+

请根据需要修改 development 部分的用户名和密码。

3.16 创建 Rails 环境

Rails 默认提供三个环境:开发环境、测试环境和生产环境。多数情况下,这就够用了,但有时可能需要更多环境。

比如说想要一个服务器,镜像生产环境,但是只用于测试。这样的服务器通常称为“交付准备服务器”。如果想为这个服务器创建名为“staging”的环境,只需创建 config/environments/staging.rb 文件。请参照 config/environments 目录中的现有文件,根据需要修改。

自己创建的环境与默认的没有区别,启动服务器使用 rails server -e staging,启动控制台使用 rails console stagingRails.env.staging? 也能正常使用,等等。

3.17 部署到子目录(URL 相对于根路径)

默认情况下,Rails 预期应用在根路径(即 /)上运行。本节说明如何在目录中运行应用。

假设我们想把应用部署到“/app1”。Rails 要知道这个目录,这样才能生成相应的路由:

+
+config.relative_url_root = "/app1"
+
+
+
+

此外,也可以设定 RAILS_RELATIVE_URL_ROOT 环境变量。

现在生成链接时,Rails 会在前面加上“/app1”。

3.17.1 使用 Passenger

使用 Passenger 在子目录中运行应用很简单。相关配置参阅 Passenger 手册

3.17.2 使用反向代理

使用反向代理部署应用比传统方式有明显的优势:对服务器有更好的控制,因为应用所需的组件可以分层。

有很多现代的 Web 服务器可以用作代理服务器,用来均衡第三方服务器,如缓存服务器或应用服务器。

Unicorn 就是这样的应用服务器,在反向代理后面运行。

此时,要配置代理服务器(NGINX、Apache,等等),让它接收来自应用服务器(Unicorn)的连接。Unicorn 默认监听 8080 端口上的 TCP 连接,不过可以更换端口,或者换用套接字。

详情参阅 Unicorn 的自述文件,还可以了解背后的哲学

配置好应用服务器之后,还要相应配置 Web 服务器,把请求代理过去。例如,NGINX 的配置可能包含:

+
+upstream application_server {
+  server 0.0.0.0:8080
+}
+
+server {
+  listen 80;
+  server_name localhost;
+
+  root /root/path/to/your_app/public;
+
+  try_files $uri/index.html $uri.html @app;
+
+  location @app {
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Host $http_host;
+    proxy_redirect off;
+    proxy_pass http://application_server;
+  }
+
+  # 其他配置
+}
+
+
+
+

最新的信息参阅 NGINX 的文档

4 Rails 环境设置

Rails 的某些部分还可以通过环境变量在外部配置。Rails 能识别下述几个环境变量:

+
    +
  • ENV["RAILS_ENV"] 定义在哪个环境(生产环境、开发环境、测试环境,等等)中运行 Rails。

  • +
  • ENV["RAILS_RELATIVE_URL_ROOT"]部署到子目录中时供路由代码识别 URL。

  • +
  • ENV["RAILS_CACHE_ID"]ENV["RAILS_APP_VERSION"] 供 Rails 的缓存代码生成扩张的缓存键。这样可以在同一个应用中使用多个单独的缓存。

  • +
+

5 使用初始化脚本文件

加载完框架和应用依赖的 gem 之后,Rails 开始加载初始化脚本。初始化脚本是 Ruby 文件,存储在应用的 config/initializers 目录中。可以在初始化脚本中存放应该于加载完框架和 gem 之后设定的配置,例如配置各部分的设置项目的选项。

如果愿意,可以使用子文件夹组织初始化脚本,Rails 会自上而下查找整个文件夹层次结构。

如果初始化脚本有顺序要求,可以通过名称控制加载顺序。初始化脚本文件按照路径的字母表顺序加载。例如,01_critical.rb02_normal.rb 前面加载。

6 初始化事件

Rails 有 5 个初始化事件(按运行顺序列出):

+
    +
  • before_configuration:在应用常量继承 Rails::Application 时立即运行。config 调用在此之前执行。

  • +
  • before_initialize:直接在应用初始化过程之前运行,与 Rails 初始化过程靠近开头的 :bootstrap_hook 初始化脚本一起运行。

  • +
  • to_prepare:在所有 Railtie(包括应用自身)的初始化脚本运行结束之后、及早加载和构架中间件栈之前运行。更重要的是,在开发环境中每次请求都运行,而在生产和测试环境只运行一次(在启动过程中)。

  • +
  • before_eager_load:在及早加载之前直接运行。这是生产环境的默认行为,开发环境则不然。

  • +
  • after_initialize:在应用初始化之后、config/initializers 中的初始化脚本都运行完毕后直接运行。

  • +
+

若想为这些钩子定义事件,在 Rails::ApplicationRails::RailtieRails::Engine 子类中使用块句法:

+
+module YourApp
+  class Application < Rails::Application
+    config.before_initialize do
+      # 在这编写初始化代码
+    end
+  end
+end
+
+
+
+

此外,还可以通过 Rails.application 对象的 config 方法定义:

+
+Rails.application.config.before_initialize do
+  # 在这编写初始化代码
+end
+
+
+
+

调用 after_initialize 块时,应用的某些部分,尤其是路由,尚不可用。

6.1 Rails::Railtie#initializer +

有几个在启动时运行的 Rails 初始化脚本使用 Rails::Railtie 对象的 initializer 方法定义。下面以 Action Controller 中的 set_helpers_path 初始化脚本为例:

+
+initializer "action_controller.set_helpers_path" do |app|
+  ActionController::Helpers.helpers_path = app.helpers_paths
+end
+
+
+
+

initializer 方法接受三个参数,第一个是初始化脚本的名称,第二个是选项散列(上例中没有),第三个是一个块。选项散列的 :before 键指定在哪个初始化脚本之前运行,:after 键指定在哪个初始化脚本之后运行。

initializer 方法定义的初始化脚本按照定义的顺序运行,除非指定了 :before:after 键。

只要符合逻辑,可以设定一个初始化脚本在另一个之前或之后运行。假如有四个初始化脚本,名称分别为“one”到“four”(按照这个顺序定义)。如果定义“four”在“four”之前、“three”之后运行就不合逻辑,Rails 无法确定初始化脚本的执行顺序。

initializer 方法的块参数是应用自身的实例,因此可以像示例中那样使用 config 方法访问配置。

因为 Rails::Application(间接)继承自 Rails::Railtie,所以可以在 config/application.rb 文件中使用 initializer 方法为应用定义初始化脚本。

6.2 初始化脚本

下面按定义顺序(因此以此顺序运行,除非另行说明)列出 Rails 中的全部初始化脚本:

+
    +
  • load_environment_hook:一个占位符,让 :load_environment_config 在此之前运行。

  • +
  • load_active_support:引入 active_support/dependencies,设置 Active Support 的基本功能。如果 config.active_support.bare 为假值(默认),引入 active_support/all

  • +
  • initialize_logger:初始化应用的日志记录器(一个 ActiveSupport::Logger 对象),可通过 Rails.logger 访问。假定在此之前的初始化脚本没有定义 Rails.logger

  • +
  • initialize_cache:如果没有设置 Rails.cache,使用 config.cache_store 的值初始化缓存,把结果存储为 Rails.cache。如果这个对象响应 middleware 方法,它的中间件插入 Rack::Runtime 之前。

  • +
  • set_clear_dependencies_hook:这个初始化脚本(仅当 cache_classes 设为 false 时运行)使用 ActionDispatch::Callbacks.after 从对象空间中删除请求过程中引用的常量,以便在后续请求中重新加载。

  • +
  • initialize_dependency_mechanism:如果 config.cache_classes 为真,配置 ActiveSupport::Dependencies.mechanism 使用 require 引入依赖,而不使用 load

  • +
  • bootstrap_hook:运行配置的全部 before_initialize 块。

  • +
  • i18n.callbacks:在开发环境中设置一个 to_prepare 回调,如果自上次请求后本地化有变,调用 I18n.reload!。在生产环境,这个回调只在第一次请求时运行。

  • +
  • active_support.deprecation_behavior:设定各个环境报告弃用的方式,在开发环境中默认为 :log,在生产环境中默认为 :notify,在测试环境中默认为 :stderr。如果没为 config.active_support.deprecation 设定一个值,这个初始化脚本提示用户在当前环境的配置文件(config/environments 目录里)中设定。可以设为一个数组。

  • +
  • active_support.initialize_time_zone:根据 config.time_zone 设置为应用设定默认的时区。默认为“UTC”。

  • +
  • active_support.initialize_beginning_of_week:根据 config.beginning_of_week 设置为应用设定一周从哪一天开始。默认为 :monday

  • +
  • active_support.set_configs:使用 config.active_support 设置 Active Support,把方法名作为设值方法发给 ActiveSupport,并传入选项的值。

  • +
  • action_dispatch.configure:配置 ActionDispatch::Http::URL.tld_length,设为 config.action_dispatch.tld_length 的值。

  • +
  • action_view.set_configs:使用 config.action_view 设置 Action View,把方法名作为设值方法发给 ActionView::Base,并传入选项的值。

  • +
  • action_controller.assets_config:如果没有明确配置,把 config.actions_controller.assets_dir 设为应用的 public 目录。

  • +
  • action_controller.set_helpers_path:把 Action Controller 的 helpers_path 设为应用的 helpers_path

  • +
  • action_controller.parameters_config:为 ActionController::Parameters 配置健壮参数选项。

  • +
  • action_controller.set_configs:使用 config.action_controller 设置 Action Controller,把方法名作为设值方法发给 ActionController::Base,并传入选项的值。

  • +
  • action_controller.compile_config_methods:初始化指定的配置选项,得到方法,以便快速访问。

  • +
  • active_record.initialize_timezone:把 ActiveRecord::Base.time_zone_aware_attributes 设为 true,并把 ActiveRecord::Base.default_timezone 设为 UTC。从数据库中读取属性时,转换成 Time.zone 指定的时区。

  • +
  • active_record.logger:把 ActiveRecord::Base.logger 设为 Rails.logger(如果还未设定)。

  • +
  • active_record.migration_error:配置中间件,检查待运行的迁移。

  • +
  • active_record.check_schema_cache_dump:如果配置了,而且有缓存,加载模式缓存转储。

  • +
  • active_record.warn_on_records_fetched_greater_than:查询返回大量记录时启用提醒。

  • +
  • active_record.set_configs:使用 config.active_record 设置 Active Record,把方法名作为设值方法发给 ActiveRecord::Base,并传入选项的值。

  • +
  • active_record.initialize_database:从 config/database.yml 中加载数据库配置,并在当前环境中连接数据库。

  • +
  • active_record.log_runtime:引入 ActiveRecord::Railties::ControllerRuntime,把 Active Record 调用的耗时记录到日志中。

  • +
  • active_record.set_reloader_hooks:如果 config.cache_classes 设为 false,还原所有可重新加载的数据库连接。

  • +
  • active_record.add_watchable_files:把 schema.rbstructure.sql 添加到可监视的文件列表中。

  • +
  • active_job.logger:把 ActiveJob::Base.logger 设为 Rails.logger(如果还未设定)。

  • +
  • active_job.set_configs:使用 config.active_job 设置 Active Job,把方法名作为设值方法发给 ActiveJob::Base,并传入选项的值。

  • +
  • action_mailer.logger:把 ActionMailer::Base.logger 设为 Rails.logger(如果还未设定)。

  • +
  • action_mailer.set_configs:使用 config.action_mailer 设定 Action Mailer,把方法名作为设值方法发给 ActionMailer::Base,并传入选项的值。

  • +
  • action_mailer.compile_config_methods:初始化指定的配置选项,得到方法,以便快速访问。

  • +
  • set_load_path:在 bootstrap_hook 之前运行。把 config.load_paths 指定的路径和所有自动加载路径添加到 $LOAD_PATH 中。

  • +
  • set_autoload_paths:在 bootstrap_hook 之前运行。把 app 目录中的所有子目录,以及 config.autoload_pathsconfig.eager_load_pathsconfig.autoload_once_paths 指定的路径添加到 ActiveSupport::Dependencies.autoload_paths 中。

  • +
  • add_routing_paths:加载所有的 config/routes.rb 文件(应用和 Railtie 中的,包括引擎),然后设置应用的路由。

  • +
  • add_locales:把(应用、Railtie 和引擎的)config/locales 目录中的文件添加到 I18n.load_path 中,让那些文件中的翻译可用。

  • +
  • add_view_paths:把应用、Railtie 和引擎的 app/views 目录添加到应用查找视图文件的路径中。

  • +
  • load_environment_config:加载 config/environments 目录中针对当前环境的配置文件。

  • +
  • prepend_helpers_path:把应用、Railtie 和引擎中的 app/helpers 目录添加到应用查找辅助方法的路径中。

  • +
  • load_config_initializers:加载应用、Railtie 和引擎中 config/initializers 目录里的全部 Ruby 文件。这个目录中的文件可用于存放应该在加载完全部框架之后设定的设置。

  • +
  • engines_blank_point:在初始化过程中提供一个点,以便在加载引擎之前做些事情。在这一点之后,运行所有 Railtie 和引擎初始化脚本。

  • +
  • add_generator_templates:寻找应用、Railtie 和引擎中 lib/templates 目录里的生成器模板,把它们添加到 config.generators.templates 设置中,供所有生成器引用。

  • +
  • ensure_autoload_once_paths_as_subset:确保 config.autoload_once_paths 只包含 config.autoload_paths 中的路径。如果有额外路径,抛出异常。

  • +
  • add_to_prepare_blocks:把应用、Railtie 或引擎中的每个 config.to_prepare 调用都添加到 Action Dispatch 的 to_prepare 回调中。这些回调在开发环境中每次请求都运行,在生产环境中只在第一次请求之前运行。

  • +
  • add_builtin_route:如果应用在开发环境中运行,把针对 rails/info/properties 的路由添加到应用的路由中。这个路由在 Rails 应用的 public/index.html 文件中提供一些详细信息,例如 Rails 和 Ruby 的版本。

  • +
  • build_middleware_stack:为应用构建中间件栈,返回一个对象,它有一个 call 方法,参数是请求的 Rack 环境对象。

  • +
  • eager_load!:如果 config.eager_loadtrue,运行 config.before_eager_load 钩子,然后调用 eager_load!,加载全部 config.eager_load_namespaces

  • +
  • finisher_hook:在应用初始化过程结束的位置提供一个钩子,并且运行应用、Railtie 和引擎的所有 config.after_initialize 块。

  • +
  • set_routes_reloader:让 Action Dispatch 使用 ActionDispatch::Callbacks.to_prepare 重新加载路由文件。

  • +
  • disable_dependency_loading:如果 config.eager_loadtrue,禁止自动加载依赖。

  • +
+

7 数据库池

Active Record 数据库连接由 ActiveRecord::ConnectionAdapters::ConnectionPool 管理,确保连接池的线程访问量与有限个数据库连接数同步。这一限制默认为 5,可以在 database.yml 文件中配置。

+
+development:
+  adapter: sqlite3
+  database: db/development.sqlite3
+  pool: 5
+  timeout: 5000
+
+
+
+

连接池默认在 Active Record 内部处理,因此所有应用服务器(Thin、mongrel、Unicorn,等等)的行为应该一致。数据库连接池一开始是空的,随着连接数的增加,会不断创建,直至连接池上限。

每个请求在首次访问数据库时会检出连接,请求结束再检入连接。这样,空出的连接位置就可以提供给队列中的下一个请求使用。

如果连接数超过可用值,Active Record 会阻塞,等待池中有空闲的连接。如果无法获得连接,会抛出类似下面的超时错误。

+
+ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)
+
+
+
+

如果出现上述错误,可以考虑增加连接池的数量,即在 database.yml 文件中增加 pool 选项的值。

如果是多线程环境,有可能多个线程同时访问多个连接。因此,如果请求量很大,极有可能发生多个线程争夺有限个连接的情况。

8 自定义配置

我们可以通过 Rails 配置对象为自己的代码设定配置。如下所示:

+
+config.payment_processing.schedule = :daily
+config.payment_processing.retries  = 3
+config.super_debugger = true
+
+
+
+

这些配置选项可通过配置对象访问:

+
+Rails.configuration.payment_processing.schedule # => :daily
+Rails.configuration.payment_processing.retries  # => 3
+Rails.configuration.super_debugger              # => true
+Rails.configuration.super_debugger.not_set      # => nil
+
+
+
+

还可以使用 Rails::Application.config_for 加载整个配置文件:

+
+# config/payment.yml:
+production:
+  environment: production
+  merchant_id: production_merchant_id
+  public_key:  production_public_key
+  private_key: production_private_key
+development:
+  environment: sandbox
+  merchant_id: development_merchant_id
+  public_key:  development_public_key
+  private_key: development_private_key
+
+
+
+
+
+# config/application.rb
+module MyApp
+  class Application < Rails::Application
+    config.payment = config_for(:payment)
+  end
+end
+
+
+
+
+
+Rails.configuration.payment['merchant_id'] # => production_merchant_id or development_merchant_id
+
+
+
+

9 搜索引擎索引

有时,你可能不想让应用中的某些页面出现在搜索网站中,如 Google、Bing、Yahoo 或 Duck Duck Go。索引网站的机器人首先分析 http://your-site.com/robots.txt 文件,了解允许它索引哪些页面。

Rails 为你创建了这个文件,在 /public 文件夹中。默认情况下,允许搜索引擎索引应用的所有页面。如果不想索引应用的任何页面,使用下述内容:

+
+User-agent: *
+Disallow: /
+
+
+
+

若想禁止索引指定的页面,需要使用更复杂的句法。详情参见官方文档

10 事件型文件系统监控程序

如果加载了 listen gem,而且 config.cache_classesfalse,Rails 使用一个事件型文件系统监控程序监测变化:

+
+group :development do
+  gem 'listen', '~> 3.0.4'
+end
+
+
+
+

否则,每次请求 Rails 都会遍历应用树,检查有没有变化。

在 Linux 和 macOS 中无需额外的 gem,*BSDWindows 可能需要。

注意,某些设置不支持

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/contributing_to_ruby_on_rails.html b/contributing_to_ruby_on_rails.html new file mode 100644 index 0000000..02885cf --- /dev/null +++ b/contributing_to_ruby_on_rails.html @@ -0,0 +1,641 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

为 Ruby on Rails 做贡献

本文介绍几种参与 Ruby on Rails 开发的方式。

读完本文后,您将学到:

+
    +
  • 如何使用 GitHub 报告问题;

  • +
  • 如果克隆 master,运行测试组件;

  • +
  • 如何帮助解决现有问题;

  • +
  • 如何为 Ruby on Rails 文档做贡献;

  • +
  • 如何为 Ruby on Rails 代码做贡献。

  • +
+

Ruby on Rails 不是某一个人的框架。这些年,有成百上千个人为 Ruby on Rails 做贡献,小到修正一个字符,大到调整重要的架构或文档——目的都是把 Ruby on Rails 变得更好,适合所有人使用。即便你现在不想编写代码或文档,也能通过其他方式做贡献,例如报告问题和测试补丁。

Rails 的自述文件说道,参与 Rails 及其子项目代码基开发的人,参与问题追踪系统、聊天室和邮件列表的人,都要遵守 Rails 的行为准则

1 报告错误

Ruby on Rails 使用 GitHub 的问题追踪系统追踪问题(主要是解决缺陷和贡献新代码)。如果你发现 Ruby on Rails 有缺陷,首先应该发布到这个系统中。若想提交问题、评论问题或创建拉取请求, 你要注册一个 GitHub 账户(免费)。

Ruby on Rails 最新版的缺陷最受关注。此外,Rails 核心团队始终欢迎能对最新开发版做测试的人反馈。本文后面会说明如何测试最新开发版。

1.1 创建一个缺陷报告

如果你在 Ruby on Rails 中发现一个没有安全风险的问题,在 GitHub 的问题追踪系统中搜索一下,说不定已经有人报告了。如果之前没有人报告,接下来你要创建一个。(报告安全问题的方法参见下一节。)

问题报告应该包含标题,而且要使用简洁的语言描述问题。你应该尽量多提供相关的信息,而且至少要有一个代码示例,演示所述的问题。如果能提供一个单元测试,说明预期行为更好。你的目标是让你自己以及其他人能重现缺陷,找出修正方法。

然后,耐心等待。除非你报告的是紧急问题,会导致世界末日,否则你要等待可能有其他人也遇到同样的问题,与你一起去解决。不要期望你报告的问题能立即得到关注,有人立刻着手解决。像这样报告问题基本上是让自己迈出修正问题的第一步,并且让其他遇到同样问题的人复议。

1.2 创建可执行的测试用例

提供重现问题的方式有助于别人帮你确认、研究并最终解决问题。为此,你可以提供可执行的测试用例。为了简化这一过程,我们准备了几个缺陷报告模板供你参考:

+
    +
  • 报告 Active Record(模型、数据库)问题的模板:gem / master

  • +
  • 报告 Action Pack(控制器、路由)问题的模板:gem / master

  • +
  • 其他问题的通用模板:gem / master

  • +
+

这些模板包含样板代码,供你着手编写测试用例,分别针对 Rails 的发布版(*_gem.rb)和最新开发版(*_master.rb)。

你只需把相应模板中的内容复制到一个 .rb 文件中,然后做必要的改动,说明问题。如果想运行测试,只需在终端里执行 ruby the_file.rb。如果一切顺利,测试用例应该失败。

随后,可以通过一个 gist 分享你的可执行测试用例,或者直接粘贴到问题描述中。

1.3 特殊对待安全问题

请不要在公开的 GitHub 问题报告中报告安全漏洞。安全问题的报告步骤在 Rails 安全方针页面中有详细说明。

1.4 功能请求怎么办?

请勿在 GitHub 问题追踪系统中请求新功能。如果你想把新功能添加到 Ruby on Rails 中,你要自己编写代码,或者说服他人与你一起编写代码。本文后面会详述如何为 Ruby on Rails 提请补丁。如果在 GitHub 问题追踪系统发布希望含有的功能,但是没有提供代码,在审核阶段会将其标记为“无效”。

有时,很难区分“缺陷”和“功能”。一般来说,功能是为了添加新行为,而缺陷是导致不正确行为的缘由。有时,核心团队会做判断。尽管如此,区别通常影响的是补丁放在哪个发布版中。我们十分欢迎你提交功能!只不过,新功能不会添加到维护分支中。

如果你想在着手打补丁之前征询反馈,请向 rails-core 邮件列表发送电子邮件。你可能得不到回应,这表明大家是中立的。你可能会发现有人对你提议的功能感兴趣;可能会有人说你的提议不可行。但是新想法就应该在那里讨论。GitHub 问题追踪系统不是集中讨论特性请求的正确场所。

2 帮助解决现有问题

除了报告问题之外,你还可以帮助核心团队解决现有问题。如果查看 GitHub 中的问题列表,你会发现很多问题都得到了关注。为此你能做些什么呢?其实,你能做的有很多。

2.1 确认缺陷报告

对新人来说,帮助确认缺陷报告就行了。你能在自己的电脑中重现报告的问题吗?如果能,可以在问题的评论中说你发现了同样的问题。

如果问题描述不清,你能帮忙说得更具体些吗?或许你可以提供额外的信息,帮助重现缺陷,或者去掉说明问题所不需要的步骤。

如果发现缺陷报告中没有测试,你可以贡献一个失败测试。这是学习源码的好机会:查看现有的测试文件能让你学到如何编写更好的测试。新测试最好以补丁的形式提供,详情参阅 为 Rails 代码做贡献

不管你自己写不写代码,只要你能把缺陷报告变得更简洁、更便于重现,就能为尝试修正缺陷的人提供帮助。

2.2 测试补丁

你还可以帮忙检查通过 GitHub 为 Ruby on Rails 提交的拉取请求。在使用别人的改动之前,你要创建一个专门的分支:

+
+$ git checkout -b testing_branch
+
+
+
+

然后可以使用他们的远程分支更新代码基。假如 GitHub 用户 JohnSmith 派生了 Rails 源码,地址是 https://github.com/JohnSmith/rails,然后推送到主题分支“orange”:

+
+$ git remote add JohnSmith https://github.com/JohnSmith/rails.git
+$ git pull JohnSmith orange
+
+
+
+

然后,使用主题分支中的代码做测试。下面是一些考虑的事情:

+
    +
  • 改动可用吗?

  • +
  • 你对测试满意吗?你能理解测试吗?缺少测试吗?

  • +
  • 有适度的文档覆盖度吗?其他地方的文档需要更新吗?

  • +
  • 你喜欢他的实现方式吗?你能以更好或更快的方式实现部分改动吗?

  • +
+

拉取请求中的改动让你满意之后,在 GitHub 问题追踪系统中发表评论,表明你赞成。你的评论应该说你喜欢这个改动,以及你的观点。比如说:

+
+

我喜欢你对 generate_finder_sql 这部分代码的调整,现在更好了。测试也没问题。

+
+

如果你的评论只是说“+1”,其他评审很难严肃对待。你要表明你花时间审查拉取请求了。

3 为 Rails 文档做贡献

Ruby on Rails 主要有两份文档:这份指南,帮你学习 Ruby on Rails;API,作为参考资料。

你可以帮助改进这份 Rails 指南,把它变得更简单、更为一致,也更易于理解。你可以添加缺少的信息、更正错误、修正错别字或者针对最新的 Rails 开发版做更新。

如果经常做贡献,可以向 Rails 发送拉取请求,或者向 Rails 核心团队索要 docrails 的提交权限。请勿直接向 docrails 发送拉取请求,如果想征询别人对你的改动有何意见,在 Rails 的问题追踪系统中询问。

docrails 定期合并到 master 分支,因此 Ruby on Rails 的文档能得到及时更新。

如果你对文档的改动有疑问,可以在 Rails 的问题追踪系统发工单。

如果你想为文档做贡献,请阅读API 文档指导方针Ruby on Rails 指南指导方针

前面说过,常规的代码补丁应该有适当的文档覆盖度。docrails 项目只是为了在单独的地方改进文档。

为了减轻 CI 服务器的压力,关于文档的提交消息中应该包含 [ci skip],跳过构建步骤。只修改文档的提交一定要这么做。

docrails 有个十分严格的方针:不能触碰任何代码,不管改动有多小都不行。通过 docrails 只能编辑 RDoc 和指南。此外,在 docrails 中也不能编辑 CHANGELOG。

4 翻译 Rails 指南

我们欢迎人们自发把 Rails 指南翻译成其他语言。如果你想把 Rails 指南翻译成你的母语,请遵照下述步骤:

+
    +
  • 派生项目(rails/rails)

  • +
  • 为你的语言添加一个文件夹,例如针对意大利语的 guides/source/it-IT

  • +
  • 把 guides/source 中的内容复制到你创建的文件夹中,然后翻译

  • +
  • 不要翻译 HTML 文件,因为那是自动生成的

  • +
+

如果想生成这份指南的 HTML 格式,进入 guides 目录,然后执行(以 it-IT 为例):

+
+$ bundle install
+$ bundle exec rake guides:generate:html GUIDES_LANGUAGE=it-IT
+
+
+
+

上述命令在 output 目录中生成这份指南。

上述说明针对 Rails 4 及以上版本。Redcarpet gem 无法在 JRuby 中使用。

已知的翻译成果:

+ +

5 为 Rails 代码做贡献

5.1 搭建开发环境

过了提交缺陷这个初级阶段之后,若想帮助解决现有问题,或者为 Ruby on Rails 贡献自己的代码,必须要能运行测试组件。这一节教你在自己的电脑中搭建测试的环境。

5.1.1 简单方式

搭建开发环境最简单、也是推荐的方式是使用 Rails 开发虚拟机

5.1.2 笨拙方式

如果你不便使用 Rails 开发虚拟机,请阅读安装开发依赖

5.2 克隆 Rails 仓库

若想贡献代码,需要克隆 Rails 仓库:

+
+$ git clone https://github.com/rails/rails.git
+
+
+
+

然后创建一个专门的分支:

+
+$ cd rails
+$ git checkout -b my_new_branch
+
+
+
+

分支的名称无关紧要,因为这个分支只存在于你的本地电脑和你在 GitHub 上的个人仓库中,不会出现在 Rails 的 Git 仓库里。

5.3 bundle install

安装所需的 gem:

+
+$ bundle install
+
+
+
+

5.4 使用本地分支运行应用

如果想使用虚拟的 Rails 应用测试改动,执行 rails new 命令时指定 --dev 旗标,使用本地分支生成一个应用:

+
+$ cd rails
+$ bundle exec rails new ~/my-test-app --dev
+
+
+
+

上述命令使用本地分支在 ~/my-test-app 目录中生成一个应用,重启服务器后便能看到改动的效果。

5.5 编写你的代码

现在可以着手添加和编辑代码了。你处在自己的分支中,可以编写任何你想编写的代码(使用 git branch -a 确定你处于正确的分支中)。不过,如果你打算把你的改动提交到 Rails 中,要注意几点:

+
    +
  • 代码要写得正确。

  • +
  • 使用 Rails 习惯用法和辅助方法。

  • +
  • 包含测试,在没有你的代码时失败,添加之后则通过。

  • +
  • 更新(相应的)文档、别处的示例和指南。只要受你的代码影响,都更新。

  • +
+

装饰性的改动,没有为 Rails 的稳定性、功能或可测试性做出实质改进的改动一般不会接受(关于这一决定的讨论参见这里)。

5.5.1 遵守编程约定

Rails 遵守下述简单的编程风格约定:

+
    +
  • (缩进)使用两个空格,不用制表符。

  • +
  • 行尾没有空白。空行不能有任何空白。

  • +
  • 私有和受保护的方法多一层缩进。

  • +
  • 使用 Ruby 1.9 及以上版本采用的散列句法。使用 { a: :b },而非 { :a => :b }

  • +
  • 较之 and/or,尽量使用 &&/||

  • +
  • 编写类方法时,较之 self.method,尽量使用 class << self

  • +
  • 使用 my_method(my_arg),而非 my_method( my_arg )my_method my_arg

  • +
  • 使用 a = b,而非 a=b

  • +
  • 使用 assert_not 方法,而非 refute

  • +
  • 编写单行块时,较之 method{do_stuff},尽量使用 method { do_stuff }

  • +
  • 遵照源码中在用的其他约定。

  • +
+

以上是指导方针,使用时请灵活应变。

5.6 对你的代码做基准测试

如果你的改动对 Rails 的性能有影响,请使用 benchmark-ips gem 做基准测试,并提供测试结果以供比较。

下面是使用 benchmark-ips 的一个示例:

+
+require 'benchmark/ips'
+
+Benchmark.ips do |x|
+  x.report('addition') { 1 + 2 }
+  x.report('addition with send') { 1.send(:+, 2) }
+end
+
+
+
+

上述代码会生成一份报告,包含下述信息:

+
+Calculating -------------------------------------
+            addition   132.013k i/100ms
+  addition with send   125.413k i/100ms
+-------------------------------------------------
+            addition      9.677M (± 1.7%) i/s -     48.449M
+  addition with send      6.794M (± 1.1%) i/s -     33.987M
+
+
+
+

详情参见 benchmark-ips 的自述文件

5.7 运行测试

在推送改动之前,通常不运行整个测试组件。railties 的测试组件所需的时间特别长,如果按照推荐的工作流程,使用 rails-dev-box 把源码挂载到 /vagrant,时间更长。

作为一种折中方案,应该测试明显受到影响的代码;如果不是改动 railties,运行受影响的组件的整个测试组件。如果所有测试都能通过,表明你可以提请你的贡献了。为了捕获别处预料之外的问题,我们配备了 Travis CI,作为一个安全保障。

5.7.1 整个 Rails

运行全部测试:

+
+$ cd rails
+$ bundle exec rake test
+
+
+
+
5.7.2 某个组件

可以只运行某个组件(如 Action Pack)的测试。例如,运行 Action Mailer 的测试:

+
+$ cd actionmailer
+$ bundle exec rake test
+
+
+
+
5.7.3 运行单个测试

可以通过 ruby 运行单个测试。例如:

+
+$ cd actionmailer
+$ bundle exec ruby -w -Itest test/mail_layout_test.rb -n test_explicit_class_layout
+
+
+
+

-n 选项指定运行单个方法,而非整个文件。

5.7.4 测试 Active Record

首先,创建所需的数据库。对 MySQL 和 PostgreSQL 来说,运行 SQL 语句 create database activerecord_unittestcreate database activerecord_unittest2 就行。SQLite3 无需这一步。

只使用 SQLite3 运行 Active Record 的测试组件:

+
+$ cd activerecord
+$ bundle exec rake test:sqlite3
+
+
+
+

然后分别运行:

+
+test:mysql2
+test:postgresql
+
+
+
+

最后,一次运行前述三个测试:

+
+$ bundle exec rake test
+
+
+
+

也可以单独运行某个测试:

+
+$ ARCONN=sqlite3 bundle exec ruby -Itest test/cases/associations/has_many_associations_test.rb
+
+
+
+

使用全部适配器运行某个测试:

+
+$ bundle exec rake TEST=test/cases/associations/has_many_associations_test.rb
+
+
+
+

此外,还可以调用 test_jdbcmysqltest_jdbcsqlite3test_jdbcpostgresql。针对其他数据库的测试参见 activerecord/RUNNING_UNIT_TESTS.rdoc 文件,持续集成服务器运行的测试组件参见 ci/travis.rb 文件。

5.8 提醒

运行测试组件的命令启用了提醒。理想情况下,Ruby on Rails 不应该发出提醒,不过你可能会见到一些,其中部分可能来自第三方库。如果看到提醒,请忽略(或修正),然后提交不发出提醒的补丁。

如果确信自己在做什么,想得到干净的输出,可以覆盖这个旗标:

+
+$ RUBYOPT=-W0 bundle exec rake test
+
+
+
+

5.9 更新 CHANGELOG

CHANGELOG 是每次发布的重要一环,保存着每个 Rails 版本的改动列表。

如果添加或删除了功能、提交了缺陷修正,或者添加了弃用提示,应该在框架的 CHANGELOG 顶部添加一条记录。重构和文档修改一般不应该在 CHANGELOG 中记录。

CHANGELOG 中的记录应该概述所做的改动,并且在末尾加上作者的名字。如果需要,可以写成多行,也可以缩进四个空格,添加代码示例。如果改动与某个工单有关,应该加上工单号。下面是一条 CHANGELOG 记录示例:

+
+*   Summary of a change that briefly describes what was changed. You can use multiple
+    lines and wrap them at around 80 characters. Code examples are ok, too, if needed:
+
+        class Foo
+          def bar
+            puts 'baz'
+          end
+        end
+
+    You can continue after the code example and you can attach issue number. GH#1234
+
+    *Your Name*
+
+
+
+

如果没有代码示例,或者没有分成多行,可以直接在最后一个词后面加上作者的名字。否则,最好新起一段。

5.10 更新 Gemfile.lock

有些改动需要更新依赖。此时,要执行 bundle update 命令,获取依赖的正确版本,并且随改动一起提交 Gemfile.lock 文件。

5.11 健全性检查

在提交之前,你不一定是唯一查看代码的人。如果你认识其他使用 Rails 的人,试着邀请他们检查你的代码。如果不认识使用 Rails 的人,可以在 IRC 聊天室中找人帮忙,或者在 rails-core 邮件列表中发布你的想法。在公开补丁之前做检查是一种“冒烟测试”:如果你不能让另一个开发者认同你的代码,核心团队可能也不会认同。

5.12 提交改动

在自己的电脑中对你的代码满意之后,要把改动提交到 Git 仓库中:

+
+$ git commit -a
+
+
+
+

上述命令会启动编辑器,让你编写一个提交消息。写完之后,保存并关闭编辑器,然后继续往下做。

行文好,而且具有描述性的提交消息有助于别人理解你为什么做这项改动,因此请认真对待提交消息。

好的提交消息类似下面这样:

+
+Short summary (ideally 50 characters or less)
+
+More detailed description, if necessary. It should be wrapped to
+72 characters. Try to be as descriptive as you can. Even if you
+think that the commit content is obvious, it may not be obvious
+to others. Add any description that is already present in the
+relevant issues; it should not be necessary to visit a webpage
+to check the history.
+
+The description section can have multiple paragraphs.
+
+Code examples can be embedded by indenting them with 4 spaces:
+
+    class ArticlesController
+      def index
+        render json: Article.limit(10)
+      end
+    end
+
+You can also add bullet points:
+
+- make a bullet point by starting a line with either a dash (-)
+  or an asterisk (*)
+
+- wrap lines at 72 characters, and indent any additional lines
+  with 2 spaces for readability
+
+
+
+

如果合适,请把多条提交压缩成一条提交。这样便于以后挑选,而且能保持 Git 日志整洁。

5.13 更新你的分支

你在改动的过程中,master 分支很有可能有变化。请获取这些变化:

+
+$ git checkout master
+$ git pull --rebase
+
+
+
+

然后在最新的改动上重新应用你的补丁:

+
+$ git checkout my_new_branch
+$ git rebase master
+
+
+
+

没有冲突?测试依旧能通过?你的改动依然合理?那就往下走。

5.14 派生

打开 GitHub 中的 Rails 仓库,点击右上角的“Fork”按钮。

把派生的远程仓库添加到本地设备中的本地仓库里:

+
+$ git remote add mine https://github.com:<your user name>/rails.git
+
+
+
+

推送到你的远程仓库:

+
+$ git push mine my_new_branch
+
+
+
+

你可能已经把派生的仓库克隆到本地设备中了,因此想把 Rails 仓库添加为远程仓库。此时,要这么做。

在你克隆的派生仓库的目录中:

+
+$ git remote add rails https://github.com/rails/rails.git
+
+
+
+

从官方仓库中下载新提交和分支:

+
+$ git fetch rails
+
+
+
+

合并新内容:

+
+$ git checkout master
+$ git rebase rails/master
+
+
+
+

更新你派生的仓库:

+
+$ git push origin master
+
+
+
+

如果想更新另一个分支:

+
+$ git checkout branch_name
+$ git rebase rails/branch_name
+$ git push origin branch_name
+
+
+
+

5.15 创建拉取请求

打开你刚刚推送的目标仓库(例如 https://github.com/your-user-name/rails),点击“New pull request”按钮。

如果需要修改比较的分支(默认比较 master 分支),点击“Edit”,然后点击“Click to create a pull request for this comparison”。

确保包含你所做的改动。填写补丁的详情,以及一个有意义的标题。然后点击“Send pull request”。Rails 核心团队会收到关于此次提交的通知。

5.16 获得反馈

多数拉取请求在合并之前会经过几轮迭代。不同的贡献者有时有不同的观点,而且有些补丁要重写之后才能合并。

有些 Rails 贡献者开启了 GitHub 的邮件通知,有些则没有。此外,Rails 团队中(几乎)所有人都是志愿者,因此你的拉取请求可能要等几天才能得到第一个反馈。别失望!有时快,有时慢。这就是开源世界的日常。

如果过了一周还是无人问津,你可以尝试主动推进。你可以在 rubyonrails-core 邮件列表中发消息,也可以在拉取请求中发一个评论。

在你等待反馈的过程中,可以再创建其他拉取请求,也可以给别人的拉取请求反馈。我想,他们会感激你的,正如你会感激给你反馈的人一样。

5.17 必要时做迭代

很有可能你得到的反馈是让你修改。别灰心,为活跃的开源项目做贡献就要跟上社区的步伐。如果有人建议你调整代码,你应该做调整,然后重新提交。如果你得到的反馈是,你的代码不应该添加到核心中,或许你可以考虑发布成一个 gem。

5.17.1 压缩提交

我们要求你做的一件事可能是让你“压缩提交”,把你的全部提交合并成一个提交。我们喜欢只有一个提交的拉取请求。这样便于把改动逆向移植(backport)到稳定分支中,压缩后易于还原不良提交,而且 Git 历史条理更清晰。Rails 是个大型项目,过多无关的提交容易扰乱视线。

为此,Git 仓库中要有一个指向官方 Rails 仓库的远程仓库。这样做是有必要的,如果你还没有这么做,确保先执行下述命令:

+
+$ git remote add upstream https://github.com/rails/rails.git
+
+
+
+

这个远程仓库的名称随意,如果你使用的不是 upstream,请相应修改下述说明。

假设你的远程分支是 my_pull_request,你要这么做:

+
+$ git fetch upstream
+$ git checkout my_pull_request
+$ git rebase -i upstream/master
+
+< Choose 'squash' for all of your commits except the first one. >
+< Edit the commit message to make sense, and describe all your changes. >
+
+$ git push origin my_pull_request -f
+
+
+
+

此时,GitHub 中的拉取请求会刷新,更新为最新的提交。

5.17.2 更新拉取请求

有时,你得到的反馈是让你修改已经提交的代码。此时可能需要修正现有的提交。在这种情况下,Git 不允许你推送改动,因为你推送的分支和本地分支不匹配。你无须重新发起拉取请求,而是可以强制推送到 GitHub 中的分支,如前一节的压缩提交命令所示:

+
+$ git push origin my_pull_request -f
+
+
+
+

这个命令会更新 GitHub 中的分支和拉取请求。不过注意,强制推送可能会导致远程分支中的提交丢失。使用时要小心。

5.18 旧版 Ruby on Rails

如果想修正旧版 Ruby on Rails,要创建并切换到本地跟踪分支(tracking branch)。下例切换到 4-0-stable 分支:

+
+$ git branch --track 4-0-stable origin/4-0-stable
+$ git checkout 4-0-stable
+
+
+
+

为了明确知道你处于代码的哪个版本,可以把 Git 分支名放到 shell 提示符中

5.18.1 逆向移植

合并到 master 分支中的改动针对 Rails 的下一个主发布版。有时,你的改动可能需要逆向移植到旧的稳定分支中。一般来说,安全修正和缺陷修正会做逆向移植,而新特性和引入行为变化的补丁不会这么做。如果不确定,在逆向移植之前最好询问一位 Rails 团队成员,以免浪费精力。

对简单的修正来说,逆向移植最简单的方法是根据 master 分支的改动提取差异(diff),然后在目标分支应用改动。

首先,确保你的改动是当前分支与 master 分支之间的唯一差别:

+
+$ git log master..HEAD
+
+
+
+

然后,提取差异:

+
+$ git format-patch master --stdout > ~/my_changes.patch
+
+
+
+

切换到目标分支,然后应用改动:

+
+$ git checkout -b my_backport_branch 3-2-stable
+$ git apply ~/my_changes.patch
+
+
+
+

简单的改动可以这么做。然而,如果改动较为复杂,或者 master 分支的代码与目标分支之间差异巨大,你可能要做更多的工作。逆向移植的工作量有大有小,有时甚至不值得为此付出精力。

解决所有冲突,并且确保测试都能通过之后,推送你的改动,然后为逆向移植单独发起一个拉取请求。还应注意,旧分支的构建目标可能与 master 分支不同。如果可能,提交拉取请求之前最好在本地使用 .travis.yml 文件中给出的 Ruby 版本测试逆向移植。

然后……可以思考下一次贡献了!

6 Rails 贡献者

所有贡献者,不管是通过 master 还是 docrails 贡献的,都在 Rails Contributors 页面中列出。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/credits.html b/credits.html new file mode 100644 index 0000000..80aee15 --- /dev/null +++ b/credits.html @@ -0,0 +1,312 @@ + + + + + + + +Ruby on Rails Guides: Credits + + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Credits

+ +

We'd like to thank the following people for their tireless contributions to this project.

+ + + + +
+
+ +
+
+
+ + +

Rails Guides Reviewers

+ +
Vijay Dev

Vijay Dev

+ Vijayakumar, found as Vijay Dev on the web, is a web applications developer and an open source enthusiast who lives in Chennai, India. He started using Rails in 2009 and began actively contributing to Rails documentation in late 2010. He tweets a lot and also blogs. +

+
Xavier Noria

Xavier Noria

+ Xavier Noria has been into Ruby on Rails since 2005. He is a Rails core team member and enjoys combining his passion for Rails and his past life as a proofreader of math textbooks. Xavier is currently an independent Ruby on Rails consultant. Oh, he also tweets and can be found everywhere as "fxn". +

+

Rails Guides Designers

+ +
Jason Zimdars

Jason Zimdars

+ Jason Zimdars is an experienced creative director and web designer who has lead UI and UX design for numerous websites and web applications. You can see more of his design and writing at Thinkcage.com or follow him on Twitter. +

+

Rails Guides Authors

+ +
Ryan Bigg

Ryan Bigg

+ Ryan Bigg works as a Rails developer at Marketplacer and has been working with Rails since 2006. He's the author of Multi Tenancy With Rails and co-author of Rails 4 in Action. He's written many gems which can be seen on his GitHub page and he also tweets prolifically as @ryanbigg. +

+
Oscar Del Ben

Oscar Del Ben

+Oscar Del Ben is a software engineer at Wildfire. He's a regular open source contributor (GitHub account) and tweets regularly at @oscardelben. +

+
Frederick Cheung

Frederick Cheung

+ Frederick Cheung is Chief Wizard at Texperts where he has been using Rails since 2006. He is based in Cambridge (UK) and when not consuming fine ales he blogs at spacevatican.org. +

+
Tore Darell

Tore Darell

+ Tore Darell is an independent developer based in Menton, France who specialises in cruft-free web applications using Ruby, Rails and unobtrusive JavaScript. You can follow him on Twitter. +

+
Jeff Dean

Jeff Dean

+ Jeff Dean is a software engineer with Pivotal Labs. +

+
Mike Gunderloy

Mike Gunderloy

+ Mike Gunderloy is a consultant with ActionRails. He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at A Fresh Cup and he twitters too much. +

+
Mikel Lindsaar

Mikel Lindsaar

+ Mikel Lindsaar has been working with Rails since 2006 and is the author of the Ruby Mail gem and core contributor (he helped re-write Action Mailer's API). Mikel is the founder of RubyX, has a blog and tweets. +

+
Cássio Marques

Cássio Marques

+ Cássio Marques is a Brazilian software developer working with different programming languages such as Ruby, JavaScript, CPP and Java, as an independent consultant. He blogs at /* CODIFICANDO */, which is mainly written in Portuguese, but will soon get a new section for posts with English translation. +

+
James Miller

James Miller

+ James Miller is a software developer for JK Tech in San Diego, CA. You can find James on GitHub, Gmail, Twitter, and Freenode as "bensie". +

+
Pratik Naik

Pratik Naik

+ Pratik Naik is a Ruby on Rails developer at Basecamp and also a member of the Rails core team. He maintains a blog at has_many :bugs, :through => :rails and has a semi-active twitter account. +

+
Emilio Tagua

Emilio Tagua

+ Emilio Tagua —a.k.a. miloops— is an Argentinian entrepreneur, developer, open source contributor and Rails evangelist. Cofounder of Eventioz. He has been using Rails since 2006 and contributing since early 2008. Can be found at gmail, twitter, freenode, everywhere as "miloops". +

+
Heiko Webers

Heiko Webers

+ Heiko Webers is the founder of bauland42, a German web application security consulting and development company focused on Ruby on Rails. He blogs at the Ruby on Rails Security Project. After 10 years of desktop application development, Heiko has rarely looked back. +

+
Akshay Surve

Akshay Surve

+ Akshay Surve is the Founder at DeltaX, hackathon specialist, a midnight code junkie and occasionally writes prose. You can connect with him on Twitter, Linkedin, Personal Blog or Quora. +

+

Rails 指南中文译者

+ +
+ Akshay Surve +

安道

+

+ 高校老师 / 自由翻译,翻译了大量 Ruby 资料。博客 +

+
+ +
+ Akshay Surve +

chinakr

+

+ GitHub +

+
+ +

其他贡献者

+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/debugging_rails_applications.html b/debugging_rails_applications.html new file mode 100644 index 0000000..5f9a87d --- /dev/null +++ b/debugging_rails_applications.html @@ -0,0 +1,964 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

调试 Rails 应用

本文介绍如何调试 Rails 应用。

读完本文后,您将学到:

+
    +
  • 调试的目的;

  • +
  • 如何追查测试没有发现的问题;

  • +
  • 不同的调试方法;

  • +
  • 如何分析堆栈跟踪。

  • +
+

1 调试相关的视图辅助方法

一个常见的需求是查看变量的值。在 Rails 中,可以使用下面这三个方法:

+
    +
  • debug

  • +
  • to_yaml

  • +
  • inspect

  • +
+

1.1 debug +

debug 方法使用 YAML 格式渲染对象,把结果放在 <pre> 标签中,可以把任何对象转换成人类可读的数据格式。例如,在视图中有以下代码:

+
+<%= debug @article %>
+<p>
+  <b>Title:</b>
+  <%= @article.title %>
+</p>
+
+
+
+

渲染后会看到如下结果:

+
+--- !ruby/object Article
+attributes:
+  updated_at: 2008-09-05 22:55:47
+  body: It's a very helpful guide for debugging your Rails app.
+  title: Rails debugging guide
+  published: t
+  id: "1"
+  created_at: 2008-09-05 22:55:47
+attributes_cache: {}
+
+
+Title: Rails debugging guide
+
+
+
+

1.2 to_yaml +

在任何对象上调用 to_yaml 方法可以把对象转换成 YAML。转换得到的对象可以传给 simple_format 辅助方法,格式化输出。debug 就是这么做的:

+
+<%= simple_format @article.to_yaml %>
+<p>
+  <b>Title:</b>
+  <%= @article.title %>
+</p>
+
+
+
+

渲染后得到的结果如下:

+
+--- !ruby/object Article
+attributes:
+updated_at: 2008-09-05 22:55:47
+body: It's a very helpful guide for debugging your Rails app.
+title: Rails debugging guide
+published: t
+id: "1"
+created_at: 2008-09-05 22:55:47
+attributes_cache: {}
+
+Title: Rails debugging guide
+
+
+
+

1.3 inspect +

另一个用于显示对象值的方法是 inspect,显示数组和散列时使用这个方法特别方便。inspect 方法以字符串的形式显示对象的值。例如:

+
+<%= [1, 2, 3, 4, 5].inspect %>
+<p>
+  <b>Title:</b>
+  <%= @article.title %>
+</p>
+
+
+
+

渲染后得到的结果如下:

+
+[1, 2, 3, 4, 5]
+
+Title: Rails debugging guide
+
+
+
+

2 日志记录器

运行时把信息写入日志文件也很有用。Rails 分别为各个运行时环境维护着单独的日志文件。

2.1 日志记录器是什么?

Rails 使用 ActiveSupport::Logger 类把信息写入日志。当然也可以换用其他库,比如 Log4r

若想替换日志库,可以在 config/application.rb 或其他环境的配置文件中设置,例如:

+
+config.logger = Logger.new(STDOUT)
+config.logger = Log4r::Logger.new("Application Log")
+
+
+
+

或者在 config/environment.rb 中添加下述代码中的某一行:

+
+Rails.logger = Logger.new(STDOUT)
+Rails.logger = Log4r::Logger.new("Application Log")
+
+
+
+

默认情况下,日志文件都保存在 Rails.root/log/ 目录中,日志文件的名称对应于各个环境。

2.2 日志等级

如果消息的日志等级等于或高于设定的等级,就会写入对应的日志文件中。如果想知道当前的日志等级,可以调用 Rails.logger.level 方法。

可用的日志等级包括 :debug:info:warn:error:fatal:unknown,分别对应数字 0-5。修改默认日志等级的方式如下:

+
+config.log_level = :warn # 在环境的配置文件中
+Rails.logger.level = 0 # 任何时候
+
+
+
+

这么设置在开发环境和交付准备环境中很有用,在生产环境中则不会写入大量不必要的信息。

Rails 为所有环境设定的默认日志等级是 debug

2.3 发送消息

把消息写入日志文件可以在控制器、模型或邮件程序中调用 logger.(debug|info|warn|error|fatal) 方法。

+
+logger.debug "Person attributes hash: #{@person.attributes.inspect}"
+logger.info "Processing the request..."
+logger.fatal "Terminating application, raised unrecoverable error!!!"
+
+
+
+

下面这个例子增加了额外的写日志功能:

+
+class ArticlesController < ApplicationController
+  # ...
+
+  def create
+    @article = Article.new(params[:article])
+    logger.debug "New article: #{@article.attributes.inspect}"
+    logger.debug "Article should be valid: #{@article.valid?}"
+
+    if @article.save
+      flash[:notice] =  'Article was successfully created.'
+      logger.debug "The article was saved and now the user is going to be redirected..."
+      redirect_to(@article)
+    else
+      render action: "new"
+    end
+  end
+
+  # ...
+end
+
+
+
+

执行上述动作后得到的日志如下:

+
+Processing ArticlesController#create (for 127.0.0.1 at 2008-09-08 11:52:54) [POST]
+  Session ID: BAh7BzoMY3NyZl9pZCIlMDY5MWU1M2I1ZDRjODBlMzkyMWI1OTg2NWQyNzViZjYiCmZsYXNoSUM6J0FjdGl
+vbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2VkewA=--b18cd92fba90eacf8137e5f6b3b06c4d724596a4
+  Parameters: {"commit"=>"Create", "article"=>{"title"=>"Debugging Rails",
+ "body"=>"I'm learning how to print in logs!!!", "published"=>"0"},
+ "authenticity_token"=>"2059c1286e93402e389127b1153204e0d1e275dd", "action"=>"create", "controller"=>"articles"}
+New article: {"updated_at"=>nil, "title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs!!!",
+ "published"=>false, "created_at"=>nil}
+Article should be valid: true
+  Article Create (0.000443)   INSERT INTO "articles" ("updated_at", "title", "body", "published",
+ "created_at") VALUES('2008-09-08 14:52:54', 'Debugging Rails',
+ 'I''m learning how to print in logs!!!', 'f', '2008-09-08 14:52:54')
+The article was saved and now the user is going to be redirected...
+Redirected to # Article:0x20af760>
+Completed in 0.01224 (81 reqs/sec) | DB: 0.00044 (3%) | 302 Found [http://localhost/articles]
+
+
+
+

加入这种日志信息有助于发现异常现象。如果添加了额外的日志消息,记得要合理设定日志等级,免得把大量无用的消息写入生产环境的日志文件。

2.4 为日志打标签

运行多用户、多账户的应用时,使用自定义的规则筛选日志信息能节省很多时间。Active Support 中的 TaggedLogging 模块可以实现这种功能,可以在日志消息中加入二级域名、请求 ID 等有助于调试的信息。

+
+logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
+logger.tagged("BCX") { logger.info "Stuff" }                            # Logs "[BCX] Stuff"
+logger.tagged("BCX", "Jason") { logger.info "Stuff" }                   # Logs "[BCX] [Jason] Stuff"
+logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff"
+
+
+
+

2.5 日志对性能的影响

如果把日志写入磁盘,肯定会对应用有点小的性能影响。不过可以做些小调整::debug 等级比 :fatal 等级对性能的影响更大,因为写入的日志消息量更多。

如果按照下面的方式大量调用 Logger,也有潜在的问题:

+
+logger.debug "Person attributes hash: #{@person.attributes.inspect}"
+
+
+
+

在上述代码中,即使日志等级不包含 :debug 也会对性能产生影响。这是因为 Ruby 要初始化字符串,再花时间做插值。因此建议把代码块传给 logger 方法,只有等于或大于设定的日志等级时才执行其中的代码。重写后的代码如下:

+
+logger.debug {"Person attributes hash: #{@person.attributes.inspect}"}
+
+
+
+

代码块中的内容,即字符串插值,仅当允许 :debug 日志等级时才会执行。这种节省性能的方式只有在日志量比较大时才能体现出来,但却是个好的编程习惯。

3 使用 byebug gem 调试

如果代码表现异常,可以在日志或控制台中诊断问题。但有时使用这种方法效率不高,无法找到导致问题的根源。如果需要检查源码,byebug gem 可以助你一臂之力。

如果想学习 Rails 源码但却无从下手,也可使用 byebug gem。随便找个请求,然后按照这里介绍的方法,从你编写的代码一直研究到 Rails 框架的代码。

3.1 安装

byebug gem 可以设置断点,实时查看执行的 Rails 代码。安装方法如下:

+
+$ gem install byebug
+
+
+
+

在任何 Rails 应用中都可以使用 byebug 方法呼出调试器。

下面举个例子:

+
+class PeopleController < ApplicationController
+  def new
+    byebug
+    @person = Person.new
+  end
+end
+
+
+
+

3.2 Shell

在应用中调用 byebug 方法后,在启动应用的终端窗口中会启用调试器 shell,并显示调试器的提示符 (byebug)。提示符前面显示的是即将执行的代码,当前行以“=>”标记,例如:

+
+[1, 10] in /PathTo/project/app/controllers/articles_controller.rb
+    3:
+    4:   # GET /articles
+    5:   # GET /articles.json
+    6:   def index
+    7:     byebug
+=>  8:     @articles = Article.find_recent
+    9:
+   10:     respond_to do |format|
+   11:       format.html # index.html.erb
+   12:       format.json { render json: @articles }
+
+(byebug)
+
+
+
+

如果是浏览器中执行的请求到达了那里,当前浏览器标签页会处于挂起状态,等待调试器完工,跟踪完整个请求。

例如:

+
+=> Booting Puma
+=> Rails 5.0.0 application starting in development on http://0.0.0.0:3000
+=> Run `rails server -h` for more startup options
+Puma starting in single mode...
+* Version 3.4.0 (ruby 2.3.1-p112), codename: Owl Bowl Brawl
+* Min threads: 5, max threads: 5
+* Environment: development
+* Listening on tcp://localhost:3000
+Use Ctrl-C to stop
+Started GET "/" for 127.0.0.1 at 2014-04-11 13:11:48 +0200
+  ActiveRecord::SchemaMigration Load (0.2ms)  SELECT "schema_migrations".* FROM "schema_migrations"
+Processing by ArticlesController#index as HTML
+
+[3, 12] in /PathTo/project/app/controllers/articles_controller.rb
+    3:
+    4:   # GET /articles
+    5:   # GET /articles.json
+    6:   def index
+    7:     byebug
+=>  8:     @articles = Article.find_recent
+    9:
+   10:     respond_to do |format|
+   11:       format.html # index.html.erb
+   12:       format.json { render json: @articles }
+(byebug)
+
+
+
+

现在可以深入分析应用的代码了。首先我们来查看一下调试器的帮助信息,输入 help

+
+(byebug) help
+
+  break      -- Sets breakpoints in the source code
+  catch      -- Handles exception catchpoints
+  condition  -- Sets conditions on breakpoints
+  continue   -- Runs until program ends, hits a breakpoint or reaches a line
+  debug      -- Spawns a subdebugger
+  delete     -- Deletes breakpoints
+  disable    -- Disables breakpoints or displays
+  display    -- Evaluates expressions every time the debugger stops
+  down       -- Moves to a lower frame in the stack trace
+  edit       -- Edits source files
+  enable     -- Enables breakpoints or displays
+  finish     -- Runs the program until frame returns
+  frame      -- Moves to a frame in the call stack
+  help       -- Helps you using byebug
+  history    -- Shows byebug's history of commands
+  info       -- Shows several informations about the program being debugged
+  interrupt  -- Interrupts the program
+  irb        -- Starts an IRB session
+  kill       -- Sends a signal to the current process
+  list       -- Lists lines of source code
+  method     -- Shows methods of an object, class or module
+  next       -- Runs one or more lines of code
+  pry        -- Starts a Pry session
+  quit       -- Exits byebug
+  restart    -- Restarts the debugged program
+  save       -- Saves current byebug session to a file
+  set        -- Modifies byebug settings
+  show       -- Shows byebug settings
+  source     -- Restores a previously saved byebug session
+  step       -- Steps into blocks or methods one or more times
+  thread     -- Commands to manipulate threads
+  tracevar   -- Enables tracing of a global variable
+  undisplay  -- Stops displaying all or some expressions when program stops
+  untracevar -- Stops tracing a global variable
+  up         -- Moves to a higher frame in the stack trace
+  var        -- Shows variables and its values
+  where      -- Displays the backtrace
+
+(byebug)
+
+
+
+

如果想查看前面十行代码,输入 list-(或 l-)。

+
+(byebug) l-
+
+[1, 10] in /PathTo/project/app/controllers/articles_controller.rb
+   1  class ArticlesController < ApplicationController
+   2    before_action :set_article, only: [:show, :edit, :update, :destroy]
+   3
+   4    # GET /articles
+   5    # GET /articles.json
+   6    def index
+   7      byebug
+   8      @articles = Article.find_recent
+   9
+   10      respond_to do |format|
+
+
+
+

这样我们就可以在文件内移动,查看 byebug 所在行上面的代码。如果想查看你在哪一行,输入 list=

+
+(byebug) list=
+
+[3, 12] in /PathTo/project/app/controllers/articles_controller.rb
+    3:
+    4:   # GET /articles
+    5:   # GET /articles.json
+    6:   def index
+    7:     byebug
+=>  8:     @articles = Article.find_recent
+    9:
+   10:     respond_to do |format|
+   11:       format.html # index.html.erb
+   12:       format.json { render json: @articles }
+(byebug)
+
+
+
+

3.3 上下文

开始调试应用时,会进入堆栈中不同部分对应的不同上下文。

到达一个停止点或者触发某个事件时,调试器就会创建一个上下文。上下文中包含被终止应用的信息,调试器用这些信息审查帧堆栈,计算变量的值,以及调试器在应用的什么地方终止执行。

任何时候都可执行 backtrace 命令(或别名 where)打印应用的回溯信息。这有助于理解是如何执行到当前位置的。只要你想知道应用是怎么执行到当前代码的,就可以通过 backtrace 命令获得答案。

+
+(byebug) where
+--> #0  ArticlesController.index
+      at /PathToProject/app/controllers/articles_controller.rb:8
+    #1  ActionController::BasicImplicitRender.send_action(method#String, *args#Array)
+      at /PathToGems/actionpack-5.0.0/lib/action_controller/metal/basic_implicit_render.rb:4
+    #2  AbstractController::Base.process_action(action#NilClass, *args#Array)
+      at /PathToGems/actionpack-5.0.0/lib/abstract_controller/base.rb:181
+    #3  ActionController::Rendering.process_action(action, *args)
+      at /PathToGems/actionpack-5.0.0/lib/action_controller/metal/rendering.rb:30
+...
+
+
+
+

当前帧使用 --> 标记。在回溯信息中可以执行 frame n 命令移动(从而改变上下文),其中 n 为帧序号。如果移动了,byebug 会显示新的上下文。

+
+(byebug) frame 2
+
+[176, 185] in /PathToGems/actionpack-5.0.0/lib/abstract_controller/base.rb
+   176:       # is the intended way to override action dispatching.
+   177:       #
+   178:       # Notice that the first argument is the method to be dispatched
+   179:       # which is *not* necessarily the same as the action name.
+   180:       def process_action(method_name, *args)
+=> 181:         send_action(method_name, *args)
+   182:       end
+   183:
+   184:       # Actually call the method associated with the action. Override
+   185:       # this method if you wish to change how action methods are called,
+(byebug)
+
+
+
+

可用的变量和逐行执行代码时一样。毕竟,这就是调试的目的。

向前或向后移动帧可以执行 up [n]down [n] 命令,分别向前或向后移动 n 帧。n 的默认值为 1。向前移动是指向较高的帧数移动,向下移动是指向较低的帧数移动。

3.4 线程

thread 命令(缩写为 th)可以列出所有线程、停止线程、恢复线程,或者在线程之间切换。其选项如下:

+
    +
  • thread:显示当前线程;

  • +
  • thread list:列出所有线程及其状态,+ 符号表示当前线程;

  • +
  • thread stop n:停止线程 n

  • +
  • thread resume n:恢复线程 n

  • +
  • thread switch n:把当前线程切换到线程 n

  • +
+

调试并发线程时,如果想确认代码中没有条件竞争,使用这个命令十分方便。

3.5 审查变量

任何表达式都可在当前上下文中求值。如果想计算表达式的值,直接输入表达式即可。

下面这个例子说明如何查看当前上下文中实例变量的值:

+
+[3, 12] in /PathTo/project/app/controllers/articles_controller.rb
+    3:
+    4:   # GET /articles
+    5:   # GET /articles.json
+    6:   def index
+    7:     byebug
+=>  8:     @articles = Article.find_recent
+    9:
+   10:     respond_to do |format|
+   11:       format.html # index.html.erb
+   12:       format.json { render json: @articles }
+
+(byebug) instance_variables
+[:@_action_has_layout, :@_routes, :@_request, :@_response, :@_lookup_context,
+ :@_action_name, :@_response_body, :@marked_for_same_origin_verification,
+ :@_config]
+
+
+
+

你可能已经看出来了,在控制器中可以使用的实例变量都显示出来了。这个列表随着代码的执行会动态更新。例如,使用 next 命令(本文后面会进一步说明这个命令)执行下一行代码:

+
+(byebug) next
+
+[5, 14] in /PathTo/project/app/controllers/articles_controller.rb
+   5     # GET /articles.json
+   6     def index
+   7       byebug
+   8       @articles = Article.find_recent
+   9
+=> 10       respond_to do |format|
+   11         format.html # index.html.erb
+   12        format.json { render json: @articles }
+   13      end
+   14    end
+   15
+(byebug)
+
+
+
+

然后再查看 instance_variables 的值:

+
+(byebug) instance_variables
+[:@_action_has_layout, :@_routes, :@_request, :@_response, :@_lookup_context,
+ :@_action_name, :@_response_body, :@marked_for_same_origin_verification,
+ :@_config, :@articles]
+
+
+
+

实例变量中出现了 @articles,因为执行了定义它的代码。

执行 irb 命令可进入 irb 模式(这不显然吗),irb 会话使用当前上下文。

var 命令是显示变量值最便捷的方式:

+
+(byebug) help var
+
+  [v]ar <subcommand>
+
+  Shows variables and its values
+
+
+  var all      -- Shows local, global and instance variables of self.
+  var args     -- Information about arguments of the current scope
+  var const    -- Shows constants of an object.
+  var global   -- Shows global variables.
+  var instance -- Shows instance variables of self or a specific object.
+  var local    -- Shows local variables in current scope.
+
+
+
+

上述方法可以很轻易查看当前上下文中的变量值。例如,下述代码确认没有局部变量:

+
+(byebug) var local
+(byebug)
+
+
+
+

审查对象的方法也可以使用这个命令:

+
+(byebug) var instance Article.new
+@_start_transaction_state = {}
+@aggregation_cache = {}
+@association_cache = {}
+@attributes = #<ActiveRecord::AttributeSet:0x007fd0682a9b18 @attributes={"id"=>#<ActiveRecord::Attribute::FromDatabase:0x007fd0682a9a00 @name="id", @value_be...
+@destroyed = false
+@destroyed_by_association = nil
+@marked_for_destruction = false
+@new_record = true
+@readonly = false
+@transaction_state = nil
+@txn = nil
+
+
+
+

display 命令可用于监视变量,查看在代码执行过程中变量值的变化:

+
+(byebug) display @articles
+1: @articles = nil
+
+
+
+

display 命令后跟的变量值会随着执行堆栈的推移而变化。如果想停止显示变量值,可以执行 undisplay n 命令,其中 n 是变量的代号(在上例中是 1)。

3.6 逐步执行

现在你知道在运行代码的什么位置,以及如何查看变量的值了。下面我们继续执行应用。

step 命令(缩写为 s)可以一直执行应用,直到下一个逻辑停止点,再把控制权交给调试器。next 命令的作用和 step 命令类似,但是 step 命令会在执行下一行代码之前停止,一次只执行一步,而 next 命令会执行下一行代码,但不跳出方法。

我们来看看下面这种情形:

+
+Started GET "/" for 127.0.0.1 at 2014-04-11 13:39:23 +0200
+Processing by ArticlesController#index as HTML
+
+[1, 6] in /PathToProject/app/models/article.rb
+   1: class Article < ApplicationRecord
+   2:   def self.find_recent(limit = 10)
+   3:     byebug
+=> 4:     where('created_at > ?', 1.week.ago).limit(limit)
+   5:   end
+   6: end
+
+(byebug)
+
+
+
+

如果使用 next,不会深入方法调用,byebug 会进入同一上下文中的下一行。这里,进入的是当前方法的最后一行,因此 byebug 会返回调用方的下一行。

+
+(byebug) next
+[4, 13] in /PathToProject/app/controllers/articles_controller.rb
+    4:   # GET /articles
+    5:   # GET /articles.json
+    6:   def index
+    7:     @articles = Article.find_recent
+    8:
+=>  9:     respond_to do |format|
+   10:       format.html # index.html.erb
+   11:       format.json { render json: @articles }
+   12:     end
+   13:   end
+
+(byebug)
+
+
+
+

如果使用 stepbyebug 会进入要执行的下一个 Ruby 指令——这里是 Active Support 的 week 方法。

+
+(byebug) step
+
+[49, 58] in /PathToGems/activesupport-5.0.0/lib/active_support/core_ext/numeric/time.rb
+   49:
+   50:   # Returns a Duration instance matching the number of weeks provided.
+   51:   #
+   52:   #   2.weeks # => 14 days
+   53:   def weeks
+=> 54:     ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
+   55:   end
+   56:   alias :week :weeks
+   57:
+   58:   # Returns a Duration instance matching the number of fortnights provided.
+(byebug)
+
+
+
+

逐行执行代码是找出代码缺陷的最佳方式。

还可以使用 step nnext n 一次向前移动 n 步。

3.7 断点

断点设置在何处终止执行代码。调试器会在设定断点的行呼出。

断点可以使用 break 命令(缩写为 b)动态添加。添加断点有三种方式:

+
    +
  • break n:在当前源码文件的第 n 行设定断点。

  • +
  • break file:n [if expression]:在文件 file 的第 n 行设定断点。如果指定了表达式 expression,其返回结果必须为 true 才会启动调试器。

  • +
  • break class(.|#)method [if expression]:在 class 类的 method 方法中设置断点,.# 分别表示类和实例方法。表达式 expression 的作用与 file:n 中的一样。

  • +
+

例如,在前面的情形下:

+
+[4, 13] in /PathToProject/app/controllers/articles_controller.rb
+    4:   # GET /articles
+    5:   # GET /articles.json
+    6:   def index
+    7:     @articles = Article.find_recent
+    8:
+=>  9:     respond_to do |format|
+   10:       format.html # index.html.erb
+   11:       format.json { render json: @articles }
+   12:     end
+   13:   end
+
+(byebug) break 11
+Successfully created breakpoint with id 1
+
+
+
+

使用 info breakpoints 命令可以列出断点。如果指定了数字,只会列出对应的断点,否则列出所有断点。

+
+(byebug) info breakpoints
+Num Enb What
+1   y   at /PathToProject/app/controllers/articles_controller.rb:11
+
+
+
+

如果想删除断点,使用 delete n 命令,删除编号为 n 的断点。如果不指定数字,则删除所有在用的断点。

+
+(byebug) delete 1
+(byebug) info breakpoints
+No breakpoints.
+
+
+
+

断点也可以启用或禁用:

+
    +
  • enable breakpoints [n [m […​]]]:在指定的断点列表或者所有断点处停止应用。这是创建断点后的默认状态。

  • +
  • disable breakpoints [n [m […​]]]:让指定的断点(或全部断点)在应用中不起作用。

  • +
+

3.8 捕获异常

catch exception-name 命令(或 cat exception-name)可捕获 exception-name 类型的异常,源码很有可能没有处理这个异常。

执行 catch 命令可以列出所有可用的捕获点。

3.9 恢复执行

有两种方法可以恢复被调试器终止执行的应用:

+
    +
  • continue [n](或 c):从停止的地方恢复执行程序,设置的断点失效。可选的参数 n 指定一个行数,设定一个一次性断点,应用执行到这一行时,断点会被删除。

  • +
  • finish [n]:一直执行,直到指定的堆栈帧返回为止。如果没有指定帧序号,应用会一直执行,直到当前堆栈帧返回为止。当前堆栈帧就是最近刚使用过的帧,如果之前没有移动帧的位置(执行 updownframe 命令),就是第 0 帧。如果指定了帧序号,则运行到指定的帧返回为止。

  • +
+

3.10 编辑

下面这个方法可以在调试器中使用编辑器打开源码:

+
    +
  • +edit [file:n]:使用环境变量 EDITOR 指定的编辑器打开文件 file。还可指定行数 n
  • +
+

3.11 退出

若想退出调试器,使用 quit 命令(缩写为 q)。也可以输入 q!,跳过 Really quit? (y/n) 提示,无条件地退出。

退出后会终止所有线程,因此服务器也会停止,需要重启。

3.12 设置

byebug 有几个选项,可用于调整行为:

+
+(byebug) help set
+
+  set <setting> <value>
+
+  Modifies byebug settings
+
+  Boolean values take "on", "off", "true", "false", "1" or "0". If you
+  don't specify a value, the boolean setting will be enabled. Conversely,
+  you can use "set no<setting>" to disable them.
+
+  You can see these environment settings with the "show" command.
+
+  List of supported settings:
+
+  autosave       -- Automatically save command history record on exit
+  autolist       -- Invoke list command on every stop
+  width          -- Number of characters per line in byebug's output
+  autoirb        -- Invoke IRB on every stop
+  basename       -- <file>:<line> information after every stop uses short paths
+  linetrace      -- Enable line execution tracing
+  autopry        -- Invoke Pry on every stop
+  stack_on_error -- Display stack trace when `eval` raises an exception
+  fullpath       -- Display full file names in backtraces
+  histfile       -- File where cmd history is saved to. Default: ./.byebug_history
+  listsize       -- Set number of source lines to list by default
+  post_mortem    -- Enable/disable post-mortem mode
+  callstyle      -- Set how you want method call parameters to be displayed
+  histsize       -- Maximum number of commands that can be stored in byebug history
+  savefile       -- File where settings are saved to. Default: ~/.byebug_save
+
+
+
+

可以把这些设置保存在家目录中的 .byebugrc 文件里。启动时,调试器会读取这些全局设置。例如:

+
+
+
+set callstyle short
+set listsize 25
+
+
+
+
+

4 使用 web-console gem 调试

Web Console 的作用与 byebug 有点类似,不过它在浏览器中运行。在任何页面中都可以在视图或控制器的上下文中请求控制台。控制台在 HTML 内容下面渲染。

4.1 控制台

在任何控制器动作或视图中,都可以调用 console 方法呼出控制台。

例如,在一个控制器中:

+
+class PostsController < ApplicationController
+  def new
+    console
+    @post = Post.new
+  end
+end
+
+
+
+

或者在一个视图中:

+
+<% console %>
+
+<h2>New Post</h2>
+
+
+
+

控制台在视图中渲染。调用 console 的位置不用担心,它不会在调用的位置显示,而是显示在 HTML 内容下方。

控制台可以执行纯 Ruby 代码,你可以定义并实例化类、创建新模型或审查变量。

一个请求只能渲染一个控制台,否则 web-console 会在第二个 console 调用处抛出异常。

4.2 审查变量

可以调用 instance_variables 列出当前上下文中的全部实例变量。如果想列出全部局部变量,调用 local_variables

4.3 设置

+
    +
  • config.web_console.whitelisted_ips:授权的 IPv4 或 IPv6 地址和网络列表(默认值:127.0.0.1/8, ::1)。

  • +
  • config.web_console.whiny_requests:禁止渲染控制台时记录一条日志(默认值:true)。

  • +
+

web-console 会在远程服务器中执行 Ruby 代码,因此别在生产环境中使用。

5 调试内存泄露

Ruby 应用(Rails 或其他)可能会导致内存泄露,泄露可能由 Ruby 代码引起,也可能由 C 代码引起。

本节介绍如何使用 Valgrind 等工具查找并修正内存泄露问题。

5.1 Valgrind

Valgrind 应用能检测 C 语言层的内存泄露和条件竞争。

Valgrind 提供了很多工具,能自动检测很多内存管理和线程问题,也能详细分析程序。例如,如果 C 扩展调用了 malloc() 函数,但没调用 free() 函数,这部分内存就会一直被占用,直到应用终止执行。

关于如何安装以及如何在 Ruby 中使用 Valgrind,请阅读 Evan Weaver 写的 Valgrind and Ruby 一文。

6 用于调试的插件

有很多 Rails 插件可以帮助你查找问题和调试应用。下面列出一些有用的调试插件:

+
    +
  • Footnotes:在应用的每个页面底部显示请求信息,并链接到源码(可通过 TextMate 打开);

  • +
  • Query Trace:在日志中写入请求源信息;

  • +
  • Query Reviewer:这个 Rails 插件在开发环境中会在每个 SELECT 查询前执行 EXPLAIN 查询,并在每个页面中添加一个 div 元素,显示分析到的查询问题;

  • +
  • Exception Notifier:提供了一个邮件程序和一组默认的邮件模板,Rails 应用出现问题后发送邮件通知;

  • +
  • Better Errors:使用全新的页面替换 Rails 默认的错误页面,显示更多的上下文信息,例如源码和变量的值;

  • +
  • RailsPanel:一个 Chrome 扩展,在浏览器的开发者工具中显示 development.log 文件的内容,显示的内容包括:数据库查询时间、渲染时间、总时间、参数列表、渲染的视图,等等。

  • +
+

7 参考资源

+ + + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/development_dependencies_install.html b/development_dependencies_install.html new file mode 100644 index 0000000..e3c4590 --- /dev/null +++ b/development_dependencies_install.html @@ -0,0 +1,482 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

安装开发依赖

本文说明如何搭建 Ruby on Rails 核心开发环境。

读完本文后,您将学到:

+
    +
  • 如何设置你的设备供 Rails 开发;

  • +
  • 如何运行 Rails 测试组件中特定的单元测试组;

  • +
  • Rails 测试组件中的 Active Record 部分是如何运作的。

  • +
+

1 简单方式

搭建开发环境最简单、也是推荐的方式是使用 Rails 开发虚拟机

2 笨拙方式

如果你不便使用 Rails 开发虚拟机,参见下述说明。这些步骤说明如何自己动手搭建开发环境,供 Ruby on Rails 核心开发使用。

2.1 安装 Git

Ruby on Rails 使用 Git 做源码控制。Git 的安装说明参见官网。网上有很多学习 Git 的资源:

+
    +
  • Try Git 是个交互式课程,教你基本用法。

  • +
  • 官方文档十分全面,也有一些 Git 基本用法的视频。

  • +
  • Everyday Git 教你一些技能,足够日常使用。

  • +
  • GitHub 帮助页面中有很多 Git 资源的链接。

  • +
  • Pro Git 是一本讲解 Git 的书,基于知识共享许可证发布。

  • +
+

2.2 克隆 Ruby on Rails 仓库

进入你想保存 Ruby on Rails 源码的文件夹,然后执行(会创建 rails 子目录):

+
+$ git clone git://github.com/rails/rails.git
+$ cd rails
+
+
+
+

2.3 准备工作和运行测试

提交的代码必须通过测试组件。不管你是编写新的补丁,还是评估别人的代码,都要运行测试。

首先,安装 sqlite3 gem 所需的 SQLite3 及其开发文件 。macOS 用户这么做:

+
+$ brew install sqlite3
+
+
+
+

Ubuntu 用户这么做:

+
+$ sudo apt-get install sqlite3 libsqlite3-dev
+
+
+
+

Fedora 或 CentOS 用户这么做:

+
+$ sudo yum install sqlite3 sqlite3-devel
+
+
+
+

Arch Linux 用户要这么做:

+
+$ sudo pacman -S sqlite
+
+
+
+

FreeBSD 用户这么做:

+
+# pkg install sqlite3
+
+
+
+

或者编译 databases/sqlite3 port。

然后安装最新版 Bundler

+
+$ gem install bundler
+$ gem update bundler
+
+
+
+

再执行:

+
+$ bundle install --without db
+
+
+
+

这个命令会安装除了 MySQL 和 PostgreSQL 的 Ruby 驱动之外的所有依赖。稍后再安装那两个驱动。

如果想运行使用 memcached 的测试,要安装并运行 memcached。

+
+

在 macOS 中可以使用 Homebrew 安装 memcached:

+
+
+$ brew install memcached
+
+
+
+

在 Ubuntu 中可以使用 apt-get 安装 memcached:

+
+
+$ sudo apt-get install memcached
+
+
+
+

在 Fedora 或 CentOS 中这么做:

+
+
+$ sudo yum install memcached
+
+
+
+

在 Arch Linux 中这么做:

+
+
+$ sudo pacman -S memcached
+
+
+
+

在 FreeBSD 中这么做:

+
+
+# pkg install memcached
+
+
+
+

或者编译 databases/memcached port。

+
+

安装好依赖之后,可以执行下述命令运行测试组件:

+
+$ bundle exec rake test
+
+
+
+

还可以运行某个组件(如 Action Pack)的测试,方法是进入组件所在的目录,然后执行相同的命令:

+
+$ cd actionpack
+$ bundle exec rake test
+
+
+
+

如果想运行某个目录中的测试,使用 TEST_DIR 环境变量指定。例如,下述命令只运行 railties/test/generators 目录中的测试:

+
+$ cd railties
+$ TEST_DIR=generators bundle exec rake test
+
+
+
+

可以像下面这样运行某个文件中的测试:

+
+$ cd actionpack
+$ bundle exec ruby -Itest test/template/form_helper_test.rb
+
+
+
+

还可以运行某个文件中的某个测试:

+
+$ cd actionpack
+$ bundle exec ruby -Itest path/to/test.rb -n test_name
+
+
+
+

2.4 为 Active Record 做准备

Active Record 的测试组件运行三次:一次针对 SQLite3,一次针对 MySQL,还有一次针对 PostgreSQL。下面说明如何为这三种数据库搭建环境。

编写 Active Record 代码时,必须确保测试至少能在 MySQL、PostgreSQL 和 SQLite3 中通过。如果只使用 MySQL 测试,虽然测试能通过,但是不同适配器之间的差异没有考虑到。

2.4.1 数据库配置

Active Record 测试组件需要一个配置文件:activerecord/test/config.ymlactiverecord/test/config.example.yml 文件中有些示例。你可以复制里面的内容,然后根据你的环境修改。

2.4.2 MySQL 和 PostgreSQL

为了运行针对 MySQL 和 PostgreSQL 的测试组件,要安装相应的 gem。首先安装服务器、客户端库和开发文件。

在 macOS 中可以这么做:

+
+$ brew install mysql
+$ brew install postgresql
+
+
+
+

然后按照 Homebrew 给出的说明做。

在 Ubuntu 中只需这么做:

+
+$ sudo apt-get install mysql-server libmysqlclient-dev
+$ sudo apt-get install postgresql postgresql-client postgresql-contrib libpq-dev
+
+
+
+

在 Fedora 或 CentOS 中只需这么做:

+
+$ sudo yum install mysql-server mysql-devel
+$ sudo yum install postgresql-server postgresql-devel
+
+
+
+

MySQL 不再支持 Arch Linux,因此你要使用 MariaDB(参见这个声明):

+
+$ sudo pacman -S mariadb libmariadbclient mariadb-clients
+$ sudo pacman -S postgresql postgresql-libs
+
+
+
+

FreeBSD 用户要这么做:

+
+# pkg install mysql56-client mysql56-server
+# pkg install postgresql94-client postgresql94-server
+
+
+
+

或者通过 port 安装(在 databases 文件夹中)。在安装 MySQL 的过程中如何遇到问题,请查阅 MySQL 文档

安装好之后,执行下述命令:

+
+$ rm .bundle/config
+$ bundle install
+
+
+
+

首先,我们要删除 .bundle/config 文件,因为 Bundler 记得那个文件中的配置。我们前面配置了,不安装“db”分组(此外也可以修改那个文件)。

为了使用 MySQL 运行测试组件,我们要创建一个名为 rails 的用户,并且赋予它操作测试数据库的权限:

+
+$ mysql -uroot -p
+
+mysql> CREATE USER 'rails'@'localhost';
+mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.*
+       to 'rails'@'localhost';
+mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.*
+       to 'rails'@'localhost';
+mysql> GRANT ALL PRIVILEGES ON inexistent_activerecord_unittest.*
+       to 'rails'@'localhost';
+
+
+
+

然后创建测试数据库:

+
+$ cd activerecord
+$ bundle exec rake db:mysql:build
+
+
+
+

PostgreSQL 的身份验证方式有所不同。为了使用开发账户搭建开发环境,在 Linux 或 BSD 中要这么做:

+
+$ sudo -u postgres createuser --superuser $USER
+
+
+
+

在 macOS 中这么做:

+
+$ createuser --superuser $USER
+
+
+
+

然后,执行下述命令创建测试数据库:

+
+$ cd activerecord
+$ bundle exec rake db:postgresql:build
+
+
+
+

可以执行下述命令创建 PostgreSQL 和 MySQL 的测试数据库:

+
+$ cd activerecord
+$ bundle exec rake db:create
+
+
+
+

可以使用下述命令清理数据库:

+
+$ cd activerecord
+$ bundle exec rake db:drop
+
+
+
+

使用 rake 任务创建测试数据库能保障数据库使用正确的字符集和排序规则。

在 PostgreSQL 9.1.x 及早期版本中激活 HStore 扩展会看到这个提醒(或本地化的提醒):“WARNING: => is deprecated as an operator”。

如果使用其他数据库,默认的连接信息参见 activerecord/test/config.ymlactiverecord/test/config.example.yml 文件。如果有必要,可以在你的设备中编辑 activerecord/test/config.yml 文件,提供不同的凭据。不过显然,不应该把这种改动推送回 Rails 仓库。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/engines.html b/engines.html new file mode 100644 index 0000000..a31fa85 --- /dev/null +++ b/engines.html @@ -0,0 +1,232 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+

引擎入门

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/form_helpers.html b/form_helpers.html new file mode 100644 index 0000000..4984d69 --- /dev/null +++ b/form_helpers.html @@ -0,0 +1,1065 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

表单辅助方法

表单是 Web 应用中用户输入的基本界面。尽管如此,由于需要处理表单控件的名称和众多属性,编写和维护表单标记可能很快就会变得单调乏味。Rails 提供用于生成表单标记的视图辅助方法来消除这种复杂性。然而,由于这些辅助方法具有不同的用途和用法,开发者在使用之前需要知道它们之间的差异。

读完本文后,您将学到:

+
    +
  • 如何在 Rails 应用中创建搜索表单和类似的不针对特定模型的通用表单;

  • +
  • 如何使用针对特定模型的表单来创建和修改对应的数据库记录;

  • +
  • 如何使用多种类型的数据生成选择列表;

  • +
  • Rails 提供了哪些日期和时间辅助方法;

  • +
  • 上传文件的表单有什么特殊之处;

  • +
  • 如何用 post 方法把表单提交到外部资源并设置真伪令牌;

  • +
  • 如何创建复杂表单。

  • +
+

本文不是所有可用表单辅助方法及其参数的完整文档。关于表单辅助方法的完整介绍,请参阅 Rails API 文档

1 处理基本表单

form_tag 方法是最基本的表单辅助方法。

+
+<%= form_tag do %>
+  Form contents
+<% end %>
+
+
+
+

无参数调用 form_tag 方法会创建 <form> 标签,在提交表单时会向当前页面发起 POST 请求。例如,假设当前页面是 /home/index,上面的代码会生成下面的 HTML(为了提高可读性,添加了一些换行):

+
+<form accept-charset="UTF-8" action="http://github.com/" method="post">
+  <input name="utf8" type="hidden" value="&#x2713;" />
+  <input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
+  Form contents
+</form>
+
+
+
+

我们注意到,上面的 HTML 的第二行是一个 hidden 类型的 input 元素。这个 input 元素很重要,一旦缺少,表单就不能成功提交。这个 input 元素的 name 属性的值是 utf8,用于说明浏览器处理表单时使用的字符编码方式。对于所有表单,不管表单动作是“GET”还是“POST”,都会生成这个 input 元素。

上面的 HTML 的第三行也是一个 input 元素,元素的 name 属性的值是 authenticity_token。这个 input 元素是 Rails 的一个名为跨站请求伪造保护的安全特性。在启用跨站请求伪造保护的情况下,表单辅助方法会为所有非 GET 表单生成这个 input 元素。关于跨站请求伪造保护的更多介绍,请参阅 安全指南

1.1 通用搜索表单

搜索表单是网上最常见的基本表单,包含:

+
    +
  • 具有“GET”方法的表单元素

  • +
  • 文本框的 label 标签

  • +
  • 文本框

  • +
  • 提交按钮

  • +
+

我们可以分别使用 form_taglabel_tagtext_field_tagsubmit_tag 标签来创建搜索表单,就像下面这样:

+
+<%= form_tag("/search", method: "get") do %>
+  <%= label_tag(:q, "Search for:") %>
+  <%= text_field_tag(:q) %>
+  <%= submit_tag("Search") %>
+<% end %>
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<form accept-charset="UTF-8" action="http://github.com/search" method="get">
+  <input name="utf8" type="hidden" value="&#x2713;" />
+  <label for="q">Search for:</label>
+  <input id="q" name="q" type="text" />
+  <input name="commit" type="submit" value="Search" />
+</form>
+
+
+
+

表单中的文本框会根据 name 属性(在上面的例子中值为 q)生成 id 属性。id 属性在应用 CSS 样式或使用 JavaScript 操作表单控件时非常有用。

text_field_tagsubmit_tag 方法之外,每个 HTML 表单控件都有对应的辅助方法。

搜索表单的方法都应该设置为“GET”,这样用户就可以把搜索结果添加为书签。一般来说,Rails 推荐为表单动作使用正确的 HTTP 动词。

1.2 在调用表单辅助方法时使用多个散列

form_tag 辅助方法接受两个参数:提交表单的地址和选项散列。选项散列用于指明提交表单的方法,以及 HTML 选项,例如表单的 class 属性。

link_to 辅助方法一样,提交表单的地址可以是字符串,也可以是散列形式的 URL 参数。Rails 路由能够识别这个散列,将其转换为有效的 URL 地址。尽管如此,由于 form_tag 方法的两个参数都是散列,如果我们想同时指定两个参数,就很容易遇到问题。假如有下面的代码:

+
+form_tag(controller: "people", action: "search", method: "get", class: "nifty_form")
+# => '<form accept-charset="UTF-8" action="http://github.com/people/search?method=get&class=nifty_form" method="post">'
+
+
+
+

在上面的代码中,methodclass 选项的值会被添加到生成的 URL 地址的查询字符串中,不管我们是不是想要使用两个散列作为参数,Rails 都会把这些选项当作一个散列。为了告诉 Rails 我们想要使用两个散列作为参数,我们可以把第一个散列放在大括号中,或者把两个散列都放在大括号中。这样就可以生成我们想要的 HTML 了:

+
+form_tag({controller: "people", action: "search"}, method: "get", class: "nifty_form")
+# => '<form accept-charset="UTF-8" action="http://github.com/people/search" method="get" class="nifty_form">'
+
+
+
+

1.3 用于生成表单元素的辅助方法

Rails 提供了一系列用于生成表单元素(如复选框、文本字段和单选按钮)的辅助方法。这些名称以 _tag 结尾的基本辅助方法(如 text_field_tagcheck_box_tag)只生成单个 input 元素,并且第一个参数都是 input 元素的 name 属性的值。在提交表单时,name 属性的值会和表单数据一起传递,这样在控制器中就可以通过 params 来获得各个 input 元素的值。例如,如果表单包含 <%= text_field_tag(:query) %>,我们就可以通过 params[:query] 来获得这个文本字段的值。

在给 input 元素命名时,Rails 有一些命名约定,使我们可以提交非标量值(如数组或散列),这些值同样可以通过 params 来获得。关于这些命名约定的更多介绍,请参阅 理解参数命名约定

关于这些辅助方法的用法的详细介绍,请参阅 API 文档

1.3.1 复选框

复选框表单控件为用户提供一组可以启用或禁用的选项:

+
+<%= check_box_tag(:pet_dog) %>
+<%= label_tag(:pet_dog, "I own a dog") %>
+<%= check_box_tag(:pet_cat) %>
+<%= label_tag(:pet_cat, "I own a cat") %>
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<input id="pet_dog" name="pet_dog" type="checkbox" value="1" />
+<label for="pet_dog">I own a dog</label>
+<input id="pet_cat" name="pet_cat" type="checkbox" value="1" />
+<label for="pet_cat">I own a cat</label>
+
+
+
+

check_box_tag 辅助方法的第一个参数是生成的 input 元素的 name 属性的值。可选的第二个参数是 input 元素的值,当对应复选框被选中时,这个值会包含在表单数据中,并可以通过 params 来获得。

1.3.2 单选按钮

和复选框类似,单选按钮表单控件为用户提供一组选项,区别在于这些选项是互斥的,用户只能从中选择一个:

+
+<%= radio_button_tag(:age, "child") %>
+<%= label_tag(:age_child, "I am younger than 21") %>
+<%= radio_button_tag(:age, "adult") %>
+<%= label_tag(:age_adult, "I'm over 21") %>
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<input id="age_child" name="age" type="radio" value="child" />
+<label for="age_child">I am younger than 21</label>
+<input id="age_adult" name="age" type="radio" value="adult" />
+<label for="age_adult">I'm over 21</label>
+
+
+
+

check_box_tag 一样,radio_button_tag 辅助方法的第二个参数是生成的 input 元素的值。因为两个单选按钮的 name 属性的值相同(都是 age),所以用户只能从中选择一个,params[:age] 的值要么是 "child" 要么是 "adult"

在使用复选框和单选按钮时一定要指定 label 标签。label 标签为对应选项提供说明文字,并扩大可点击区域,使用户更容易选中想要的选项。

1.4 其他你可能感兴趣的辅助方法

其他值得一提的表单控件包括文本区域、密码框、隐藏输入字段、搜索字段、电话号码字段、日期字段、时间字段、颜色字段、日期时间字段、本地日期时间字段、月份字段、星期字段、URL 地址字段、电子邮件地址字段、数字字段和范围字段:

+
+<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
+<%= password_field_tag(:password) %>
+<%= hidden_field_tag(:parent_id, "5") %>
+<%= search_field(:user, :name) %>
+<%= telephone_field(:user, :phone) %>
+<%= date_field(:user, :born_on) %>
+<%= datetime_local_field(:user, :graduation_day) %>
+<%= month_field(:user, :birthday_month) %>
+<%= week_field(:user, :birthday_week) %>
+<%= url_field(:user, :homepage) %>
+<%= email_field(:user, :address) %>
+<%= color_field(:user, :favorite_color) %>
+<%= time_field(:task, :started_at) %>
+<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
+<%= range_field(:product, :discount, in: 1..100) %>
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<textarea id="message" name="message" cols="24" rows="6">Hi, nice site</textarea>
+<input id="password" name="password" type="password" />
+<input id="parent_id" name="parent_id" type="hidden" value="5" />
+<input id="user_name" name="user[name]" type="search" />
+<input id="user_phone" name="user[phone]" type="tel" />
+<input id="user_born_on" name="user[born_on]" type="date" />
+<input id="user_graduation_day" name="user[graduation_day]" type="datetime-local" />
+<input id="user_birthday_month" name="user[birthday_month]" type="month" />
+<input id="user_birthday_week" name="user[birthday_week]" type="week" />
+<input id="user_homepage" name="user[homepage]" type="url" />
+<input id="user_address" name="user[address]" type="email" />
+<input id="user_favorite_color" name="user[favorite_color]" type="color" value="#000000" />
+<input id="task_started_at" name="task[started_at]" type="time" />
+<input id="product_price" max="20.0" min="1.0" name="product[price]" step="0.5" type="number" />
+<input id="product_discount" max="100" min="1" name="product[discount]" type="range" />
+
+
+
+

隐藏输入字段不显示给用户,但和其他 input 元素一样可以保存数据。我们可以使用 JavaScript 来修改隐藏输入字段的值。

搜索字段、电话号码字段、日期字段、时间字段、颜色字段、日期时间字段、本地日期时间字段、月份字段、星期字段、URL 地址字段、电子邮件地址字段、数字字段和范围字段都是 HTML5 控件。要想在旧版本浏览器中拥有一致的体验,我们需要使用 HTML5 polyfill(针对 CSS 或 JavaScript 代码)。HTML5 Cross Browser Polyfills 提供了 HTML5 polyfill 的完整列表,目前最流行的工具是 Modernizr,通过检测 HTML5 特性是否存在来添加缺失的功能。

使用密码框时可以配置 Rails 应用,不把密码框的值写入日志,详情参阅 安全指南

2 处理模型对象

2.1 模型对象辅助方法

表单经常用于修改或创建模型对象。这种情况下当然可以使用 *_tag 辅助方法,但使用起来却有些麻烦,因为我们需要确保每个标记都使用了正确的参数名称并设置了合适的默认值。为此,Rails 提供了量身定制的辅助方法。这些辅助方法的名称不使用 _tag 后缀,例如 text_fieldtext_area

这些辅助方法的第一个参数是实例变量,第二个参数是在这个实例变量对象上调用的方法(通常是模型属性)的名称。 Rails 会把 input 控件的值设置为所调用方法的返回值,并为 input 控件的 name 属性设置合适的值。假设我们在控制器中定义了 @person 实例变量,这个人的名字是 Henry,那么表单中的下述代码:

+
+<%= text_field(:person, :name) %>
+
+
+
+

会生成下面的 HTML:

+
+<input id="person_name" name="person[name]" type="text" value="Henry"/>
+
+
+
+

提交表单时,用户输入的值储存在 params[:person][:name] 中。params[:person] 这个散列可以传递给 Person.new 方法作为参数,而如果 @personPerson 模型的实例,这个散列还可以传递给 @person.update 方法作为参数。尽管这些辅助方法的第二个参数通常都是模型属性的名称,但不是必须这样做。在上面的例子中,只要 @person 对象拥有 namename= 方法即可省略第二个参数。

传入的参数必须是实例变量的名称,如 :person"person",而不是模型实例本身。

Rails 还提供了用于显示模型对象数据验证错误的辅助方法,详情参阅 Active Record 数据验证

2.2 把表单绑定到对象上

上一节介绍的辅助方法使用起来虽然很方便,但远非完美的解决方案。如果 Person 模型有很多属性需要修改,那么实例变量对象的名称就需要重复写很多遍。更好的解决方案是把表单绑定到模型对象上,为此我们可以使用 form_for 辅助方法。

假设有一个用于处理文章的控制器 app/controllers/articles_controller.rb

+
+def new
+  @article = Article.new
+end
+
+
+
+

在对应的 app/views/articles/new.html.erb 视图中,可以像下面这样使用 form_for 辅助方法:

+
+<%= form_for @article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
+  <%= f.text_field :title %>
+  <%= f.text_area :body, size: "60x12" %>
+  <%= f.submit "Create" %>
+<% end %>
+
+
+
+

这里有几点需要注意:

+
    +
  • 实际需要修改的对象是 @article

  • +
  • form_for 辅助方法的选项是一个散列,其中 :url 键对应的值是路由选项,:html 键对应的值是 HTML 选项,这两个选项本身也是散列。还可以提供 :namespace 选项来确保表单元素具有唯一的 ID 属性,自动生成的 ID 会以 :namespace 选项的值和下划线作为前缀。

  • +
  • form_for 辅助方法会产出一个表单生成器对象,即变量 f

  • +
  • 用于生成表单控件的辅助方法都在表单生成器对象 f 上调用。

  • +
+

上面的代码会生成下面的 HTML:

+
+<form accept-charset="UTF-8" action="http://github.com/articles" method="post" class="nifty_form">
+  <input id="article_title" name="article[title]" type="text" />
+  <textarea id="article_body" name="article[body]" cols="60" rows="12"></textarea>
+  <input name="commit" type="submit" value="Create" />
+</form>
+
+
+
+

form_for 辅助方法的第一个参数决定了 params 使用哪个键来访问表单数据。在上面的例子中,这个参数为 @article,因此所有 input 控件的 name 属性都是 article[attribute_name] 这种形式,而在 create 动作中 params[:article] 是一个拥有 :title:body 键的散列。关于 input 控件 name 属性重要性的更多介绍,请参阅 理解参数命名约定

在表单生成器上调用的辅助方法和模型对象辅助方法几乎完全相同,区别在于前者无需指定需要修改的对象,因为表单生成器已经指定了需要修改的对象。

使用 fields_for 辅助方法也可以把表单绑定到对象上,但不会创建 <form> 标签。需要在同一个表单中修改多个模型对象时可以使用 fields_for 方法。例如,假设 Person 模型和 ContactDetail 模型关联,我们可以在下面这个表单中同时创建这两个模型的对象:

+
+<%= form_for @person, url: {action: "create"} do |person_form| %>
+  <%= person_form.text_field :name %>
+  <%= fields_for @person.contact_detail do |contact_detail_form| %>
+    <%= contact_detail_form.text_field :phone_number %>
+  <% end %>
+<% end %>
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<form accept-charset="UTF-8" action="http://github.com/people" class="new_person" id="new_person" method="post">
+  <input id="person_name" name="person[name]" type="text" />
+  <input id="contact_detail_phone_number" name="contact_detail[phone_number]" type="text" />
+</form>
+
+
+
+

form_for 辅助方法一样, fields_for 方法产出的对象是一个表单生成器(实际上 form_for 方法在内部调用了 fields_for 方法)。

2.3 使用记录识别技术

Article 模型对我们来说是直接可用的,因此根据 Rails 开发的最佳实践,我们应该把这个模型声明为资源:

+
+resources :articles
+
+
+
+

资源的声明有许多副作用。关于设置和使用资源的更多介绍,请参阅 Rails 路由全解

在处理 REST 架构的资源时,使用记录识别技术可以大大简化 form_for 辅助方法的调用。简而言之,使用记录识别技术后,我们只需把模型实例传递给 form_for 方法作为参数,Rails 会找出模型名称和其他信息:

+
+## 创建一篇新文章
+# 冗长风格:
+form_for(@article, url: articles_path)
+# 简短风格,效果一样(用到了记录识别技术):
+form_for(@article)
+
+## 编辑一篇现有文章
+# 冗长风格:
+form_for(@article, url: article_path(@article), html: {method: "patch"})
+# 简短风格:
+form_for(@article)
+
+
+
+

注意,不管是新建记录还是修改已有记录,form_for 方法调用的短格式都是相同的,很方便。记录识别技术很智能,能够通过调用 record.new_record? 方法来判断记录是否为新记录,同时还能选择正确的提交地址,并根据对象的类设置 name 属性的值。

Rails 还会自动为表单的 classid 属性设置合适的值,例如,用于创建文章的表单,其 idclass 属性的值都会被设置为 new_article。用于修改 ID 为 23 的文章的表单,其 class 属性会被设置为 edit_article,其 id 属性会被设置为 edit_article_23。为了行文简洁,后文会省略这些属性。

在模型中使用单表继承(single-table inheritance,STI)时,如果只有父类声明为资源,在子类上就不能使用记录识别技术。这时,必须显式说明模型名称、:url:method

2.3.1 处理命名空间

如果在路由中使用了命名空间,我们同样可以使用 form_for 方法调用的短格式。例如,假设有 admin 命名空间,那么 form_for 方法调用的短格式可以写成:

+
+form_for [:admin, @article]
+
+
+
+

上面的代码会创建提交到 admin 命名空间中 ArticlesController 控制器的表单(在更新文章时会提交到 admin_article_path(@article) 这个地址)。对于多层命名空间的情况,语法也类似:

+
+form_for [:admin, :management, @article]
+
+
+
+

关于 Rails 路由及其相关约定的更多介绍,请参阅xml#rails-routing-from-the-outside-in

2.4 表单如何处理 PATCH、PUT 或 DELETE 请求方法?

Rails 框架鼓励应用使用 REST 架构的设计,这意味着除了 GET 和 POST 请求,应用还要处理许多 PATCH 和 DELETE 请求。不过,大多数浏览器只支持表单的 GET 和 POST 方法,而不支持其他方法。

为了解决这个问题,Rails 使用 name 属性的值为 _method 的隐藏的 input 标签和 POST 方法来模拟其他方法,从而实现相同的效果:

+
+form_tag(search_path, method: "patch")
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<form accept-charset="UTF-8" action="http://github.com/search" method="post">
+  <input name="_method" type="hidden" value="patch" />
+  <input name="utf8" type="hidden" value="&#x2713;" />
+  <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
+  ...
+</form>
+
+
+
+

在处理提交的数据时,Rails 会考虑 _method 这个特殊参数的值,并按照指定的 HTTP 方法处理请求(在本例中为 PATCH)。

3 快速创建选择列表

选择列表由大量 HTML 标签组成(需要为每个选项分别创建 option 标签),因此最适合动态生成。

下面是选择列表的一个例子:

+
+<select name="city_id" id="city_id">
+  <option value="1">Lisbon</option>
+  <option value="2">Madrid</option>
+  ...
+  <option value="12">Berlin</option>
+</select>
+
+
+
+

这个选择列表显示了一组城市的列表,用户看到的是城市的名称,应用处理的是城市的 ID。每个 option 标签的 value 属性的值就是城市的 ID。下面我们会看到 Rails 为生成选择列表提供了哪些辅助方法。

3.1 selectoption 标签

最通用的辅助方法是 select_tag,故名思义,这个辅助方法用于生成 select 标签,并在这个 select 标签中封装选项字符串:

+
+<%= select_tag(:city_id, '<option value="1">Lisbon</option>...') %>
+
+
+
+

使用 select_tag 辅助方法只是第一步,仅靠它我们还无法动态生成 option 标签。接下来,我们可以使用 options_for_select 辅助方法生成 option 标签:

+
+<%= options_for_select([['Lisbon', 1], ['Madrid', 2], ...]) %>
+
+
+
+

输出:

+
+<option value="1">Lisbon</option>
+<option value="2">Madrid</option>
+...
+
+
+
+

options_for_select 辅助方法的第一个参数是嵌套数组,其中每个子数组都有两个元素:选项文本(城市名称)和选项值(城市 ID)。选项值会提交给控制器。选项值通常是对应的数据库对象的 ID,但并不一定是这样。

掌握了上述知识,我们就可以联合使用 select_tagoptions_for_select 辅助方法来动态生成选择列表了:

+
+<%= select_tag(:city_id, options_for_select(...)) %>
+
+
+
+

options_for_select 辅助方法允许我们传递第二个参数来设置默认选项:

+
+<%= options_for_select([['Lisbon', 1], ['Madrid', 2], ...], 2) %>
+
+
+
+

输出:

+
+<option value="1">Lisbon</option>
+<option value="2" selected="selected">Madrid</option>
+...
+
+
+
+

当 Rails 发现生成的选项值和第二个参数指定的值一样时,就会为这个选项添加 selected 属性。

options_for_select 辅助方法的第二个参数必须和选项值完全一样。例如,如果选项值是整数 2,就必须指定整数 2,而不是字符串 "2"。需要注意的是,从 params 散列中提取的值都是字符串。

如果 select 标签的 required 属性的值为 truesize 属性的值为 1,multiple 属性未设置为 true,并且未设置 :include_blank:prompt 选项时,:include_blank 选项的值会被强制设置为 true

我们可以通过散列为选项添加任意属性:

+
+<%= options_for_select(
+  [
+    ['Lisbon', 1, { 'data-size' => '2.8 million' }],
+    ['Madrid', 2, { 'data-size' => '3.2 million' }]
+  ], 2
+) %>
+
+
+
+

输出:

+
+<option value="1" data-size="2.8 million">Lisbon</option>
+<option value="2" selected="selected" data-size="3.2 million">Madrid</option>
+...
+
+
+
+

3.2 用于处理模型的选择列表

在大多数情况下,表单控件会绑定到特定的数据库模型,和我们期望的一样,Rails 为此提供了辅助方法。与其他表单辅助方法一致,在处理模型时,需要从 select_tag 中删除 _tag 后缀:

+
+# controller:
+@person = Person.new(city_id: 2)
+
+
+
+
+
+# view:
+<%= select(:person, :city_id, [['Lisbon', 1], ['Madrid', 2], ...]) %>
+
+
+
+

需要注意的是,select 辅助方法的第三个参数,即选项数组,和传递给 options_for_select 辅助方法作为参数的选项数组是一样的。如果用户已经设置了默认城市,Rails 会从 @person.city_id 属性中读取这一设置,一切都是自动的,十分方便。

和其他辅助方法一样,如果要在绑定到 @person 对象的表单生成器上使用 select 辅助方法,相关句法如下:

+
+# select on a form builder
+<%= f.select(:city_id, ...) %>
+
+
+
+

我们还可以把块传递给 select 辅助方法:

+
+<%= f.select(:city_id) do %>
+  <% [['Lisbon', 1], ['Madrid', 2]].each do |c| -%>
+    <%= content_tag(:option, c.first, value: c.last) %>
+  <% end %>
+<% end %>
+
+
+
+

如果我们使用 select 辅助方法(或类似的辅助方法,如 collection_selectselect_tag)来设置 belongs_to 关联,就必须传入外键的名称(在上面的例子中是 city_id),而不是关联的名称。在上面的例子中,如果传入的是 city 而不是 city_id,在把 params 传递给 Person.newupdate 方法时,Active Record 会抛出 ActiveRecord::AssociationTypeMismatch: City(#17815740) expected, got String(#1138750) 错误。换一个角度看,这说明表单辅助方法只能修改模型属性。我们还应该注意到允许用户直接修改外键的潜在安全后果。

3.3 从任意对象组成的集合创建 option 标签

使用 options_for_select 辅助方法生成 option 标签需要创建包含各个选项的文本和值的数组。但如果我们已经拥有 City 模型(可能是 Active Record 模型),并且想要从这些对象的集合生成 option 标签,那么应该怎么做呢?一个解决方案是创建并遍历嵌套数组:

+
+<% cities_array = City.all.map { |city| [city.name, city.id] } %>
+<%= options_for_select(cities_array) %>
+
+
+
+

这是一个完全有效的解决方案,但 Rails 提供了一个更简洁的替代方案:options_from_collection_for_select 辅助方法。这个辅助方法接受一个任意对象组成的集合作为参数,以及两个附加参数,分别用于读取选项值和选项文本的方法的名称:

+
+<%= options_from_collection_for_select(City.all, :id, :name) %>
+
+
+
+

顾名思义,options_from_collection_for_select 辅助方法只生成 option 标签。和 options_for_select 辅助方法一样,要想生成可用的选择列表,我们需要联合使用 options_from_collection_for_selectselect_tag 辅助方法。在处理模型对象时,select 辅助方法联合使用了 select_tagoptions_for_select 辅助方法,同样,collection_select 辅助方法联合使用了 select_tagoptions_from_collection_for_select 辅助方法。

+
+<%= collection_select(:person, :city_id, City.all, :id, :name) %>
+
+
+
+

和其他辅助方法一样,如果要在绑定到 @person 对象的表单生成器上使用 collection_select 辅助方法,相关句法如下:

+
+<%= f.collection_select(:city_id, City.all, :id, :name) %>
+
+
+
+

总结一下,options_from_collection_for_select 对于 collection_select 辅助方法,就如同 options_for_select 对于 select 辅助方法。

传递给 options_for_select 辅助方法作为参数的嵌套数组,子数组的第一个元素是选项文本,第二个元素是选项值,然而传递给 options_from_collection_for_select 辅助方法作为参数的嵌套数组,子数组的第一个元素是读取选项值的方法的名称,第二个元素是读取选项文本的方法的名称。

3.4 时区和国家选择列表

要想利用 Rails 提供的时区相关功能,首先需要设置用户所在的时区。为此,我们可以使用 collection_select 辅助方法从预定义时区对象生成选择列表,我们也可以使用更简单的 time_zone_select 辅助方法:

+
+<%= time_zone_select(:person, :time_zone) %>
+
+
+
+

Rails 还提供了 time_zone_options_for_select 辅助方法用于手动生成定制的时区选择列表。关于 time_zone_selecttime_zone_options_for_select 辅助方法的更多介绍,请参阅 API 文档。

Rails 的早期版本提供了用于生成国家选择列表的 country_select 辅助方法,现在这一功能被放入独立的 country_select 插件。需要注意的是,在使用这个插件生成国家选择列表时,一些特定地区是否应该被当作国家还存在争议,这也是 Rails 不再内置这一功能的原因。

4 使用日期和时间的表单辅助方法

我们可以选择不使用生成 HTML5 日期和时间输入字段的表单辅助方法,而使用替代的日期和时间辅助方法。这些日期和时间辅助方法与所有其他表单辅助方法主要有两点不同:

+
    +
  • 日期和时间不是在单个 input 元素中输入,而是每个时间单位(年、月、日等)都有各自的 input 元素。因此在 params 散列中没有表示日期和时间的单个值。

  • +
  • 其他表单辅助方法使用 _tag 后缀区分独立的辅助方法和处理模型对象的辅助方法。对于日期和时间辅助方法,select_dateselect_timeselect_datetime 是独立的辅助方法,date_selecttime_selectdatetime_select 是对应的处理模型对象的辅助方法。

  • +
+

这两类辅助方法都会为每个时间单位(年、月、日等)生成各自的选择列表。

4.1 独立的辅助方法

select_* 这类辅助方法的第一个参数是 DateTimeDateTime 类的实例,用于指明选中的日期时间。如果省略这个参数,选中当前的日期时间。例如:

+
+<%= select_date Date.today, prefix: :start_date %>
+
+
+
+

上面的代码会生成下面的 HTML(为了行文简洁,省略了实际选项值):

+
+<select id="start_date_year" name="start_date[year]"> ... </select>
+<select id="start_date_month" name="start_date[month]"> ... </select>
+<select id="start_date_day" name="start_date[day]"> ... </select>
+
+
+
+

上面的代码会使 params[:start_date] 成为拥有 :year:month:day 键的散列。要想得到实际的 DateTimeDateTime 对象,我们需要提取 params[:start_date] 中的信息并传递给适当的构造方法,例如:

+
+Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i)
+
+
+
+

:prefix 选项用于说明从 params 散列中取回时间信息的键名。这个选项的默认值是 date,在上面的例子中被设置为 start_date

4.2 处理模型对象的辅助方法

在更新或创建 Active Record 对象的表单中,select_date 辅助方法不能很好地工作,因为 Active Record 期望 params 散列的每个元素都对应一个模型属性。处理模型对象的日期和时间辅助方法使用特殊名称提交参数,Active Record 一看到这些参数就知道必须把这些参数和其他参数一起传递给对应字段类型的构造方法。例如:

+
+<%= date_select :person, :birth_date %>
+
+
+
+

上面的代码会生成下面的 HTML(为了行文简洁,省略了实际选项值):

+
+<select id="person_birth_date_1i" name="person[birth_date(1i)]"> ... </select>
+<select id="person_birth_date_2i" name="person[birth_date(2i)]"> ... </select>
+<select id="person_birth_date_3i" name="person[birth_date(3i)]"> ... </select>
+
+
+
+

上面的代码会生成下面的 params 散列:

+
+{'person' => {'birth_date(1i)' => '2008', 'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}}
+
+
+
+

当把这个 params 散列传递给 Person.newupdate 方法时,Active Record 会发现应该把这些参数都用于构造 birth_date 属性,并且会使用附加信息来确定把这些参数传递给构造方法(如 Date.civil 方法)的顺序。

4.3 通用选项

这两类辅助方法使用一组相同的核心函数来生成选择列表,因此使用的选项也大体相同。特别是默认情况下,Rails 生成的年份选项会包含当前年份的前后 5 年。如果这个范围不能满足使用需求,可以使用 :start_year:end_year 选项覆盖这一默认设置。关于这两类辅助方法的可用选项的更多介绍,请参阅 API 文档

根据经验,在处理模型对象时应该使用 date_select 辅助方法,在其他情况下应该使用 select_date 辅助方法。例如在根据日期过滤搜索结果时就应该使用 select_date 辅助方法。

在许多情况下,内置的日期选择器显得笨手笨脚,不能帮助用户正确计算出日期和星期几之间的关系。

4.4 独立组件

偶尔我们需要显示单个日期组件,例如年份或月份。为此,Rails 提供了一系列辅助方法,每个时间单位对应一个辅助方法,即 select_yearselect_monthselect_dayselect_hourselect_minuteselect_second 辅助方法。这些辅助方法的用法非常简单。默认情况下,它们会生成以时间单位命名的输入字段(例如,select_year 辅助方法生成名为“year”的输入字段,select_month 辅助方法生成名为“month”的输入字段),我们可以使用 :field_name 选项指定输入字段的名称。:prefix 选项的用法和在 select_dateselect_time 辅助方法中一样,默认值也一样。

这些辅助方法的第一个参数可以是 DateTimeDateTime 类的实例(会从实例中取出对应的值)或数值,用于指明选中的日期时间。例如:

+
+<%= select_year(2009) %>
+<%= select_year(Time.now) %>
+
+
+
+

如果当前年份是 2009 年,上面的代码会成生相同的 HTML。用户选择的年份可以通过 params[:date][:year] 取回。

5 上传文件

上传某种类型的文件是常见任务,例如上传某人的照片或包含待处理数据的 CSV 文件。在上传文件时特别需要注意的是,表单的编码必须设置为 multipart/form-data。使用 form_for 辅助方法时会自动完成这一设置。如果使用 form_tag 辅助方法,就必须手动完成这一设置,具体操作可以参考下面的例子。

下面这两个表单都用于上传文件。

+
+<%= form_tag({action: :upload}, multipart: true) do %>
+  <%= file_field_tag 'picture' %>
+<% end %>
+
+<%= form_for @person do |f| %>
+  <%= f.file_field :picture %>
+<% end %>
+
+
+
+

Rails 同样为上传文件提供了一对辅助方法:独立的辅助方法 file_field_tag 和处理模型的辅助方法 file_field。这两个辅助方法和其他辅助方法的唯一区别是,我们无法为文件上传控件设置默认值,因为这样做没有意义。和我们期望的一样,在上述例子的第一个表单中上传的文件通过 params[:picture] 取回,在第二个表单中通过 params[:person][:picture] 取回。

5.1 上传的内容

在上传文件时,params 散列中保存的文件对象实际上是 IO 类的子类的实例。根据上传文件大小的不同,这个实例有可能是 StringIO 类的实例,也可能是临时文件的 File 类的实例。在这两种情况下,文件对象具有 original_filename 属性,其值为上传的文件在用户计算机上的文件名,也具有 content_type 属性,其值为上传的文件的 MIME 类型。下面这段代码把上传的文件保存在 #{Rails.root}/public/uploads 文件夹中,文件名不变(假设使用上一节例子中的表单来上传文件)。

+
+def upload
+  uploaded_io = params[:person][:picture]
+  File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
+    file.write(uploaded_io.read)
+  end
+end
+
+
+
+

一旦文件上传完毕,就可以执行很多后续操作,例如把文件储存到磁盘、Amazon S3 等位置并和模型关联起来,缩放图片并生成缩略图等。这些复杂的操作已经超出本文的范畴,不过有一些 Ruby 库可以帮助我们完成这些操作,其中两个众所周知的是 CarrierWavePaperclip

如果用户没有选择要上传的文件,对应参数会是空字符串。

5.2 处理 Ajax

和其他表单不同,异步上传文件的表单可不是为 form_for 辅助方法设置 remote: true 选项这么简单。在这个 Ajax 表单中,上传文件的序列化是通过浏览器端的 JavaScript 完成的,而 JavaScript 无法读取硬盘上的文件,因此文件无法上传。最常见的解决方案是使用不可见的 iframe 作为表单提交的目标。

6 定制表单生成器

前面说过,form_forfields_for 辅助方法产出的对象是 FormBuilder 类或其子类的实例,即表单生成器。表单生成器为单个对象封装了显示表单所需的功能。我们可以用常规的方式使用表单辅助方法,也可以继承 FormBuilder 类并添加其他辅助方法。例如:

+
+<%= form_for @person do |f| %>
+  <%= text_field_with_label f, :first_name %>
+<% end %>
+
+
+
+

可以写成:

+
+<%= form_for @person, builder: LabellingFormBuilder do |f| %>
+  <%= f.text_field :first_name %>
+<% end %>
+
+
+
+

在使用前需要定义 LabellingFormBuilder 类:

+
+class LabellingFormBuilder < ActionView::Helpers::FormBuilder
+  def text_field(attribute, options={})
+    label(attribute) + super
+  end
+end
+
+
+
+

如果经常这样使用,我们可以定义 labeled_form_for 辅助方法,自动应用 builder: LabellingFormBuilder 选项。

+
+def labeled_form_for(record, options = {}, &block)
+  options.merge! builder: LabellingFormBuilder
+  form_for record, options, &block
+end
+
+
+
+

表单生成器还会确定进行下面的渲染时应该执行的操作:

+
+<%= render partial: f %>
+
+
+
+

如果表单生成器 fFormBuilder 类的实例,那么上面的代码会渲染局部视图 form,并把传入局部视图的对象设置为表单生成器。如果表单生成器 fLabellingFormBuilder 类的实例,那么上面的代码会渲染局部视图 labelling_form

7 理解参数命名约定

从前面几节我们可以看到,表单提交的数据可以保存在 params 散列或嵌套的子散列中。例如,在 Person 模型的标准 create 动作中,params[:person] 通常是储存了创建 Person 实例所需的所有属性的散列。params 散列也可以包含数组、散列构成的数组等等。

从根本上说,HTML 表单并不理解任何类型的结构化数据,表单提交的数据都是普通字符串组成的键值对。我们在应用中看到的数组和散列都是 Rails 根据参数命名约定生成的。

7.1 基本结构

数组和散列是两种基本数据结构。散列句法用于访问 params 中的值。例如,如果表单包含:

+
+<input id="person_name" name="person[name]" type="text" value="Henry"/>
+
+
+
+

params 散列会包含:

+
+{'person' => {'name' => 'Henry'}}
+
+
+
+

在控制器中可以使用 params[:person][:name] 取回表单提交的值。

散列可以根据需要嵌套,不限制层级,例如:

+
+<input id="person_address_city" name="person[address][city]" type="text" value="New York"/>
+
+
+
+

params 散列会包含:

+
+{'person' => {'address' => {'city' => 'New York'}}}
+
+
+
+

通常 Rails 会忽略重复的参数名。如果参数名包含一组空的方括号 [],Rails 就会用这些参数的值生成一个数组。例如,要想让用户输入多个电话号码,我们可以在表单中添加:

+
+<input name="person[phone_number][]" type="text"/>
+<input name="person[phone_number][]" type="text"/>
+<input name="person[phone_number][]" type="text"/>
+
+
+
+

得到的 params[:person][:phone_number] 是包含用户输入的电话号码的数组。

7.2 联合使用

我们可以联合使用数组和散列。散列的元素可以是前面例子中那样的数组,也可以是散列构成的数组。例如,通过重复使用下面的表单控件我们可以添加任意长度的多行地址:

+
+<input name="addresses[][line1]" type="text"/>
+<input name="addresses[][line2]" type="text"/>
+<input name="addresses[][city]" type="text"/>
+
+
+
+

得到的 params[:addresses] 是散列构成的数组,散列的键包括 line1line2city。如果 Rails 发现输入控件的名称已经存在于当前散列的键中,就会新建一个散列。

不过还有一个限制,尽管散列可以任意嵌套,但数组只能有一层。数组通常可以用散列替换。例如,模型对象的数组可以用以模型对象 ID 、数组索引或其他参数为键的散列替换。

数组参数在 check_box 辅助方法中不能很好地工作。根据 HTML 规范,未选中的复选框不提交任何值。然而,未选中的复选框也提交值往往会更容易处理。为此,check_box 辅助方法通过创建辅助的同名隐藏 input 元素来模拟这一行为。如果复选框未选中,只有隐藏的 input 元素的值会被提交;如果复选框被选中,复选框本身的值和隐藏的 input 元素的值都会被提交,但复选框本身的值优先级更高。在处理数组参数时,这样的重复提交会把 Rails 搞糊涂,因为 Rails 无法确定什么时候创建新的数组元素。这种情况下,我们可以使用 check_box_tag 辅助方法,或者用散列代替数组。

7.3 使用表单辅助方法

在前面两节中我们没有使用 Rails 表单辅助方法。尽管我们可以手动为 input 元素命名,然后直接把它们传递给 text_field_tag 这类辅助方法,但 Rails 支持更高级的功能。我们可以使用 form_forfields_for 辅助方法的 name 参数以及 :index 选项。

假设我们想要渲染一个表单,用于修改某人地址的各个字段。例如:

+
+<%= form_for @person do |person_form| %>
+  <%= person_form.text_field :name %>
+  <% @person.addresses.each do |address| %>
+    <%= person_form.fields_for address, index: address.id do |address_form|%>
+      <%= address_form.text_field :city %>
+    <% end %>
+  <% end %>
+<% end %>
+
+
+
+

如果某人有两个地址,ID 分别为 23 和 45,那么上面的代码会生成下面的 HTML:

+
+<form accept-charset="UTF-8" action="http://github.com/people/1" class="edit_person" id="edit_person_1" method="post">
+  <input id="person_name" name="person[name]" type="text" />
+  <input id="person_address_23_city" name="person[address][23][city]" type="text" />
+  <input id="person_address_45_city" name="person[address][45][city]" type="text" />
+</form>
+
+
+
+

得到的 params 散列会包含:

+
+{'person' => {'name' => 'Bob', 'address' => {'23' => {'city' => 'Paris'}, '45' => {'city' => 'London'}}}}
+
+
+
+

Rails 之所以知道这些输入控件的值是 person 散列的一部分,是因为我们在第一个表单生成器上调用了 fields_for 辅助方法。指定 :index 选项是为了告诉 Rails,不要把输入控件命名为 person[address][city],而要在 addresscity 之间插入索引(放在 [] 中)。这样要想确定需要修改的 Address 记录就变得很容易,因此往往也很有用。:index 选项的值还可以是其他重要数字、字符串甚至 nil(使用 nil 时会创建数组参数)。

要想创建更复杂的嵌套,我们可以显式指定输入控件名称的 name 参数(在上面的例子中是 person[address]):

+
+<%= fields_for 'person[address][primary]', address, index: address do |address_form| %>
+  <%= address_form.text_field :city %>
+<% end %>
+
+
+
+

上面的代码会生成下面的 HTML:

+
+<input id="person_address_primary_1_city" name="person[address][primary][1][city]" type="text" value="bologna" />
+
+
+
+

一般来说,输入控件的最终名称是 fields_forform_for 辅助方法的 name 参数,加上 :index 选项的值,再加上属性名。我们也可以直接把 :index 选项传递给 text_field 这样的辅助方法作为参数,但在表单生成器中指定这个选项比在输入控件中分别指定这个选项要更为简洁。

还有一种简易写法,可以在 name 参数后加上 [] 并省略 :index 选项。这种简易写法和指定 index: address 选项的效果是一样的:

+
+<%= fields_for 'person[address][primary][]', address do |address_form| %>
+  <%= address_form.text_field :city %>
+<% end %>
+
+
+
+

上面的代码生成的 HTML 和前一个例子完全相同。

8 处理外部资源的表单

Rails 表单辅助方法也可用于创建向外部资源提交数据的表单。不过,有时我们需要为这些外部资源设置 authenticity_token,具体操作是为 form_tag 辅助方法设置 authenticity_token: 'your_external_token' 选项:

+
+<%= form_tag 'http://farfar.away/form', authenticity_token: 'external_token' do %>
+  Form contents
+<% end %>
+
+
+
+

在向外部资源(例如支付网关)提交数据时,有时表单中可用的字段会受到外部 API 的限制,并且不需要生成 authenticity_token。通过设置 authenticity_token: false 选项即可禁用 authenticity_token

+
+<%= form_tag 'http://farfar.away/form', authenticity_token: false do %>
+  Form contents
+<% end %>
+
+
+
+

相同的技术也可用于 form_for 辅助方法:

+
+<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %>
+  Form contents
+<% end %>
+
+
+
+

或者,如果想要禁用 authenticity_token

+
+<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %>
+  Form contents
+<% end %>
+
+
+
+

9 创建复杂表单

许多应用可不只是在表单中修改单个对象这样简单。例如,在创建 Person 模型的实例时,我们可能还想让用户在同一个表单中创建多条地址记录(如家庭地址、单位地址等)。之后在修改 Person 模型的实例时,用户应该能够根据需要添加、删除或修改地址。

9.1 配置模型

为此,Active Record 通过 accepts_nested_attributes_for 方法在模型层面提供支持:

+
+class Person < ApplicationRecord
+  has_many :addresses
+  accepts_nested_attributes_for :addresses
+end
+
+class Address < ApplicationRecord
+  belongs_to :person
+end
+
+
+
+

上面的代码会在 Person 模型上创建 addresses_attributes= 方法,用于创建、更新或删除地址。

9.2 嵌套表单

通过下面的表单我们可以创建 Person 模型的实例及其关联的地址:

+
+<%= form_for @person do |f| %>
+  Addresses:
+  <ul>
+    <%= f.fields_for :addresses do |addresses_form| %>
+      <li>
+        <%= addresses_form.label :kind %>
+        <%= addresses_form.text_field :kind %>
+
+        <%= addresses_form.label :street %>
+        <%= addresses_form.text_field :street %>
+        ...
+      </li>
+    <% end %>
+  </ul>
+<% end %>
+
+
+
+

如果关联支持嵌套属性,fields_for 方法会为关联中的每个元素执行块。如果 Person 模型的实例没有关联地址,就不会显示地址字段。一般的做法是构建一个或多个空的子属性,这样至少会显示一组字段。下面的例子会在新建 Person 模型实例的表单中显示两组地址字段。

+
+def new
+  @person = Person.new
+  2.times { @person.addresses.build}
+end
+
+
+
+

fields_for 辅助方法会产出表单生成器,而 accepts_nested_attributes_for 方法需要参数名。例如,当创建具有两个地址的 Person 模型的实例时,表单提交的参数如下:

+
+{
+  'person' => {
+    'name' => 'John Doe',
+    'addresses_attributes' => {
+      '0' => {
+        'kind' => 'Home',
+        'street' => '221b Baker Street'
+      },
+      '1' => {
+        'kind' => 'Office',
+        'street' => '31 Spooner Street'
+      }
+    }
+  }
+}
+
+
+
+

:addresses_attributes 散列的键是什么并不重要,只要每个地址的键互不相同即可。

如果关联对象在数据库中已存在,fields_for 方法会使用这个对象的 ID 自动生成隐藏输入字段。通过设置 include_id: false 选项可以禁止自动生成隐藏输入字段。如果自动生成的隐藏输入字段位置不对,导致 HTML 无效,或者 ORM 中子对象不存在 ID,那么我们就应该禁止自动生成隐藏输入字段。

9.3 控制器

照例,我们需要在控制器中把参数列入白名单,然后再把参数传递给模型:

+
+def create
+  @person = Person.new(person_params)
+  # ...
+end
+
+private
+  def person_params
+    params.require(:person).permit(:name, addresses_attributes: [:id, :kind, :street])
+  end
+
+
+
+

9.4 删除对象

通过为 accepts_nested_attributes_for 方法设置 allow_destroy: true 选项,用户就可以删除关联对象。

+
+class Person < ApplicationRecord
+  has_many :addresses
+  accepts_nested_attributes_for :addresses, allow_destroy: true
+end
+
+
+
+

如果对象属性散列包含 _destroy 键并且值为 1,这个对象就会被删除。下面的表单允许用户删除地址:

+
+<%= form_for @person do |f| %>
+  Addresses:
+  <ul>
+    <%= f.fields_for :addresses do |addresses_form| %>
+      <li>
+        <%= addresses_form.check_box :_destroy %>
+        <%= addresses_form.label :kind %>
+        <%= addresses_form.text_field :kind %>
+        ...
+      </li>
+    <% end %>
+  </ul>
+<% end %>
+
+
+
+

别忘了在控制器中更新参数白名单,添加 _destroy 字段。

+
+def person_params
+  params.require(:person).
+    permit(:name, addresses_attributes: [:id, :kind, :street, :_destroy])
+end
+
+
+
+

9.5 防止创建空记录

通常我们需要忽略用户没有填写的字段。要实现这个功能,我们可以为 accepts_nested_attributes_for 方法设置 :reject_if 选项,这个选项的值是一个 Proc 对象。在表单提交每个属性散列时都会调用这个 Proc 对象。当 Proc 对象的返回值为 true 时,[1]Active Record 不会为这个属性 Hash 创建关联对象。在下面的例子中,当设置了 kind 属性时,Active Record 才会创建地址:

+
+class Person < ApplicationRecord
+  has_many :addresses
+  accepts_nested_attributes_for :addresses, reject_if: lambda {|attributes| attributes['kind'].blank?}
+end
+
+
+
+

方便起见,我们可以把 :reject_if 选项的值设为 :all_blank,此时创建的 Proc 对象会拒绝为除 _destroy 之外的其他属性都为空的属性散列创建关联对象。

9.6 按需添加字段

有时,与其提前显示多组字段,倒不如等用户点击“添加新地址”按钮后再添加。Rails 没有内置这种功能。在生成这些字段时,我们必须保证关联数组的键是唯一的,这种情况下通常会使用 JavaScript 的当前时间(从 1970 年 1 月 1 日午夜开始经过的毫秒数)。

[1] 原文为 false,但根据上下文应为 true。——译者注

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/generators.html b/generators.html new file mode 100644 index 0000000..f9590b4 --- /dev/null +++ b/generators.html @@ -0,0 +1,848 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

创建及定制 Rails 生成器和模板

如果你打算改进自己的工作流程,Rails 生成器是必备工具。本文教你创建及定制生成器的方式。

读完本文后,您将学到:

+
    +
  • 如何查看应用中有哪些生成器可用;

  • +
  • 如何使用模板创建生成器;

  • +
  • 在调用生成器之前,Rails 如何搜索生成器;

  • +
  • Rails 内部如何使用模板生成 Rails 代码;

  • +
  • 如何通过创建新生成器定制脚手架;

  • +
  • 如何通过修改生成器模板定制脚手架;

  • +
  • 如何使用后备机制防范覆盖大量生成器;

  • +
  • 如何创建应用模板。

  • +
+

1 第一次接触

使用 rails 命令创建应用时,使用的其实就是一个 Rails 生成器。创建应用之后,可以使用 rails generator 命令列出全部可用的生成器:

+
+$ rails new myapp
+$ cd myapp
+$ bin/rails generate
+
+
+
+

你会看到 Rails 自带的全部生成器。如果想查看生成器的详细描述,比如说 helper 生成器,可以这么做:

+
+$ bin/rails generate helper --help
+
+
+
+

2 创建首个生成器

自 Rails 3.0 起,生成器使用 Thor 构建。Thor 提供了强大的解析选项和处理文件的丰富 API。举个例子。我们来构建一个生成器,在 config/initializers 目录中创建一个名为 initializer.rb 的初始化脚本。

第一步是创建 lib/generators/initializer_generator.rb 文件,写入下述内容:

+
+class InitializerGenerator < Rails::Generators::Base
+  def create_initializer_file
+    create_file "config/initializers/initializer.rb", "# 这里是初始化文件的内容"
+  end
+end
+
+
+
+

create_fileThor::Actions 提供的一个方法。create_file 即其他 Thor 方法的文档参见 Thor 的文档

这个生成器相当简单:继承自 Rails::Generators::Base,定义了一个方法。调用生成器时,生成器中的公开方法按照定义的顺序依次执行。最后,我们调用 create_file 方法在指定的位置创建一个文件,写入指定的内容。如果你熟悉 Rails Application Templates API,对这个生成器 API 就不会感到陌生。

若想调用这个生成器,只需这么做:

+
+$ bin/rails generate initializer
+
+
+
+

在继续之前,先看一下这个生成器的描述:

+
+$ bin/rails generate initializer --help
+
+
+
+

如果把生成器放在命名空间里(如 ActiveRecord::Generators::ModelGenerator),Rails 通常能生成好的描述,但这里没有。这一问题有两个解决方法。第一个是,在生成器中调用 desc

+
+class InitializerGenerator < Rails::Generators::Base
+  desc "This generator creates an initializer file at config/initializers"
+  def create_initializer_file
+    create_file "config/initializers/initializer.rb", "# Add initialization content here"
+  end
+end
+
+
+
+

现在,调用生成器时指定 --help 选项便能看到刚添加的描述。添加描述的第二个方法是,在生成器所在的目录中创建一个名为 USAGE 的文件。下一节将这么做。

3 使用生成器创建生成器

生成器本身也有一个生成器:

+
+$ bin/rails generate generator initializer
+      create  lib/generators/initializer
+      create  lib/generators/initializer/initializer_generator.rb
+      create  lib/generators/initializer/USAGE
+      create  lib/generators/initializer/templates
+
+
+
+

下述代码是这个生成器生成的:

+
+class InitializerGenerator < Rails::Generators::NamedBase
+  source_root File.expand_path("../templates", __FILE__)
+end
+
+
+
+

首先注意,我们继承的是 Rails::Generators::NamedBase,而不是 Rails::Generators::Base。这表明,我们的生成器至少需要一个参数,即初始化脚本的名称,在代码中通过 name 变量获取。

查看这个生成器的描述可以证实这一点(别忘了删除旧的生成器文件):

+
+$ bin/rails generate initializer --help
+Usage:
+  rails generate initializer NAME [options]
+
+
+
+

还能看到,这个生成器有个名为 source_root 的类方法。这个方法指向生成器模板(如果有的话)所在的位置,默认是生成的 lib/generators/initializer/templates 目录。

为了弄清生成器模板的作用,下面创建 lib/generators/initializer/templates/initializer.rb 文件,写入下述内容:

+
+# Add initialization content here
+
+
+
+

然后修改生成器,调用时复制这个模板:

+
+class InitializerGenerator < Rails::Generators::NamedBase
+  source_root File.expand_path("../templates", __FILE__)
+
+  def copy_initializer_file
+    copy_file "initializer.rb", "config/initializers/#{file_name}.rb"
+  end
+end
+
+
+
+

下面执行这个生成器:

+
+$ bin/rails generate initializer core_extensions
+
+
+
+

可以看到,这个命令生成了 config/initializers/core_extensions.rb 文件,里面的内容与模板中一样。这表明,copy_file 方法的作用是把源根目录中的文件复制到指定的目标路径。file_name 方法是继承自 Rails::Generators::NamedBase 之后自动创建的。

生成器中可用的方法在本章最后一节说明。

4 查找生成器

执行 rails generate initializer core_extensions 命令时,Rails 按照下述顺序引入文件,直到找到所需的生成器为止:

+
+rails/generators/initializer/initializer_generator.rb
+generators/initializer/initializer_generator.rb
+rails/generators/initializer_generator.rb
+generators/initializer_generator.rb
+
+
+
+

如果最后找不到,显示一个错误消息。

上述示例把文件放在应用的 lib 目录中,因为这个目录在 $LOAD_PATH 中。

5 定制工作流程

Rails 自带的生成器十分灵活,可以定制脚手架。生成器在 config/application.rb 文件中配置,下面是一些默认值:

+
+config.generators do |g|
+  g.orm             :active_record
+  g.template_engine :erb
+  g.test_framework  :test_unit, fixture: true
+end
+
+
+
+

在定制工作流程之前,先看看脚手架是什么:

+
+$ bin/rails generate scaffold User name:string
+      invoke  active_record
+      create    db/migrate/20130924151154_create_users.rb
+      create    app/models/user.rb
+      invoke    test_unit
+      create      test/models/user_test.rb
+      create      test/fixtures/users.yml
+      invoke  resource_route
+       route    resources :users
+      invoke  scaffold_controller
+      create    app/controllers/users_controller.rb
+      invoke    erb
+      create      app/views/users
+      create      app/views/users/index.html.erb
+      create      app/views/users/edit.html.erb
+      create      app/views/users/show.html.erb
+      create      app/views/users/new.html.erb
+      create      app/views/users/_form.html.erb
+      invoke    test_unit
+      create      test/controllers/users_controller_test.rb
+      invoke    helper
+      create      app/helpers/users_helper.rb
+      invoke    jbuilder
+      create      app/views/users/index.json.jbuilder
+      create      app/views/users/show.json.jbuilder
+      invoke  assets
+      invoke    coffee
+      create      app/assets/javascripts/users.coffee
+      invoke    scss
+      create      app/assets/stylesheets/users.scss
+      invoke  scss
+      create    app/assets/stylesheets/scaffolds.scss
+
+
+
+

通过上述输出不难看出 Rails 3.0 及以上版本中生成器的工作方式。脚手架生成器其实什么也不生成,只是调用其他生成器。因此,我们可以添加、替换和删除任何生成器。例如,脚手架生成器调用了 scaffold_controller 生成器,而它调用了 erb、test_unit 和 helper 生成器。因为各个生成器的职责单一,所以可以轻易复用,从而避免代码重复。

我们定制工作流程的第一步是,不让脚手架生成样式表、JavaScript 和测试固件文件。为此,我们要像下面这样修改配置:

+
+config.generators do |g|
+  g.orm             :active_record
+  g.template_engine :erb
+  g.test_framework  :test_unit, fixture: false
+  g.stylesheets     false
+  g.javascripts     false
+end
+
+
+
+

如果再使用脚手架生成器生成一个资源,你会看到,它不再创建样式表、JavaScript 和固件文件了。如果想进一步定制,例如使用 DataMapper 和 RSpec 替换 Active Record 和 TestUnit,只需添加相应的 gem,然后配置生成器。

下面举个例子。我们将创建一个辅助方法生成器,添加一些实例变量读值方法。首先,在 rails 命名空间(Rails 在这里搜索作为钩子的生成器)中创建一个生成器:

+
+$ bin/rails generate generator rails/my_helper
+      create  lib/generators/rails/my_helper
+      create  lib/generators/rails/my_helper/my_helper_generator.rb
+      create  lib/generators/rails/my_helper/USAGE
+      create  lib/generators/rails/my_helper/templates
+
+
+
+

然后,把 templates 目录和 source_root 类方法删除,因为用不到。然后添加下述方法,此时生成器如下所示:

+
+# lib/generators/rails/my_helper/my_helper_generator.rb
+class Rails::MyHelperGenerator < Rails::Generators::NamedBase
+  def create_helper_file
+    create_file "app/helpers/#{file_name}_helper.rb", <<-FILE
+module #{class_name}Helper
+  attr_reader :#{plural_name}, :#{plural_name.singularize}
+end
+    FILE
+  end
+end
+
+
+
+

下面为 products 创建一个辅助方法,试试这个新生成器:

+
+$ bin/rails generate my_helper products
+      create  app/helpers/products_helper.rb
+
+
+
+

上述命令会在 app/helpers 目录中生成下述辅助方法文件:

+
+module ProductsHelper
+  attr_reader :products, :product
+end
+
+
+
+

这正是我们预期的。接下来再次编辑 config/application.rb,告诉脚手架使用这个新辅助方法生成器:

+
+config.generators do |g|
+  g.orm             :active_record
+  g.template_engine :erb
+  g.test_framework  :test_unit, fixture: false
+  g.stylesheets     false
+  g.javascripts     false
+  g.helper          :my_helper
+end
+
+
+
+

然后调用这个生成器,实测一下:

+
+$ bin/rails generate scaffold Article body:text
+      [...]
+      invoke    my_helper
+      create      app/helpers/articles_helper.rb
+
+
+
+

从输出中可以看出,Rails 调用了这个新辅助方法生成器,而不是默认的那个。不过,少了点什么:没有生成测试。我们将复用旧的辅助方法生成器测试。

自 Rails 3.0 起,测试很容易,因为有了钩子。辅助方法无需限定于特定的测试框架,只需提供一个钩子,让测试框架实现钩子即可。

为此,我们可以按照下述方式修改生成器:

+
+# lib/generators/rails/my_helper/my_helper_generator.rb
+class Rails::MyHelperGenerator < Rails::Generators::NamedBase
+  def create_helper_file
+    create_file "app/helpers/#{file_name}_helper.rb", <<-FILE
+module #{class_name}Helper
+  attr_reader :#{plural_name}, :#{plural_name.singularize}
+end
+    FILE
+  end
+
+  hook_for :test_framework
+end
+
+
+
+

现在,如果再调用这个辅助方法生成器,而且配置的测试框架是 TestUnit,它会调用 Rails::TestUnitGeneratorTestUnit::MyHelperGenerator。这两个生成器都没定义,我们可以告诉生成器去调用 TestUnit::Generators::HelperGenerator。这个生成器是 Rails 自带的。为此,我们只需添加:

+
+# 搜索 :helper,而不是 :my_helper
+hook_for :test_framework, as: :helper
+
+
+
+

现在,你可以使用脚手架再生成一个资源,你会发现它生成了测试。

6 通过修改生成器模板定制工作流程

前面我们只想在生成的辅助方法中添加一行代码,而不增加额外的功能。为此有种更为简单的方式:替换现有生成器的模板。这里要替换的是 Rails::Generators::HelperGenerator 的模板。

在 Rails 3.0 及以上版本中,生成器搜索模板时不仅查看源根目录,还会在其他路径中搜索模板。其中一个是 lib/templates。我们要定制的是 Rails::Generators::HelperGenerator,因此可以在 lib/templates/rails/helper 目录中放一个模板副本,名为 helper.rb。创建这个文件,写入下述内容:

+
+module <%= class_name %>Helper
+  attr_reader :<%= plural_name %>, :<%= plural_name.singularize %>
+end
+
+
+
+

然后撤销之前对 config/application.rb 文件的修改:

+
+config.generators do |g|
+  g.orm             :active_record
+  g.template_engine :erb
+  g.test_framework  :test_unit, fixture: false
+  g.stylesheets     false
+  g.javascripts     false
+end
+
+
+
+

再生成一个资源,你将看到,得到的结果完全一样。如果你想定制脚手架模板和(或)布局,只需在 lib/templates/erb/scaffold 目录中创建 edit.html.erbindex.html.erb,等等。

Rails 的脚手架模板经常使用 ERB 标签,这些标签要转义,这样生成的才是有效的 ERB 代码。

例如,在模板中要像下面这样转义 ERB 标签(注意多了个 %):

+
+<%%= stylesheet_include_tag :application %>
+
+
+
+

生成的内容如下:

+
+<%= stylesheet_include_tag :application %>
+
+
+
+

7 为生成器添加后备机制

生成器最后一个相当有用的功能是插件生成器的后备机制。比如说我们想在 TestUnit 的基础上添加类似 shoulda 的功能。因为 TestUnit 已经实现了 Rails 所需的全部生成器,而 shoulda 只是覆盖其中部分,所以 shoulda 没必要重新实现某些生成器。相反,shoulda 可以告诉 Rails,在 Shoulda 命名空间中找不到某个生成器时,使用 TestUnit 中的生成器。

我们可以再次修改 config/application.rb 文件,模拟这种行为:

+
+config.generators do |g|
+  g.orm             :active_record
+  g.template_engine :erb
+  g.test_framework  :shoulda, fixture: false
+  g.stylesheets     false
+  g.javascripts     false
+
+  # 添加后备机制
+  g.fallbacks[:shoulda] = :test_unit
+end
+
+
+
+

现在,使用脚手架生成 Comment 资源时,你会看到调用了 shoulda 生成器,而它调用的其实是 TestUnit 生成器:

+
+$ bin/rails generate scaffold Comment body:text
+      invoke  active_record
+      create    db/migrate/20130924143118_create_comments.rb
+      create    app/models/comment.rb
+      invoke    shoulda
+      create      test/models/comment_test.rb
+      create      test/fixtures/comments.yml
+      invoke  resource_route
+       route    resources :comments
+      invoke  scaffold_controller
+      create    app/controllers/comments_controller.rb
+      invoke    erb
+      create      app/views/comments
+      create      app/views/comments/index.html.erb
+      create      app/views/comments/edit.html.erb
+      create      app/views/comments/show.html.erb
+      create      app/views/comments/new.html.erb
+      create      app/views/comments/_form.html.erb
+      invoke    shoulda
+      create      test/controllers/comments_controller_test.rb
+      invoke    my_helper
+      create      app/helpers/comments_helper.rb
+      invoke    jbuilder
+      create      app/views/comments/index.json.jbuilder
+      create      app/views/comments/show.json.jbuilder
+      invoke  assets
+      invoke    coffee
+      create      app/assets/javascripts/comments.coffee
+      invoke    scss
+
+
+
+

后备机制能让生成器专注于实现单一职责,尽量复用代码,减少重复代码量。

8 应用模板

至此,我们知道生成器可以在应用内部使用,但是你知道吗,生成器也可用于生成应用?这种生成器叫“模板”(template)。本节简介 Templates API,详情参阅Rails 应用模板

+
+gem "rspec-rails", group: "test"
+gem "cucumber-rails", group: "test"
+
+if yes?("Would you like to install Devise?")
+  gem "devise"
+  generate "devise:install"
+  model_name = ask("What would you like the user model to be called? [user]")
+  model_name = "user" if model_name.blank?
+  generate "devise", model_name
+end
+
+
+
+

在上述模板中,我们指定应用要使用 rspec-railscucumber-rails 两个 gem,因此把它们添加到 Gemfiletest 组。然后,我们询问用户是否想安装 Devise。如果用户回答“y”或“yes”,这个模板会将其添加到 Gemfile 中,而且不放在任何分组中,然后运行 devise:install 生成器。然后,这个模板获取用户的输入,运行 devise 生成器,并传入用户对前一个问题的回答。

假如这个模板保存在名为 template.rb 的文件中。我们可以使用它修改 rails new 命令的输出,方法是把文件名传给 -m 选项:

+
+$ rails new thud -m template.rb
+
+
+
+

上述命令会生成 Thud 应用,然后把模板应用到生成的输出上。

模板不一定非得存储在本地系统中,-m 选项也支持在线模板:

+
+$ rails new thud -m https://gist.github.com/radar/722911/raw/
+
+
+
+

本章最后一节虽然不说明如何生成大多数已知的优秀模板,但是会详细说明可用的方法,供你自己开发模板。那些方法也可以在生成器中使用。

9 生成器方法

下面是可供 Rails 生成器和模板使用的方法。

本文不涵盖 Thor 提供的方法。如果想了解,参阅 Thor 的文档

9.1 gem +

指定应用的一个 gem 依赖。

+
+gem "rspec", group: "test", version: "2.1.0"
+gem "devise", "1.1.5"
+
+
+
+

可用的选项:

+
    +
  • :group:把 gem 添加到 Gemfile 中的哪个分组里。

  • +
  • :version:要使用的 gem 版本号,字符串。也可以在 gem 方法的第二个参数中指定。

  • +
  • :git:gem 的 Git 仓库的 URL。

  • +
+

传给这个方法的其他选项放在行尾:

+
+gem "devise", git: "git://github.com/plataformatec/devise", branch: "master"
+
+
+
+

上述代码在 Gemfile 中写入下面这行代码:

+
+gem "devise", git: "git://github.com/plataformatec/devise", branch: "master"
+
+
+
+

9.2 gem_group +

把 gem 放在一个分组里:

+
+gem_group :development, :test do
+  gem "rspec-rails"
+end
+
+
+
+

9.3 add_source +

Gemfile 中添加指定的源:

+
+add_source "http://gems.github.com/"
+
+
+
+

这个方法也接受块:

+
+add_source "http://gems.github.com/" do
+  gem "rspec-rails"
+end
+
+
+
+

9.4 inject_into_file +

在文件中的指定位置插入一段代码:

+
+inject_into_file 'name_of_file.rb', after: "#The code goes below this line. Don't forget the Line break at the end\n" do <<-'RUBY'
+  puts "Hello World"
+RUBY
+end
+
+
+
+

9.5 gsub_file +

替换文件中的文本:

+
+gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code'
+
+
+
+

使用正则表达式替换的效果更精准。可以使用类似的方式调用 append_fileprepend_file,分别在文件的末尾和开头添加代码。

9.6 application +

config/application.rb 文件中应用类定义后面直接添加内容:

+
+application "config.asset_host = 'http://example.com/'"
+
+
+
+

这个方法也接受块:

+
+application do
+  "config.asset_host = 'http://example.com/'"
+end
+
+
+
+

可用的选项:

+
    +
  • +

    :env:指定配置选项所属的环境。如果想在块中使用这个选项,建议使用下述句法:

    +
    +
    +application(nil, env: "development") do
    +  "config.asset_host = 'http://localhost:3000/'"
    +end
    +
    +
    +
    +
  • +
+

9.7 git +

运行指定的 Git 命令:

+
+git :init
+git add: "."
+git commit: "-m First commit!"
+git add: "onefile.rb", rm: "badfile.cxx"
+
+
+
+

这里的散列是传给指定 Git 命令的参数或选项。如最后一行所示,一次可以指定多个 Git 命令,但是命令的运行顺序不一定与指定的顺序一样。

9.8 vendor +

vendor 目录中放一个文件,内有指定的代码:

+
+vendor "sekrit.rb", '#top secret stuff'
+
+
+
+

这个方法也接受块:

+
+vendor "seeds.rb" do
+  "puts 'in your app, seeding your database'"
+end
+
+
+
+

9.9 lib +

lib 目录中放一个文件,内有指定的代码:

+
+lib "special.rb", "p Rails.root"
+
+
+
+

这个方法也接受块

+
+lib "super_special.rb" do
+  puts "Super special!"
+end
+
+
+
+

9.10 rakefile +

在应用的 lib/tasks 目录中创建一个 Rake 文件:

+
+rakefile "test.rake", "hello there"
+
+
+
+

这个方法也接受块:

+
+rakefile "test.rake" do
+  %Q{
+    task rock: :environment do
+      puts "Rockin'"
+    end
+  }
+end
+
+
+
+

9.11 initializer +

在应用的 config/initializers 目录中创建一个初始化脚本:

+
+initializer "begin.rb", "puts 'this is the beginning'"
+
+
+
+

这个方法也接受块,期待返回一个字符串:

+
+initializer "begin.rb" do
+  "puts 'this is the beginning'"
+end
+
+
+
+

9.12 generate +

运行指定的生成器,第一个参数是生成器的名称,后续参数直接传给生成器:

+
+generate "scaffold", "forums title:string description:text"
+
+
+
+

9.13 rake +

运行指定的 Rake 任务:

+
+rake "db:migrate"
+
+
+
+

可用的选项:

+
    +
  • :env:指定在哪个环境中运行 Rake 任务。

  • +
  • :sudo:是否使用 sudo 运行任务。默认为 false

  • +
+

9.14 capify! +

在应用的根目录中运行 Capistrano 提供的 capify 命令,生成 Capistrano 配置。

+
+capify!
+
+
+
+

9.15 route +

config/routes.rb 文件中添加文本:

+
+route "resources :people"
+
+
+
+

9.16 readme +

输出模板的 source_path 中某个文件的内容,通常是 README 文件:

+
+readme "README"
+
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/getting_started.html b/getting_started.html new file mode 100644 index 0000000..bd216ba --- /dev/null +++ b/getting_started.html @@ -0,0 +1,1337 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Rails 入门

本文介绍如何开始使用 Ruby on Rails。

读完本文后,您将学到:

+
    +
  • 如何安装 Rails、创建 Rails 应用,如何连接数据库;

  • +
  • Rails 应用的基本文件结构;

  • +
  • MVC(模型、视图、控制器)和 REST 架构的基本原理;

  • +
  • 如何快速生成 Rails 应用骨架。

  • +
+

1 前提条件

本文针对想从零开始开发 Rails 应用的初学者,不要求 Rails 使用经验。不过,为了能顺利阅读,还是需要事先安装好一些软件:

+ +

Rails 是使用 Ruby 语言开发的 Web 应用框架。如果之前没接触过 Ruby,会感到直接学习 Rails 的学习曲线很陡。这里提供几个学习 Ruby 的在线资源:

+ +

需要注意的是,有些资源虽然很好,但针对的是 Ruby 1.8 甚至 1.6 这些老版本,因此不涉及一些 Rails 日常开发的常见句法。

2 Rails 是什么?

Rails 是使用 Ruby 语言编写的 Web 应用开发框架,目的是通过解决快速开发中的共通问题,简化 Web 应用的开发。与其他编程语言和框架相比,使用 Rails 只需编写更少代码就能实现更多功能。有经验的 Rails 程序员常说,Rails 让 Web 应用开发变得更有趣。

Rails 有自己的设计原则,认为问题总有最好的解决方法,并且有意识地通过设计来鼓励用户使用最好的解决方法,而不是其他替代方案。一旦掌握了“Rails 之道”,就可能获得生产力的巨大提升。在 Rails 开发中,如果不改变使用其他编程语言时养成的习惯,总想使用原有的设计模式,开发体验可能就不那么让人愉快了。

Rails 哲学包含两大指导思想:

+
    +
  • 不要自我重复(DRY): DRY 是软件开发中的一个原则,意思是“系统中的每个功能都要具有单一、准确、可信的实现。”。不重复表述同一件事,写出的代码才更易维护、更具扩展性,也更不容易出问题。

  • +
  • 多约定,少配置: Rails 为 Web 应用的大多数需求都提供了最好的解决方法,并且默认使用这些约定,而不是在长长的配置文件中设置每个细节。

  • +
+

3 创建 Rails 项目

阅读本文的最佳方法是一步步跟着操作。所有这些步骤对于运行示例应用都是必不可少的,同时也不需要更多的代码或步骤。

通过学习本文,你将学会如何创建一个名为 Blog 的 Rails 项目,这是一个非常简单的博客。在动手开发之前,请确保已经安装了 Rails。

文中的示例代码使用 UNIX 风格的命令行提示符 $,如果你的命令行提示符是自定义的,看起来可能会不一样。在 Windows 中,命令行提示符可能类似 c:\source_code>

3.1 安装 Rails

打开命令行:在 Mac OS X 中打开 Terminal.app,在 Windows 中要在开始菜单中选择“运行”,然后输入“cmd.exe”。本文中所有以 $ 开头的代码,都应该在命令行中执行。首先确认是否安装了 Ruby 的最新版本:

+
+$ ruby -v
+ruby 2.3.0p0
+
+
+
+

有很多工具可以帮助你快速地在系统中安装 Ruby 和 Ruby on Rails。Windows 用户可以使用 Rails Installer,Mac OS X 用户可以使用 Tokaido。更多操作系统中的安装方法请访问 ruby-lang.org

很多类 UNIX 系统都预装了版本较新的 SQLite3。在 Windows 中,通过 Rails Installer 安装 Rails 会同时安装 SQLite3。其他操作系统中 SQLite3 的安装方法请参阅 SQLite3 官网。接下来,确认 SQLite3 是否在 PATH 中:

+
+$ sqlite3 --version
+
+
+
+

执行结果应该显示 SQLite3 的版本号。

安装 Rails,请使用 RubyGems 提供的 gem install 命令:

+
+$ gem install rails
+
+
+
+

执行下面的命令来确认所有软件是否都已正确安装:

+
+$ rails --version
+
+
+
+

如果执行结果类似 Rails 5.0.0,那么就可以继续往下读了。

3.2 创建 Blog 应用

Rails 提供了许多名为“生成器”(generator)的脚本,这些脚本可以为特定任务生成所需的全部文件,从而简化开发。其中包括新应用生成器,这个脚本用于创建 Rails 应用骨架,避免了手动编写基础代码。

要使用新应用生成器,请打开终端,进入具有写权限的文件夹,输入:

+
+$ rails new blog
+
+
+
+

这个命令会在文件夹 blog 中创建名为 Blog 的 Rails 应用,然后执行 bundle install 命令安装 Gemfile 中列出的 gem 及其依赖。

执行 rails new -h 命令可以查看新应用生成器的所有命令行选项。

创建 blog 应用后,进入该文件夹:

+
+$ cd blog
+
+
+
+

blog 文件夹中有许多自动生成的文件和文件夹,这些文件和文件夹组成了 Rails 应用的结构。本文涉及的大部分工作都在 app 文件夹中完成。下面简单介绍一下这些用新应用生成器默认选项生成的文件和文件夹的功能:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
文件/文件夹作用
app/包含应用的控制器、模型、视图、辅助方法、邮件程序和静态资源文件。这个文件夹是本文剩余内容关注的重点。
bin/包含用于启动应用的 rails 脚本,以及用于安装、更新、部署或运行应用的其他脚本。
config/配置应用的路由、数据库等。详情请参阅configuring.xml。
config.ru基于 Rack 的服务器所需的 Rack 配置,用于启动应用。
db/包含当前数据库的模式,以及数据库迁移文件。
Gemfile, Gemfile.lock这两个文件用于指定 Rails 应用所需的 gem 依赖。Bundler gem 需要用到这两个文件。关于 Bundler 的更多介绍,请访问 Bundler 官网。
lib/应用的扩展模块。
log/应用日志文件。
public/仅有的可以直接从外部访问的文件夹,包含静态文件和编译后的静态资源文件。
Rakefile定位并加载可在命令行中执行的任务。这些任务在 Rails 的各个组件中定义。如果要添加自定义任务,请不要修改 Rakefile,真接把自定义任务保存在 lib/tasks 文件夹中即可。
README.md应用的自述文件,说明应用的用途、安装方法等。
test/单元测试、固件和其他测试装置。详情请参阅testing.xml。
tmp/临时文件(如缓存和 PID 文件)。
vendor/包含第三方代码,如第三方 gem。
+

4 Hello, Rails!

首先,让我们快速地在页面中添加一些文字。为了访问页面,需要运行 Rails 应用服务器(即 Web 服务器)。

4.1 启动 Web 服务器

实际上这个 Rails 应用已经可以正常运行了。要访问应用,需要在开发设备中启动 Web 服务器。请在 blog 文件夹中执行下面的命令:

+
+$ bin/rails server
+
+
+
+

Windows 用户需要把 bin 文件夹下的脚本文件直接传递给 Ruby 解析器,例如 ruby bin\rails server

编译 CoffeeScript 和压缩 JavaScript 静态资源文件需要 JavaScript 运行时,如果没有运行时,在压缩静态资源文件时会报错,提示没有 execjs。Mac OS X 和 Windows 一般都提供了 JavaScript 运行时。在 Rails 应用的 Gemfile 中,therubyracer gem 被注释掉了,如果需要使用这个 gem,请去掉注释。对于 JRuby 用户,推荐使用 therubyrhino 这个运行时,在 JRuby 中创建 Rails 应用的 Gemfile 中默认包含了这个 gem。要查看 Rails 支持的所有运行时,请参阅 ExecJS

上述命令会启动 Puma,这是 Rails 默认使用的 Web 服务器。要查看运行中的应用,请打开浏览器窗口,访问 http://localhost:3000。这时应该看到默认的 Rails 欢迎页面:

默认的 Rails 欢迎页面

要停止 Web 服务器,请在终端中按 Ctrl+C 键。服务器停止后命令行提示符会重新出现。在大多数类 Unix 系统中,包括 Mac OS X,命令行提示符是 $ 符号。在开发模式中,一般情况下无需重启服务器,服务器会自动加载修改后的文件。

欢迎页面是创建 Rails 应用的冒烟测试,看到这个页面就表示应用已经正确配置,能够正常工作了。

4.2 显示“Hello, Rails!”

要让 Rails 显示“Hello, Rails!”,需要创建控制器和视图。

控制器接受向应用发起的特定访问请求。路由决定哪些访问请求被哪些控制器接收。一般情况下,一个控制器会对应多个路由,不同路由对应不同动作。动作搜集数据并把数据提供给视图。

视图以人类能看懂的格式显示数据。有一点要特别注意,数据是在控制器而不是视图中获取的,视图只是显示数据。默认情况下,视图模板使用 eRuby(嵌入式 Ruby)语言编写,经由 Rails 解析后,再发送给用户。

可以用控制器生成器来创建控制器。下面的命令告诉控制器生成器创建一个包含“index”动作的“Welcome”控制器:

+
+$ bin/rails generate controller Welcome index
+
+
+
+

上述命令让 Rails 生成了多个文件和一个路由:

+
+create  app/controllers/welcome_controller.rb
+ route  get 'welcome/index'
+invoke  erb
+create    app/views/welcome
+create    app/views/welcome/index.html.erb
+invoke  test_unit
+create    test/controllers/welcome_controller_test.rb
+invoke  helper
+create    app/helpers/welcome_helper.rb
+invoke  assets
+invoke    coffee
+create      app/assets/javascripts/welcome.coffee
+invoke    scss
+create      app/assets/stylesheets/welcome.scss
+
+
+
+

其中最重要的文件是控制器和视图,控制器位于 app/controllers/welcome_controller.rb 文件 ,视图位于 app/views/welcome/index.html.erb 文件 。

在文本编辑器中打开 app/views/welcome/index.html.erb 文件,删除所有代码,然后添加下面的代码:

+
+<h1>Hello, Rails!</h1>
+
+
+
+

4.3 设置应用主页

现在我们已经创建了控制器和视图,还需要告诉 Rails 何时显示“Hello, Rails!”,我们希望在访问根地址 http://localhost:3000 时显示。目前根地址显示的还是默认的 Rails 欢迎页面。

接下来需要告诉 Rails 真正的主页在哪里。

在编辑器中打开 config/routes.rb 文件。

+
+Rails.application.routes.draw do
+  get 'welcome/index'
+
+  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
+end
+
+
+
+

这是应用的路由文件,使用特殊的 DSL(domain-specific language,领域专属语言)编写,告诉 Rails 把访问请求发往哪个控制器和动作。编辑这个文件,添加一行代码 root 'welcome#index',此时文件内容应该变成下面这样:

+
+Rails.application.routes.draw do
+  get 'welcome/index'
+
+  root 'welcome#index'
+end
+
+
+
+

root 'welcome#index' 告诉 Rails 对根路径的访问请求应该发往 welcome 控制器的 index 动作,get 'welcome/index' 告诉 Rails 对 http://localhost:3000/welcome/index 的访问请求应该发往 welcome 控制器的 index 动作。后者是之前使用控制器生成器创建控制器(bin/rails generate controller Welcome index)时自动生成的。

如果在生成控制器时停止了服务器,请再次启动服务器(bin/rails server),然后在浏览器中访问 http://localhost:3000。我们会看到之前添加到 app/views/welcome/index.html.erb 文件 的“Hello, Rails!”信息,这说明新定义的路由确实把访问请求发往了 WelcomeControllerindex 动作,并正确渲染了视图。

关于路由的更多介绍,请参阅Rails 路由全解

5 启动并运行起来

前文已经介绍了如何创建控制器、动作和视图,接下来我们要创建一些更具实用价值的东西。

在 Blog 应用中创建一个资源(resource)。资源是一个术语,表示一系列类似对象的集合,如文章、人或动物。资源中的项目可以被创建、读取、更新和删除,这些操作简称 CRUD(Create, Read, Update, Delete)。

Rails 提供了 resources 方法,用于声明标准的 REST 资源。把 article 资源添加到 config/routes.rb 文件,此时文件内容应该变成下面这样:

+
+Rails.application.routes.draw do
+
+  resources :articles
+
+  root 'welcome#index'
+end
+
+
+
+

执行 bin/rails routes 命令,可以看到所有标准 REST 动作都具有对应的路由。输出结果中各列的意义稍后会作说明,现在只需注意 Rails 从 article 的单数形式推导出了它的复数形式,并进行了合理使用。

+
+$ bin/rails routes
+      Prefix Verb   URI Pattern                  Controller#Action
+    articles GET    /articles(.:format)          articles#index
+             POST   /articles(.:format)          articles#create
+ new_article GET    /articles/new(.:format)      articles#new
+edit_article GET    /articles/:id/edit(.:format) articles#edit
+     article GET    /articles/:id(.:format)      articles#show
+             PATCH  /articles/:id(.:format)      articles#update
+             PUT    /articles/:id(.:format)      articles#update
+             DELETE /articles/:id(.:format)      articles#destroy
+        root GET    /                            welcome#index
+
+
+
+

下一节,我们将为应用添加新建文章和查看文章的功能。这两个操作分别对应于 CRUD 的“C”和“R”:创建和读取。下面是用于新建文章的表单:

用于新建文章的表单

表单看起来很简陋,不过没关系,之后我们再来美化。

5.1 打地基

首先,应用需要一个页面用于新建文章,/articles/new 是个不错的选择。相关路由之前已经定义过了,可以直接访问。打开 http://localhost:3000/articles/new,会看到下面的路由错误:

路由错误,常量 ArticlesController 未初始化

产生错误的原因是,用于处理该请求的控制器还没有定义。解决问题的方法很简单:创建 Articles 控制器。执行下面的命令:

+
+$ bin/rails generate controller Articles
+
+
+
+

打开刚刚生成的 app/controllers/articles_controller.rb 文件,会看到一个空的控制器:

+
+class ArticlesController < ApplicationController
+end
+
+
+
+

控制器实际上只是一个继承自 ApplicationController 的类。接在来要在这个类中定义的方法也就是控制器的动作。这些动作对文章执行 CRUD 操作。

在 Ruby 中,有 publicprivateprotected 三种方法,其中只有 public 方法才能作为控制器的动作。详情请参阅 Programming Ruby 一书。

现在刷新 http://localhost:3000/articles/new,会看到一个新错误:

未知动作,在 ArticlesController 中找不到 new 动作

这个错误的意思是,Rails 在刚刚生成的 ArticlesController 中找不到 new 动作。这是因为在 Rails 中生成控制器时,如果不指定想要的动作,生成的控制器就会是空的。

在控制器中手动定义动作,只需要定义一个新方法。打开 app/controllers/articles_controller.rb 文件,在 ArticlesController 类中定义 new 方法,此时控制器应该变成下面这样:

+
+class ArticlesController < ApplicationController
+  def new
+  end
+end
+
+
+
+

ArticlesController 中定义 new 方法后,再次刷新 http://localhost:3000/articles/new,会看到另一个错误:

未知格式,缺少对应模板

产生错误的原因是,Rails 要求这样的常规动作有用于显示数据的对应视图。如果没有视图可用,Rails 就会抛出异常。

上图中下面的几行都被截断了,下面是完整信息:

+
+

ArticlesController#new is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you’re loading it in a web browser, we assume that you expected to actually render a template, not… nothing, so we’re showing an error to be extra-clear. If you expect 204 No Content, carry on. That’s what you’ll get from an XHR or API request. Give it a shot.

+
+

内容还真不少!让我们快速浏览一下,看看各部分是什么意思。

第一部分说明缺少哪个模板,这里缺少的是 articles/new 模板。Rails 首先查找这个模板,如果找不到再查找 application/new 模板。之所以会查找后面这个模板,是因为 ArticlesController 继承自 ApplicationController

下一部分是 request.formats,说明响应使用的模板格式。当我们在浏览器中请求页面时,request.formats 的值是 text/html,因此 Rails 会查找 HTML 模板。request.variants 指明伺服的是何种物理设备,帮助 Rails 判断该使用哪个模板渲染响应。它的值是空的,因为没有为其提供信息。

在本例中,能够工作的最简单的模板位于 app/views/articles/new.html.erb 文件中。文件的扩展名很重要:第一个扩展名是模板格式,第二个扩展名是模板处理器。Rails 会尝试在 app/views 文件夹中查找 articles/new 模板。这个模板的格式只能是 html,模板处理器只能是 erbbuildercoffee 中的一个。:erb 是最常用的 HTML 模板处理器,:builder 是 XML 模板处理器,:coffee 模板处理器用 CoffeeScript 创建 JavaScript 模板。因为我们要创建 HTML 表单,所以应该使用能够在 HTML 中嵌入 Ruby 的 ERB 语言。

所以我们需要创建 articles/new.html.erb 文件,并把它放在应用的 app/views 文件夹中。

现在让我们继续前进。新建 app/views/articles/new.html.erb 文件,添加下面的代码:

+
+<h1>New Article</h1>
+
+
+
+

刷新 http://localhost:3000/articles/new,会看到页面有了标题。现在路由、控制器、动作和视图都可以协调地工作了!是时候创建用于新建文章的表单了。

5.2 第一个表单

在模板中创建表单,可以使用表单构建器。Rails 中最常用的表单构建器是 form_for 辅助方法。让我们使用这个方法,在 app/views/articles/new.html.erb 文件中添加下面的代码:

+
+<%= form_for :article do |f| %>
+  <p>
+    <%= f.label :title %><br>
+    <%= f.text_field :title %>
+  </p>
+
+  <p>
+    <%= f.label :text %><br>
+    <%= f.text_area :text %>
+  </p>
+
+  <p>
+    <%= f.submit %>
+  </p>
+<% end %>
+
+
+
+

现在刷新页面,会看到和前文截图一样的表单。在 Rails 中创建表单就是这么简单!

调用 form_for 辅助方法时,需要为表单传递一个标识对象作为参数,这里是 :article 符号。这个符号告诉 form_for 辅助方法表单用于处理哪个对象。在 form_for 辅助方法的块中,f 表示 FormBuilder 对象,用于创建两个标签和两个文本字段,分别用于添加文章的标题和正文。最后在 f 对象上调用 submit 方法来为表单创建提交按钮。

不过这个表单还有一个问题,查看 HTML 源代码会看到表单 action 属性的值是 /articles/new,指向的是当前页面,而当前页面只是用于显示新建文章的表单。

应该把表单指向其他 URL,为此可以使用 form_for 辅助方法的 :url 选项。在 Rails 中习惯用 create 动作来处理提交的表单,因此应该把表单指向这个动作。

修改 app/views/articles/new.html.erb 文件的 form_for 这一行,改为:

+
+<%= form_for :article, url: articles_path do |f| %>
+
+
+
+

这里我们把 articles_path 辅助方法传递给 :url 选项。要想知道这个方法有什么用,我们可以回过头看一下 bin/rails routes 的输出结果:

+
+$ bin/rails routes
+      Prefix Verb   URI Pattern                  Controller#Action
+    articles GET    /articles(.:format)          articles#index
+             POST   /articles(.:format)          articles#create
+ new_article GET    /articles/new(.:format)      articles#new
+edit_article GET    /articles/:id/edit(.:format) articles#edit
+     article GET    /articles/:id(.:format)      articles#show
+             PATCH  /articles/:id(.:format)      articles#update
+             PUT    /articles/:id(.:format)      articles#update
+             DELETE /articles/:id(.:format)      articles#destroy
+        root GET    /                            welcome#index
+
+
+
+

articles_path 辅助方法告诉 Rails 把表单指向和 articles 前缀相关联的 URI 模式。默认情况下,表单会向这个路由发起 POST 请求。这个路由和当前控制器 ArticlesControllercreate 动作相关联。

有了表单和与之相关联的路由,我们现在可以填写表单,然后点击提交按钮来新建文章了,请实际操作一下。提交表单后,会看到一个熟悉的错误:

未知动作,在 `ArticlesController` 中找不到 `create` 动作

解决问题的方法是在 ArticlesController 中创建 create 动作。

5.3 创建文章

要消除“未知动作”错误,我们需要修改 app/controllers/articles_controller.rb 文件,在 ArticlesController 类的 new 动作之后添加 create 动作,就像下面这样:

+
+class ArticlesController < ApplicationController
+  def new
+  end
+
+  def create
+  end
+end
+
+
+
+

现在重新提交表单,会看到什么都没有改变。别着急!这是因为当我们没有说明动作的响应是什么时,Rails 默认返回 204 No Content response。我们刚刚添加了 create 动作,但没有说明响应是什么。这里,create 动作应该把新建文章保存到数据库中。

表单提交后,其字段以参数形式传递给 Rails,然后就可以在控制器动作中引用这些参数,以执行特定任务。要想查看这些参数的内容,可以把 create 动作的代码修改成下面这样:

+
+def create
+  render plain: params[:article].inspect
+end
+
+
+
+

这里 render 方法接受了一个简单的散列(hash)作为参数,:plain 键的值是 params[:article].inspectparams 方法是代表表单提交的参数(或字段)的对象。params 方法返回 ActionController::Parameters 对象,这个对象允许使用字符串或符号访问散列的键。这里我们只关注通过表单提交的参数。

请确保牢固掌握 params 方法,这个方法很常用。让我们看一个示例 URL:http://www.example.com/?username=dhh&email=dhh@email.com。在这个 URL 中,params[:username] 的值是“dhh”,params[:email] 的值是“dhh@email.com”。

如果再次提交表单,就不会再看到缺少模板错误,而是会看到下面这些内容:

+
+<ActionController::Parameters {"title"=>"First Article!", "text"=>"This is my first article."} permitted: false>
+
+
+
+

create 动作把表单提交的参数都显示出来了,但这并没有什么用,只是看到了参数实际上却什么也没做。

5.4 创建 Article 模型

在 Rails 中,模型使用单数名称,对应的数据库表使用复数名称。Rails 提供了用于创建模型的生成器,大多数 Rails 开发者在新建模型时倾向于使用这个生成器。要想新建模型,请执行下面的命令:

+
+$ bin/rails generate model Article title:string text:text
+
+
+
+

上面的命令告诉 Rails 创建 Article 模型,并使模型具有字符串类型的 title 属性和文本类型的 text 属性。这两个属性会自动添加到数据库的 articles 表中,并映射到 Article 模型上。

为此 Rails 会创建一堆文件。这里我们只关注 app/models/article.rbdb/migrate/20140120191729_create_articles.rb 这两个文件 (后面这个文件名和你看到的可能会有点不一样)。后者负责创建数据库结构,下一节会详细说明。

Active Record 很智能,能自动把数据表的字段名映射到模型属性上,因此无需在 Rails 模型中声明属性,让 Active Record 自动完成即可。

5.5 运行迁移

如前文所述,bin/rails generate model 命令会在 db/migrate 文件夹中生成数据库迁移文件。迁移是用于简化创建和修改数据库表操作的 Ruby 类。Rails 使用 rake 命令运行迁移,并且在迁移作用于数据库之后还可以撤销迁移操作。迁移的文件名包含了时间戳,以确保迁移按照创建时间顺序运行。

让我们看一下 db/migrate/YYYYMMDDHHMMSS_create_articles.rb 文件(记住,你的文件名可能会有点不一样),会看到下面的内容:

+
+class CreateArticles < ActiveRecord::Migration[5.0]
+  def change
+    create_table :articles do |t|
+      t.string :title
+      t.text :text
+
+      t.timestamps
+    end
+  end
+end
+
+
+
+

上面的迁移创建了 change 方法,在运行迁移时会调用这个方法。在 change 方法中定义的操作都是可逆的,在需要时 Rails 知道如何撤销这些操作。运行迁移后会创建 articles 表,这个表包括一个字符串字段和一个文本字段,以及两个用于跟踪文章创建和更新时间的时间戳字段。

关于迁移的更多介绍,请参阅Active Record 迁移

现在可以使用 bin/rails 命令运行迁移了:

+
+$ bin/rails db:migrate
+
+
+
+

Rails 会执行迁移命令并告诉我们它创建了 Articles 表。

+
+==  CreateArticles: migrating ==================================================
+-- create_table(:articles)
+   -> 0.0019s
+==  CreateArticles: migrated (0.0020s) =========================================
+
+
+
+

因为默认情况下我们是在开发环境中工作,所以上述命令应用于 config/database.yml 文件中 development 部分定义的的数据库。要想在其他环境中执行迁移,例如生产环境,就必须在调用命令时显式传递环境变量:bin/rails db:migrate RAILS_ENV=production

5.6 在控制器中保存数据

回到 ArticlesController,修改 create 动作,使用新建的 Article 模型把数据保存到数据库。打开 app/controllers/articles_controller.rb 文件,像下面这样修改 create 动作:

+
+def create
+  @article = Article.new(params[:article])
+
+  @article.save
+  redirect_to @article
+end
+
+
+
+

让我们看一下上面的代码都做了什么:Rails 模型可以用相应的属性初始化,它们会自动映射到对应的数据库字段。create 动作中的第一行代码完成的就是这个操作(记住,params[:article] 包含了我们想要的属性)。接下来 @article.save 负责把模型保存到数据库。最后把页面重定向到 show 动作,这个 show 动作我们稍后再定义。

你可能想知道,为什么在上面的代码中 Article.newA 是大写的,而在本文的其他地方引用 articles 时大都是小写的。因为这里我们引用的是在 app/models/article.rb 文件中定义的 Article 类,而在 Ruby 中类名必须以大写字母开头。

之后我们会看到,@article.save 返回布尔值,以表明文章是否保存成功。

现在访问 http://localhost:3000/articles/new,我们就快要能够创建文章了,但我们还会看到下面的错误:

禁用属性错误

Rails 提供了多种安全特性来帮助我们编写安全的应用,上面看到的就是一种安全特性。这个安全特性叫做 健壮参数(strong parameter),要求我们明确地告诉 Rails 哪些参数允许在控制器动作中使用。

为什么我们要这样自找麻烦呢?一次性获取所有控制器参数并自动赋值给模型显然更简单,但这样做会造成恶意使用的风险。设想一下,如果有人对服务器发起了一个精心设计的请求,看起来就像提交了一篇新文章,但同时包含了能够破坏应用完整性的额外字段和值,会怎么样?这些恶意数据会批量赋值给模型,然后和正常数据一起进入数据库,这样就有可能破坏我们的应用或者造成更大损失。

所以我们只能为控制器参数设置白名单,以避免错误地批量赋值。这里,我们想在 create 动作中合法使用 titletext 参数,为此需要使用 requirepermit 方法。像下面这样修改 create 动作中的一行代码:

+
+@article = Article.new(params.require(:article).permit(:title, :text))
+
+
+
+

上述代码通常被抽象为控制器类的一个方法,以便在控制器的多个动作中重用,例如在 createupdate 动作中都会用到。除了批量赋值问题,为了禁止从外部调用这个方法,通常还要把它设置为 private。最后的代码像下面这样:

+
+def create
+  @article = Article.new(article_params)
+
+  @article.save
+  redirect_to @article
+end
+
+private
+  def article_params
+    params.require(:article).permit(:title, :text)
+  end
+
+
+
+

关于键壮参数的更多介绍,请参阅上面提供的参考资料和这篇博客

5.7 显示文章

现在再次提交表单,Rails 会提示找不到 show 动作。尽管这个提示没有多大用处,但在继续前进之前我们还是先添加 show 动作吧。

之前我们在 bin/rails routes 命令的输出结果中看到,show 动作对应的路由是:

+
+article GET    /articles/:id(.:format)      articles#show
+
+
+
+

特殊句法 :id 告诉 Rails 这个路由期望接受 :id 参数,在这里也就是文章的 ID。

和前面一样,我们需要在 app/controllers/articles_controller.rb 文件中添加 show 动作,并创建对应的视图文件。

常见的做法是按照以下顺序在控制器中放置标准的 CRUD 动作:indexshowneweditcreateupdatedestroy。你也可以按照自己的顺序放置这些动作,但要记住它们都是公开方法,如前文所述,必须放在控制器的私有方法或受保护的方法之前才能正常工作。

有鉴于此,让我们像下面这样添加 show 动作:

+
+class ArticlesController < ApplicationController
+  def show
+    @article = Article.find(params[:id])
+  end
+
+  def new
+  end
+
+  # 为了行文简洁,省略以下内容
+
+
+
+

上面的代码中有几个问题需要注意。我们使用 Article.find 来查找文章,并传入 params[:id] 以便从请求中获得 :id 参数。我们还使用实例变量(前缀为 @)保存对文章对象的引用。这样做是因为 Rails 会把所有实例变量传递给视图。

现在新建 app/views/articles/show.html.erb 文件,添加下面的代码:

+
+<p>
+  <strong>Title:</strong>
+  <%= @article.title %>
+</p>
+
+<p>
+  <strong>Text:</strong>
+  <%= @article.text %>
+</p>
+
+
+
+

通过上面的修改,我们终于能够新建文章了。访问 http://localhost:3000/articles/new,自己试一试吧!

显示文章

5.8 列出所有文章

我们还需要列出所有文章,下面就来完成这个功能。在 bin/rails routes 命令的输出结果中,和列出文章对应的路由是:

+
+articles GET    /articles(.:format)          articles#index
+
+
+
+

app/controllers/articles_controller.rb 文件的 ArticlesController 中为上述路由添加对应的 index 动作。在编写 index 动作时,常见的做法是把它作为控制器的第一个方法,就像下面这样:

+
+class ArticlesController < ApplicationController
+  def index
+    @articles = Article.all
+  end
+
+  def show
+    @article = Article.find(params[:id])
+  end
+
+  def new
+  end
+
+  # 为了行文简洁,省略以下内容
+
+
+
+

最后,在 app/views/articles/index.html.erb 文件中为 index 动作添加视图:

+
+<h1>Listing articles</h1>
+
+
+
+
+
+

现在访问 http://localhost:3000/articles,会看到已创建的所有文章的列表。

5.9 添加链接

至此,我们可以创建、显示、列出文章了。下面我们添加一些指向这些页面的链接。

打开 app/views/welcome/index.html.erb 文件,修改成下面这样:

+
+<h1>Hello, Rails!</h1>
+<%= link_to 'My Blog', controller: 'articles' %>
+
+
+
+

link_to 方法是 Rails 内置的视图辅助方法之一,用于创建基于链接文本和地址的超链接。在这里地址指的是文章列表页面的路径。

接下来添加指向其他视图的链接。首先在 app/views/articles/index.html.erb 文件中添加“New Article”链接,把这个链接放在 +``

接着在 app/views/articles/show.html.erb 模板中添加 Edit 链接,这样文章页面也有 Edit 链接了。把这个链接添加到模板底部:

+
+...
+
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
+
+
+
+

下面是文章列表现在的样子:

文章列表

5.10 使用局部视图去掉视图中的重复代码

编辑文章页面和新建文章页面看起来很相似,实际上这两个页面用于显示表单的代码是相同的。现在我们要用局部视图来去掉这些重复代码。按照约定,局部视图的文件名以下划线开头。

关于局部视图的更多介绍,请参阅Rails 布局和视图渲染

新建 app/views/articles/_form.html.erb 文件,添加下面的代码:

+
+<%= form_for @article do |f| %>
+
+  <% if @article.errors.any? %>
+    <div id="error_explanation">
+      <h2>
+        <%= pluralize(@article.errors.count, "error") %> prohibited
+        this article from being saved:
+      </h2>
+      <ul>
+        <% @article.errors.full_messages.each do |msg| %>
+          <li><%= msg %></li>
+        <% end %>
+      </ul>
+    </div>
+  <% end %>
+
+  <p>
+    <%= f.label :title %><br>
+    <%= f.text_field :title %>
+  </p>
+
+  <p>
+    <%= f.label :text %><br>
+    <%= f.text_area :text %>
+  </p>
+
+  <p>
+    <%= f.submit %>
+  </p>
+
+<% end %>
+
+
+
+

除了第一行 form_for 的用法变了之外,其他代码都和之前一样。之所以能用这个更短、更简单的 form_for 声明来代替新建文章页面和编辑文章页面的两个表单,是因为 @article 是一个资源,对应于一套 REST 式路由,Rails 能够推断出应该使用哪个地址和方法。关于 form_for 用法的更多介绍,请参阅“面向资源的风格”。

现在更新 app/views/articles/new.html.erb 视图,以使用新建的局部视图。把文件内容替换为下面的代码:

+
+<h1>New article</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Back', articles_path %>
+
+
+
+

然后按照同样的方法修改 app/views/articles/edit.html.erb 视图:

+
+<h1>Edit article</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Back', articles_path %>
+
+
+
+

5.11 删除文章

现在该介绍 CRUD 中的“D”操作了,也就是从数据库删除文章。按照 REST 架构的约定,在 bin/rails routes 命令的输出结果中删除文章的路由是:

+
+DELETE /articles/:id(.:format)      articles#destroy
+
+
+
+

删除资源的路由应该使用 delete 路由方法。如果在删除资源时仍然使用 get 路由,就可能给那些设计恶意地址的人提供可乘之机:

+
+<a href='http://example.com/articles/1/destroy'>look at this cat!</a>
+
+
+
+

我们用 delete 方法来删除资源,对应的路由会映射到 app/controllers/articles_controller.rb 文件中的 destroy 动作,稍后我们要创建这个动作。destroy 动作是控制器中的最后一个 CRUD 动作,和其他公共 CRUD 动作一样,这个动作应该放在 privateprotected 方法之前。打开 app/controllers/articles_controller.rb 文件,添加下面的代码:

+
+def destroy
+  @article = Article.find(params[:id])
+  @article.destroy
+
+  redirect_to articles_path
+end
+
+
+
+

app/controllers/articles_controller.rb 文件中,ArticlesController 的完整代码应该像下面这样:

+
+class ArticlesController < ApplicationController
+  def index
+    @articles = Article.all
+  end
+
+  def show
+    @article = Article.find(params[:id])
+  end
+
+  def new
+    @article = Article.new
+  end
+
+  def edit
+    @article = Article.find(params[:id])
+  end
+
+  def create
+    @article = Article.new(article_params)
+
+    if @article.save
+      redirect_to @article
+    else
+      render 'new'
+    end
+  end
+
+  def update
+    @article = Article.find(params[:id])
+
+    if @article.update(article_params)
+      redirect_to @article
+    else
+      render 'edit'
+    end
+  end
+
+  def destroy
+    @article = Article.find(params[:id])
+    @article.destroy
+
+    redirect_to articles_path
+  end
+
+  private
+    def article_params
+      params.require(:article).permit(:title, :text)
+    end
+end
+
+
+
+

在 Active Record 对象上调用 destroy 方法,就可从数据库中删除它们。注意,我们不需要为 destroy 动作添加视图,因为完成操作后它会重定向到 index 动作。

最后,在 index 动作的模板(app/views/articles/index.html.erb)中加上“Destroy”链接,这样就大功告成了:

+
+<h1>Listing Articles</h1>
+<%= link_to 'New article', new_article_path %>
+
+
+
+
+

在上面的代码中,link_to 辅助方法生成“Destroy”链接的用法有点不同,其中第二个参数是具名路由(named route),还有一些选项作为其他参数。method: :deletedata: { confirm: 'Are you sure?' } 选项用于设置链接的 HTML5 属性,这样点击链接后 Rails 会先向用户显示一个确认对话框,然后用 delete 方法发起请求。这些操作是通过 JavaScript 脚本 jquery_ujs 实现的,这个脚本在生成应用骨架时已经被自动包含在了应用的布局中(app/views/layouts/application.html.erb)。如果没有这个脚本,确认对话框就无法显示。

确认对话框

关于 jQuery 非侵入式适配器(jQuery UJS)的更多介绍,请参阅在 Rails 中使用 JavaScript

恭喜你!现在你已经可以创建、显示、列出、更新和删除文章了!

通常 Rails 鼓励用资源对象来代替手动声明路由。关于路由的更多介绍,请参阅Rails 路由全解

6 添加第二个模型

现在是为应用添加第二个模型的时候了。这个模型用于处理文章评论。

6.1 生成模型

接下来将要使用的生成器,和之前用于创建 Article 模型的一样。这次我们要创建 Comment 模型,用于保存文章评论。在终端中执行下面的命令:

+
+$ bin/rails generate model Comment commenter:string body:text article:references
+
+
+
+

上面的命令会生成 4 个文件:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
文件用途
db/migrate/20140120201010_create_comments.rb用于在数据库中创建 comments 表的迁移文件(你的文件名会包含不同的时间戳)
app/models/comment.rbComment 模型文件
test/models/comment_test.rbComment 模型的测试文件
test/fixtures/comments.yml用于测试的示例评论
+

首先看一下 app/models/comment.rb 文件:

+
+class Comment < ApplicationRecord
+  belongs_to :article
+end
+
+
+
+

可以看到,Comment 模型文件的内容和之前的 Article 模型差不多,仅仅多了一行 belongs_to :article,这行代码用于建立 Active Record 关联。下一节会简单介绍关联。

在上面的 Bash 命令中使用的 :references 关键字是一种特殊的模型数据类型,用于在数据表中新建字段。这个字段以提供的模型名加上 _id 后缀作为字段名,保存整数值。之后通过分析 db/schema.rb 文件可以更好地理解这些内容。

除了模型文件,Rails 还生成了迁移文件,用于创建对应的数据表:

+
+class CreateComments < ActiveRecord::Migration[5.0]
+  def change
+    create_table :comments do |t|
+      t.string :commenter
+      t.text :body
+      t.references :article, foreign_key: true
+
+      t.timestamps
+    end
+  end
+end
+
+
+
+

t.references 这行代码创建 article_id 整数字段,为这个字段建立索引,并建立指向 articles 表的 id 字段的外键约束。下面运行这个迁移:

+
+$ bin/rails db:migrate
+
+
+
+

Rails 很智能,只会运行针对当前数据库还没有运行过的迁移,运行结果像下面这样:

+
+==  CreateComments: migrating =================================================
+-- create_table(:comments)
+   -> 0.0115s
+==  CreateComments: migrated (0.0119s) ========================================
+
+
+
+

6.2 模型关联

Active Record 关联让我们可以轻易地声明两个模型之间的关系。对于评论和文章,我们可以像下面这样声明:

+
    +
  • 每一条评论都属于某一篇文章

  • +
  • 一篇文章可以有多条评论

  • +
+

实际上,这种表达方式和 Rails 用于声明模型关联的句法非常接近。前文我们已经看过 Comment 模型中用于声明模型关联的代码,这行代码用于声明每一条评论都属于某一篇文章:

+
+class Comment < ApplicationRecord
+  belongs_to :article
+end
+
+
+
+

现在修改 app/models/article.rb 文件来添加模型关联的另一端:

+
+class Article < ApplicationRecord
+  has_many :comments
+  validates :title, presence: true,
+                    length: { minimum: 5 }
+end
+
+
+
+

这两行声明能够启用一些自动行为。例如,如果 @article 实例变量表示一篇文章,就可以使用 @article.comments 以数组形式取回这篇文章的所有评论。

关于模型关联的更多介绍,请参阅Active Record 关联

6.3 为评论添加路由

welcome 控制器一样,在添加路由之后 Rails 才知道在哪个地址上查看评论。再次打开 config/routes.rb 文件,像下面这样进行修改:

+
+resources :articles do
+  resources :comments
+end
+
+
+
+

上面的代码在 articles 资源中创建 comments 资源,这种方式被称为嵌套资源。这是表明文章和评论之间层级关系的另一种方式。

关于路由的更多介绍,请参阅Rails 路由全解

6.4 生成控制器

有了模型,下面应该创建对应的控制器了。还是使用前面用过的生成器:

+
+$ bin/rails generate controller Comments
+
+
+
+

上面的命令会创建 5 个文件和一个空文件夹:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
文件/文件夹用途
app/controllers/comments_controller.rbComments 控制器文件
app/views/comments/控制器的视图保存在这里
test/controllers/comments_controller_test.rb控制器的测试文件
app/helpers/comments_helper.rb视图辅助方法文件
app/assets/javascripts/comment.coffee控制器的 CoffeeScript 文件
app/assets/stylesheets/comment.scss控制器的样式表文件
+

在博客中,读者看完文章后可以直接发表评论,并且马上可以看到这些评论是否在页面上显示出来了。我们的博客采取同样的设计。这里 CommentsController 需要提供创建评论和删除垃圾评论的方法。

首先修改显示文章的模板(app/views/articles/show.html.erb),添加发表评论的功能:

+
+<p>
+  <strong>Title:</strong>
+  <%= @article.title %>
+</p>
+
+<p>
+  <strong>Text:</strong>
+  <%= @article.text %>
+</p>
+
+<h2>Add a comment:</h2>
+<%= form_for([@article, @article.comments.build]) do |f| %>
+  <p>
+    <%= f.label :commenter %><br>
+    <%= f.text_field :commenter %>
+  </p>
+  <p>
+    <%= f.label :body %><br>
+    <%= f.text_area :body %>
+  </p>
+  <p>
+    <%= f.submit %>
+  </p>
+<% end %>
+
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
+
+
+
+

上面的代码在显示文章的页面中添加了用于新建评论的表单,通过调用 CommentsControllercreate 动作来发表评论。这里 form_for 辅助方法以数组为参数,会创建嵌套路由,例如 /articles/1/comments

接下来在 app/controllers/comments_controller.rb 文件中添加 create 动作:

+
+class CommentsController < ApplicationController
+  def create
+    @article = Article.find(params[:article_id])
+    @comment = @article.comments.create(comment_params)
+    redirect_to article_path(@article)
+  end
+
+  private
+    def comment_params
+      params.require(:comment).permit(:commenter, :body)
+    end
+end
+
+
+
+

上面的代码比 Articles 控制器的代码复杂得多,这是嵌套带来的副作用。对于每一个发表评论的请求,都必须记录这条评论属于哪篇文章,因此需要在 Article 模型上调用 find 方法来获取文章对象。

此外,上面的代码还利用了关联特有的方法,在 @article.comments 上调用 create 方法来创建和保存评论,同时自动把评论和对应的文章关联起来。

添加评论后,我们使用 article_path(@article) 辅助方法把用户带回原来的文章页面。如前文所述,这里调用了 ArticlesControllershow 动作来渲染 show.html.erb 模板,因此需要修改 app/views/articles/show.html.erb 文件来显示评论:

+
+<p>
+  <strong>Title:</strong>
+  <%= @article.title %>
+</p>
+
+<p>
+  <strong>Text:</strong>
+  <%= @article.text %>
+</p>
+
+<h2>Comments</h2>
+<% @article.comments.each do |comment| %>
+  <p>
+    <strong>Commenter:</strong>
+    <%= comment.commenter %>
+  </p>
+
+  <p>
+    <strong>Comment:</strong>
+    <%= comment.body %>
+  </p>
+<% end %>
+
+<h2>Add a comment:</h2>
+<%= form_for([@article, @article.comments.build]) do |f| %>
+  <p>
+    <%= f.label :commenter %><br>
+    <%= f.text_field :commenter %>
+  </p>
+  <p>
+    <%= f.label :body %><br>
+    <%= f.text_area :body %>
+  </p>
+  <p>
+    <%= f.submit %>
+  </p>
+<% end %>
+
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
+
+
+
+

现在可以在我们的博客中为文章添加评论了,评论添加后就会显示在正确的位置上。

带有评论的文章

7 重构

现在博客的文章和评论都已经正常工作,打开 app/views/articles/show.html.erb 文件,会看到文件代码变得又长又不美观。因此下面我们要用局部视图来重构代码。

7.1 渲染局部视图集合

首先创建评论的局部视图,把显示文章评论的代码抽出来。创建 app/views/comments/_comment.html.erb 文件,添加下面的代码:

+
+<p>
+  <strong>Commenter:</strong>
+  <%= comment.commenter %>
+</p>
+
+<p>
+  <strong>Comment:</strong>
+  <%= comment.body %>
+</p>
+
+
+
+

然后像下面这样修改 app/views/articles/show.html.erb 文件:

+
+<p>
+  <strong>Title:</strong>
+  <%= @article.title %>
+</p>
+
+<p>
+  <strong>Text:</strong>
+  <%= @article.text %>
+</p>
+
+<h2>Comments</h2>
+<%= render @article.comments %>
+
+<h2>Add a comment:</h2>
+<%= form_for([@article, @article.comments.build]) do |f| %>
+  <p>
+    <%= f.label :commenter %><br>
+    <%= f.text_field :commenter %>
+  </p>
+  <p>
+    <%= f.label :body %><br>
+    <%= f.text_area :body %>
+  </p>
+  <p>
+    <%= f.submit %>
+  </p>
+<% end %>
+
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
+
+
+
+

这样对于 @article.comments 集合中的每条评论,都会渲染 app/views/comments/_comment.html.erb 文件中的局部视图。render 方法会遍历 @article.comments 集合,把每条评论赋值给局部视图中的同名局部变量,也就是这里的 comment 变量。

7.2 渲染局部视图表单

我们把添加评论的代码也移到局部视图中。创建 app/views/comments/_form.html.erb 文件,添加下面的代码:

+
+<%= form_for([@article, @article.comments.build]) do |f| %>
+  <p>
+    <%= f.label :commenter %><br>
+    <%= f.text_field :commenter %>
+  </p>
+  <p>
+    <%= f.label :body %><br>
+    <%= f.text_area :body %>
+  </p>
+  <p>
+    <%= f.submit %>
+  </p>
+<% end %>
+
+
+
+

然后像下面这样修改 app/views/articles/show.html.erb 文件:

+
+<p>
+  <strong>Title:</strong>
+  <%= @article.title %>
+</p>
+
+<p>
+  <strong>Text:</strong>
+  <%= @article.text %>
+</p>
+
+<h2>Comments</h2>
+<%= render @article.comments %>
+
+<h2>Add a comment:</h2>
+<%= render 'comments/form' %>
+
+<%= link_to 'Edit', edit_article_path(@article) %> |
+<%= link_to 'Back', articles_path %>
+
+
+
+

上面的代码中第二个 render 方法的参数就是我们刚刚定义的 comments/form 局部视图。Rails 很智能,能够发现字符串中的斜线,并意识到我们想渲染 app/views/comments 文件夹中的 _form.html.erb 文件。

@article 是实例变量,因此在所有局部视图中都可以使用。

8 删除评论

博客还有一个重要功能是删除垃圾评论。为了实现这个功能,我们需要在视图中添加一个链接,并在 CommentsController 中添加 destroy 动作。

首先在 app/views/comments/_comment.html.erb 局部视图中添加删除评论的链接:

+
+<p>
+  <strong>Commenter:</strong>
+  <%= comment.commenter %>
+</p>
+
+<p>
+  <strong>Comment:</strong>
+  <%= comment.body %>
+</p>
+
+<p>
+  <%= link_to 'Destroy Comment', [comment.article, comment],
+               method: :delete,
+               data: { confirm: 'Are you sure?' } %>
+</p>
+
+
+
+

点击“Destroy Comment”链接后,会向 CommentsController 发起 DELETE /articles/:article_id/comments/:id 请求,这个请求将用于删除指定评论。下面在控制器(app/controllers/comments_controller.rb)中添加 destroy 动作:

+
+class CommentsController < ApplicationController
+  def create
+    @article = Article.find(params[:article_id])
+    @comment = @article.comments.create(comment_params)
+    redirect_to article_path(@article)
+  end
+
+  def destroy
+    @article = Article.find(params[:article_id])
+    @comment = @article.comments.find(params[:id])
+    @comment.destroy
+    redirect_to article_path(@article)
+  end
+
+  private
+    def comment_params
+      params.require(:comment).permit(:commenter, :body)
+    end
+end
+
+
+
+

destroy 动作首先找到指定文章,然后在 @article.comments 集合中找到指定评论,接着从数据库删除这条评论,最后重定向到显示文章的页面。

8.1 删除关联对象

如果要删除一篇文章,文章的相关评论也需要删除,否则这些评论还会占用数据库空间。在 Rails 中可以使用关联的 dependent 选项来完成这一工作。像下面这样修改 app/models/article.rb 文件中的 Article 模型:

+
+class Article < ApplicationRecord
+  has_many :comments, dependent: :destroy
+  validates :title, presence: true,
+                    length: { minimum: 5 }
+end
+
+
+
+

9 安全

9.1 基本身份验证

现在如果我们把博客放在网上,任何人都能够添加、修改、删除文章或删除评论。

Rails 提供了一个非常简单的 HTTP 身份验证系统,可以很好地解决这个问题。

我们需要一种方法来禁止未认证用户访问 ArticlesController 的动作。这里我们可以使用 Rails 的 http_basic_authenticate_with 方法,通过这个方法的认证后才能访问所请求的动作。

要使用这个身份验证系统,可以在 app/controllers/articles_controller 文件中的 ArticlesController 的顶部进行指定。这里除了 indexshow 动作,其他动作都要通过身份验证才能访问,为此要像下面这样添加代码:

+
+class ArticlesController < ApplicationController
+
+  http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]
+
+  def index
+    @articles = Article.all
+  end
+
+  # 为了行文简洁,省略以下内容
+
+
+
+

同时只有通过身份验证的用户才能删除评论,为此要在 CommentsControllerapp/controllers/comments_controller.rb)中像下面这样添加代码:

+
+class CommentsController < ApplicationController
+
+  http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy
+
+  def create
+    @article = Article.find(params[:article_id])
+    # ...
+  end
+
+  # 为了行文简洁,省略以下内容
+
+
+
+

现在如果我们试着新建文章,就会看到 HTTP 基本身份验证对话框:

HTTP 基本认证对话框

此外,还可以在 Rails 中使用其他身份验证方法。在众多选择中,DeviseAuthlogic 是两个流行的 Rails 身份验证扩展。

9.2 其他安全注意事项

安全,尤其是 Web 应用的安全,是一个广泛和值得深入研究的领域。关于 Rails 应用安全的更多介绍,请参阅安全指南

10 接下来做什么?

至此,我们已经完成了第一个 Rails 应用,请在此基础上尽情修改、试验。

记住你不需要独自完成一切,在安装和运行 Rails 时如果需要帮助,请随时使用下面的资源:

+ +

11 配置问题

在 Rails 中,储存外部数据最好都使用 UTF-8 编码。虽然 Ruby 库和 Rails 通常都能将使用其他编码的外部数据转换为 UTF-8 编码,但并非总是能可靠地工作,所以最好还是确保所有的外部数据都使用 UTF-8 编码。

编码出错的最常见症状是在浏览器中出现带有问号的黑色菱形块,另一个常见症状是本该出现“ü”字符的地方出现了“ü”字符。Rails 内部采取了许多步骤来解决常见的可以自动检测和纠正的编码问题。尽管如此,如果不使用 UTF-8 编码来储存外部数据,偶尔还是会出现无法自动检测和纠正的编码问题。

下面是非 UTF-8 编码数据的两种常见来源:

+
    +
  • 文本编辑器:大多数文本编辑器(例如 TextMate)默认使用 UTF-8 编码保存文件。如果你的文本编辑器未使用 UTF-8 编码,就可能导致在模板中输入的特殊字符(例如 é)在浏览器中显示为带有问号的黑色菱形块。这个问题也会出现在 i18n 翻译文件中。大多数未默认使用 UTF-8 编码的文本编辑器(例如 Dreamweaver 的某些版本)提供了将默认编码修改为 UTF-8 的方法,别忘了进行修改。

  • +
  • 数据库:默认情况下,Rails 会把从数据库中取出的数据转换成 UTF-8 格式。尽管如此,如果数据库内部不使用 UTF-8 编码,就有可能无法保存用户输入的所有字符。例如,如果数据库内部使用 Latin-1 编码,而用户输入了俄语、希伯来语或日语字符,那么在把数据保存到数据库时就会造成数据永久丢失。因此,只要可能,就请在数据库内部使用 UTF-8 编码。

  • +
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/i18n.html b/i18n.html new file mode 100644 index 0000000..348ae21 --- /dev/null +++ b/i18n.html @@ -0,0 +1,1244 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+ +
+ +
+
+
+

Rails 国际化 API

Rails(Rails 2.2 及以上版本)自带的 Ruby I18n(internationalization 的简写)gem,提供了易用、可扩展的框架,用于把应用翻译成英语之外的语言,或为应用提供多语言支持。

“国际化”(internationalization)过程通常是指,把所有字符串及本地化相关信息(例如日期或货币格式)从应用中抽取出来。“本地化”(localization)过程通常是指,翻译这些字符串并提供相关信息的本地格式。[1]

因此,在国际化 Rails 应用的过程中,我们需要:

+
    +
  • 确保 Rails 提供了 I18n 支持;

  • +
  • 把区域设置字典(locale dictionary)的位置告诉 Rails;

  • +
  • 告诉 Rails 如何设置、保存和切换区域(locale)。

  • +
+

在本地化 Rails 应用的过程中,我们可能需要完成下面三项工作:

+
    +
  • 替换或补充 Rails 的默认区域设置,例如日期和时间格式、月份名称、Active Record 模型名等;

  • +
  • 从应用中抽取字符串,并放入字典,例如视图中的闪现信息(flash message)、静态文本等;

  • +
  • 把生成的字典储存在某个地方。

  • +
+

本文介绍 Rails I18n API,并提供国际化 Rails 应用的入门教程。

读完本文后,您将学到:

+
    +
  • Rails 中 I18n 的工作原理;

  • +
  • 在 REST 式应用中正确使用 I18n 的几种方式;

  • +
  • 如何使用 I18n 翻译 Active Record 错误或 Action Mailer 电子邮件主题;

  • +
  • 用于进一步翻译应用的其他工具。

  • +
+

Ruby I18n 框架提供了 Rails 应用国际化/本地化所需的全部必要支持。我们还可以使用各种 gem 来添加附加功能或特性。更多介绍请参阅 rails-18n gem

1 Rails 中 I18n 的工作原理

国际化是一个复杂的问题。自然语言在很多方面(例如复数规则)有所不同,要想一次性提供解决所有问题的工具很难。因此,Rails I18n API 专注于:

+
    +
  • 支持英语及类似语言

  • +
  • 易于定制和扩展,以支持其他语言

  • +
+

作为这个解决方案的一部分,Rails 框架中的每个静态字符串(例如,Active Record 数据验证信息、时间和日期格式)都已国际化。Rails 应用的本地化意味着把这些静态字符串翻译为所需语言。

1.1 I18n 库的总体架构

因此,Ruby I18n gem 分为两部分:

+
    +
  • I18n 框架的公开 API——包含公开方法的 Ruby 模块,定义 I18n 库的工作方式

  • +
  • 实现这些方法的默认后端(称为简单后端)

  • +
+

作为用户,我们应该始终只访问 I18n 模块的公开方法,但了解后端的功能也很有帮助。

我们可以把默认的简单后端替换为其他功能更强的后端,这时翻译数据可能会储存在关系数据库、GetText 字典或类似解决方案中。更多介绍请参阅 使用不同的后端

1.2 I18n 公开 API

I18n API 中最重要的两个方法是:

+
+translate # 查找文本翻译
+localize  # 把日期和时间对象转换为本地格式(本地化)
+
+
+
+

这两个方法的别名分别为 #t#l,用法如下:

+
+I18n.t 'store.title'
+I18n.l Time.now
+
+
+
+

对于下列属性,I18n API 还提供了属性读值方法和设值方法:

+
+load_path         # 自定义翻译文件的路径
+locale            # 获取或设置当前区域
+default_locale    # 获取或设置默认区域
+exception_handler # 使用其他异常处理程序
+backend           # 使用其他后端
+
+
+
+

现在,我们已经掌握了 Rails I18n API 的基本用法,从下一节开始,我们将从头开始国际化一个简单的 Rails 应用。

2 Rails 应用的国际化设置

本节介绍为 Rails 应用提供 I18n 支持的几个步骤。

2.1 配置 I18n 模块

根据“多约定,少配置”原则,Rails I18n 库提供了默认翻译字符串。如果需要不同的翻译字符串,可以直接覆盖默认值。

Rails 会把 config/locales 文件夹中的 .rb.yml 文件自动添加到翻译文件加载路径中。

这个文件夹中的 en.yml 区域设置文件包含了一个翻译字符串示例:

+
+en:
+  hello: "Hello world"
+
+
+
+

上面的代码表示,在 :en 区域设置中,键 hello 会映射到 Hello world 字符串上。在 Rails 中,字符串都以这种方式进行国际化,例如,Active Model 的数据验证信息位于 activemodel/lib/active_model/locale/en.yml 文件中,时间和日期格式位于 activesupport/lib/active_support/locale/en.yml 文件中。我们可以使用 YAML 或标准 Ruby 散列,把翻译信息储存在默认的简单后端中。

I18n 库使用英语作为默认的区域设置,例如,如果未设置为其他区域,那就使用 :en 区域来查找翻译。

经过讨论,I18n 库在选取区域设置的键时最终采取了务实的方式,也就是仅包含语言部分,例如 :en:pl,而不是传统上使用的语言和区域两部分,例如 :en-US:en-GB。很多国际化的应用都是这样做的,例如把 :cs:th:es 分别用于捷克语、泰语和西班牙语。尽管如此,在同一语系中也可能存在重要的区域差异,例如,:en-US 使用 $ 作为货币符号,而 :en-GB 使用 £ 作为货币符号。因此,如果需要,我们也可以使用传统方式,例如,在 :en-GB 字典中提供完整的 "English - United Kingdom" 区域。像 Globalize3 这样的 gem 可以实现这一功能。

Rails 会自动加载翻译文件加载路径(I18n.load_path),这是一个保存有翻译文件路径的数组。通过配置翻译文件加载路径,我们可以自定义翻译文件的目录结构和文件命名规则。

I18n 库的后端采用了延迟加载技术,相关翻译信息仅在第一次查找时加载。我们可以根据需要,随时替换默认后端。

默认的 config/application.rb 文件中有如何从其他目录添加区域设置,以及如何设置不同默认区域的说明。

+
+# 默认区域设置是 :en,config/locales/ 文件夹下的 .rb 和 .yml 翻译文件会被自动加载
+# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+# config.i18n.default_locale = :de
+
+
+
+

在查找翻译文件之前,必须先指定翻译文件加载路径。应该通过初始化脚本修改默认区域设置,而不是 config/application.rb 文件:

+
+# config/initializers/locale.rb
+
+# 指定 I18n 库搜索翻译文件的路径
+I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
+
+# 修改默认区域设置(默认是 :en)
+I18n.default_locale = :pt
+
+
+
+

2.2 跨请求管理区域设置

除非显式设置了 I18n.locale,默认区域设置将会应用于所有翻译文件。

本地化应用有时需要支持多区域设置。此时,需要在每个请求之前设置区域,这样在请求的整个生命周期中,都会根据指定区域,对所有字符串进行翻译。

我们可以在 ApplicationController 中使用 before_action 方法设置区域:

+
+before_action :set_locale
+
+def set_locale
+  I18n.locale = params[:locale] || I18n.default_locale
+end
+
+
+
+

上面的例子说明了如何使用 URL 查询参数来设置区域。例如,对于 http://example.com/books?locale=pt 会使用葡萄牙语进行本地化,对于 http://localhost:3000?locale=de 会使用德语进行本地化。

接下来介绍区域设置的几种不同方式。

2.2.1 根据域名设置区域

第一种方式是,根据应用的域名设置区域。例如,通过 www.example.com 加载英语(或默认)区域设置,通过 www.example.es 加载西班牙语区域设置。也就是根据顶级域名设置区域。这种方式有下列优点:

+
    +
  • 区域设置成为 URL 地址显而易见的一部分

  • +
  • 用户可以直观地判断出页面所使用的语言

  • +
  • 在 Rails 中非常容易实现

  • +
  • 搜索引擎偏爱这种把不同语言内容放在不同域名上的做法

  • +
+

ApplicationController 中,我们可以进行如下配置:

+
+before_action :set_locale
+
+def set_locale
+  I18n.locale = extract_locale_from_tld || I18n.default_locale
+end
+
+# 从顶级域名中获取区域设置,如果获取失败会返回 nil
+# 需要在 /etc/hosts 文件中添加如下设置:
+#   127.0.0.1 application.com
+#   127.0.0.1 application.it
+#   127.0.0.1 application.pl
+def extract_locale_from_tld
+  parsed_locale = request.host.split('.').last
+  I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
+end
+
+
+
+

我们还可以通过类似方式,根据子域名设置区域:

+
+# 从子域名中获取区域设置(例如 http://it.application.local:3000)
+# 需要在 /etc/hosts 文件中添加如下设置:
+#   127.0.0.1 gr.application.local
+def extract_locale_from_subdomain
+  parsed_locale = request.subdomains.first
+  I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
+end
+
+
+
+

要想为应用添加区域设置切换菜单,可以使用如下代码:

+
+link_to("Deutsch", "#{APP_CONFIG[:deutsch_website_url]}#{request.env['PATH_INFO']}")
+
+
+
+

其中 APP_CONFIG[:deutsch_website_url] 的值类似 http://www.application.de

尽管这个解决方案具有上面提到的各种优点,但通过不同域名来提供不同的本地化版本(“语言版本”)有时并非我们的首选。在其他各种可选方案中,在 URL 参数(或请求路径)中包含区域设置是最常见的。

2.2.2 根据 URL 参数设置区域

区域设置(和传递)的最常见方式,是将其包含在 URL 参数中,例如,在前文第一个示例中,before_action 方法调用中的 I18n.locale = params[:locale]。此时,我们会使用 www.example.com/books?locale=jawww.example.com/ja/books 这样的网址。

和根据域名设置区域类似,这种方式具有不少优点,尤其是 REST 式的命名风格,顺应了当前的互联网潮流。不过采用这种方式所需的工作量要大一些。

从 URL 参数获取并设置区域并不难,只要把区域设置包含在 URL 中并通过请求传递即可。当然,没有人愿意在生成每个 URL 地址时显式添加区域设置,例如 link_to(books_url(/service/locale: I18n.locale))

Rails 的 ApplicationController#default_url_options 方法提供的“集中修改 URL 动态生成规则”的功能,正好可以解决这个问题:我们可以设置 url_for 及相关辅助方法的默认行为(通过覆盖 default_url_options 方法)。

我们可以在 ApplicationController 中添加下面的代码:

+
+# app/controllers/application_controller.rb
+def default_url_options
+  { locale: I18n.locale }
+end
+
+
+
+

这样,所有依赖于 url_for 的辅助方法(例如,具名路由辅助方法 root_pathroot_url,资源路由辅助方法 books_pathbooks_url 等等)都会自动在查询字符串中添加区域设置,例如:http://localhost:3001/?locale=ja

至此,我们也许已经很满意了。但是,在应用的每个 URL 地址的末尾添加区域设置,会影响 URL 地址的可读性。此外,从架构的角度看,区域设置的层级应该高于 URL 地址中除域名之外的其他组成部分,这一点也应该通过 URL 地址自身体现出来。

要想使用 http://www.example.com/en/books(加载英语区域设置)和 http://www.example.com/nl/books(加载荷兰语区域设置)这样的 URL 地址,我们可以使用前文提到的覆盖 default_url_options 方法的方式,通过 scope 方法设置路由:

+
+# config/routes.rb
+scope "/:locale" do
+  resources :books
+end
+
+
+
+

现在,当我们调用 books_path 方法时,就会得到 "/en/books"(对于默认区域设置)。像 http://localhost:3001/nl/books 这样的 URL 地址会加载荷兰语区域设置,之后调用 books_path 方法时会返回 "/nl/books"(因为区域设置发生了变化)。

由于 default_url_options 方法的返回值是根据请求分别缓存的,因此无法通过循环调用辅助方法来生成 URL 地址中的区域设置, 也就是说,无法在每次迭代中设置相应的 I18n.locale。正确的做法是,保持 I18n.locale 不变,向辅助方法显式传递 :locale 选项,或者编辑 request.original_fullpath

如果不想在路由中强制使用区域设置,我们可以使用可选的路径作用域(用括号表示),就像下面这样:

+
+# config/routes.rb
+scope "(:locale)", locale: /en|nl/ do
+  resources :books
+end
+
+
+
+

通过这种方式,访问不带区域设置的 http://localhost:3001/books URL 地址时就不会抛出 Routing Error 错误了。这样,我们就可以在不指定区域设置时,使用默认的区域设置。

当然,我们需要特别注意应用的根地址﹝通常是“主页(homepage)”或“仪表盘(dashboard)”﹞。像 root to: "books#index" 这样的不考虑区域设置的路由声明,会导致 http://localhost:3001/nl 无法正常访问。(尽管“只有一个根地址”看起来并没有错)

因此,我们可以像下面这样映射 URL 地址:

+
+# config/routes.rb
+get '/:locale' => 'dashboard#index'
+
+
+
+

需要特别注意路由的声明顺序,以避免这条路由覆盖其他路由。(我们可以把这条路由添加到 root :to 路由声明之前)

有一些 gem 可以简化路由设置,如 routing_filterrails-translate-routesroute_translator

2.2.3 根据用户偏好设置进行区域设置

支持用户身份验证的应用,可能会允许用户在界面中选择区域偏好设置。通过这种方式,用户选择的区域偏好设置会储存在数据库中,并用于处理该用户发起的请求。

+
+def set_locale
+  I18n.locale = current_user.try(:locale) || I18n.default_locale
+end
+
+
+
+
2.2.4 使用隐式区域设置

如果没有显式地为请求设置区域(例如,通过上面提到的各种方式),应用就会尝试推断出所需区域。

2.2.4.1 根据 HTTP 首部推断区域设置

Accept-Language HTTP 首部指明响应请求时使用的首选语言。浏览器根据用户的语言偏好设置设定这个 HTTP 首部,这是推断区域设置的首选方案。

下面是使用 Accept-Language HTTP 首部的一个简单实现:

+
+def set_locale
+  logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}"
+  I18n.locale = extract_locale_from_accept_language_header
+  logger.debug "* Locale set to '#{I18n.locale}'"
+end
+
+private
+  def extract_locale_from_accept_language_header
+    request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
+  end
+
+
+
+

实际上,我们通常会使用更可靠的代码。Iain Hecker 开发的 http_accept_language 或 Ryan Tomayko 开发的 locale Rack 中间件就提供了更好的解决方案。

2.2.4.2 根据 IP 地理位置推断区域设置

我们可以通过客户端请求的 IP 地址来推断客户端所处的地理位置,进而推断其区域设置。GeoIP Lite Country 这样的服务或 geocoder 这样的 gem 就可以实现这一功能。

一般来说,这种方式远不如使用 HTTP 首部可靠,因此并不适用于大多数 Web 应用。

2.2.5 在会话或 Cookie 中储存区域设置

我们可能会认为,可以把区域设置储存在会话或 Cookie 中。但是,我们不能这样做。区域设置应该是透明的,并作为 URL 地址的一部分。这样,我们就不会打破用户的正常预期:如果我们发送一个 URL 地址给朋友,他们应该看到和我们一样的页面和内容。这就是所谓的 REST 规则。关于 REST 规则的更多介绍,请参阅 Stefan Tilkov 写的系列文章。后文将讨论这个规则的一些例外情况。

3 国际化和本地化

现在,我们已经完成了对 Rails 应用 I18n 支持的初始化,进行了区域设置,并在不同请求中应用了区域设置。

接下来,我们要通过抽象本地化相关元素,完成应用的国际化。最后,通过为这些抽象元素提供必要翻译,完成应用的本地化。

下面给出一个例子:

+
+# config/routes.rb
+Rails.application.routes.draw do
+  root to: "home#index"
+end
+
+
+
+
+
+# app/controllers/application_controller.rb
+class ApplicationController < ActionController::Base
+  before_action :set_locale
+
+  def set_locale
+    I18n.locale = params[:locale] || I18n.default_locale
+  end
+end
+
+
+
+
+
+# app/controllers/home_controller.rb
+class HomeController < ApplicationController
+  def index
+    flash[:notice] = "Hello Flash"
+  end
+end
+
+
+
+
+
+# app/views/home/index.html.erb
+<h1>Hello World</h1>
+<p><%= flash[:notice] %></p>
+
+
+
+

demo untranslated

3.1 抽象本地化代码

在我们的代码中有两个英文字符串("Hello Flash""Hello World"),它们在响应用户请求时显示。为了国际化这部分代码,需要用 Rails 提供的 #t 辅助方法来代替这两个字符串,同时为每个字符串选择合适的键:

+
+# app/controllers/home_controller.rb
+class HomeController < ApplicationController
+  def index
+    flash[:notice] = t(:hello_flash)
+  end
+end
+
+
+
+
+
+# app/views/home/index.html.erb
+<h1><%= t :hello_world %></h1>
+<p><%= flash[:notice] %></p>
+
+
+
+

现在,Rails 在渲染 index 视图时会显示错误信息,告诉我们缺少 :hello_world:hello_flash 这两个键的翻译。

demo translation missing

Rails 为视图添加了 ttranslate)辅助方法,从而避免了反复使用 I18n.t 这么长的写法。此外,t 辅助方法还能捕获缺少翻译的错误,把生成的错误信息放在 <span class="translation_missing"> 元素里。

3.2 为国际化字符串提供翻译

下面,我们把缺少的翻译添加到翻译字典文件中:

+
+# config/locales/en.yml
+en:
+  hello_world: Hello world!
+  hello_flash: Hello flash!
+
+# config/locales/pirate.yml
+pirate:
+  hello_world: Ahoy World
+  hello_flash: Ahoy Flash
+
+
+
+

因为我们没有修改 default_locale,翻译会使用 :en 区域设置,响应请求时生成的视图会显示英文字符串:

demo translated en

如果我们通过 URL 地址(http://localhost:3000?locale=pirate)把区域设置为 pirate,响应请求时生成的视图就会显示海盗黑话:

demo translated pirate

添加新的区域设置文件后,需要重启服务器。

要想把翻译储存在 SimpleStore 中,我们可以使用 YAML(.yml)或纯 Ruby(.rb)文件。大多数 Rails 开发者会优先选择 YAML。不过 YAML 有一个很大的缺点,它对空格和特殊字符非常敏感,因此有可能出现应用无法正确加载字典的情况。而 Ruby 文件如果有错误,在第一次加载时应用就会崩溃,因此我们很容易就能找出问题。(如果在使用 YAML 字典时遇到了“奇怪的问题”,可以尝试把字典的相关部分放入 Ruby 文件中。)

3.3 把变量传递给翻译

成功完成应用国际化的一个关键因素是,避免在抽象本地化代码时,对语法规则做出不正确的假设。某个区域设置的基本语法规则,在另一个区域设置中可能不成立。

下面给出一个不正确抽象的例子,其中对翻译的不同组成部分的排序进行了假设。注意,为了处理这个例子中出现的情况,Rails 提供了 number_to_currency 辅助方法。

+
+# app/views/products/show.html.erb
+<%= "#{t('currency')}#{@product.price}" %>
+
+
+
+
+
+# config/locales/en.yml
+en:
+  currency: "$"
+
+# config/locales/es.yml
+es:
+  currency: "€"
+
+
+
+

如果产品价格是 10,那么西班牙语的正确翻译是“10 €”而不是“€10”,但上面的抽象并不能正确处理这种情况。

为了创建正确的抽象,I18n gem 提供了变量插值(variable interpolation)功能,它允许我们在翻译定义(translation definition)中使用变量,并把这些变量的值传递给翻译方法。

下面给出一个正确抽象的例子:

+
+# app/views/products/show.html.erb
+<%= t('product_price', price: @product.price) %>
+
+
+
+
+
+# config/locales/en.yml
+en:
+  product_price: "$%{price}"
+
+# config/locales/es.yml
+es:
+  product_price: "%{price} €"
+
+
+
+

所有的语法和标点都由翻译定义自己决定,所以抽象可以给出正确的翻译。

defaultscope 是保留关键字,不能用作变量名。如果误用,Rails 会抛出 I18n::ReservedInterpolationKey 异常。如果没有把翻译所需的插值变量传递给 #translate 方法,Rails 会抛出 I18n::MissingInterpolationArgument 异常。

3.4 添加日期/时间格式

现在,我们要给视图添加时间戳,以便演示日期/时间的本地化功能。要想本地化时间格式,可以把时间对象传递给 I18n.l 方法或者(最好)使用 #l 辅助方法。可以通过 :format 选项指定时间格式(默认情况下使用 :default 格式)。

+
+# app/views/home/index.html.erb
+<h1><%=t :hello_world %></h1>
+<p><%= flash[:notice] %></p>
+<p><%= l Time.now, format: :short %></p>
+
+
+
+

然后在 pirate 翻译文件中添加时间格式(Rails 默认使用的英文翻译文件已经包含了时间格式):

+
+# config/locales/pirate.yml
+pirate:
+  time:
+    formats:
+      short: "arrrround %H'ish"
+
+
+
+

得到的结果如下:

demo localized pirate

现在,我们可能需要添加一些日期/时间格式,这样 I18n 后端才能按照预期工作(至少应该为 pirate 区域设置添加日期/时间格式)。当然,很可能已经有人通过翻译 Rails 相关区域设置的默认值,完成了这些工作。GitHub 上的 rails-i18n 仓库提供了各种本地化文件的存档。把这些本地化文件放在 config/locales/ 文件夹中即可正常使用。

3.5 其他区域的变形规则

Rails 允许我们为英语之外的区域定义变形规则(例如单复数转换规则)。在 config/initializers/inflections.rb 文件中,我们可以为多个区域定义规则。这个初始化脚本包含了为英语指定附加规则的例子,我们可以参考这些例子的格式为其他区域定义规则。

3.6 本地化视图

假设应用中包含 BooksControllerindex 动作默认会渲染 app/views/books/index.html.erb 模板。如果我们在同一个文件夹中创建了包含本地化变量的 index.es.html.erb 模板,当区域设置为 :es 时,index 动作就会渲染这个模板,而当区域设置为默认区域时, index 动作会渲染通用的 index.html.erb 模板。(在 Rails 的未来版本中,本地化的这种自动化魔术,有可能被应用于 public 文件夹中的资源)

本地化视图功能很有用,例如,如果我们有大量静态内容,就可以使用本地化视图,从而避免把所有东西都放进 YAML 或 Ruby 字典里的麻烦。但要记住,一旦我们需要修改模板,就必须对每个模板文件逐一进行修改。

3.7 区域设置文件的组织

当我们使用 I18n 库自带的 SimpleStore 时,字典储存在磁盘上的纯文本文件中。对于每个区域,把应用的各部分翻译都放在一个文件中,可能会带来管理上的困难。因此,把每个区域的翻译放在多个文件中,分层进行管理是更好的选择。

例如,我们可以像下面这样组织 config/locales 文件夹:

+
+|-defaults
+|---es.rb
+|---en.rb
+|-models
+|---book
+|-----es.rb
+|-----en.rb
+|-views
+|---defaults
+|-----es.rb
+|-----en.rb
+|---books
+|-----es.rb
+|-----en.rb
+|---users
+|-----es.rb
+|-----en.rb
+|---navigation
+|-----es.rb
+|-----en.rb
+
+
+
+

这样,我们就可以把模型和属性名同视图中的文本分离,同时还能使用“默认值”(例如日期和时间格式)。I18n 库的不同后端可以提供不同的分离方式。

Rails 默认的区域设置加载机制,无法自动加载上面例子中位于嵌套文件夹中的区域设置文件。因此,我们还需要进行显式设置:

+
+
+
+# config/application.rb
+config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
+
+
+
+
+

4 I18n API 功能概述

现在我们已经对 I18n 库有了较好的了解,知道了如何国际化简单的 Rails 应用。在下面几个小节中,我们将更深入地了解相关功能。

这几个小节将展示使用 I18n.translate 方法以及 translate 视图辅助方法的示例(注意视图辅助方法提供的附加功能)。

所涉及的功能如下:

+
    +
  • 查找翻译

  • +
  • 把数据插入翻译中

  • +
  • 复数的翻译

  • +
  • 使用安全 HTML 翻译(只针对视图辅助方法)

  • +
  • 本地化日期、数字、货币等

  • +
+

4.1 查找翻译

4.1.1 基本查找、作用域和嵌套键

Rails 通过键来查找翻译,其中键可以是符号或字符串。这两种键是等价的,例如:

+
+I18n.t :message
+I18n.t 'message'
+
+
+
+

translate 方法接受 :scope 选项,选项的值可以包含一个或多个附加键,用于指定翻译键(translation key)的“命名空间”或作用域:

+
+I18n.t :record_invalid, scope: [:activerecord, :errors, :messages]
+
+
+
+

上述代码会在 Active Record 错误信息中查找 :record_invalid 信息。

此外,我们还可以用点号分隔的键来指定翻译键和作用域:

+
+I18n.translate "activerecord.errors.messages.record_invalid"
+
+
+
+

因此,下列调用是等效的:

+
+I18n.t 'activerecord.errors.messages.record_invalid'
+I18n.t 'errors.messages.record_invalid', scope: :activerecord
+I18n.t :record_invalid, scope: 'activerecord.errors.messages'
+I18n.t :record_invalid, scope: [:activerecord, :errors, :messages]
+
+
+
+
4.1.2 默认值

如果指定了 :default 选项,在缺少翻译的情况下,就会返回该选项的值:

+
+I18n.t :missing, default: 'Not here'
+# => 'Not here'
+
+
+
+

如果 :default 选项的值是符号,这个值会被当作键并被翻译。我们可以为 :default 选项指定多个值,第一个被成功翻译的键或遇到的字符串将被作为返回值。

例如,下面的代码首先尝试翻译 :missing 键,然后是 :also_missing 键。由于两次翻译都不能得到结果,最后会返回 "Not here" 字符串。

+
+I18n.t :missing, default: [:also_missing, 'Not here']
+# => 'Not here'
+
+
+
+
4.1.3 批量查找和命名空间查找

要想一次查找多个翻译,我们可以传递键的数组作为参数:

+
+I18n.t [:odd, :even], scope: 'errors.messages'
+# => ["must be odd", "must be even"]
+
+
+
+

此外,键可以转换为一组翻译的(可能是嵌套的)散列。例如,下面的代码可以生成所有 Active Record 错误信息的散列:

+
+I18n.t 'activerecord.errors.messages'
+# => {:inclusion=>"is not included in the list", :exclusion=> ... }
+
+
+
+
4.1.4 惰性查找

Rails 实现了一种在视图中查找区域设置的便捷方法。如果有下述字典:

+
+es:
+  books:
+    index:
+      title: "Título"
+
+
+
+

我们就可以像下面这样在 app/views/books/index.html.erb 模板中查找 books.index.title 的值(注意点号):

+
+<%= t '.title' %>
+
+
+
+

只有 translate 视图辅助方法支持根据片段自动补全翻译作用域的功能。

我们还可以在控制器中使用惰性查找(lazy lookup):

+
+en:
+  books:
+    create:
+      success: Book created!
+
+
+
+

用于设置闪现信息:

+
+class BooksController < ApplicationController
+  def create
+    # ...
+    redirect_to books_url, notice: t('.success')
+  end
+end
+
+
+
+

4.2 复数转换

在英语中,一个字符串只有一种单数形式和一种复数形式,例如,“1 message”和“2 messages”。其他语言(阿拉伯语日语俄语等)则具有不同的语法,有更多或更少的复数形式。因此,I18n API 提供了灵活的复数转换功能。

:count 插值变量具有特殊作用,既可以把它插入翻译,又可以用于从翻译中选择复数形式(根据 CLDR 定义的复数转换规则):

+
+I18n.backend.store_translations :en, inbox: {
+  one: 'one message',
+  other: '%{count} messages'
+}
+I18n.translate :inbox, count: 2
+# => '2 messages'
+
+I18n.translate :inbox, count: 1
+# => 'one message'
+
+
+
+

:en 区域设置的复数转换算法非常简单:

+
+entry[count == 1 ? 0 : 1]
+
+
+
+

也就是说,表示为 :one 的翻译用作单数,另一个翻译用作复数(包括 count 等于 0 的情况)。

如果查找键没能返回可转换为复数形式的散列,就会引发 I18n::InvalidPluralizationData 异常。

4.3 区域的设置和传递

区域设置可以伪全局地设置为 I18n.locale(使用 Thread.current,例如 Time.zone),也可以作为选项传递给 #translate#localize 方法。

如果我们没有传递区域设置,Rails 就会使用 I18n.locale

+
+I18n.locale = :de
+I18n.t :foo
+I18n.l Time.now
+
+
+
+

显式传递区域设置:

+
+I18n.t :foo, locale: :de
+I18n.l Time.now, locale: :de
+
+
+
+

I18n.locale 的默认值是 I18n.default_locale ,而 I18n.default_locale 的默认值是 :en。可以像下面这样设置默认区域:

+
+I18n.default_locale = :de
+
+
+
+

4.4 使用安全 HTML 翻译

带有 '_html' 后缀的键和名为 'html' 的键被认为是 HTML 安全的。当我们在视图中使用这些键时,HTML 不会被转义。

+
+# config/locales/en.yml
+en:
+  welcome: <b>welcome!</b>
+  hello_html: <b>hello!</b>
+  title:
+    html: <b>title!</b>
+
+
+
+
+
+# app/views/home/index.html.erb
+<div><%= t('welcome') %></div>
+<div><%= raw t('welcome') %></div>
+<div><%= t('hello_html') %></div>
+<div><%= t('title.html') %></div>
+
+
+
+

不过插值是会被转义的。例如,对于:

+
+en:
+  welcome_html: "<b>Welcome %{username}!</b>"
+
+
+
+

我们可以安全地传递用户设置的用户名:

+
+<%# This is safe, it is going to be escaped if needed. %>
+<%= t('welcome_html', username: @current_user.username) %>
+
+
+
+

另一方面,安全字符串是逐字插入的。

只有 translate 视图辅助方法支持 HTML 安全翻译文本的自动转换。

demo html safe

4.5 Active Record 模型的翻译

我们可以使用 Model.model_name.humanModel.human_attribute_name(attribute) 方法,来透明地查找模型名和属性名的翻译。

例如,当我们添加了下述翻译:

+
+en:
+  activerecord:
+    models:
+      user: Dude
+    attributes:
+      user:
+        login: "Handle"
+      # 会把 User 的属性 "login" 翻译为 "Handle"
+
+
+
+

User.model_name.human 会返回 "Dude",而 User.human_attribute_name("login") 会返回 "Handle"

我们还可以像下面这样为模型名添加复数形式:

+
+en:
+  activerecord:
+    models:
+      user:
+        one: Dude
+        other: Dudes
+
+
+
+

这时 User.model_name.human(count: 2) 会返回 "Dudes",而 User.model_name.human(count: 1)User.model_name.human 会返回 "Dude"

要想访问模型的嵌套属性,我们可以在翻译文件的模型层级中嵌套使用“模型/属性”:

+
+en:
+  activerecord:
+    attributes:
+      user/gender:
+        female: "Female"
+        male: "Male"
+
+
+
+

这时 User.human_attribute_name("gender.female") 会返回 "Female"

如果我们使用的类包含了 ActiveModel,而没有继承自 ActiveRecord::Base,我们就应该用 activemodel 替换上述例子中键路径中的 activerecord

4.5.1 错误消息的作用域

Active Record 验证的错误消息翻译起来很容易。Active Record 提供了一些用于放置消息翻译的命名空间,以便为不同的模型、属性和验证提供不同的消息和翻译。当然 Active Record 也考虑到了单表继承问题。

这就为根据应用需求灵活调整信息,提供了非常强大的工具。

假设 User 模型对 name 属性进行了验证:

+
+class User < ApplicationRecord
+  validates :name, presence: true
+end
+
+
+
+

此时,错误信息的键是 :blank。Active Record 会在命名空间中查找这个键:

+
+activerecord.errors.models.[model_name].attributes.[attribute_name]
+activerecord.errors.models.[model_name]
+activerecord.errors.messages
+errors.attributes.[attribute_name]
+errors.messages
+
+
+
+

因此,在本例中,Active Record 会按顺序查找下列键,并返回第一个结果:

+
+activerecord.errors.models.user.attributes.name.blank
+activerecord.errors.models.user.blank
+activerecord.errors.messages.blank
+errors.attributes.name.blank
+errors.messages.blank
+
+
+
+

如果模型使用了继承,Active Record 还会在继承链中查找消息。

例如,对于继承自 User 模型的 Admin 模型:

+
+class Admin < User
+  validates :name, presence: true
+end
+
+
+
+

Active Record 会按下列顺序查找消息:

+
+activerecord.errors.models.admin.attributes.name.blank
+activerecord.errors.models.admin.blank
+activerecord.errors.models.user.attributes.name.blank
+activerecord.errors.models.user.blank
+activerecord.errors.messages.blank
+errors.attributes.name.blank
+errors.messages.blank
+
+
+
+

这样,我们就可以在模型继承链的不同位置,以及属性、模型或默认作用域中,为各种错误消息提供特殊翻译。

4.5.2 错误消息的插值

翻译后的模型名、属性名,以及值,始终可用于插值。

因此,举例来说,我们可以用 "Please fill in your %{attribute}" 这样的属性名来代替默认的 "cannot be blank" 错误信息。

count 方法可用时,可根据需要用于复数转换:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
验证选项信息插值
confirmation-:confirmationattribute
acceptance-:accepted-
presence-:blank-
absence-:present-
length:within, :in:too_shortcount
length:within, :in:too_longcount
length:is:wrong_lengthcount
length:minimum:too_shortcount
length:maximum:too_longcount
uniqueness-:taken-
format-:invalid-
inclusion-:inclusion-
exclusion-:exclusion-
associated-:invalid-
numericality-:not_a_number-
numericality:greater_than:greater_thancount
numericality:greater_than_or_equal_to:greater_than_or_equal_tocount
numericality:equal_to:equal_tocount
numericality:less_than:less_thancount
numericality:less_than_or_equal_to:less_than_or_equal_tocount
numericality:other_than:other_thancount
numericality:only_integer:not_an_integer-
numericality:odd:odd-
numericality:even:even-
+
4.5.3 为 Active Record 的 error_messages_for 辅助方法添加翻译

在使用 Active Record 的 error_messages_for 辅助方法时,我们可以为其添加翻译。

Rails 自带以下翻译:

+
+en:
+  activerecord:
+    errors:
+      template:
+        header:
+          one:   "1 error prohibited this %{model} from being saved"
+          other: "%{count} errors prohibited this %{model} from being saved"
+        body:    "There were problems with the following fields:"
+
+
+
+

要想使用 error_messages_for 辅助方法,我们需要在 Gemfile 中添加一行 gem 'dynamic_form',还要安装 DynamicForm gem。

4.6 Action Mailer 电子邮件主题的翻译

如果没有把主题传递给 mail 方法,Action Mailer 会尝试在翻译中查找主题。查找时会使用 <mailer_scope>.<action_name>.subject 形式来构造键。

+
+# user_mailer.rb
+class UserMailer < ActionMailer::Base
+  def welcome(user)
+    #...
+  end
+end
+
+
+
+
+
+en:
+  user_mailer:
+    welcome:
+      subject: "Welcome to Rails Guides!"
+
+
+
+

要想把参数用于插值,可以在调用邮件程序时使用 default_i18n_subject 方法。

+
+# user_mailer.rb
+class UserMailer < ActionMailer::Base
+  def welcome(user)
+    mail(to: user.email, subject: default_i18n_subject(user: user.name))
+  end
+end
+
+
+
+
+
+en:
+  user_mailer:
+    welcome:
+      subject: "%{user}, welcome to Rails Guides!"
+
+
+
+

4.7 提供 I18n 支持的其他内置方法概述

在 Rails 中,我们会使用固定字符串和其他本地化元素,例如,在一些辅助方法中使用的格式字符串和其他格式信息。本小节提供了简要概述。

4.7.1 Action View 辅助方法
+
    +
  • distance_of_time_in_words 辅助方法翻译并以复数形式显示结果,同时插入秒、分钟、小时的数值。更多介绍请参阅 datetime.distance_in_words

  • +
  • datetime_selectselect_month 辅助方法使用翻译后的月份名称来填充生成的 select 标签。更多介绍请参阅 date.month_namesdatetime_select 辅助方法还会从 date.order 中查找 order 选项(除非我们显式传递了 order 选项)。如果可能,所有日期选择辅助方法在翻译提示信息时,都会使用 datetime.prompts 作用域中的翻译。

  • +
  • number_to_currencynumber_with_precisionnumber_to_percentagenumber_with_delimiternumber_to_human_size 辅助方法使用 number 作用域中的数字格式设置。

  • +
+
4.7.2 Active Model 方法
+
    +
  • model_name.humanhuman_attribute_name 方法会使用 activerecord.models 作用域中可用的模型名和属性名的翻译。像错误消息的作用域中介绍的那样,这两个方法也支持继承的类名的翻译(例如,用于 STI)。

  • +
  • ActiveModel::Errors#generate_message 方法(在 Active Model 验证时使用,也可以手动使用)会使用上面介绍的 model_name.humanhuman_attribute_name 方法。像错误消息的作用域中介绍的那样,这个方法也会翻译错误消息,并支持继承的类名的翻译。

  • +
  • ActiveModel::Errors#full_messages 方法使用分隔符把属性名添加到错误消息的开头,然后在 errors.format 中查找(默认格式为 "%{attribute} %{message}")。

  • +
+
4.7.3 Active Support 方法
+
    +
  • +Array#to_sentence 方法使用 support.array 作用域中的格式设置。
  • +
+

5 如何储存自定义翻译

Active Support 自带的简单后端,允许我们用纯 Ruby 或 YAML 格式储存翻译。[2]

通过 Ruby 散列储存翻译的示例如下:

+
+{
+  pt: {
+    foo: {
+      bar: "baz"
+    }
+  }
+}
+
+
+
+

对应的 YAML 文件如下:

+
+pt:
+  foo:
+    bar: baz
+
+
+
+

正如我们看到的,在这两种情况下,顶层的键是区域设置。:foo 是命名空间的键,:bar 是翻译 "baz" 的键。

下面是来自 Active Support 自带的 YAML 格式的翻译文件 en.yml 的“真实”示例:

+
+en:
+  date:
+    formats:
+      default: "%Y-%m-%d"
+      short: "%b %d"
+      long: "%B %d, %Y"
+
+
+
+

因此,下列查找效果相同,都会返回短日期格式 "%b %d"

+
+I18n.t 'date.formats.short'
+I18n.t 'formats.short', scope: :date
+I18n.t :short, scope: 'date.formats'
+I18n.t :short, scope: [:date, :formats]
+
+
+
+

一般来说,我们推荐使用 YAML 作为储存翻译的格式。然而,在有些情况下,我们可能需要把 Ruby lambda 作为储存的区域设置信息的一部分,例如特殊的日期格式。

6 自定义 I18n 设置

6.1 使用不同的后端

由于某些原因,Active Support 自带的简单后端只为 Ruby on Rails 做了“完成任务所需的最少量工作”[3],这意味着只有对英语以及和英语高度类似的语言,简单后端才能保证正常工作。此外,简单后端只能读取翻译,而不能动态地把翻译储存为任何格式。

这并不意味着我们会被这些限制所困扰。Ruby I18n gem 让我们能够轻易地把简单后端替换为其他更适合实际需求的后端。例如,我们可以把简单后端替换为 Globalize 的 Static 后端:

+
+I18n.backend = Globalize::Backend::Static.new
+
+
+
+

我们还可以使用 Chain 后端,把多个后端链接在一起。当我们想要通过简单后端使用标准翻译,同时把自定义翻译储存在数据库或其他后端中时,链接多个后端的方式非常有用。例如,我们可以使用 Active Record 后端,并在需要时退回到默认的简单后端:

+
+I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
+
+
+
+

6.2 使用不同的异常处理程序

I18n API 定义了下列异常,这些异常会在相应的意外情况发生时由后端抛出:

+
+MissingTranslationData       # 找不到键对应的翻译
+InvalidLocale                # I18n.locale 的区域设置无效(例如 nil)
+InvalidPluralizationData     # 传递了 count 参数,但翻译数据无法转换为复数形式
+MissingInterpolationArgument # 翻译所需的插值参数未传递
+ReservedInterpolationKey     # 翻译包含的插值变量名使用了保留关键字(例如,scope 或 default)
+UnknownFileType              # 后端不知道应该如何处理添加到 I18n.load_path 中的文件类型
+
+
+
+

当后端抛出上述异常时,I18n API 会捕获这些异常,把它们传递给 default_exception_handler 方法。这个方法会再次抛出除了 MissingTranslationData 之外的异常。当捕捉到 MissingTranslationData 异常时,这个方法会返回异常的错误消息字符串,其中包含了所缺少的键/作用域。

这样做的原因是,在开发期间,我们通常希望在缺少翻译时仍然渲染视图。

不过,在其他上下文中,我们可能想要改变此行为。例如,默认的异常处理程序不允许在自动化测试期间轻易捕获缺少的翻译;要改变这一行为,可以使用不同的异常处理程序。所使用的异常处理程序必需是 I18n 模块中的方法,或具有 #call 方法的类。

+
+module I18n
+  class JustRaiseExceptionHandler < ExceptionHandler
+    def call(exception, locale, key, options)
+      if exception.is_a?(MissingTranslationData)
+        raise exception.to_exception
+      else
+        super
+      end
+    end
+  end
+end
+
+I18n.exception_handler = I18n::JustRaiseExceptionHandler.new
+
+
+
+

这个例子中使用的异常处理程序只会重新抛出 MissingTranslationData 异常,并把其他异常传递给默认的异常处理程序。

不过,如果我们使用了 I18n::Backend::Pluralization 异常处理程序,则还会抛出 I18n::MissingTranslationData: translation missing: en.i18n.plural.rule 异常,而这个异常通常应该被忽略,以便退回到默认的英语区域设置的复数转换规则。为了避免这种情况,我们可以对翻译键进行附加检查:

+
+if exception.is_a?(MissingTranslationData) && key.to_s != 'i18n.plural.rule'
+  raise exception.to_exception
+else
+  super
+end
+
+
+
+

默认行为不太适用的另一个例子,是 Rails 的 TranslationHelper 提供的 #t 辅助方法(和 #translate 辅助方法)。当上下文中出现了 MissingTranslationData 异常时,这个辅助方法会把错误消息放到 <span class="translation_missing"> 元素中。

不管是什么异常处理程序,这个辅助方法都能够通过设置 :raise 选项,强制 I18n#translate 方法抛出异常:

+
+I18n.t :foo, raise: true # 总是重新抛出来自后端的异常
+
+
+
+

7 结论

现在,我们已经对 Ruby on Rails 的 I18n 支持有了较为全面的了解,可以开始着手翻译自己的项目了。

如果想参加讨论或寻找问题的解答,可以注册 rails-i18n 邮件列表

8 为 Rails I18n 作贡献

I18n 是在 Ruby on Rails 2.2 中引入的,并且仍在不断发展。该项目继承了 Ruby on Rails 开发的优良传统,各种解决方案首先应用于 gem 和真实应用,然后再把其中最好和最广泛使用的部分纳入 Rails 核心。

因此,Rails 鼓励每个人在 gem 或其他库中试验新想法和新特性,并将它们贡献给社区。(别忘了在邮件列表上宣布我们的工作!)

如果在 Ruby on Rails 的示例翻译数据库中没找到想要的区域设置(语言),可以派生仓库,添加翻译数据,然后发送拉取请求

9 资源

+ +

10 作者

+ +

[1] 维基百科的定义是:“国际化是指在设计软件时,将软件与特定语言及地区脱钩的过程。当软件被移植到不同的语言及地区时,软件本身不用做内部工程上的改变或修正。本地化则是指在移植软件时,加上与特定区域设置有关的信息和翻译文件的过程。”

[2] 其他后端可能允许或要求使用其他格式,例如,GetText 后端允许读取 GetText 文件。

[3] 其中一个原因是,我们不想为不需要 I18n 支持的应用增加不必要的负载,因此对于英语,I18n 库应该尽可能保持简单。另一个原因是,为所有现存语言的 I18n 相关问题提供一揽子解决方案是不可能的。因此,一个允许被完全替换的解决方案更加合适。这样对特定功能和扩展进行试验就会更容易。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/images/akshaysurve.jpg b/images/akshaysurve.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cfc33339583ac5043a1be147f8dc00dfca2a28bd GIT binary patch literal 3444 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 b%-ROq3f3X*4F;+>Mu$bIZ}T#9g) JxPTUeH2|hU4O{>K literal 0 HcmV?d00001 diff --git a/images/chapters_icon.gif b/images/chapters_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..a61c28c02d30261b24faf98ce076c36d1862e65b GIT binary patch literal 620 zcmV-y0+anmNk%v~VIlw^0QElrHgTby7#{NS^2f}p`0K3WkmymANQfgl&6{ z=CiQ<`RDra#{Bl!%F@9eO>g$)mLyhtye=op*3&p$crRv>85L{`~SN zQ*hbj?L&H};+K)Agp%8RcHi2k=jZ56PIcqL#X)6%+1c3o@$vQc_SKJ%b&jAKM`r*3 z|Bs}wEC2ui03rY&000L6K%a0(EE01lm~qK$a!4eUOxdi`3@)NA5P)*3)kq6KUSuNN z?iajd++uHz1OwYm*CQwU{Qdj%_8jG#K(L@e zf&lL^8F;Ya3=bd_F1bcQgT;#&EqZ_`ama-RIw)owsbOP89StrN`KUtxjRMSiP*6d$ zrcIh3K7d%jpa24q0V#c4X!#OHg%qC&7f7D#Y_!za)N0uU51Dq%xX3Sh&E z1>2!RR0UIeB0!mSYXu2EHkb%8wl0OTXDc{hKx6I4whSD+RiMB^g1I3QD^ARUMTH-F z`L1msge8Kaf+a{G{3FGU7K?S@*lQJ~%9S8nUM^68fos=r4M|rL!o3u@=!&!5y z9%qONo)>VAEPkA3pRTusk(sEs!H}M&zR%lPfFG~F%A&Em zz|!8t*5b(8=g;Ert-Z*)%-7TB^ogTCk+4HvfGw!ORb`qNjiiW^xj$ioG-`chfw3%n zh>vB7Ayt49puSCZlvi@1BC*8De5Wmcuq&p)Q*4YVhpRYVh8cN=hpxn1p}L>U;po-r z_R8JqEC2ui02BZa000J^K%a0(B=#DUqOy2IjFL-bbGLg&jSU2qDuG;mN0MnP;T0hz zFL;47z-)=~ITLt5dJ7sM<-VDT5Oe?l4+}CZ40|qrL@_6Wg8>Q$H4KYOcoC3;lR1o1 z3!0k_pO~SLq+dgs0I5*}A|F2;7&9s_C#~Dot|g_ literal 0 HcmV?d00001 diff --git a/images/credits_pic_blank.gif b/images/credits_pic_blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..a6b335d0c98d6049ab22cbdc0bf253fbb76c08bf GIT binary patch literal 597 zcmV-b0;>H-Nk%v~VOs!O0Q4UKHgTbZtjo^i@;r8=M0}~k-0jlm^;wIwR*AA?l)AOi z<$R{bmbuhyn!a_R!*QO$OM$Gc%HWBx&YHc~zu4-z)aSj|>5#S2$l&j3m%Lw)x3JCP zpTOBshOpJ?_N2w!EC2ui09ycC06+!*peK%GX`X1Ru59bRa4gUCXdFPU?|h#awO}yO zD;jwfq0)spI**X0)b)5i3DYdq%42B1B8&vWEjtN~i2&>|ILz?4e8+Ju=J@=4&F=gE zfPsR8Uj`oz9X%R#glr6YItYzI0gyTvlQaSg1eO^sa6jP7RE2Ic>}i2CmFH@)FyAS)7c`)mXh9WyAR_e zAC{o!BOH1g>?fmU6Y(e;bKUF|3j?tO3nCDEv?~q)fnWq&AXBiR4hSD+RB}l1NG}!! za#h@DB)|%W97Fa%Xs@KnlPFW#s$9vkrOTIJ1Sn9D1f~rM8jUnqr;G7v8CjOR|z zf|3SDxhq8@$c1dPQq z;H1_(X-#678)xZBTyYLSE$Oxl$&}E_XizBtBpe4PEg*oj0F$>5QVR~qaDnPC4nIW_ zsNBdvVUb22U}K{|f(F!hf^wxHfiG-JkY!Z4-EhF_7U_6bRM6tC@QPSb1V3I;T#DDs jHxhr2pt|+z*t2Wj&b_<$?+D=898bQy`Sa+{hX4RORs9~k literal 0 HcmV?d00001 diff --git a/images/csrf.png b/images/csrf.png new file mode 100644 index 0000000000000000000000000000000000000000..a8123d47c3e98fb1fade3a53f02fde4612907a6c GIT binary patch literal 32179 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 literal 0 HcmV?d00001 diff --git a/images/edge_badge.png b/images/edge_badge.png new file mode 100644 index 0000000000000000000000000000000000000000..a3c1843d1d1cfdf3b6cdb6eb40ed133914b64e75 GIT binary patch literal 5695 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 literal 0 HcmV?d00001 diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..87192a8a07a7b4e40f1d6c987104aa118d66fee3 GIT binary patch literal 16958 zcmeHNS%@4}6n&kEnb9mGF0tc`=@wiPg1G!>G}2?-qM}iM6a<;X6*Za<#U<#piX!C0 z1=J{t1B&D$1ocA{g0x^<;Hu<9h@fT&q6txKiA$@UF3-JHZ|Y5TRad3EHj;kL>HGG3 z&#kIgZz-h;_>GMz{Fl{|l}asCN-Y79rK$kuOF-GWwKnXG{(s*CeGl|K;O7ClLn*RS z#D{)XWS2)6LR01cdOKGdf(_>b_XEeYmnWG+1?b!dq;(HG;j*FC(EA1Ouc5!}mZue? zEr$N2{eb692YSdyZ&{b7C+T({JCgFl6)rDY@1r*h{v{tflH$L@;D4K;_YcIM0WcP1 z5$IdPmZZ3Izh}DaXdG$H`#3j0ix_Q8iGSH;M~G9#ytOs*{z>w>>%LQdziED9l4jvr z{G7r)aCDd@*_G3ahdKY{hc|z|^XR*TeUPL3pH2eTdw^}gwf1vI6AAM_HoNCruJ3&C zdkpx}!*i>{e-!ymPnjOORS{ZvP;E*zv(T0d?Zwe@-xenhU)b2A9WGLOTQa zVb_oYT^3Lt2mecL9p*pHgFaph{Q`VqmLwCW4FUWx4seh)@izf=diBA$sE|Ke03B7} zH$&HtZh2BM!ZYZ*-aml+6K$<@b3mP5`9JEi^4)uBLGK*5PEs-2Zt!E??*Ukw@;s0O z%?5S@z4G<8pOo&W|Jugkzo7H@>Egs9bSL!e0iFaF`>Ub5QRcP3*EIHf%piMSy3ZZZ zx6~|6E-rg+M|AF=??d`NW*_WFf6hI|+GP&H_usR?U}t->D5aZVm%cu6$z?N{&{;Fn zc}mH;@T-`8aBH3zhTB3H#LWNgaGiOpL9fN=gMH}B7z6Ug)z2Qnx<%$^ag70Eep>RK zM>ocJ4{XXe*C6ZY&6s@fJNm)AKP&{zO~TqGRW5V(shE6lS7$2;Yeix|ozb~o+NE?J zY~uBDuVcXv=p$gRFKZN@pR$hk(`M+ek49jNvtLhZ9NT*J0p{4=z&hH_V^(-;rJJVf zVAHR_$AELq=y}9@<M*D`cC-bVuo|kQFX#n}SH+%NM7R?@g zoeJ>$!1U|&Zh4w98GnM#1+jkQ;CsDH+oQ(U+5JhM=b~R;CvjV6U(zj2Cl2j1s4s9jJ#?|m#c z`pkH*oGoE{i0v|MZXmq@@a!MRv+#kZuGub1oZt6YZ{;b_Rj^5)3DgijE!a946JP1k z2kh@v!8&vaKO3@dSJXMlN!bs*1^NonbP(otGrntza_!AJyeD*TXI=CX>TnxAx2|-q zn?)({IL>oClh?tD2?>RT3WypIA z&|}kQ*>Q}bnXZJbyMS)^a~mFio&ttuYNPqcTMI-OFJ`t(KSf8v&c}g2fo}c4&(rGk zZSO^+teG!zdysK^6L|0(s#`zcey1_F&%DOuERoNam?xhrW8Bh#_cmnTU(a>B@kI@N zTmnRVFKOLrNvgs&lNVp}jR5A%I>`Nj`9JOO)HU0M#reFJ-?SHdNRgitMn#bl{NH6T(A~`Qyg+3ktCV}n1ULeQ^7+bOqbUEz%8sN3f(u21~=1^s{ z)fj2-L%tz79d#(QA3EH^n8-M~ z8~3n@hr?R+%ljVad!X-uz6bgqU=LU!0h=qTggPu2Bf_!>*$R-DY^vgfWwBfY!Lnq^ zs*~2TW~UotwybGcM*0oQnu27#EQ>60+E*O5tUBZBFS z!jM5uPs^&4uBm|ooDbPxIi(79md~le)CA;^QZ>jXOC%e!m0AN?pQY5&MuRy}0^_+$Uqay7FR%=`haCWn(6z4bR*sf>{!X%{YgAG-H bYz$j9maS52Sgu>8Wizw1Y&vOFiW>e0=iGN5 literal 0 HcmV?d00001 diff --git a/images/feature_tile.gif b/images/feature_tile.gif new file mode 100644 index 0000000000000000000000000000000000000000..5268ef837389471f3e356c44a306f326e66f2b65 GIT binary patch literal 35 ncmZ?wbh9u|WMp7s_`tw$_2susSKsO|00BsZfr-h5i@_QIwnhkk literal 0 HcmV?d00001 diff --git a/images/footer_tile.gif b/images/footer_tile.gif new file mode 100644 index 0000000000000000000000000000000000000000..3fe21a8275022abfc50b4f8b721b97ffc76536d0 GIT binary patch literal 36 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 Iol`;+063`v?f?J) literal 0 HcmV?d00001 diff --git a/images/getting_started/challenge.png b/images/getting_started/challenge.png new file mode 100644 index 0000000000000000000000000000000000000000..5b88a842b282ce7be73462cf3841955e06da85aa GIT binary patch literal 21690 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 literal 0 HcmV?d00001 diff --git a/images/getting_started/confirm_dialog.png b/images/getting_started/confirm_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..9755f581a6aff256e6d8099f9e51f280b99917b0 GIT binary patch literal 18809 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 MN=dR*+~CXq0&rbfjsO4v literal 0 HcmV?d00001 diff --git a/images/getting_started/form_with_errors.png b/images/getting_started/form_with_errors.png new file mode 100644 index 0000000000000000000000000000000000000000..98bff37d4a30e8038e644582a52305656a9573ef GIT binary patch literal 12447 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 M#N#x5a%E?Nq|MeF} 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 cy~D0L=_>J4T1f?3_x_TTQkEEn}M! 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 literal 0 HcmV?d00001 diff --git a/images/getting_started/rails_welcome.png b/images/getting_started/rails_welcome.png new file mode 100644 index 0000000000000000000000000000000000000000..baccb113225d2718d934d939874bf94c545125b9 GIT binary patch literal 1053549 zcmeFZby!sI7B-A@3Ic+ZG)Ru1fHVk5cel#WrF6rfsDN}yH;D95(jbyUNOyO`&@u3C zP=Du~_k7p)|My+TO9$qez4udV-RoZWdd5H%C22fta%?0dBs^IeNi`%SRDa-~7A88- zA}v6siG+lWWho({A}b+5qvBw1W@%%Jgd`K_9qX#0F-p?bS3gK$`*Q8^;mjn`fM=AE zl<9+)Yd=(4Ls9R4dPGN;hDrF%zhA{fT(Xn^mAE90i~;izmk!c>=NU8wg&CN~MNxgP zy|-g8-$lxqi3pO+PIp$8n+}rS`=1)2VNo2ykDk2`T|~xg62rtq7K)0A1TQWx-wi)^ zM3{4g($z-P*VxojJ5y^DWx0iFor}x_DMFbkp}h9T>RQb{9+n;}W(dcC{)Ab)i$JX!W7n*$wsiTG0)sb0aW9+>Me%Y85s z6O@@ybtB|Z&-9=)X22$DqKhjXEeZmh4aFPU)0XaDP z?Z9YxOg_c~G1N=32cJ;L(vUPDB)>4)nkaQpFy^p@Ak>)XiAXr{e0SnmQEV_g#W*`K zJ~pYUptCkxs^ItfAEZ$kplUbcy}`iszqj|`O*63@)=D#-&IcMy3{@IdhP$25<-*ak z@VRK@JMK7q^h$gA2=}!_pbB|8)dbG6gp>-I1{#l;==0=XnrkFaQH9?#rRlEW9o~D< z4AyxN`yu8P)t5VyO?D;Jb@$9#I^U2ap-{h2okBMb*lnVJOzMLLN<#{IpOL<# zqW1{B>+W(OwzyRKv#-ftg*33fkq>{~cz%?=lm7iH{}9Gg5=E)Oemx7v@+TA2J=YlC1XxKFWX5krL5?U`&`_JqJhqvu-&EIIhY5C4F zBDTn&RpPAObBt}K%E3MPL9l{(;n51|H zcEA6c^k>E$+E~KGz|p|PpH&QmvMFFWI8$r5OO%}KstlhjQ5HU!7Ai0vN-3vAPt7nI zQQL{%Y0p9&#NC=e_*^!dGV7^Ik!p(C%z^4z`I*5f-Kood%t6II-a-8W^B&v&Wi>lmNWzb8^7aUcjH z=(;Ds;iPC08I-}Qvi+5P!^jHnNWfX{0b2px79Ay9639!-P0Y})41MwrH;`I-`h!q<;D$ot{*t4IrKVMI%qne zIKben@GJN@oCB^*{0SR3;8DQqfQJF@Qo2(3t=mD0L1EFDa=6(R*(P${a`IiQU68Je z=*bv!jh`9@8c>Y{jW$h|Z(83vzYTvo87{HHt$0>JWc6;Nq$a|n+@t#35KpH?hyKOl z`?heV7lRs4RLk@n6@m*)Gh>Q|vv|@K2VF*cN9;y@vNOLDWjN~ODz63?McCEZh3uFJ z(+X?X+thQ`^PO*;vm+c37wE(&((eq>snCn@cyQ_Ql*vUNXOO!;*nYCXb#7zxx|_?6 zH-$&_Db|y`$7Cj$PwF0^eNN1Ipsqh?m_w>4`h_epJ0Y3xqQw9v)LYl@WtQAk)8Wjs z$;7e5@r6W_#6Z5r^vg1fd{Io&{lRY&8}SwX&hMQIkIF+56bpLD616L9Dk&$mCK&~v z)Ka-jA3ySBz7V>&gF%bo`;q%&ZYVs|rk$zXotZw@R%yETfjQr5ORov%04IAKdYrp9 z(I{0>y&ag(xQe^Vd}m{a@`MwAtYvudQ~Rk$_EF&Gq%b5mc=cW%vk|LNr;(_qNqv1C ztUmQ(?abz6{UH0??%4Lw@UZNN?a*_pcq4UXmZ*uEfczIh39$vW4si$G0M^7kCuSYG zXH4JeQAr62)F_}O&97Se@zm2_q*teBQfTs;+0|9ZzE;1?kxxA1d%|ao+43Ik1J4KV z*B;#Y@i_CG^Y`Zu*ab(pMqrqmpB6ri%LI31bgVxL{+jWXtP<@4)020CwT8iivyC%{ zeZ{%J(Z+O3Ey>)#kP;;FxPkFbDnab8_(#zX;>K#F%;Z;M(-}gtrWov?y72xb_fU#l zUNpJ!F9Q**pD*2ybMtb%<9H+N;*C6xZ_L;eB&T1Tcv z$MYhVI8a=aU}c||@v_h1)fWT`2JT%-(LF{G-L6Z6osaBQF0xkh_U=&w2$ACYcwY+jJc(`gUX`C zSYOvKAo~&$g_5>D+p9G{1?=jTz3txtq##qnE((LUcSvMX0A#BKE_S0*zjtErl)B$A7gg$-8>3q`H3 z4O~@sUY{{W$Ops)#yN5x6oCzO*OWF=YP%W)#>=W#_bbw@Pdw{AF^Xyp8{J#>+bTp7 z8`$_b?2PJ6UGfij7hNu>76ok)FA#-|4-f+aFNJ=&j4s)=r>(yn{Z*3=Ytd@a-W{K< zeLK5+l^k(IFOhkbiQo3T{X0J0!)~F^zNhD^=b6jxwe4Js?#ies(LymEdWigqVh#h7 zoouX&z$^2HzK63-hH=qcGUN!*V@H{)3+Y{ zi$pu>>*f`GhQ?D3pAQJ#>KK?lR+FQt$h4@cBGu)g_z`{ve-vlH*)KFLDt1Rdf3mUf zHhbEJuuqcKhneP^;)*5nAYIkoc_Yo;C7TsPz(l_(CwW+gUIJ-0MpUR};2w@PgmjB% zbb3DAEqsdfofApK(XDQoNN8r296a_B$%*-T)8^Oc6{!*I9b15u8k}YS{suJ>(zW6B zowlgPWZS|lfF&Yfy^+y%L_#8Ay!m%WR*hi~3F%I%rG}1^j-rBqiM=i7E3o}*Q%*PA zH^9|MNJ4G`z^}HZPOoU(Y;Eiu1>A(`Zm$pke!po3(b3#q;$$sMr=zGsBVq4gO2fnX zl=Cs22sRB3jgSM_Oh8TY#h=@OcfxcQPEKzGKpe$ZoX5H~jm za0Q2>yPeZ3Hx4^T`ri-v`y5GAM-vCjH%^xJb~HE7ef8Sj*-4m=?xv%E{`?-Nshj1$ zda`r;Gc90(pqo!XT%3_@5$HpNi;L%}(CrQX_0hk& z{I^?m|NU03$NzrozkT%QRw2;M6#i{Wzt`)w6<9D4Y$4D;i!XwGi5#yD><6W#q_PI^ z6ZvLyfFEqY%cI{vf!|TAx;3u^ej*`>A<0ULYq;Inn#S>>)EqzEXI8YgTu)ZpiLO+! z(@$$MR%zlOz2^;y&VR15N7#gee$;vr0%{;9#xu$+M&Bny^%oeg7jZ(RWn%ewrL5rflSI3kxbgV$>GA!z7g8A8&1<06eQsRe6cV9m6PN!N~=jZ}s$$El=o=v)OUQEb`2AmqOWg^gP`#Ywg5WAH-p3r*{VVzlbT zHghY{@N6K_QpfCN*k|EW8g2NKa?7YKFY`hLAxnsiY6RN_jp|?UY3c)}d1-JFP4#=4 zLPTr&#|3q7=U;9> zs{z|&5GyCMnwa&5mts78WD+W5Ah*&R5qWlyz4ZNzjs@M0cjm&c&by`OgQ?!>mA;yg zDRf?dES1I}C zAgdz!gh3R$zAC)=NW(is@&VLH(c3U9Hy2C<~@J2H5lGg>Cb z36b5!-rn+(Cn+!xfrc{w%f#2Q2r%XPLR@KYBTl$8L{mGuGgeeIrewDCBNZ!iIU<$Z zvdp-W2}_ko?@a->Vom8QM3y=8? z(B9|x9MUT>$?N?cxL+}_G-oyEEJ8Ql?Kg_bJ9E;$XINoo;B9*9P{M_=RU0iwedn;P zoihefU6U!v?T1Xt zQ)h}ZKF$WUbNv(wU9C^bK|{$cOer2g-QIin+{bge0XmXh@BgCmcTT`&oL{^A4&HvA z$kwb4w8D*f>W)a;Z|#}g;~XMB3ty_lyYAY97ci81YNsM-|86!-DlnmC$L(;w-z|}t zHr_Qi9-F*{6%c7NAJ&>_-WyK8dxds@d6rqj@^|#l0J_j|M>6uy*sYNzB;e<|q#eg` z#+?(K^(C48gSlN1jTiUt(1J8b+$Db-I3x+10JDolRPZ-GG&MBEw#Uk>=5|S`H`6?9 zLpCwn0Z9vA`6(ED|K)}f`;R}0kOF{sfG)Ow@20;x+7hdMW-v_M_vD3{W3s$r7U0wl zTeGR*3+sc9$rQ(7e^+KH1__c@_w6qCyW1AAf~K89{cObPAlO3Pehb@37l$~o`}?_E z{K2HLu04$8pKbmRn&fwaS}A<3tm{70nz22zUEjT`8Y&&55S|$;#1PddL?7lLrS;oY z#E>9Un7|A}1U;p0XWXPQhe$B)ti9gn7__Y`hkpGkQ@-$;jK{2iSn&ZUGgl#&>&bCk zKL*tU&bGOW-A+564NHqn-u~y4rYA+>_q;h76b)CGf0@8D%1p0}A38tciTnpE>R5m+ zNIZH`bh{|nIxmkZQln<1AD-A?1-~GLeL=Y!j_AD%r*wmbaPMbDakIgS3dC4RQ)8-)%goRTFZ|**x2|H)6HU_hn6A2EkIcQSw>?GzcsQbj>@sd_8|0 zc|lSBvA9_v8ZPUHgj3(P7-L(!dk62D^24-ZI^~#|DKukzF< zi4w7t$$j>YTBZ^UcDq2p4nh0@Sl4)?DF?aTE(g{U^Dql5yTpuA6I*kMM*1-}>EuVA z&uJ%jJC{FX<|;=?G+xYdADlzq+iZE&%DdQaM`1B@$mp1xH=i5NaO`^354;%+*qn`B z=#0W0l_J^ka7}iKH3Ur>d&x=;2MkM0>nP+HzRl~dKe5YK)cwaSiQfZe>HqZwHsr=E z!|{>Nr|V~~rbtakYfhHFe%y&!$Wv!8t2ij+8Sq(Hw|Wic;de+8ZF}hRrQ7o>=d0e- z<|E;Oi@i+fdKexQk*y7Gd?G^AE^+|Y%hq*m$Irev-uQVEO3s*Ts}IUxO0K+EJMSul zuH&D;Qj%-gXSqGvocJ5I`P*Oc>h6T&{bRb6048_c6RN#6-AC+qyorD5kIrT>x%;pi zlth}W!urERA9?ICjGN5GXfGe(r_d*aM6h)ZbhN>_o}9#;Z4iEoY04~Kj-iA3JcP(DG^RY7ahQNi7Bjlf^)mZ}I*kIoh?dp^V2 zszcwFqo?0}-mSZ+4^g#-+Ie+2QE2@GRz~*$w;4{LpS^XPGukvu_{eG_L*hmV3PvWA z5~eW|@7dIxjL$_X;$uPGT;!WKCg4{o!YurD4N1RhG=9D=%B(7?73UQ`%zZzlEV9~S zMXb62e~;%_^6~<{Jm7wo3m)~{WuCrRi+=)c4)P83;d}b#+klTl_n`7uK?}4Wo9MBPbj8W; zMl+$PtSL`rl~gics#V{w^Kl;wB2tQ4kBj>NLZk2;OUJr<*6SC5&domM4q0lS0C}-?cEF7Th=r_^*TNK)usrC zN3;j~n3sBa0V|owy*qz#z-2w&7nN{&addE{SSfn_{6_0_|gwufHfN#8xBILq1^{(-{JH+%H6J@I$LV^TNwFUnD=?3>R9_UeLuI5U41TKkkGCR&_L3v%~L#ib$yM8W*ksnRF&Q?FOuLjEa z9;mrz9ujQ~G)&V|5|N@VefQ<0a_=Gf8#S8PZt^ZQ^(CU4T%$=HdDjaeYKj0II6BPt zKgof0TF+AMd+qk7c1>Jg8J!-DN#I8iO=AJ;OrLsIy@m9ipsEW^2NP;aAr577ZArdtM-fa_#Kmc zQD8L0u#c3C z6Dh)HUxeeYtC+#?c=PuMmELEtfqQi-hggM+)a{oQs!Yj<^wZY5->J}zN9}zF#ulbc zGk(jOIzW&(e9;%^d^X+13fnzBpOpsVZtz1sp^sWr>NG;wJ7z)oQnLY83PGiLfN6 zo*s5MAdc7CD=#(M9y;uGaHr7xBNGva0^9u~PhReJyTc_Qw%3<&HQgH~{N0eVB4vx~ zxM)hA_BWZsshn{$KoX(KxVZdfh1qnWlbPJE{rTVBMY^+#0~opwl^XJ`p$idMB>H^a z!rJb5m&9Q9s!O^zCX<3%&Y;v)c8Rc5BL7PM`1+7Xwkp`@Uc;rW#Uqc1#lEB3#QPys zn{G7>pZ*%-sV)#RQms>=^fv>3Mpv={=N^YIsfT7QyU}I7=(L>lWRIHOZ(}7By?zAS zrlY9y*w7{PD5QrE#5A5`X3LuUs4%6HMzgGPMn*1%Ih%@lWO!EMcZ@WO(xb2$#Ti=H znvT|5oAy<1=WQ!bEBQ=qwX}pXwo?`|O^T=k8A*a3xz%P$tuKgTGYVtpGhtHQnhpQq zV?syJNNcLu&EJZmx$L;#5#0qN1h|i;qm|m{t?K`khR=~ zY&*(1?l$}GTb*cBvf=Lc(%?4EVn*&} z%sgF;((bq?TC0BO_kOqq1WB{)yOy8fyoPS+R7?ahEFPiyb2BmA$`cS|LV)~<#mK7O zqAQf`m!oTP!C6|u~Wy%)gr`nkc)J> z?F$>=E-JJ`bf&)@E>LW8=^eOl?xoVPZT%pf?$|{raa^>HeL@>a^<7jcsMnfn0}IBq zhx}4@VWa-_xvRV5KJ)Of*LY)+GCnd@Re@|9rPIrSIuZ{Wi_O6v=*B=kqrNx|Rf3qx zz)BnTty570i5C1-wmSIMpSsZmU?OaZ*F#_2pL1rXDPK~$RS#zmNx>NjvPkznrCy5N z{l4y4*;V5S)4I{JbgL=Zbw3*I3w;5w&IH7#0qUqp{_oW6ynL6>?)Wb38XTl+OhZzO^Ao2oT3*o>SQ`2~l@)1LVIhsm9$FIvmR0mn#--lqO3p zUV`yYVVA#@zO!3TAP9-x2{fyscS^f8|?sc%nA5vE_nF9=?7C6Pg)2~ zRe&t@ZLpEQ2|XJ6OZRWy0ooKwaUE-M^22U-k#6qC-usN)Cy?2A+sOSIFC5f$v;h=x z53xt%i#O_3o&MQ2IKQkxsAR#I+h-=}J%YrF#$p*QPR1AJh_&3)hKwveu3|=g>%>O) z0GEzQpi8}d=T5r^-&%AKX#7m|K498jZvSw7UVhZYr7+^HbZ_NBWprg{yV$QonB1`K zvTtHJB~`Ep(>Vw1VEL_N5B{={)d4$#~W7V^PL(}vtfCe&}AGM_!b z9I$8cg->X5TP?hQ54Dnz7~oxe1E_FvI&t}E9t1M@=&hpITm)IOEL%PDML{5|5hEhZ zE^;2hTXwkT2gDwH4MN>pMW6#8vW(GlA5o-!cKHRqkF&HUz0sm;aM82d;VF6+0Em*5 z24}kt9emfqms5e4x#XDSzTN%Y+q0bIQ%5`7lcp`ZJBorY9fwjMKF0Of29#KL)2q(d zi?G?3-32J%YwIFF0}G7;2rses>y3zy3G80&8&#%h+l=FH`Vi3CVqb7fGV>sbG5f*8 zQ|})+0S_=I+^*ljk5?O`RYq($Xb7S?ERSzWn@K0_8kb6fBkNV6w)Ed~oc|Pf=<}h{nhSx}VSploQ!GS^k{A(J2W21afuEImz z*qta16!F1g9d^fEL`dQEdZx5M@wtXxlmNBUCWixn0P!W%)8Z#G%Us7L63eH)Pho2a zbDaj;G=!!*qWeIKg0g&y7usA7Z2Q5(20pmMlD#;({|0qrmFP)p1b2ckS;ed*|N8c5 z53j7XVX0i)UuN=k7LDf!3HcTi?}%dI+Rm^Sck9!5qCcO%#~sysrQ$Z!UOo_<1@QC_ z#4vNJc=#v$miGn*I#0jpC`~tr)O|GEoQcw2K_@)U!Dv{y6gim8ttG=8cv8PVgR!(t zVW-s5IE-9>cNI~}`KrtbS$tkqqsp6}wh)Xnb9!nzaMFFvq@P?e1z>=puT6NBh@-kc zq#s$Bz^UuQJd7e_qzw1>*igBFY&|-jdiRzI?WOtoR7d-aYh0QPy(jEf?lm{?&Q>_< zsHV^76RngKD8B0M*!1$|K5jx;{#j*=XKp`;f)CSAMLd75g%1eG4s#sw#u-8tX1T_!&O(KPl1s72qww@@57Wk~sWlB;@ zMel~KO}4pu?~{!0U0e`CZJdLT-t#f&hKGo$oVYfCHhuOM8TcO?3GELBI82o(GZ!!r zM2kf_HShO<0KFk4+{s&j?ZLh1Q1V^z-=Y!~V2V56BUx{#fLIE)&DnuEbR&p+aH^;9 zI$5FdFmjI)6wQi-9rS4IKyZbH1iVS)WQ}3i+ zF#Dp`H7A+}S-jK$X5OP3_w=}xv)pZ2j^Qud)I2q%j}_ zD>QBn`)eCNa8K@xDnRugvY_$SP+`UA#0wtoiW5^|brb=Z92>@UyS52V^s62c1gE{wpY*870HAl(_|~@|hAs1QHNo{qTtH`vu&lguhwpW+02V^e4Uv}c z=4{#B>W3+4N=rPMAa&&0N1?hrSOY;{)hk;x{`E-=P_OSi8-awqP4n|473b zv)F0y!Ok1YFY$U?0(>t}ZQbF;&<(itYuBY8`TNp6F({4arsKvv2iX|WZh!c&SO!3b zC5d8h-x7cI8%}y6WzyCWn7qxs;urr45{mDuQHj`;Qnmn!6YMy%p0LNo6h6Mi1!o(+ z9R(C3Y#%je?Y=91!-LyMXF62GsFN^sAg3J|qn_G7D!46P2+x z*l<7r{QWgh5OVmb>_el@`3%$&?I!q}9|i#X^mT6|n($U&XSnxZV><>Q;87t~4UyZR zaz+~-1XL~F^V*q5p2n@`|auj^>nVJj)~G*is|B6R2Hk{LII)iHZM+fZ?LiVWLfu_)_EIFPUWHY_Atg4$5pQovi2|xifgZ;>$H-AF*?QdP^{_K#VNO8&Gdn#Kth$OT zxNbF^Uo|?l|D%2O=xI%3qgvLwbn2&GWE}De#cJs)863&E^?o_!Bf<9|alJZfD3=VrwGx886d?ZW4wLcUg322;v5?bs-yQeyiNkWr^J)7) z;`Kq!VD{9v@3$U~?JT7jC|aAHnS)&vtz5^t7$ox0{cota$?@#0LtJf@eH>7oV6S>I z@$!d1(bB0e=Mz0fRDWDuT+*8Rm;Q+v^Am-A!!oqsT zRv3LFdXeL;}X*2aN5{tW#f=NX^&iTJ{ABwVTmyxpsq z7XI;;gla;xL-lBCM~Yw@B2Q*@Ba%oa!ri%9vciF+gbRb}Q9CCh__N@`o53j}Oz!1C z-S|SW@CJ3;H!48l{i*I`G1Z)r#%YejII?Bu)J4JF{Z<Gd)we3^u3Wj zOZr{JECs-Kl%;}(%vBMCLsadO*E$=;nw}u??6&5-#@dT2+3T|F2eNG&ou8ErI2|{3 zpc9{ueovJcu+udEA|veIQw?gm0LWP#z|ykdv2|mWG61S>l!^VydeRr}?pr7QV%J`X z-^r_$;MOSxm?3FP<6MSM_Tbpg9~-4|CMAm*2#5=t9dBc4;|(TQ_o&<5Vgf4UI8!+? zdACSWC*=gki<|DN#i2#~c_|Kf#k?qnWi^$a+bVkd8xV^V<*)?^oQ`6+S6v&SVa>6B zMw$kU6uCen=(ac(p3;OvWd5!8f%_KpvF1=lhN_jMin2$5(t+W461@c=LUf7GewSkM zJ!NM}5nwE&B*KLDy`br6xUc_P&7G6FA$RHj0an{%XJO@ZVZ<4yyq86qX0fFcet(~JW))rf^i zN$3^0o=6!=g*k9Qc^6&y6eHea{)~kb0`$S{eU zri=H_h7{bGPN5$5hnp3AsVz2HDq)o5@^!lBz@c{V`317Lz1No7y8Z-VR39L*Xx>R@ z1CNBHMyV1p|16MSmHGxr>kRIVHQcQS32HUO_wKxyQGaSzKza15o_pE<;6?1X`*WI( z&`8HgVxT02Giyv0HJ2DHN~@oG?%55sY5elGN0WQCsp5S3p?LU-qLA zO?(>)fL~Aj2_MwjwyHpAmu|dzCHXV_vDM|X_|Z3w3jFpFg-)2LDzD9b(02Sl?|Zm| zOH`7>yt~6;CjJN4n)+=!;yt!-^TV{XPV;o~2T3`r6xfz1Rgc zm*jwGX`HP16eBN&(y=^gZ$R{i=S-QmSdHCPjg1jJYiqnxn3fMmU;;d~HGlS=P;0_q zPLf7ucDM<~240qyH$53CB1zjsw;{5m+VabqH!59NMlKZJjCd>=TpWy{?w! zMeM&?zqsJ;|M1~Qb%N)tJ@|Y%_(@l~I)p};XwujsiciERersnoRy746P>(5b1r9#H z2TYbR{Cf?JF|s%y6Mh5*B)wU{DvFK!`DX-?zz9IYB<{aQU@+I3hY?)q7`M1?CfIx< z9}QidMD4g(EHaHB-qb>yrNNE(NlYKF_iAOUD$0Iz0s*%1YBeQ}57hAda88pcOcgi@ zbryopI7JpDro!|suaS=$SsXZXP`ncMEiN!OInv{f+n+QU4NyqF`mx1j-127~oH`Y5 zb=xdm`!xuM5{_+o3~XAzQf_~UrLt17GGY+mzM|fJm&FA&TUO&`Cg#xT3B8AR(K+08 zZn8o8Ng_=0^p375KvoQD3ynb$@vR4R4IVOKZx5|5n9}cbX74|ztMPKQc5^8vlk{1F z87Glok#nAc5KDLr`}cc*Z8aR_HFkc>7vY#F>V9E)UwJ|~)F*>h=v-DgPAt4Ayk2?) zMI6w#e*))!jxumeSB^%xsa1}@B?#Zn#!UqdI6qB(vNE znq@G-7ktLXPv%x_=#np+w=L4PB`VR@C)zc#k{)B<^(&`)haqS8t6L+2ft&BMPv`h? zoKb1Tb;pavyMmHHnObKldwDiFe-?o4;;Jc5X!F|oVAj&uSwtMYuWO;Zv`fRJFnppn zs-!sKvCviNb}Hy=b-GJC$OYltzqSxTV*obycx-2J5ZfUyeMNFVERw72E^v^Gnn7x@ zjX#np@D{jfRMr5Pz^?zm@(0&{d+qPfO0@mN2o&%95fc97i?_9uK)|R{HJ-NqIg#@3 zS74&{qyO8be+wq5H_Ta9N?qYL-u}l6(24Eun&-bihhXo2o&0aP{=-lJBl(|o{ogC{ zKR@{&to%26{?AYT=O_Pe75@vr|DR3rj{$; za|*TXjGl4yxE}BV18y?BDZ89U3jCH40$55+vZvG>3NE{|oSHYx&L#_232?c&Uf)N? z1WUYpH|5w;?SPox7q|AFH655bqTpZs^u1qDFcwz9nA?G{Gz$|`NqAF-cLxdFkdxtQRY>M8u&EW#8xfD$lm#!qI0sFyflZo&+v^hx<{qJ=Z8l zK>dW#DQBT-!Px;q1@FLPbO?}b!PMY^!6zvjmOdPRsgu(oVtbs$i9=!HqdV5X7yWJV zm&r(by0`rt88RBtjc^r2tYVX&v# zQx!TSQ-|Lxd`n(<#Lcj4m7Uw@T=^w=cJaKve;4jT^GF&&u&MVN2bJKB43I5JgfqMo z(?dqUO!t@6f4(?jC|r`VN%7;S#AGeBjB2+t`eK&iKDn|i8n>S7)k>Jr@Pt8I&|R8v zA~TzxLK5|SIi)pf*&`7HWS>eP)zxi`IzY5${5B37bvk+`k;+?Jh4q^#D3zsF1{p&i z@qB45)G=W!sJ2KGlJ>K|0xMqb)!{;oxm}z@FGA}%VLwit*Az@wlz}{a6*vs>4ajJ; z-DN57;6QM9WnM+p=uw4_G`R3je`{QQBZ53!IN-CnJ~D2CBLOkDGiF%zv5udwSql)q z|3-fU+|)DgLXbQzHF8Ffe2u}z=0X57kjkOM*;KA5r#Yt{15Q{;kVr^f2s0OQ;_wvPplwgR znqK}3qv^G!4z>vs1yFl9H6jYM0vKmQ4}bYMBU=L`d^VH5Y|~o0e9U` zdia(r;*7$Xhg|E2O{MlpmSbX|zL(Dt6*YM0ZIBSS*(L(YJ}fyr$+n@l{Bbnd=vUn5 zLa#Y={$uhe>%x;7^n88rdZGEYw<)5XwP|TuOoj7;c4Wr}kniteSpbzv8ei1s!g}(C z**PLJEQoyDZI^6ZZ$n!>XWb@l5Cl$MSeQQ=BXkPt7b&b9GD756f0M}vUaVOv8L4-f_w)*dc=~JqW135k;OI#o?dpy?)I9` zi!^Az);TXUJT>vK!ZMrpTocdm9m{fKZFN`ql?KhD>_fQuqR__2C46jtao`JD5AH3g zh=qU&-l(PdE)!Otj>&`L3nftorUp4zyUQ!yl2hbi6$VEtT2O^gth6t+Ij-bHaN2W` zsI>GHYdRK>J)n#&to~vV*2dF1@Tn=>MrWFqZPW>trV!0Fskgi(-*8Wt>}qq`xXmP} z83&b;nSUx zRBp|y3pL7D);uRsu3?^MqxhZPICL18#6TS{?MJ@4oCXcDgmrAkS=lz)JAa-+tD*;S zD@)_0&!@+2AkE1=a@p0j;=TN1@R~B@yojy)EjvGBL;LQ5)g&h}vF_%-M*E=EQDH(N z8Aa%$u2LXG=3hLWg9xmG{s8P>3EyEL&T)+~Ec z3qPBl&bkztFzEs}cuD;D`5nT#ZrP}4KvBLXZ;EaB7T)_ORMqaQN(9-2*oIY6Wa z$&q6HRnAVUnu!)OknOD;`dCl%5$wacsk3>U4b=l;)q_V5U52U8vA~P8!qmgTa+C-n`a&3Rc28+buX?FTH{i^TQlS< z94!AKP8M|w-QQ|*2(=DJ{VL>Hr_nZhj_`yk{De2qb$}&*Q>8uFhtx6sa*@U1uo}GeMReYWR_lj1%4-{h^MUfeIzSj7%SP zfPHZ%Jh6Qk6X>msa$ga8nM=*FR{Lq2&DN~1pdr6rP&)jR<~W@L|N2KsmtJFlN&vw@ z<%L%r8DtByz-Ni%$U4QDlv8D#eS220JzfDXPd20dr!pZ`G|7FNh4$y>pQ5r~7o)6r z&4F}%7UBjUE=su-;;bFWaA+JPNQD`Lo$lD805}euLC_$HovqMOs$PE^+`X0$%ceiH z<~OSgQS@#I9Cme{$MAO;#ou=y%sd6owF0(v?**ZFlkJ^F`EtS&^6<8uWrtD}qGuG& zG;|6=BN_C{^VtU%^v6> z??>dpXY?vxk#(_AbP4ZXjVo^AY~oF7H1ZIdbzdVAWf6&jcGP9KG`f6Y z-9%bAiueM=N5+T;o%@|12JrPY_mY7Qs4*HZ%rH1NI5}e4nTocWbNlVI;8FyI9D|FI z?1yW!is3wWH8|E=g84GWXflT@ zdoYJ*8dNpqVy2bfCb9Hv{ywrhM>tToO-8&=2g)tBAT%mWxTNS$JH=8eWXuNuz2a7T zMTYFoT4J&+tmd$FG*Zo0s4nimIUsOv^769J^qkB%a9rBm`{U)g)y_H5yM>M59{7RO z;4&Lb!6n0vd8+nlRg}x%L&c5UChbBaxMIAk>?HzKiuHH!Ng4n26S*qW4f7}F7}hVa z!^LSwFE4vU1`20j9ru|$O$REonWi{~|4#};_!sPXG-S*y27p>Ja`L{oW!p=!T!g;# zpiBeJd_lSC1UOYT?urkVhP?7c;lfG}_@m2KxXL32!4DraRA0a>oIj@bXUc;WIxWbG z8~3I&jYF;yYy{5Pbf#J5?S+NgxdX-@ny7vROZzsycfk#u5jbjJ>tD>y%93mgJ29E0 zWZM%Lt_Z+Ss1cK0=3Qu5Yiai}sP-G?m59w&+^Z&AYqIyYm4otB(` zKAzqn{d|5mVtzL~Qg-n`^wCY3yinfzkYweGQak{joVqRc>sP3cGwuX!i=x3%%n-y} ztuyOQD$D*@i3D%KW=wNEn_Lbx`=DA)^b{K+{AXktK&!Wat%0uo)WTc}YZBn`?W28r zaPnZ8GX$wO$g?O0ZFH78O3zR_wWhm!9w*$zCiXr^h)q6@BPJWK2Ywo~c7fZvWdt0` zf<94-9PHI$2qsBpgwSs#TWnDEbOd@D1hLdU&5xo$hNNPgYC|=~sb6UmF>^8-XE>-FAumcE9({i3IY_N$ ziQk$<6$ycG%$M`oPcqfln=BW=M3@|zb)|TZlNq8%pLV+1Us<3xzm8$PZ-9mO?PbZi z;NxGpT|zV{lSf{*+U{zmB708N@FWvl<&BT$qq3U=xyyOX6w86N)U$k5x@j6#4M%t^ zjhBbz1y0Z_XExLIL1kD}Pgv*l31~9^%PBJfdrUBAomj8%t{1;;vq9;SyaHXVJUl%) zpWcb-sAxx>c~h&rYfwHla-}^b{34FbI}A0e;1av~&3^mx<=pf5_}-6g+X!a?JLDv923T=s&vJ%|MRM+TzC6WXcJAI(Zy$wxH|ah^+xTAdINKy(6Owj?2fYlq zj$uxY`!Y_#Mj-4#< zhVSdqymKL9&mSV6tjUO~aC z8(T#X+@Y|bTmuIkr4mL`U|H62vbWJZqg0qVNk@;x5>U>xY{08F<7X*2doup?k>gi= z>jIW4AKwzaO{*`ju_Ydv?Yiz}`Q*4i7P9-8{SLeS%6>X_-?oP@o7 z#^J@3&pK|G@&8jzON?w^C7!Ft)E!A zpJd}4Kk!XH$+TikHl9=Xtm^>r`lXgd@;jF<;sNq5`rW`wj$z7Rp7%B7=ij=K#r93r z9V5ODLKyG`sjT&VT#&_Wc{k}6$d9z0ccPq$JoUaQ3PRSMHXp9w< zQvoMv$b1a73M-BnY?D$!$quq;pdR)K`jP z^(G;OZ*Dr3m0|@-u>!?if(O^) zr8oq4cZxe-c%J9H-#KT!-yiU;b=JCnAPINwJ+o)7xn}m>lSz-T4Iu0blH>w70WxeP zVf*X2=@rA$wZ`!d<*hR%aM!+sNAyFI?qu&xub+|KfE zekVuM47B+vX!9&HAp)o2jWf)V!r$QZDF=37LFQq=pgvUXDot0L1k@dE8&E+-zhZppx~roz&K z#Mj2sf;_Gt<-gFpX$d|L80AB;i>cJzZfMhrQ{qgR=f=Oiz*yRX#O&{U`5;y~d^-`= zi*|a$5^;eUMDSG$C6#R*TQ=!x`A~p8i;BL?;>h&_ttF8DP!9<1Mx;R zNkhyWJ^gZxe-*!cbF1891OX>>D>S$UWu)(g$}oR!gQq#l@LCBQJ--y(m>Ws=jmGdw zmBa{I2bZVLcVQU*coPj18&duL8yGhBJ%3VPTe?Z3q@l*3Dv6CJ%}d6gtzX6aR7Abug~$EtJ}2V3DlG?}^`x->JsX+fB-z7TlQF znpa$Or(s~ZS(;GOJ6jEHG_ZRfvw#VZ)#-A~ukm_`VB-4_U0mEXDqxWS1smv=H@@q; zOLD#cR9pl5Xs%jr{WVLf+T%6ZL<;M#w?ttPT2AX0t+l6)D-(CB7rQMgB@TsLSCW#H zMY`qC8V?)M7GE$UZ(+!d7c?4%Y>;z)c7ap)i*K-R<|CeGncPRZ zCeV!P+tY1fe-n2UXnOQ}2=@!7oSCJGn3AFAL0-^Vy1*aB^r^nc=WOF3lVslIB$(4e z@cma`w_zRtP6d3cx%sOuFTe@7{R0X|CLihj&CEjlbO(EhvRA`5U$pyNMtx41qp+eo z*BL=RkheDN8|L4tvy(yw(&;*(JzfBv5ZGHDgH57hV?0DP$y*B;zQA69g->#T=i#_X zYWV?Iu?&4%Bi7>$*xJPyQph{WkY5HbMoRPEw)KDu540q~WF|oj=3YW_Zk$%G7-WKr+EztIZ{AKm3_#rt5RT&!@Rz<` z9vBW+rPWfHTp~akvj$g%i`CvJe6U>COCF@8!}BCJT6Lx>>`n}^N~lG`lFJ*0@5KLZ z=Wff_aaBw3DC7~Cc}Ty8Yar>?8Liz!w=mdqik|Ogcxf(9m%sY7RgxZFT~u+@3ke_w zc%?)MjX|-<^ zu{%3Qp^dvKZ+wS^CSjDj|77I);`;h@M^mHB#pc9Pvt0~r$X?}Z67_?n#r<7crf89! z>Xa?okY!7UNZAVdbNs|upJE0OzG8vfPn?!u*Ys3m^LJ{~N+qdl(H6|Prb0>G$G7+~ zf}&tIsdoOV^0VlW7W?-}-@`X2=505-D6F@!rOwvHiB_%fi1zpGLZYKV+c4Nt-Q2?zDleZCezY^vwfH*_LO& zrZ@Zb9rNR?S#E$))Mk=q{scX3xZFJyO)sKzt5_66$k8@IBw zy<|{tA19vGCJzR4JsDiC#HN2FqQe;r;AUQAA2Uhm(E^?-ccdo*{|j z^Jbrd&SIccZFwxE6}%-Np9aOV*eRbWZE$uMe-@3hf|^w#;HHvUidKaKhkwT_O~Y zi4oM$=`yT1FU)mob`#kLt)?q-q}L~NV?lKe*svFB^EQT_M*JTy8XQ9Gqz4NI2ZkJh zIxP&*>)gy9V-}z#SrVAr*nNH#&5Cd*l~oQR=%zkR(rv5x%KwIL#)#Y=EN!3A{VLCU z95d1Oe3$)WWk#4bw_OD!p&CtOV_#UDx#=K3u!Gj9)pYkuP|rY3)|X z8m^W(?C|1`=`;ZWS#XjjO+-YqEQ(M)By*-1w&HRgX}cNRnKS6cw)sv2p@=~EwLSEG zoPRznP#IP^W2qI}^QohABSyUA_j+z)&f@Dr(*hR~qn8aI(@hSzoW9?+Hd2TQ7VkN} zCtB(#LmnTcy761%&`>I+EQwp2nDzF#0lCE~rbaC#-A}0|2&Gy@*fAnF zdydr*A-Q9N6v9&GntotDiz1k~`U@2}G+`}40o{GV{dtSIfsW}J6|oK>r>R74Z} z#x}auT0W(hoa0jZLh%@WHtVT#07+2=27($|Ar`bdEpk=OkG5RvAaiDACo+S9p&039 zsg;6Xxcs*+@`HB$LBZS;@Z>kuOBO%6FXxP(>AEpFut*m1gbVpd77&J5vwoBgWL#K@ z`m5aJ)Z$q~)OsKc0(C-ys`sB>31#FnP!u0{3*!(NX|8Prr)_pLHb&PlY`$20J0>Vj zLo3RS@!1#z^?4y#~uTiaKZo!ndJ z9uJFT!m}~z)?jjF9xOo7no|Yyxp1f~b72A0n1!Q!gqislw73yg6BMv`7%D?|1wUgd z2M2~P+IpV@6lnngY-eg&x3E;GC?4XJU(dNrEOC+dA($0 z1LA~Y&_THGC12vFQL2q7Yqw?^Cen;)3nD;RZdz2^^%wZg+-(qe$8~v^m3>9g_vbWh*Hk5C)Wcd?dGy%5&H~(Yy7krC zV)*9G^#}!oo|G8U+}hd5$Yh7>@44LSPKt`5A0_2@xjwzSo>ze+3941~X)QfeHTM`h zCLm2iV}k)`4+gFr9-uBQKA`j1n@Um8;K7;MWg?6vH83;aMl!F4ch_XZZgp*%Uww2s z0R(ftrY~qaJ+E3fqf+2$_LR4~mu;0+VzH@7j6VG0XR6eoD!PQN*w6)EYFc{Qp!Y^c zOT7*FNvIT&OoRLjuUw1ylt#u;jz$!7)$Vb=OO>f_s>`18$86r!BUl`aZ7pYPJcBfi zYQ1wk-)V-|JNfj&$_#J(3zECjGmyu|nDF`Lt?T9bG+UBVEucGhp{*~CVgwNU${RTEa`@UbJl!(Zc#~>_)10lMVw>XJ6hX{9xL9m z97Q{fN&+q{Hclwr`v)f#xn9gLgZ<21=y2m|im?eO{> z_*6Z8sWOFN{PNEyb6>x8sXdkwO#^EgLA&WPG!WPn;e~Q*qbNcy+K(4*DYVvel;k4| zhJ-t^m%9|G{W>tj)19<)56^94=mpV-h|u)y zg9gJh9{ZfyuiI4X1WSYlhuzC4+2)^&EaPLBvS;{cxcgmy8ybKl<0P~OxkOn*e(YCp zcxBwO`JS*ihdh7@e*kq;es^S9kATrlfKeOg{wp13OgHfA>3rVs%V*sjDuIiMyWcZE z{XvaJOJ5&-CFje0H9oIil8^+Bdf?gy=8*uo$(-<~R;q|c!rKUP=d%XtRv9v24AFLf z408r8ylY&7_OCW#6XTv6EGW$^#F??gNnru>6Be%YtX+Ti+v&5z*Da=o&ZU$8nhNsQ zWOEpRS83F8QF2hyKqBj@z+Yz!6z-Y1T#DD7VjAYTSXv_7 z!Zy$5LZ=3@i21?UbU(Et%;!~|wg+8xZ)r;N%eAmLp6dA{_05o!Xr^Q`?KpeR#X?JW z-CqAOb?@lT2Yxg#BgAVirz!hZTy8iR>?U0zjgW=76KdW9t(FFym}DvpXWs-Z!%1-n z9elaP(7-uj-T{<92Hx@BmrFLUjY8l1d^6P_IV{SCeSgDnQr)Zj{V=O08(h|QCMCF6 z8c^D{1s1%xF@MFJP}|yT{+2X^1biCyCD}K`T5NarcD+&Jq${JvH}=Op#KL57+4CMo?Td4#7A0i0y&K{ttOY(BPWa(xbE;!9|Jq}r zD1gIN-s{(3`NzCL%(|9mz~wQb$^0ZJ_1mWE^Pu(0RAPFgqaiep0kZyTof%m~&GBO+ zK|Ocb#nr1NBj%kD;>2HE<3C=@VOS2Q!V`?9x${H!8!TRI;ojcNn^t3+2j3R2em3r- zZy7Uv>Jljv9uxB9*U?prMq<8O<@I}DeMhYcVjGnUE%7oix!OdZc!TFk&G(k?ZPTnV zKBt-utI-ylsWV0|8Iv}9{phxSzghIJR4tacp@u!TKnL70e0{8Bc7`7aXF`8{jBfVp zw&tU>gJlUwOT)&qA50}u)9_|5yvc5G$K>R~VrrMz?A+EMq~Csd4MN^R=()O{2(=%= zx>?*>UakI^Q$KJtAyEGQJkq1FfyY7MhNEaFhF&?PVDbHcdl{mn;?m&-BWj5TS1Sc> zF8xT1@Y(kXt%uT+_rg>6rO|E4eqsx%OM(2$(|@?&Y;U@`Mo2xcL6n`5vh8$GoS~?W zuf)u{F)6^Ef68Wei(=p?_SmB!>YzA9h{vYz&xiE=P;sCgAMCQfyer(SbU=xs({p zVSWldY^eYoMiKZTRETatJP-liCA9a^#++*_0RKzc8-98SmbTR!a#%H?;6h*|Q%2NK z^&epL2M9CHeTh-tT3eNS*8)X-r8g)2Ui!zC^>EdQ=ZDs{AA&K{uwoD@H5N_Zq$(=T zi+V!gMNBs;1#Q!j;NZjNnW6KTfWJWIjaZMn?#yfBT<&+=6EmjQoyv4q29tL83$}GH zZrraQ(vDokf9~q-_F)SIw}8D}T0j~$E;YJ7CJyUv61MwF<&Wxcq|_$mo}*dDhYKNA zWEHW)gAgj5xU=on6%`-uDw6Y<2ojh}|2?vUW$2SUyDGORv*mK-`R;2$IfOsI(+D($ zn^B5Xjsk6MZEblZ!_s^GRoFmry#k(RPMkNoO=!}BIeN}HJq3XlXR3R0LSv=QRbv98 zh6sjnpE^nbf<$zT%!v?E5zAaz?GFw1V8v$aN!;6?icu2=RfF*_CrT!fF~>+qPWC0J z6yD&zd^ycEZQ|M48gA~rs>;ZcQgeoE#E@9KoVZ>kTKvq!F*ohSL=jl`U_x!xn}yvk zS8tW08k9uY;O%VZHU=6A%zP?QW{aA0C&>+oHKp5aH75Qefm2;{jITX7S=JziELHRV zEq(38;`I0b+=yXMqU(BYo|^$L=Sh(6j+W9N)(brY+PnQ zXIy^mR6?>x-z3NJW^nJk{ZT7C$|6%}8#rAJ`OjQac~_?GaUa&YU5gb7+#SSIEDMSx2!9_a995*PC-|oFlaAmJO zDcd;EoD#lwk61YI^X*H0tH~l_woJL9+=mLKsc>9Lud>D(rAXC@<8te?${e(yNfM7` zO@Tin!p<;?&?s;*n;#SAYkhwh?LevgeEr`|`ubjeVa}3|f_s$rny`QDND)=E6oU zdKvQl5eGMplmka1GXTEAOz60w$xDe|KVPZBK9@5IxV-=Qg2V~;UZBN<93qrjn|+}KC))IRqJ|X=WV8C4Fsx;=#N*T!;guu2r$7VM8e3>>h) z;x7ppc#d_yM};xmCQ@UjH5qym-YkqdIBk1oz-D&j8arp6GMm$bCuY!!^rrJ*EvJzs ze-fLFc4^dxdu1XBuy`{x+$5pyy^qPDWIK3BZ`}qtukFbf)@<_{;XwEJ0?p8>m3bCu z2tPCWD^KiJuAL2`PB^ju1hPq2L7Mnuv8!2s|Mz9B-VhW1c#*T`S%6>C*V;rPi0tFk zY?<4orz3r~A+$Hv-9~h5pvW{`=c}yUo8PkqlZh$MwS!3(c6ym(LMVV^6C&?*K&Rgu z9IGZ4v`Mfeo)6eUqm2c`dW~(jZcru;%$nwQV#v(L{J({)nH6?=A>Q^~g7uj@fH82R z@upJ9HMFg}NoxlwYb8a{3-{!4(G*hMP}j~+0}=e;Yqux5zFOcmpm~;=wSu)-8%R12 za~$eawLH(3fdcJ8yY*Oc^zuvg-8dR0E&j5V!c=Y#qM`7bwj%!Us5CRF{#FdFE6ek3 zDSKz3T@{a4sai>0{hFE=!sH6S8DD`sd@}_vq`Gy!S+vk(X#8c%_jMO*PN(woz6v_) zWY!DNQ*P;=*>iCAhPm^wn3bH;z*dQE&WG-Wxu0%lVbDyUH=Isv`BNz@Xh31%8j|z} zt=UdXZ#c4x$F8gq&ZWPg_h|xro*Fw(O{%S+gWBb`RFrJfu<56#9qhq%yR|96$s&`{ z&jz0+!@?CT^&j_!AbOKVdO`1Lr6w9rw2zt-J7FJkjOxcIaw1FFV+uz?yBY3@M@XA^ z$nxIm51~QEH`!-x2i0bO?FnZqTRwUgin{x;AYqFGf_PujlKgBN62^1lOA#m@b2q3k zX|Pd_fw~|{77ww;yxgtd=mYY-q+OAVMzH{wq}g`at&3)~p0?ls@ldVaB>NE;EgDr( z;_t&VnszwAlPk=;K=6M`xa38(l-f|I1^b;`gXUY>`7d6U!uLV&BSSZBPUGHfF?c{{ z-m02~LDPPwdVnsU^N6^l+P*xHnzxE^nvPX=`Gy?K-JGgq0Qmzf>wC~_xchB05gmrc z+?_CdlNS};B81Bdv9DA8^@mNxuLCRNhmZia9^Kv_kB7(!t=~&yDPI_Z9C+#@4ZU*c zXaofw_wwA~r#mO}(1yT^n+sW#AEeSS={t^nm)KT@B{F{r=~=H$r>i|Vy(gc(dqk2& z$m}3TLp54Zw;GYC^M3yoGC_Y#fm@=>1SX{kS{da#ziD$e#MY+++ygcRBO&aj4r0&l zbr}j?d9g7>5;0BgoAeNlr4*M2NqBAP3?{$Zni?R8n42;6-BGZpUJKaG&FpmU>S-Oy zp0w}NVyuWv-7FLBAuiS};YstBhZoh(J}e7cxdmC+e#k7ma~H4QysZrSF_eu zFC6!Z*EjdK`Kc$5{8NUo_s04JKWXLS(1%Jv9DySyerCTM4LR=?$=BOg_Gh>UoGqo$ z=CFxO4A~o!zJI*^2^?fDJd$eS{`GmLD*gSyaHE(Iq;u0ss@iC0Z*TzxjkcApOm*7ak-NizF zis#eVl^QnulI6~k7MWk{z=f51ym5&a+Z$h+_ihE8 zrvpP{3R(+Iy*@v;SC-Xva?a~B%V0MI3=+g_c~o%-F1wLJY{A?*gFDZ6exHn4{)zNE zvxHQ#g|s`EB!NswRDg&(v`d-_-K=|?dm`gQkUh~H;rb%wq|y(j>h^o2j4p>NFmM#z zmzoZnUcZkOXwls$>B`WXT>B;ErE5^q_sGOuMuSsaxnHBZcpoB1O}#i7)0XPN#hB5e z@W#Oo(L$3c=w+1O`WfOcY1HfC%0R38z?6*r{HAdZ3T~3jj5TRjhNj%mLvl*wl@IDT z%}j4k_W;n@e13=k0d%V4D{Nt=c#=fr8yQBAhbq2F(j>3-(83o>b=zVU3UwEI3c{Bz z>@untX9K}MFxN?@tQ(b2vqVWZL?@E(bf@3WIYXcf#YUvB@bupcj?owL>C1}JT6f<= zo4YKJEbD8kjQ6&~Tk@$V<{(hMDO*C+4()T#a`IO1$yWFHEB&#lgpy$`T?e~HCwqv_zd&A?_zWTI<1NX%@J{IHn$pz7| zxjB|S*hSyXB+EJ_!{E$*W%OlQ6W1a zA~G)UE{vRNi-O#yYC^~C4x&pMU!eYjK5S8;CWrVzaN-r^?dY|?RgVY%PJV`6La5)|t( zo4$>0KUpybVi`5hh(Wq+s<_l>vN#_Mc3iacSnx0R-S?fEZqEn^I(S%2+P_>p>5%+2 zZG(MyjpE%~{5kL?m-)W&ZSaK6Z4UK#2;hzkl4@V;eYtk=Gk`Llt=4|H^8!7DL+``A z#OcjDLi^gm)UBB#|DC-HO7@rEd%B&mUYJvx&G^%e0S0OP_s_rj_idmE_UH@63V^gl4skPI$tnRow z+gTvKe?TLtoux%Ns;grsm!=)Cp*Y;gP1!OdzhtYMU3mOMV; zcv7_%s&6?*B7C-cdJ#43+a<=+%%R!aumKa^7xz0(+MkVLu|J#-;kRVP-)%-OMBhNr^@7)t`P-0B={~fAQy( z5z9I9=)180Y4AnuOJg&ZB#xRq7gEUih$Kfj^gQ$6<1WH&U$3~Z0>YN~tXJh`r82dF#7BzN@GirHu~+b89$n?yz;~VGm{T!`@KprQ#b%lfP-k?S%dImc&w? z$MnUJ+N?$Ay$1^2q^dW%xzbxm<9utZ~cq z)OhghtQ{!exa&QQgsx}*xzpVWoa57O8us@yIFs4met-2CwAA)RN$~Xt@0&xk^P+O! zgy}_>lbu+Hte3E9yA~d=Rz#PT>^Sp6lsNNrUDtVmj3Y`&)e`)7&=x#mD+{fb2HGrF z_eP-}YOcM{EHG_VFE{7Nd>-CZEnO3C3^sg*tQvUT&R@3haDxmVEBA?&9zObp(i5h`*1_js2fekr`@-8pw;2=2NO5K>&-oTAh;Uz0CWIM^f9mhrya{om!5${RO?ukTKP-BAyHeg!8BRzm&s}UE z&V8;{pCemv-x3|w@|L?(dwbvHb`t*Zh!-}V(If3Iczt(&zjq+OUndu{Pjd0$@!`Jc zYC$_CCfJo?$hU66x3|Ja4C9Vu7H`4n@_w}JmtfKE)bx<3nv91X$rTTeqc`iU^X&rC z&?9=x*G00o2KqH_dyrB4x+RJQr>(S6BabC~-^141Z2LKiFBG1uMcX?C88KM3MrT?x z*=_nZLn~&t`Fy(C^52@RBL6|O#D90~ zTsf?QCw{TydoN#;?R#|DM0MtQb}%R(Gv8o=@pH?5i(HRW&~FR-DEHUfp(KN&$l1@1 zyFY%XuCyePYx$>ZZ4P>fjtV>cb5fMy))I!#KkdX64W z{AX!Blo`QFW4{I zT3#|+1f_bc+8$#Q-A&plh$#!S;+#{Z!J=_|S z@2_?!XX4cErymZAw%Tt*D9KW}h|5+D>v3J)qPKb{g4UY~8Xf5`Man-c>3Bg=RW_Ec zC*O~^-37TpJ-}i~JOf*7Q`7G-xBSW1jsl4N?&3wSudomLEn6Li|2Pyrge)HwLfm=o z_*?Gn#T}+v54lra{7AO)C`Ta=SR}aYuZRMRWF(|Uv`N{ZI&fe3fl5~Om=1oQu?;zQ zpG$bGft0LM>bF?zz0<^FT*f{hQr+wF#;c0LQ70u0svf4(Jfh)DK($I&+ZffFla&C- zz%SD-xI;y~NalV*X<|gk(rrAOkMfeD6lYuAu>Z$X*PYfICPW&lf4kI!;kQgKXBI2N z-%g+!vGMnVw^&N+jjQ?qEtnH?n8I+_0)JCH`j4C7U%*)eQ~;)EcV_iGJ&Oo&%K&Lb zo5*{)t~{A_P)qn}H2;2?YCnw(EtNYw064)P*m8kVGL)Es3S<9| zJ0t-4^a!YuS}yYwHn=!}%y=JH7O`g%D6gd)Fb$3Z`9|a|FelJui2rL~T8ROlGMR*3 zZR&wx?Z-d@N3tt5yQQ6G{jwQQS<^fS)48-3DrT+Zg-a_EKKGv`Gb=6!5)FI@ zGMVb;uRn=iggRXC9t_Xh@|fJl`t2MoOyubnGo&(bL@6=E=^lk6j1trZ$*8U!_MdhI-&I&K#s24g?F2M%rJ!LZrZB^m;)7@; zd2dzkcK`s@nWbirGT;4X{7z(!Wq0q^gYjDZ ze2HMQF|Gel8%`jTGTiCn$%Xg~;r^n4Sdd=1^!*mhB8;-1t6u4I!5yTQ?LJe_yjlHiJ&5lyQ%;8&*O37gF=>0`mcxn^HP1_2^~(h ziyi(yK9_@!jReCe;$M&ZFPnhdmi9nSNh@69|M=wZml7oKu~~4s{udG@Me|R9XgampNnuIoPTw=iH<+3!bSnz4`b^&QdI0eEa z2O^C+6Cz#^v#jREKhPub9B7rLfe^<0ZVYeaj>5;P%hFK{|6Y5IXOuSc22MtqW#OD4 zPobFXAL3Q`41tZ8`I&~S3K%hEDHuEI3S-DJJHy6@-V31J2G2tC;3T`4Krw;#AAUnf zl^G)UoT@lXQCZ^D`#1|XqvKlTOe<wl+X?cAR;9UD5RlhLl`{j2$l0e z-r^Zm;}gRdMJzS}$Yg55%|s_6_ZRNJSZAS7AlM{q((AEUOj0`#_$9DiPu$;ZQ2cZL zlnl(~w8Z_Ij|;fl^$GXI(KQpb)z8mh!v916zQnhGe9YnC6SQ3;lXPdLqu~R%rMabA5SF(%TuRHBS$HLns06pG*Nve5uFU+mrw2L8RBAU1>^S-tO-gWR-&jQH#fKY^fZ53>TMsI`=iiRagg66 zdz-(5D+3}eE$8B?mefdJk9^TTIim!C{_9@@Tr`55KST+rO~U_;nsZ_+<{frOrn6)a zjk;Kd2UlTHk@d*#uT#tv#}qNLh)2C^ou)f$A-i4o5a5@~yLcS!tUxWUe~gd{agu>^ z(VtPLP5$1t@ciNY2y!T6>J0BFf672z*to_=;EyUfxlumGkSGD&dc1Cl!*LbEUHCsL zgImhledyT7VEDcNKB8eLpB}zN!KofM5(Y#9>7FkXwM0gsx z8b;S@lK-cPq}U&<5WS>Vn7<=$TAI;TxtZbDb$eMqdsl4a_qe#N3XqdCZQd&Qlo=Zp zqxp}#5;~}7HUyPoE7{L&RSx53ne?tAgXFKJ)2(}_Ha@`|Xv0xcV&n&jj=bUHf?M+& z439~8g7sH8K*Gz+UE{{$!1HDBw2Y=hz`riRk*7zKI|&Fc(9Ogla83WVQEFNgrc#9< zwM({0eM3N+`D`U@>xCB6fMNYXkD>&L;c>Sm+TY*CC!0Ad^#(dnUeuv(N&f?mMyQmC zeE-V*@es8=8C4|09dT*Hdxh`R&a@Z}O9LummF!HdhPYd#QJM9zpHrFky(`fb`US`! zFZ$3$)>A^uD7z!L+<*fUuOJEnX|obS%7D+q8a1*DRx~C5!mUhqpteCF+*zPJc)R`P zRPY><`%BR5zrvkr01XbC4@~Oq$^q-z=lPm!Z zk@QY6`&Tc36q_WI0kfReC~-I{tqmLU{gVr|%L3IW6n{)lG=0VOc`;7PSa}zi5V@5P zq@(WB=n|*lWCjyosmqkOsG284T}y@UC%eaifikXb!BipTPk1@lpIz36WRt7`#@*(S7`?ovoG+}{6u%8HMv z)sgnNe!C5+P3j`qe{fpJP*D3h@;9)nfKuwX zcUC)E8Ck=bNrS4slVB5Hf*3V@mjN_e@E?upWCJPyUr?HUG>tkcjUh6k=5J>(jdsD4 zqi4#Y{%rw#Lae(m06ePkN-pa_{(*Qyg=ax(GF(V#Y7ro|c^o+=#!tMgI*f>aHev~a z=0Ap52N9y@U~jqs+ZO|M2_o2qE98W2OK-hL01 zWE*OTp7#!+(g(a*63k79yY7>dq4U9!71S$xpYj48CFwsm*%1C6G6K<2)t8wh9|BYG zJFJ~h-;2ldOJ!mJ-WKA+Sn3@a`o4sjyiz0S21$?WU@;?@U>n{|=&Lau7_?UHR3|Ev z0}3r6r!ySjV#jC0r1qPQOWdiq?tOBvB{48~L>CgN^~9yq)!{$eM?}7HWPK$<%9^{4 zVIT=$m!e8mCiWy#U1^$@?*1EIR7l_>%m1xjl=Y9lsWaPXPX|?S^5|Q7dGP zGAN_xIA0tAUi?QVvalG{j4~;l3LMnxksk{WB-oF3Xx+wIOKeyV`LIF`S2&@u`I~^xVs;4DC;K=$7ifA5-PofMm8Ohz=sY? zf-d&N#1DpFET>h0468(vL|;~CzVdbqm_d+2(GA+;iF+=F2YKJFe{(X8{u;S9)l`Q& zWvAwOpLLgIBS9bH^b~-}s7lcOnkxW+9)hF2*A_-X?lWJfKnp}dq1o!ZAGGdvZ`*!}5?%q6Jj-(j;qj}2K%2!%A& zPpP`UdpX~1OYPh;L;4a%y+G#LM1e@noxLbhJFu}EbS85heqf=nNHV@e5utX)ob!$D zy&N)e;_K6h#kF@nzsPS1HmT>(FIuXrQD41JL!iO!V|w5yVip-u!~O0KD89ZIIxsEn zggav}yn@Wjn7%9eW8dT~uElrqB}oE&ErALVU!i?!;YxD!*`pS(LgExV(KG@JdCSsl z^usfyUZ&KRW1DJE%0QBljWSwwP^K(8@#!Sm$G|79m?02|mYR%7T_wJUPUn4(1vd0P1T$H-nl?$*ih>*e=S5LH+ zWRnE0ek`Es)Ie4mPmJ2>ZKrG?lrdGpFWkJ`i$~7sfrm-$C)yf8OKuz(cOU6jRp;VTl*rxP5Ss@-;DrQ%*a%V>!y^hWvo8i?crEs&E^Mlk6l7@#+4*dERdaFmo$f%%e6nr6~)rQr@?e0gK4-n8+brthNI@q<(%{;9-=~@e-S9+h*{-E#_rqhA;lZ^UlNobjd$IU%r$3 zWH0baPsI^8eT9Z3(s$46cLXHHU@z7Z()uBKP~VfKHnatGwbutodj2_0yw$uMBwu`c z8^|q1!4ZKKU&Dy1PM3uf^jfb|uW{0h4IJ??{USvEV|xD>B8uWX4P(@xf-jMzuha-T z%l@scu;==7+hPNA9(Her`JMT7sjmi_S*4X|l4PPbbav<_?D?EOrNdV2?am0@LDxLs z-<+mDlBq^b41rRBy3f?>VBJRY$Kl^ESfVq~g$WM7 ze>U5q!C6WMp7&TwBYA(v-T6-8tLBX^^}{csotIX9;b_VlS!)5#E?>mMZB_D*_R)&@ zV|K>=LCIoYq4{61tAJ>D+{^#Uu-#17_$o?>nJTS^lIkI1=37OHc>Sh1I(i4xJ+|852md2AEK?koQ(gPZLglQ8h+h zF|FOm;!tthm~z7rgnvYR(sFE+alfH(f%FLtvB&}xt2e@-lNyT zTF|X^v*nZ|E9C+&M**-;wI}{rWv{suh*hEW`{)dqigkB#|OW}eoVo9?I?4zK=};*K5HDeVgBe>@$)LoUoZK9*i+l7+No$gyw> zJpgK7-nz}MXotcr6!|H90e=p?jqcnlLGxy4huY zFJYgfhiTRQhsHD;+qwi>ztLTyN3teI4iObV)MSSI8 zw7oyzry6XN-8*=u>e9fYhU|K8;bS*8sabap(9R}1Cf=4p5;y!gcHREF6@uokDTu&e zhm4=1vxkXXPA60VE~6Kd>8}-ghV*ylwP1gCAI(GyF54?F3{xBK=&N5*%J}IiS0cD_ zVxiNNqu}CB=V}U0%nC@W{|H?!XRsS{UI?pX?L^Y*7Ena)NixaENTg9e`7!*B_|y|j zA7;Ytqp>aX6^G#U_ErtuU-lWUokj#-Lk7aRJu!mT!FKn9?~$pxt3 zJY)bk*}kY7qLad5AHS{qx@cWs;@2KsLs3Oo;!wMpCm;m?qay$qY`GK(Uz#i|VdJpP z7pNe+tDm#uPiUzyQt;T`>+Ze&QKrtwJ@+ofQcGd1g_zUH>GQSl&}Wt;6mxeqMj zK)y8VZNgyv`T|bh;%C$f08=c>;`iNGSw+E z40-%dep=v>??%$XE+k0}z`0#Aquub_@paO#MS{^R0zVTCe(xi|)( zo;3e;d#x!Hn9#?xR!BTHo=Rr11T(x`X8`-AcZFa4Pgp2q?)C+d3MO83;T4 ztsk!bq)NJvzrBT!yh%RnqLqcPwe{}z3G8=e`9m*;I{9r^kZp}G1{@>q==;pyEV6mE za($qV49P^4CH%w+$f)3n5W!x%zC75DX#>;=+T+BtLq9{?K8WTeBr4bGAxNpSzeMLu z_g)vD-fR~SV`1N=V((fjDB)(nsYd6B@QEDV68xAE_~mPLb0tC0@w;Pzb@-Q4s9@W` zf46yjn(Z>zADdZ%)+Z8E9U3&@tNX?O&yo!#n7bdTgJkh_m&Q%T%^C`H6hnIW2!9|Dg zvJ8fj=@^=1a4i`7?@Ui7lOEMk76YM!jjn?6Qr4-iJZ=TywH1IsNwc7$DztEAF7o}V zFTe9(=qK&13$Bg5^P&(`Uyh$eTs|}L&QaTH{iF*s#}w7~{to2ueFSCcJTMXe;7N`^ zhuj+hDW&9%*$4wHxVdLZ0#>O{a}}xkf-@9k5jL&&ymnr?Z?3!B{=nS&_0k{Rdg`r# zUa-Yj2Zu%kK?KYy}G_=*DF*AYF%6sx?7Lvjt_h#=<;&07N3dz#9zXI0xFTAX}81x`@R- z5h>9C12&j?Lbkc)~>3sFT*FAqOW*aV?z{tFsenT}V;GTFZ=?@s0^()!Kc3#V-kOY!G zyJlL{xcf{p{=}~z-8e}d{+1?&?s*u$rA??Aa|t<^+=vPj)E|0>Rk)moF9;(Gb%nQv zg1xQ;r5+~jD+N=cK!p{R+p#2T>$WOkpElnyHD6Ky6z$Zpc-+2*N7BF14;$YqB6$-t zPIA(%LyWg616lE={~pzO_uPVQm;3S4g0{H2thB8Zh;S#}rx>%t-wIa7R`#}*63>d532S$6k~37`_L&TvTs{%w7px( zhKX-ThKN_)t>=#z)s)irDSWp`M`^M%9bUF~%I3b3RR5^M3(!v1NB+wD-m$d-P8X1# zxxFa!Qo)h-p!6?2N)TL^&V(JVKE|v*R|JG7!}@gQoLjxy?p`^`-M~@{>jN`2X5Nitq$GvL#jkrK~#K?@Olkm`UQ(OsK+1GC|?)|aL z@w$oC$v^?ynlK#dSb1MdteRM|J|#t+vgdG3P)Yc)?Te(s!Vk*+uYa*Yw@MkcPbDZ| zHNON!a^RkJ-@f;}drdnXbwrUVu6~(F6ab;*M>9tMm-TAUN(e7lq*4BZ z_)mIQEYJhGz03XHy!QD#j9T<;jRRINMG-zdM8kqQF#anFW6jyCXJx{4p&~!p1G}RL>?d4vHS;cXg%`GM-}<;nd^FDvq3nQnYq@(SK%nfy%@ zssvYgHA;oADBd9sH$^w_6T?Z;HJ=M5;4L8$Yk$50hD*r^c>OvSvbd!JCOH3l-7~-c z2Q6Ev`52x49GC?>_@eXQHz^O`dj>Jo=Nxlv3l$OW1Mt<-(rjC48U(lAXsJZ-+R&Oe zYiPyAHlN_UhK$QOuzv_!P+5FCzyB`S#XjMrzJ)i#VE9XR&E|nok^vzU_yH#&sMKWr zw@;Z1IOP+I2!Rl-3W+x#p5bNe_O&!dT!Cw00&ccX-^s>pn(xG%HVXh}G@8b*zz9*; zGZ41f=@MXh_bcR%*lOis7T6{x;8qfrSCv% ztfF3-l5RKhDlyep>GUOK96b66^t?+}IK|=beV0h~Pq7CedB#g+z+w)Pot(Gs*957$ zn%d9sQ+*Ol*q{zWJGW%OgvbB;JH=(`>=QC?gPPS_!+-KVwS4(f0!Z(38jS>FGZIpx z(dfVCAB)r+ukiSdF5D`NF%v%3U2>Bj*IVN~^pEEF_RUr||IqfVj>7p#i6Joj?Gs-P z#i6)hhsJ6bubYXoWw%vRX>&UXC-izyIt!k={$O zr~s=b%!|3GM z$7k4c&0XT2OOy}3*pSrKtK!_1+YXrVoa6GE;7RN?>oH}SgaKeZQsQ1IISNaAk9jS1 zPdJ8z`$0aZR@gUJ$xKztEyv|&bEybEK7h5#-jex7$N)i^ zSVUW0@Lg0od~51E;NCRG-m@xdhL8nMWCd^M3;*j z)jj)g4}mQvFLH7YLZogMcL4EiURKv08eH86N3*7tX@kq>2}F58AKBBQI;S4ObEPq$ zT*0GRLSjanl+3-Iyb8hgou%Ha{fP*0W6T)da2=mmJW! zT;095t22w+&mI!VAh}k+0DN|Nk&n(L{16x&-|h zT}70TIt$e@MZ-u3ra*e(jo;T~O7|~x|MDWMA+Cbi`!5R}5aflBu2bnJvKmTNdg7Pfhtdy9 zhh2?ze%Zlz1Vnw&EnsO2!!21qw?mAv6CKpxen7vA$?l&8L3ZyRmgpciO(O@KN{{A} zip_s-{ZH}@%kdDJS3hS_r0LR*m)t~xY)tutybj-CAr_3XkzRBOS~lN7@YN>r)`wmX z@7+pGpYor}ULYptNO1klonGOI<)zN)f({E+>UvPw6wTu#(~UWDwP=&yIDll7!Pu*u z*YK}D5U!R)XxyX+0)!83H*Im_*#R$h+;4D-Q@ioX%1_L_}CIii}rdEs>*#SMqd0 zyRwG|$BBG8h9wqdQ(ni%6FWvy3tEN)$vL)joKXGX>7AHG5^~plrE| z#K{1>Mhb$>loaRRlKNk?Z^y6z7UT134I(L;Qlb~v1;$*xa)Vl{+oSk8L(R||6eywon z)k1uvn#)dFM|{1$WqgKUTt>?D&wvDC9OzZ@*`91ag^OyNv#FG<)A6xXCHZd8nE9EJ zlhKWuO3lhSY18K}S}~k%Gg7b?p)(iAYW)Xjs!+@~qJB^^bPn@y{vkvuSFXP9*uK)8 zYO(c-+QQ8XJC8SN{Nu&cjF9Y`dVf}Pst{zGS^H)>Kkn=Ry<8!0f+D@dfI@z2a(FG6 z(abYm8av2?$7IrBmNc=tw8WQUE{2mJjZx>TNK$2rY5uxV2C2!Tor8!c?xZ4a^_ohikZO96!?$3<4Bme*(@tcEU(Euc z(dRW9Pli%6uFt&mmsAG3UY*>6Z(aFtM{DX)T{Z*Bgt&{zJKGDbI@gv6Rg9nbOdg@)<%JD zx9A0DM8RK%aL7`^qnvfFy?L$Y$JC#Om`()|9mp5+cDQOhOb2GlAxwke)DACOB>TDz z@j*LMlbQ-VmJC9(vC;S7>~^dD(b6MldRU>IsUv#dL70ROc0W$K@}R;GHj0f<~8X@iEZvmJv++ z5V$V)lYcMWKEjJE13=gkyO*0EY#zy()!;yu_s?LL8cv>N zR4Z3d`FR=!(lL@;sls4EHTPsFO+~V z6OvuWW`zP(zR-OBx7sn)_V_Bt=*fS4fZ^z3`aRg7@A3G1$syU21=BZ2`4#(BaqJGuE^2aPn zX`1x9sBqg|gdEXrR2u(C3)lw={ITIJ^_7DSwMtC@uLmOE<1t0r`4~t(vJO8UP0cO@ zE!vs=h1Nxg!GT#IDA2ekhe@r-G&=0?81#p~`jgn_>fspstfZ)gmiO@<+AL4Q1>Kq9 zxB8HF8JpcvhNfH3uXQ8e=j0O$*r_J9$1H9cUPNYcFO71oXs6UL{XX>nA$fJ*k}KOj zW!ITMHZly^5K)*$UTjkcvH4}@cn}?@IF$GD{CzQ`aOX6L0ID9N_WC+d30J1Gx#<4W z>m3Z>g2KvCoYEeMfSi!3S;cS-FzQ>%qO@|{2)!;h8=#aQo|V7(HNoOg?cIJ!IqdZ? zC^_0i<}^ybc0!K;?-+3#t=YOAStRLFfxFZNP(y42Lus`DG9H4Q6hQ*oJ&m{+g_AH0 z#n9*oEeK-iUc%ad%03o`#3*`g`R(yuYWbgeLre)09SonL-5BH1$*(xVf=G2EKdJtY zL~xH)em`^|*i!<8KQOn$M<;-PMK>YTfB$fU$O3Ip^9ElsyQkiE7&Y$3+aA~(4`-Rz zjpSsX5{{;T#JQgsCkEc|AHe-g+;o5&QXr+%+HTv9L-E(rtMkRO(CBtYuDA&npa%w% zwoXA}zSo%}Puq?CEZV7T_w_NPB>jOQ{437h?2AE6xQWWACJIuMwU|C&`iVzqMi_l~ z@jti?9IzmeiVu%5fmgBR;$1&&jLHq5YHb}gG##eYG}PO89!A}N1e?08MNlu!Un#yu zyrs&F3emZ)^=7_tlA8HjB$B!_fAq(7VBP*io?hQil!`pQNhQPsD69?K*eOF}ji$3} z#yw`W8&@5*360BoBO*&j+pb7)++c-9VuU8xz{5Fe*Z$F$sF6vjf-YRq`*O6XG%&J> z4CaOe*W)3^{{vep&n~0s8&6l%G@Uciuqi$ixJ0=izqOxT4XcNtq>J&b2X7S5i`~e_ zl#4Be_=lmmyNl3RQfG#Xvn&?Pd?kI~XX;1!_WiAh68sm}9l@mmk32H@x_M}Veh*!h z(#f<6Zcpp-UDtkv~X$pgP6MnL#b0VtJS1T7V!jrh}McZ#?0YKoIdf=>Z( z4FO(EI=9|@j+A{f6al&Hc_5;j&tKf1RY1#Sc+*WEE(V)`%VYr=%C5qKG_{4I^@knaC!y3ibD$NDdQZjaf!px4 zB9LITAekWf>#JMgI}6FNtZ4WMWj`BGo&t#giumpi_Md?Se|Wa(Cvy9SUT&ZI{)-|VCd#@@ip z86am9!MYlXy}7KXB4*&;6;SDi(?~NB>e@b`-Qu4?!UfP$Sv$MbL(+7z&^Fs8%>9fn zN)prx{S!ccy5b{A!JFlBq;RU+|(SE9@DvHjScwYFTyRGwW?9cBg0=ur^5#;p#f`svja4iTvv!ojZJyf<639wp}N8 z-KCP~v-C@ra<^ya4E#*Y9aEBTgJ!f%$G! zbAz(jNwD!q=Ox?z$Y6N&`5F!jRz#$`1)AVL$8}Hglco*!#SGFii~Y)@V)4KEs;j)X z2wna4t3X~onZQ{aRCsc`o04q*ikOr}81tTmQMelpqTyMs*_j$ENOG9x~G zj$!6Be2b(#6Vjv#}QN?v^3h!2mG2S>GT_YJ?LxSBWsd1i?Yz;4xMh`|n zm{>I=*#t(d3=1HP-O5SjMZ;<>5*Rd{PPCuiJ# zU-r}V`@+HOqv+5g8acE$BkLQeD0OJ*Fd(@ z3A;QTGoFX?gNSmB-HjvRe?bgd{EI)R z+ihAV$H1%T8IZD(@%n`cw&Fj&l3I7GVi}qA-G9DOYz(x#V4P%o<^SO(#+CC^1ld3s z7A=FBwSX4QB4|1G`0z<5t)xbqXSWS$*3Z}0VlSZG`7eGY8a>_{9^TWx-g$BTK+>l? zhAu+-6VUrpO4Hn}bV{UDKWQP|NB_0B zrExc42ex5WTPO89>|!IhZ?-sIgg1hHaKmT))+3roxTY-9JIV<>(&_RFmLjJ`g%dg- z&Z-+1&=Jj}{6#ft9Uo4?Tm}%hq(x<=o z#r<$?HeSL2ElK19bu312w-e;oedpEN?|6svmr0-wpSEZ3?Fo-65r9d`@1*eF({^i|@0;d|=EQ=S(4t#fJ zTKP`HAa&B60D@DvK^!+Q{a1|H{kG?E_50MLj6oY}PNLBkmh|fU z41Y6edWHv3!&RL_O-}y${@Nbx{3tUNUj8RX!7PJjBxvOR)2Ssky#4|~U&boP2xctZ ze=lRf^H{XknT87U>rjjC&TG-bL$B51P0(AuY*OF%YOk@&pHeM>F(u7!IeF@3w&+xP z?#xj~u~l4l>}GYQe#RP7J(UQyOM5EBVC&MANZ5sZs3eL2`-F42?AtNG>8MI}i@;op(#$->xMCJQZA^9FQ=G|7H!1zQ?Vb zyx;@as!5@UoFf}d9$E(#p$>fE1m& z#{oN{fY$eCmrOrkbkq{Jw=!w!Jad%+GeLvqlW(J>w(@(hSK}A6N3wqaW*A%2}2l%p@e6o?e<=MRs44z zjhHUGm3t(}o^SDXXDO1{@T^l5En;AgCii2Y^G*?|e8)^y+3#egGVI-vkL)8aAX`dD znGR4NmN|L=;f0JQzwrb^K@V%qnQiuSapP3A`=)mM_sQOQiy-Kp5fDC4Y|nF6$xh|L zl^9OO1;wBa2ODL{JE)x007pNL)pywZAp%vp|NaRMn`M!0l=iSh(yDMY$8ywI6oy4{ z6EJ}HA#QFeTwf>rx!<3uPJHzFkUwU^R+RFF*x)YS)B_51mjFU;gBzw=+tF(HQc=%` z*A?cE?i4lLRLFU!gr_TU^;=!GbSz{E2|O0r6sEx`>ixu4PV)+HZ?;cZ;5KTr3c#%E zxItVf@DHUR|D+aYV`L$b^iB{23Y-cxZbDq_)8p@-%JG<(>7$NCSv9!%pZZ?K7f=4p|pvI&w&-cwVfHs zD~%BgFeK>4hLMr4x&Es<&9DCmimF1n05wV`J0xs?F8{3(4Fqt}no-!?^@6VhXCFoM ziE%|9o_=u=8j{<;K#*ckV8DcHe zkkZd2MmHCVU*HAH1G^oa6ZRSMsK(6vQJCpOSrOo1udkzlX5hrOjdi554dUVEv z046@XzGZifoN^?9$650*pT>`?+bhIDwyX>T3&maecPW{yOQK#I|4YbbSA z#~->mtRf3C`gy{-`s(!6Q`VJn%3i4lz`MIGlV=6&>4_LCnl79P->Zi=o=WMazI}gK zX}CmkJUxL|*}B_oOE9zV zeuXHa(U14w%{WuOc~ak4o$$JEaRw%>TUymhPthu@POsB4GVEoa{?V z)o-|HBCl594QhHm(H^ms2~l^OVdl>Y!{`ie({C;hq%i^(^#L>fwaE;aI&iFpDUDZv zkq^o+KpP+0-PEILN9Cc#q+lk$8Dp6GbddXy)Yu&9Ieh)3Qje+ zED!)nyjf3iQC8AeYFWNE-u=jIbaB)-+r0kxELhCidHl8h=S-%#AF~42)Ve4ug@gtc zBEl@yQ=jmuP4({t%y6*9PGt*mYsE^!+tK6Y-)W7+^Z8w9lFyT2$ci=WeGvRx_ z>G1E16!XF)WFcAQ~l7zL(DN(^oINGn7|6!oD(KH{VF#ry`f9s-Yx%70)S!CmEA7 zs!PHRjC9cHa#1xY^BmSVwNI)1*kX6x$)RalrcLt^+?$8D1QAWFdV-K1w7cp>j8~x0 znvU>?#ViQGJ%9?k78e>#UltPf1j#5Qbsv(ucu~;M#Een`i5cA2u0C}Ncl!`}Vaw(| zfycf7FUo`B@S1$l)Vr$+1b28IuG4yVwm;sDfB|Z+Z5imgsIxDi*T? ziNjy_8gGA3r_4SLC=_wIQJ4;}MQ6Jp3b+$T@L3jxrUz?N$2x%=okPj=1$mwIm?a4% zY>3MIy=7GMtE_dY$t1$LdJ}|qJ!<_G7svNH<~_EE0{OV}1;ddX25oI1a$MJ+4guyx zzFiMW__=Ts#dV|#gnQS3dlyvgx-vdAC8R5R-HfcIS+g>#^H+qqa`->{|K% zExW#y!ZJzjtEk=jz$2E}L;pg{H^t?U4M;W?C3WYL^L& zXMXvnWLN-&;T|k&Lg5J=ovuvOci@bBztk-*i(iF*XmrI^qsv_~TBK<7v-1lUt*{%G z^F-Wi%ck(`jQ8LuL(?zS-ia`?T5e1EWn0; z`^L_6M=IK0zJ!OA25I3bxezP2CEBWV@$~0rpI;93=&Tg4jrD7TIeh^wuGHO*n!mx# zIJR?rGeSBR8E*KWl+D(kaHn%t+fN3p!~O;@F6gvY3Ru_uT)8|+dV?Ka(887IHxBt8 zv4VTuP5T8{{tk?6w{rRSxF9K&Fke)X0e^bSAKejoK$ZZH;_GT}76IRHjYr}Z(QfS5 z(Y{n{u?Yn^6IqL-e;$K8{Q?}A3jBTB6EH9N3<}&(IhhqGW>3LtigY(S4pADHGo1UO zTE_&Iv+3r10jVqwim`jR*D9ugUFh*@>m zICV?e_*ZCTHFD1C8|>M$z?F^PbuNK|Y?)`#iTr_`&G^6=xG5w?@9LfSxI=v&(Y3f) z_&7iQZc@}1*1o|DhQs`7ah}bajVfh!G51BSwm*6l9(Wavny5tQ6O2>OF%73OnF#fp zG%*`p5sjD^fB!kC5~k2`V@)CD3CvY~=wH?Ep(Ov;BD8>iI;UN06UL7HQ;4Q-CMyow z9OViA3t30VyvmA634^HKU?D;5Fiq26ma;|&$fsROQq$@5N0RIjH?Hn_>-xw_H&;y*p5sVEVl z@2>dI+?dIB%<%F}9lI->+^#d!g^Lww_^b^LT@JK}??}#s$o3gmv%p4<2^X;i+4^eJ z3yi%0%RfIGMk2BJ=6_;+%m4EV?N;KZ|M9S?B)g{VCKxI9K8Y&{N)pv`_2kP zGENR}>c7!upwaHc!tt3?`tYfu1JupHN*0rD($`%w5!hk@5l$#RyRSu!U*&ksmqdco z03GGzkYp6F=J@Se>1yrYvKhOlRki&}9mu}F?0cZ4-m9W}fw}S?M?IxzO2^aFWB5GX zjQ2*=?6f#(*X9Y@cK+X;^|XptypOL#-W_?+$6*`EbRv{CN3z5d7FYN@v?;c5)n7u6MZ7 z@((9z$B%&zGZ7{fq2jWGn^r2so8eL4|4bS(&?!AV63^Zz;SMYWRFj-Ji}lC<(3VZ` zoyOjs+)^!kZzni`iNW)41=Ll~6lY@UuJq>K^(X zD|#jF_-i5k59^B5DJU71_!uJ@VHX`LcCl*?MY zC?RPs^QobcP>GqS)Qz{3)Va$@NovEKsr9f}Cks~{ZVUuV3y3&;=aiWdVoXwV8sZeo z%9kXNH^cdI?cO)a=IE?Ex*(|qV^H+8Cmmi|zIPtL%lxms`*O#A)p0!vluR5W2y{GE z2u7CC)N;PFA!rx33HnQS$fWl8QO;3rsBpYzYEit&(K|u|6IYT+Bk+XkELT;3{|+s+ zTo_jh&Y?h_kAlJs0eKm^O)Q%3SPHz^B62(lCOGM&WtVp;=&@D$|2wvdTqC4oPrLm| z4-2&#p7{s|h(ZjzlO+@M(jfCj8;>}s&H(@RZkb9#N&o0h1@RET+nKJrM~&K}r_zLk zt5}Du*KyqO%IUcQ-qKDH%faz|PI!R?9mA6u2*3|mEz{Rd19e@YJst-gCU@ykdNMMq zBW@#UuiqG9_bO3+Ubu0;cf_!UvFfYH`RkhjaiIESTxJTS+oBIj-kpa5#;{Kx>2){F zPT)YnH9v*hi+qKaSpUU3)WI8px zoZrYnqe%(hbSXIE#oTjw%Zi8l=heR(TXq$$+A0pu2mYl{>JF!uEfS*FA}HWc8@@&cgt1C{-e0IYIH;!`HAfTWDQ@aCpzmVW z!%d^c+wfV$XMMr84WU_2|nhej)B&-?3j zb*jX5FZ`cb0K6{Vw7}v<@~K1Pw^!pG@)yHK0h`$_XMfFmr;U;J;v$3y%6GPc=3KnM zcRBd(O<~~hT_zfdv#p4m=FJlPDqrKZzKU_l+X9V?@Ong~eHX9oq~4-(QlVx=P3oyz*Z ztX;52;Em~z#+s^of^`?eaYQR&B;P=;dm9TzDj6wztP{=K;g%^$ZlfAlW3Bx+_3h&;><9T7U8b!bbqhL9}<(qJm5qP z0oc~^&f-I(t*Dk^a~F5VQyPmc`j3DtK?sf<3g}YC+SN4(OJ@y z`J@&|Wvey7GmFF7&S;<4b5&_=ApWzdFXN7GvQn9Er?=<}5DH{TEcp>;3m>=2#-l(s zvu$?A)6a7O3N>(GpM}A%7u)Tld}PB9G>ol>(IT9G<`ca2q_d)i;+OA1KD%9m+ea!q zFV{I8L0^CA_AIcjywuD*fHX3^8#B9a;y3jCM!7K@m|b%!HbV6)oYDcC3k`5)>}+$O zZM@IY`yF3Jkh|I3otqozeCzoZ8|TtB^N6X(FIMzNEex!<`$ImNze|X#aqEB_S;kku zv+~&h$bA$Ez6@c!Szw*b%(cBRtD}73s`#a3h5URyn87UGcaO<+J~2VL%KKkNm4pu= zVw}v$Z8)sY z%}8TB0d@|SbRX{B4JY{EZp*3^IaZK&pmAeg#<6of5R| z;M;xQK0CLZHfPWPa@Fc}6Bu_V$4a(7B5I)@zj}Yv>E6nUU;lbJnvAKD-|DljXqZ%BpOc5m> z##P;-=F1Pb=)og({e+MCRV>;Cl#fM_b0@2~CMzFgUI=Bc=W&-aAJ`M;=Z)c`Vgs1Q z$8QXT{rA(Ku$$460z8po zTbC*+ntk~C?t}M>EInD1#BdxJlmKv+$JD}0w$PUt-;O~fdK(y@QC{F`=^05olK>tM%i`y zVe?cGRWCnEm}M_XYTm#X%3*rHD>KyUf9Ef>%vLY_m_6wszz)(Ax^VtU*#Vl^5Glip zbB;B+WbBDZVOAUc;DFP`g0f)i38I1*%R{39gYUzew~qt@$sT(XPVP8pjvD%RY-fG< zgB4bWms>n=K}R0Y=z8P~aJAKd(dx$a?>utq9hLEChncAe9A3PzkOb(X&fA-oU_j!% zUdEfok04njuh~hj?@vSkQbh09nXeNK45#@evGD>IfN}M9cQ*Q1&9qOcF&Z%*&pX&O zA|fZJ1PU-lDp4)Qf{&C1WGQ4ig-MM}fZWHS;QF7$50{n|Q8Pn#6~Xweg>RlMZs&;s zg^LyOLqqkC&Pd~bq`W=94X%G?pjF}lswabHZrwYP6R2aYj*?bhRW zO)Y()&Dl-uOiJL?8#1OG7%lTvTmK1KP1%*EDf&a*F}@m>9N= zZEf< zYq=G|`6LAlASOup@Sl%7r8edDbTPZ;{w*ieVUoCk4lNObU`?gUe-ByH&O$t!Cq(jU zU#4K!^s9p2;bEJ;6u_Y-eTsqpB;w+27{gTFI9O85$p#8ml@3Vp!h9L;h~3?ZLC~-9 z23*LF^;zmG6K}-c88yrX0j03GsXj)HhHwML#075D*$Lo-*`X>Qwz*$at=3rodn6k$ zvu-t*^41I9=T&LJblI><y%IW$-0 z_S>+cA|DS5q=J8RvM|61#Up;#B46@*+lclxa1v;Xl|Xc?4Zl-(y3V4V65V1IsmL_`mWUDHG{9tQVfI_46r9?DId+ZLtBF^e_8v^at7MD)E zLID4!Gy1PX4bp6!yV5!^K%aadLF_34!jVWEPh6aq5Q!;wxy8I&AV zbSsr(vdBmN?^l`a*IQ3|GvsV#2n#uybkOTcisqwhw#19yRcyNRFa?Z%BMD|2&Aphd zz0>DySUcu&g=Udl(fF$$BErw)+q-y?^9d+{U5&>0y6BU#1SL}8A$bNCnz1~AJWp;^ z4-QLgUoQ(#jI@6>qJUq4O(v$wlHMBXz#0y5ra^qblEpUs3$zM-m^Fs5&~!%&rMp;u zb0%2DM++Z*FWcEC$|A#-vZ{h^@p#2tL1Y#cbd@-~eSWmP6bDUrFHZAHl5mGr&6s2+ z5LVbdO+153Gm&|s

OaJ@4XAbnBXXv`>^c`vJAKLBFAuYUiVTp7K3cs|s6>2+M*X1M>u6)2+ z;5UpImj2}bhWmN1SFf=DH{5p?Yf}G57g;b1WCO)Q>~gv~W_t!y2&|Nn5#woldynze_;ToWV?f45Sl%x3My( zb`Mhk#Ifb%*w6ww^Jr%AP@)CQAJ!b`GJvF1k~jo#+C^RYL9Ti@o?mam@795Xb$#2} z@AR;SJ5v=u{BvGKEegYNCcdEgwc-o2M?P_phgk3K#X`~?){5F3Z3^4Pq@N|GbmbF882ufWkQ4=7l=DfdBxG2r@DEdIZxrKv3i>k z11jdd-+|gzU_zQ)!OKsV-*fMOw7I?c$I|?>_U~{oT7u#2JLD1srV{U>$qdD`Wmg#T ziB~ZMRwCkht^{XyXfu;C9QZESL5FO@yI%b>8JpvV4}IT=?`7`1e2h0gkaRwhDe}5C zknK1~SM9N(r9%kTcgQHo?<37djS)~sCl)|5ogFDaKOR4genj7B!ELB^c!lCB;j@T} zN%-n#!baJ@XD9Qs4t_aDf9~|FO1-{xfK#JR*eEpREqh3j1YCLf&l@=v+?(r{&jZ@+ zb`xam79wdyH^~BJ_mqcuHz8;jzODKEELzGZ7z5twbsrFq43}@Fzs`Ry{2|uwEYjr zWSDU(J7V`yejlH=n33e4_t68}$~Xfxydk^*&-~|g$wU`BEO5lQQYV+c2~gJ`D$Dm? zk6lEeVDdr(t>}M2aGSG}VN3LrN8M(dZIu_@6@lk>DMIM-ewGa@v|8}+46rjmsVl6&`+aoID`wr+V= z=-LSFVFFPYCsJ36&f~tOFroKrYu>A3Mk?(#xj&g!5dV7jXn!J8@Kowc!0LV9Xbb1% zRvGR4XNFv?_yDpAY5@zve)o?cYIFL41+%er8M(ld0Q6SBi?(6W`MLQJ7ebEbDp=bg zY+y33-5)Y7_WqK)50n4yeR8L!UUQTMd|=DZl30}}RgW-jJM z>a*x-gUthT5vR7i8)AVl$((1{K9-H7O@g|xZrfkb^`}7B^_D==LL!{OH0}HIb)BFE z4zoM`kZ@+BLe2WDE1#??U%74mO+%Uba%lJq;$zNB>e}c^XQDK9%H+M_C9SQizbYQL^X(mOeAVn1u?JB)BMg$o617DQv+{#i zF5%H9EIL}6e`A#wX=J%Cq0%AXBxiNx{7ar_`J*x|iH#e7TpOz{v$nSAWX|Imb0N7f93S= z=PY{Dn*c<_lTJ_!Pw*f6R~7E%om`+SWt~60r2bEsl;P^9I27t`z~yQwJk>vZj1p|} zbB7Tay76ORDZ)6@Tq}(u1 zjYvvuoOf7FtgODaq(8_<{n@>z4z~eZF~|?5$}tM5Q|DNjLB?OS@L^&M8IWjP+A_MA z{Cbf`Rh%Ze_2wh1%9fI%I}u%nSLk4x*SN})gf~_L#Z~CtD_TxYuj~I_y*J3u3G1zk z{4x=l+}V>TUr81e`lKFi-YWceQs%Vmc=dq<_}f}<#w|~zDo89w-*X(-<&kgyd2Oh<@3Tr)-MH1!XTh2`QL zX_I5a;jKVO*=hLuj=PL>o@=8Mx4NILr@NSMR$kPg*IPsr)XG1>P#5CW5hnzczi_;c z{?=&+<~L!Lu`wMBjJj-VT>Ev%bz<+>X*f=Bc7T;cy??0ae8I6bKA40%G)Ru_q26e8 zW6K&Ak*FKg0#@`ysjzln_wvj1;cREjn`Z6er(Zc7Uqt#SPD_Dx{k!^EAzbE5fP~Y3_4j18lhmZ*<=R-_ zUYzg5@|rZz*G}To9H!+qxnnQf@+$Tj7BRs?mXi+#4IC1#DZtfAfT*%46Vt>H3Aemcj}pwK~%~*OMz}9;}kC@JFpyRz&@Tt27yyyAX?29ZsJ61AD0?~AN8E_d}f6EMdzOj)ajcnWeyH6N)MZVslt8ceZXQ+>5&%+eDI$&ir3?EP&S zRZ(s5DBm&DWcJ2;H;7^-m+0LoX5MR`PZStg7&Nx-Dy3Lpo3X{cy2s_vg5>T%C)vjy zT{rfpyzsJ;bgb|#TMldzR=8;Nt<5Vqn**21b6q~PH+$I)-=I`JA~j6 z+$BJ83GNkrLOq(&1Wz8Fr;sr4dK z@1t|^A;`(n|B#!KE`AnW6mV>w=hK3>-T#JDnH89{Em2^0Dhf~3Mz7Wves5S#o!dy? zPx3~H9X$fL(=NHN9v!3YemT$2Hzj=O=`_Xl3xaBo$bkg z)b%LEU3&_J+RExBz~RlvsEi1smBU# zqsWoT&N7XvMAb-&Y3M)jt>ssK#m@m42K`3#^^`dEH}G0=;&5cSVU~T6hvrhb&_pWo z#XE0^!Xc?NJ!J#LU$JGz7;LtO$RbLheTBcjz@s1;hm#KH(P;{8t%VM z=F$}entunO8?qr$d=FzK*t1|~qz?hTsJIgVXRSBEH=O0yfwkOvur!{B1&ysdsCNO} zvylv7y9OY^=vSnzvn3Te#dNReSh>~1JS`RBTb_10YpLdcTq`vgJcg!!nlqGfJ>1d} zk(pi&Wyaw)$_;roj^8Tug~k8f6O7V<6fiO4-{!7f<>Gq=Ej>K=0dQDrAL=(vPJ|*P zvIclu`f4`F4Es@tosm{G#MI*W!R|mYS!1zDGbrTZhlD4i#|_hdQ!*t?)(buw$J{Tf_BWF5=4rK*)mr_)N^)uKwP zzkZcX+lcCr_TfGZG9TwJ$~wt(t@*jNo2go51MpbFm3$Rq(|(jEx6Ot%8DldwuM6LQb>F)K%RlFfuCNyNgpv>q)??+1?orkQ{)ESU z&K!o%$>}$E$dY2f&YEiX4)^%?%+c_!qT`;V+~k2{U~;-Z`#V5f)>8Qb@*f6$;QN1- z<8%geE6enH!>7`GE`|^P!>4yh79DC54=yGI8oWj;OZ-Qe#0MSkW0F4FR|eJZrsiY! z-5hD#%2tWN+?SLSldh2O4r6ljR$~mKCLrwvV`>Z{_I@8$&8}_sEhdeBTfNgABjUC{ zTnj$#_%kpJ5O?rmeOm}lphjTAgX)^6k%AAts<{5wKI9srs_%o2`|S{4`xoX+@u=2! zQ9c6Nj1ac;4=xOO%yd(7ZM68d;hx|T7Gxxob*AI*TH?60EEvQA1gxdKV6&vhqFP zzu%3fyUxeYd3M7~YOSbNvv;)aM576A#_jwnP-q_VGmAT2u1Y|2-4tjnM2W-2`4`rw z8`hQ2m;o)E>|uE68~E@Va*aV!*P0q#an1~=JVr?7A|ERivZaT6_~jktntF#RH<5>Z zRbm4otxKRJ5`Qb83T&w@Azz+v{>;u%QK%TjdHE(3VkpQ9No{Qd*$**rV zN|)`_Q^il5Y;Gtfw?yXZ**JG0K&)-nwCYU(Gr0Gp^%QeV{vc8`WV_Y@{dr_$eK_ID z)cIwGYHAG!IyR5md&;Wp*QLc^9d&^4G zJ=KE%uy)HngkJXRT6*^jDKkP3inu{npUjZ3h#K-Am||d!a7)j0j5Sk9zYYaKnfFv< z^Bs5{6S7R>snTsLyAt-A&^W<0(FdJvZ7P%c{3mbzGiihj?&nCEKZ`G?D_vlbYW8i# zxvJWfqqTna_|$h@$0V?_I4mobLtOVkzklww$JW4xj8f18iZ`o}z2xJ|D&j+vzTXi} zx$z6ZR&|)?z{y96H&PeMA@AN3`~}|0`>hkY7X-rA&LsC{xz8-H`ZOdh)$RT}tNwub z_M6B90r{!$(T6@WJpDu$?W+>|U=ZZgJZArM{6cXJ5!{d&j^m!dNIf>>5MB?3Y?A9O z9B)XNCt8SMwEKoH`|kl7bQW0AYA2 zKO;$^;Kyu08~)9zdC?U1$Q*Os6Ct-y<4@}_NU>9E8Nc)*U-_h?KkVT|R&Luqa2rFrUP59+zd>)2 zQ{N%~EBb_43?O?*#n?y*4d8m_;D8f3@l4Fs0q9<=e~96VoaNh%DSW@cD=;5^1Eh7e z2WE2a12;CF=9O1|18BD>1$W)#MOKxOV0+5&FtZp4&WK*awCql)Q6Pgr5GpbbdvpJQ z$wMjzK3TK>wuHU@WjJ*oy2^OZwnU4o8GVHqH}OgVwselW=w~Y7+xwH_pRwhYttvfk zf`xD*>{bo9*;2mGsK*Jf-;&G4yGpn{REMdYu#o6;dwyh+UZ^7sF1Du z=L4E!uK&bEPUl+Mr|I=_uH_&;fcO6yBk3?opGAF0d+ZuksW|Vjqw*swI!@$aj)CT0 z=?`09eLOc6n?lROyS9=d*2&w^$-{PEvt~G^!~}{rB)kHVqee7J?fd`-?)c=@6>&%< z{1M^Z+`J)NuAgW92Rb~~d!EA0-K80LqE`^F~M-ih-wxL6+&H#Af9zm3>n>UH&> zKOkcfVx>t-0ML-?0w7c6vBNY8H=wB|gk#D@*mm4J7EV)GK@OT*z)l;f@*g3?m`D4o}ksI zo)G{{z=kY03gna~!VZ)S1sNfNza;d zd^FX#XDT3#cfl1e~!e8+}W;IqmntwM| z66(soCVXPbXaIp?qF#cfKiz$YxG$8d1%*SiqLphEdEf-gX~F0v%f0_ zw+gS16bremaqsd)^$-uNDNWX>SOHpd&E;xPbISf+y7L#Q*_t~-MFww{zsLxa$7!xSo{ObZb!@5otfoBYx@$^IC2Th_z9 zVLKV2C~DDPx!z;wQNC-pgkSRjXK!*(!HDoXyFezM3yYw9EpYp6O#{?Iw;QPbK^}v2qz$v;VzZ zN3S7GXdKS{Nc`e90Ig?|P#?pUEZeIav}r!GzBCzJ!V;>Qv3$R;=etXX-L*jRL91;K ziWUZ7)$_bdtkIS7lQlC}Fsb1vso8(+9_}?<;I65E$hxC{{rJ5~yt^QkyW6xJL?JFp zX+mS6`5nq~!gyT9&5#V=t;s#yU%OQ_RHzR^lpB#%9;S#diE8^u+qxch6BuKSn_Ag6 zd$@49E7FKP`GW%4=y%|qLUA$`2q{=I6Em9{?})W8)TB|LlGp>IMsjIh&=IaOm_(oa zdPG!y6N>NJQBDMD{;I5tO1H|O)WMiyO#JUY0pE90pOCC!0O7PLOnM>FovgCltu|Gg zYB9f7YspqPs{>{`mCG|Kno~KxE|u9|XbXo7BW|F&)DVl0_>Ka~J5LnFh9D!2>>61K zc9;wI-Wo8hf4ZD_FdvvrX;A$o%n~8a-4-#!2*l=Jiuj3}trDSSNZg8beMJRVJ=*oH znR9*yIes$BBTpn$FRrLb?=;$^>3p-27X_?o(z(3+u0V@7$0b?j4u7)v0nhN$zV@8U z<6&^_NC{B0u?d0U&I{yHs-c#QZ7XJ@eX|5!s5u2N}lCwe5jOu>ei^C> zeh14X!I^f4+6}QKl3zSo2uz_K);e4x?nKIbyS=z35u>D2CQB@g+Ey>=>PNG}{E zEEw$1{X_|ih#`an&t6*+Tcu^15e1jqrp#48k^)j=kYlfp1N$O-8XnW^YvN5Hp~I?a zvS2e~cE9`6sYCDgXq4Q#`tt^!&(#!r6$nxi=@h@D*negKZ=8XK%j`Izoc<_jT}*l` z5iJfZ6DgREjz$AQa{7e$li+)FSL`w&m9{%y(TFgW{de+%C)Pas`n>~KQw=dY7W?c| z$bMzb%s!?4!u`;DInO*wT|ZZPeQf=`QP)er1pL0aRTB<+oOuzwqp+8M{S zn%j(DI(CJec7Fg7LpTZ(igIjls!52?vi4m*Ug~w_>rx%ii^Wg-7K@dI&`HVTOB8#e zR%xgcfTaw)R$&Ey+8p52ToSlpt_xo<)%iKNNUs=ru5<5$-E_u&-_8r`9n25xkOKf9!SPIw-Sn0a`2f%-M7V&0{GQpUX7D!%L(2wyv^y6zC>vMuyRo zUMB9V^hImo*@D6=?|Ai;t1xpkMJN0tWGu*(1-uO!DD=6z4G_JlO0-$Iu}1c>{R@$oqJGPiq*aLNaL`I}knX&1gEFRj&9OBM#B@d$dW&Ga zt3wc)gDBqfjw1J=(gfIs$9|pFViX(|=nOlxRT_2ZLTyB=*o3Y3@n75FFjIT5hs2|^ zLF6hEu+!}(Agd9AEmG%h2xU9+at4B`HQ50~ximS_@bG7J+kUq2s6T$$nADWC#W*~Y zTwi@ktY5a9=)I!z;3yiAXA_V`_VV#O%3M>_#P7ia7cQez1!CJo2SZXQmh1WEQW=K3 zl3r!}Ji7~I>I>$9G$2DO_!i zwyHT5IsD?qNxDFXgM5=eExbeoTddHRl3{8Bg=!>;x+Il4>G3l--P|sK8(|Fr{=3i^ ze1nQze`xH}oU`ZqX9-FS#0O<<1NN1W;fwaxZCX2FYk%IMl8-+}9BwP;SAv+9RrQW^ zUy&Lv^|#(TxR|k_P!Kuha)zb=Vg5ll$5p# zZQYjNc~%~!vq=7Y5iEl7$kjWZ%jOwvS7VqkT$%G=e2lPp(?osg?Y@BFya+1YIem^L zqmO`1aj!y8nE>QgICAmR{Uy%f4I_C|R~fx3>Me6j)FQ_G3!wry-GhH=Ec0K=y=L0RCWR+LyJh$VfKx(iA~o_HJu2c#Q-NO^3IQwz z|B5qcDqcFYNaV-5r0rr1HnA(eyNLq7EjN=w(X48Lm{Vb)$5%XkE^0D()i8bZz8|$~ z*-(vWi-7wpo2QmcRnPMeMyvaQ?6Emsj9!d_f}f5zqGjrx~istI_xO!ZxhDBqt#)UXx} zKNpYxaKJBay6bLF4G+4B2=iTETSmb5S3>u{oJcG-j`kS83_V7vRHV(H6| zRhj`<3&j~-1E*MRo#)6-x^>t|Lr3L0Q0Sxq;a@q+%=n|uBW+L|Q^(jw0#m@XSp0*& zdDw%r#%y!-!ItegMM9ut)LA(PXII`kvJTBc%K?&q=IjdZXPMqRwNn`<4D2)6Z3gn1 z?nS8ipl+2&wB!((xb{`&-pX~8e@PCGjY#EVEEKpnb+0S964Cmhdx-T>K9 zGu{tHKM@2_(k)Q7#j)Yx9n8&a{4HZKx#pB|oG3c}B%hjwzF%~98I^ls9R~KgiyXksH;zTa&YRi-~ zfL6or#KG^)D!ysH)c)O=C%LDSU3$)W(A*;iFMj^bTk6tA z`}8i_&3B+6jMh}iW@Op z613dwX-2BJ1eEoK9L@-miB3PWZybImCSSK+X%hO3w#U}cPnxb}m6m8O@|=wHdzLWm zY)tG*0+=9k9!HZUy%HwB_i9cR!sjr-(jZOjvtGtV5y)|B72WxXUyDJ%Pc#Z_Oc6AJ zzvjnJrk(Nri_3ksdi;m%inT$7lBHOKrK#i3y2uAD1fQB;1k|}*0gcnF3l|!X7T>K` z82srjp0%SKwuF6&T}X|8iY<@MN-111hir)61a80EW~EJJ2hBpd2$4b#wsD}0*T@?h z0o++vc5y#2s3u&%F=?}y2T!pvCqB^CCQKj>Yf~mhrz9mH5*PL~Q-%d|>zB#?lfVrL*=EK8+iiT{z5292+~( zgU;Ec6Rx=F@?_O4T!5T<^G9QKOLE|y<#OZqveH)&^vB%Ry@*1?SeFPedy< zB3_b4e%(G(G_yz%3w`!lIy+f858^b%Kw}-8z=GKlm=>zyUql=;ht3my3HU(KoYP?}NjxWx4hBlz~WGp}ttO`!^2i+#mT zd5stB`bv%3Z8x{m`9IJGbDe zJ)Qv_2#L)bsUTPi@#Dqkd7UAOp?7*B(N`Iwnak2vo}i4yLNP3_RTv?nxiKG{nA zK`5{Yv-oA@s)SddeFpJpeyOJ($XO3ZHrZ2eMc(_~6ZaB$nu#$*Uod3J{Rjg6oc!lh zV~iYw)7|!UVfeFis6l0fD1lswt-ekFW@3n6P z=u(^=#(tVidp*nB0PHm1&c0pxZBs3H@LA+Fh-&6%L)0p^siOcXAkH=Nr=lMH!p{UbqCHE;vtLTV2c>tf6^Ox~auDS56IKN4F;czbb9R3EI3L3%f&HU`- zw)yvJ9w!k#z=2ux@7Q3SKjZD5_1B(`^~D1i4o*R&JB|Qo$Zhg=P(X-2!6laebsYYv z)0+Am&kCf5;GrG9UzGK3F*h(4IFI*yf<1177zH2f+%!v)KH=$B4T5iJE~d|taJa+gnm~vn6{s7_bq#Ui0-2P&+X-0#}^L}r;AQ1 z`T5NpMS^m7u6+EvRZr64e`YW~Oe9?!c?=0AacFLh=ge>nABqC=!5?wX2}^|B#&5B2 zmV+{k?yA3h*Ch9~cIw&2#T`9u7J1S?xp^hp6x0(%*TKe-Q^3viA9`bv# zf3RUPXjPU&`zzV9fn}qjD2A>J2AtZ+Tc2?es$(?`z?$T($S%bE6IByU$bb4vyY2XG zp9K}RJ}N+GS;AN>-oMeJNWPf%QEs~j0ShC)S1kU!9W@GaqS&`2MDf$krS3{B4Vh(v zs!r_tlYl}!{JQY*a~w`%6Ib*8eLxlv~7OPX6kfi_1Of~z#Hm8FiQV^!i1876p`RT)DM_` z)6VgbGERgK;XWVZ6^)5(Q+{c8|Gn)CUYSHJZ+z10#P|WMf$pX6eav82U}K`P-rY7h z?y7&a(MnMv&WZ1=Et>B*PO>_7r+d^OXPxDI3u5(gLJ4%G8|zoeBJ}mh7ZY>Ku~1Q)>Lw~lW37SZ z#;M13(Jc8MpF76es3!+=Jg@*aG^!xKQUNkYC^j0rvJ`rDsU2!w>;EsDxjvC2V!hF2 zuf0sk*;n;K4{44fo1pPG&u2|0b2&)-6}coaa0b|f_Sk9f=k=N{@_Q+9PKRr-J#BPE zj*S)ceKZp=$42?v*d+!sw&VXh9d)_aIbHJgDmbLo@KPqDhkn*NgajH?R<|A{{N|hC zn&kRs|kx$;)Yv{keis0}?$0Zj9=UdN&kdZR*iE6^UOSrDQvFv1I zUeyDCY}K`UuX!z3PKYUBizt&;o>6I~|4(mrF8;5ct)njKbWdwR6!>p08oJ*b)P6m| zT*JW1x*mz)g#c#0)e5mpzN(A@wphcuj>}y#c`SHwA--Ub2D?~$tRwN%YeP9aG&KKI z*!gGU!jyO>7VLy0SLQU<5myndH-OK9GO&E&&s(le?V^C_9!}e1knZQV zT-g66dFTBWdbKjHNM-I@DO23!PDo zlpQ|<;}d$GubF6vNb6@xoM*5nS()(_m!YEACKHcJ4O$^SxNsj6Zy=!e*%X3Iv5uzQ z`4@n^MNL8FlntO?Z<5R+7dtAkK+}fsjXxsG&kK;gP}-0%^1XUch(zgP;_sVp;@N{r ziK?UPv*1wP97qU|h}v+sL!*hcq01>|Psb)w4h#}qm4j^u6oq}9B=d_eNxC4yy%I{YIt-sx=}SY>8eVIEy@z~C6KOZ<7} zAojIhr(#i>25S#T2#?J{&7(0&$uJ+SNXvb+S_js@VwaHx=K5lq&R~MM#zHJ2-ZhKE zbbIiv`gnPOjomZIF>$4$I_N|02%P=rUwwyyYqF>reJH8g+aXm+1L1ov=k4?mxe8?s znNy=C>yc+6!sZ+4eS_<|xamDD>?Mmuz0$`=fCp(|La*lxR9W;mpU_g}lFdmcI@W@`s zo`vPYJRM)>7nE&# zbIGKZ!F~1tf18H_DUF-*l==2qNE;Fo?6QLH+0+>%evN)C7ND|{@{dK$6i|+SmoWox z?_;Y6ZTl2l68daB%1_ob-GSr)BA4cI9AWwJy1)_q6Sha;oMhto?o{irA+aRwfw5|k z{s2q_e`dAbxz&}ym%F;1@G~Sd`%vn7>&Ux&?eXEc%-FkNj+s(8 zwxV)cArsMmp^IQh7Gxc#XirqrFcyjvb3}-&?!Zp{aRd#J%Tp?hT+?iDI^qS7hi;%a zD4l9@Q;z3JP)9f$5k#pFuG6JwIjH3F64t6xYMWk`je3D!;PP%DK5&)o<7q&X`HbWz zJX?dn8xNa&7raf}WlNy6mftKmLMB4w?fQvp=6>(XCGJD{PH{Qxvf(l5fcj288TC6# zU@M50-j?S;CdzSNmiPI6u|2%5`L7W>zKZrt_|17922X?1M-^hSWe4Hj-ucBQOzYW& zPpC9`ZP?oE-uWV!pV*kUa(?FAHFKF4f>FtFRLfjPNP!rtcGDh84L~!OW0<_VSmvAzM%9 z(@KE2u(nRy4q&vRty&mW6pqh+^JKBN}2N>Q8RCMQr7F8Rn;k-CHmwqBROmR+!)%biO*Kd78Wz zQ|1u+Lc$|%sw&OkJ;O7PPoai!@;6Q!=Rf-FZR89A!i?XoUd>36DT37xLC6ob-)T7B zT&!3mlWU)xK=Oe>jlCeexA$*cva)&-S5keDj}(vv9pO&L}1O8Y95+`PN{4ytAHU`6Ex`g1*&mxbC)-7$1Nn zMElfdiasTd*<|AJ1c3Yy6{GT1zv>^6y?$(Iq<>zEkE*%F7XI(E_KVIu8JV6)Db3(- z;#3hFS`sD_L_~!|MX?Xu&swnJ{m;!qwUXKkb!4LQIk4jTRZA^}7@e(jYh!$myAh!5 zx6VKC0@-#DIV~R#bUF&8C*Ifa&;wAZj46@wig+at0;P2C(zZ@suP z_j$YB`n0*s=L4swc07Y>TX@TwMX%rIx|0yLCBXRCeYV!$1nz%qG8h4Hp1lGUMm;RM zh`*?8TfS;orNwxdWg>%<;gQP>t_5>dbp&cCHVw%%3e!@iR9r#_9besoOfh`E*%Q`Hm+Q@73OrL%?RyDWMkRyG8|CIc*9LD`pIJ76$B%tg@)!6rR zD^>r5t*4&jj&(mhn1EP*V0j#STqkim(-gE$rORPeQS8$=*K9QKmaA^|5>C!uty9CL zruN51tJ+>TWUULgagi!Q(Zw(M1PA0(OyX1Z7kM#T= zr6BR2*j^F}j{313}n1_wI@B|^e6$hkjg*)rZN;A>{)32%o5mD{s|-jrm@-LXqdzI@3cC= ztr}pKz+Ih?Rr?lHT2p=BoaK~_+I`W~mbDv*NHn(oUf5ja54>>c9B3n5Mf6M|+BOC3Db`Jk7s%1apawcyIlLqRq0=a(~YgEAf)A;HQLdEv(H?uH0y4 ze{uf_;9ZL9YpSmLJu|WgLiG8z46?VWd^HD3r1d-0WPl;9tbS6bpxTDMBj)@ zz^K5zLKj>eMFux?fFSzp(kuWp%?YQco_HT7&H(cW~?dxzz;8`_I`tOKNTcSpDB&H2*0DSWM(@OSARX&2n>0S>I-`BrRRPB91BV+{7Dh#@Ou}Zwv0!<-{ z{;_rbnRL4~IFI2iC?aBmwrAvUZ@F+e{!JQ2%VbGyfwaNayQqqStR5IvhYJ}nzX??U zBLQN+ecsO;s*S&wKb4WA4I%kTkNpy&rs|G&6^L?h7L5OVQH3e|Y4z=jd%?20v8lT8 zkHTK%G|_M>)3e&ZAAU#~_k_gJM<@jQyIUbFaN%(SmwAIiD8a`bUk|=t=(`6P-UImw z)mOAtLoMTQK?h3xM=n~q_$wT&@1ep|i%A3_;?{?F`4&AW?x@o8oac_`6*;t`#9QH< z@eW(=RHTx75eUQ695M_UoSdxn@r!=+2Z44Y7h|3zxs0%(9Sw|`4!6HJ_fjR7 zVpG1we?In>7~y36Ujp6xKLYK%PZHf=jwYcr$ZU}q?+n@OI*NnWH;Bn2`aUQNee|ya zfMT4QB(O|q{R)4%0>TTJII>&NXL7x2@{RY7ra2Ej${gYiyGx*PupC|?B=#F;u=#^E zzs?8X@NzD{WdNYzeF=%OC=Lrz^>I1({V9+nrl$KKNrdK)5~cs`!OIwl3^kA~CMUV0 zW?3;keARLFO<+=$)3X(hw?o5#l@EAx}i}b9;pO7LbH{a!rI_Y3GQ46 zBBVfH5?6F0&RN2<9^&jHYK8Y|CQ0>6yR4%t)xn$mUOSP1oUK&Gsggdy;RqHp_yd~$ zlM4!I%BUXK>5fgt04i}8KK}H@fglG5d2_v#ywiX5=?tH3!j6ZDz$oxRKW3RG*@s2m z%JD!C#o!^aYCL`-WpZR%?(DYY%cnREV+Yqy;>1EY$iSaxR9|(-T)b$Zx#}qY-rs5! z*1muEN{^&VlT(J}abx|2{AK=;z+dbfYQVq)Dp{TGJbX*cxUF=$Trb#7sY~VQ48vLB z`ASM69YR=Se|Bju=umjcy3*`a&hs{l_b-}bZWN$WlkM~Vl@9MTd|}A1+gOJr)5BtK z#&J9Q!^&MA05n&1hvyK$1>#OMsJ~Tao>!(nC7XZ2nuBf@p2JVR?cXiu zAF>o!GK&GAzVtde3Qyzh0mE@N$2hO+}0%Yb;u%% zhxsQe^SNlkCz>FtLfp5+ZzfHUfaX^TB`p7W(V{u#0wiB*! z+`gaO+B4~txY&mqcnM|Ylm3<-R(_fnN&gk7efk^NUJ;#qGfzkbh!1Y5Trj^?Z5q6O zTmR9AA)sD>3-f8i&@V6D*SwVqTG8Q!8v%Qpw%Lnl(Q%kPM)YlsV?En=!?xV_-D3^{ zGn#)2GICU7%1AN2?J)LD6B|7unGPMprd%PP7k2+fbVo@ha~mX>)cEp((IDdmDkz(v z!3-J&K&fMu^TxN{lSR{CK6~rxW^%*|#FdWlXfK(H zj_r#uL%gTW-^LUy45%i;III@xiK$?XKr+Z*OyWOYf`NWf^X&%#+Vwa95IGJ_2c>-m zDcY!+RC|Z&{X5NT@jo;AVQ$C`YLk=(!7H3Mp7>%+?^|@m(cF}*jql8PQ{UGeW*$`p z_R7k)kObFtDw*Gu<7*+8m4`E%&Y#Pw~==`-Pj2OJDWEe zHyptbv9X~+_7A-lkuQ~*ui_1oYlmhKtnmqVv=dK%R8Jd0DL)gz?k3@jaIVE*bMK}pB!LR%(B$=F7K(K z(*2nv)j!^UNgpE1q#M6^bCebqha}G)F-MinFq}=GoUNR>HHh<2Wur#7YC@3KGHks% zG00lt_>b3D6P;fW0W+CQ3{Cyf^EYReKJd0;gZxtKx-l=3Y#9l2f~x_5u*V++c3)UMBd3 z57|lk;m5DC&e02m>L|v|>ywevbzx;#lomV%$Q0165?>_SI903`qRvj8q#LtMP1$|P z5Ha~7WgCFJcs~6+TC|U@s>!x1XWlEh_)B@uxE9w=(W&<0B&crfGq=&=v+bq~^fZ&W zlCu`D%a9Q!e)7>aGD>()o@VltQBo{EvqarjwOnuTIuPW03 z>_sVJlWQ}b!et(`-jXUQ_>Xq5NWBbecv4WF?7TGfNb?>V5RA}iEc-DRP2~}X}8CRM;nr^%)uT$bpN!2;m zi-srMUSyd8=s*=zW*rtKymtX= zUmzhOtB+BRo{Ah}45r4|-r~jy;K~xL>O-)dLp_GmLq0xj6V-lUrN^AXUF$2bHvseHfKF7Mev{&R0(nuA>4>;vZ zci3bVC575eS+YuBn@F`Uej;G!Zokj^b7RfB+}Z1@g;rU$?MQF^BotS;3IB}aN~2jC zY&+0@kaS$*R(?&g9I0BG(sToN7q2%?D8WP(gGDv145zLzqg?4R!yc2$@Hdh`1qpVB zP0fNCPwJJDiG)7#pyK4U($#%RH9x1nvOJ-SN}&w*?Gg(*6AYnKNa-?}D#cVwa#s~4 zyTNw1gF>`urfQh$-@%^jelS!eY)w~h&E5Lz-HN=6+4P{IylR{onfMqC`7>x1wYACu ziFhFbA~UAQsE{DzU{fyI;!&u4r9^&#UXJqh&(zzcVj|qD4nfr5X1{(S|7z%hvqLE^K32 z^71=AdBt=OcYCw4+lR3x0y24{R7**Uv2>b@;|wPeTrJBf&C>Fm!h z>FS4RVPE0WfT?i?5J<#Nj?aL1`P}*6J&~CyXTHHuV-RzlJiFRb4{25OwNL@onZ1-} zT2^61iU_f90}_qg(j#mu2WU3w7($;}Vk$>DMguAr67j9)@mP{%PfH2!BOV;>7%v00 zGMA7(RwWp1Vo9g?1?^?i3q{ggkn##$B+t$A=m%0jtZ#6jnQp5}>fULtmOIU=V>-{M z96=r|p1uaXd{KNm0l65!Ny$AR)Y3FA=2m!HKecfTs?1aFg9uU7V^DfOr;+ESnYQOZ zmSj?5dwg~n@qgRtY7WfNKCCx83eUWFb?UbaQhqKIIMCRRoNLb8EKv^-6v;WBSz8`| zr?IIRC{qlyF~q|PMA5oV^GO{D8u*!NbiqL2wf`p0NE^#A?wml}Z`L)jCK!NEXJ!qp zGx^i+QvcLk*W-V$dvOekOYglIL0g$dsm5@zW!=-YKX~xJ2eLoq1LC*VHF0g3 zLZ&Nb>0^TI0mmB4Z(X+3uS^0c1PT_QcXxM}4Fq?0cL?q-!CeEvU4pw`zH`n!b*t__n5wCF-s!cvpN@!w(u+jb z5BHA+0#i`ew!hZmLoLViFlZ=bG5Ob(6JO?QvfZ-bxZ$$cHjPq3F(6GnXftUxAXjxz zR0+5XCPAede@u2-}W4j}*$(!64o#LPb-Ygam0}ZlJR+&c; zg~C{0V5ZoJB%TzJk%@3f8I#!ZYzqvy6Yag}L)ZPbff3jj_eq!XJ9!+*^DUXEerGE0 zpoeJ3om<|-5t$Gxv2ek<$fPN<33#0MN5%9IOgou;a-8-VB! zE9?tB5AXK&*wt6GmPDvU;FK;T0H0tfzFFmc*g@+SRNiz^RGV&?P*^=)?ycY13AVKe z=wZ)!2YW)y4{TA+9Dc>9kUk_3ODM;5DrD;*V-VtxL}4RZE9X5>>>RwX_paPjXPl(B zwDq+A!3f|~p2QFJBj93%PM==RQwX(_ZN7;p?vUw{vFzH05e(aN!vAr0CC*)P+2R$& zVFNWH8@efpB zCJi`j9uecGabs-wyTrK6H01&*nU2LhWB%pDqXAw(qcW?0)!KW_S5P zqzRFQ>PiPCYu5pTcX*x6y)0K$#60ZBB#J;c%Z5L^1IwQ0{of+GV!v;v*}t3|3?xt9 zs$jJGpX*o+7KJT|bj2V|qLyIHFmS^Vm zXm?Ek%(MueT@)`-wvwNg5(vW78grSQx7xAnlC?MK*00QZ=C zZc}ajeAzhK6@9?ghuIXl?rAr9aDvSIjs$cfJ(0kGHQljk%`6G6nv_;vOZB@$<-Hrw zOC{|0I&HX}RQCe`&!p78nVBWjK*<@LOD`wvXRd;1<7@w1oC`L21L7Vq0VXw;gKb5o zFOWvxe}gtts)F~BvP@D0DBP$M^~b~-X^>boe{bKuTkz%6v#;R*srUPizC3J1$N)+b3J zML5n?ua6iVeLPLQ$3L^V4t?ES&DG+KKw`;K1%cE3zdtuz24MD!oo4_j7)!F}%qT;@ zj80V`LtOfW(A1XXjPo|J=PDn6^k4qQx;~N=iof&@)4*YqZEBCl1QVHs!HZ!7$upo} z#Hq{`jf*vdU={;a6!}avESgmo;yI(aNfDnEPwKC`A2po>ks_7)E!VHC=q>>uCNOl( zLjI>FA|-h>YDRI`u7vmr{J{lSX)F{~?D4otR7h&8pfLm7QlmYcPpo{mp-S!A*7eFy zu{H8yOC*75NB^Xx!TYf=ThG_eC@2JN_ouYVBx=J6o&5R@kLpD8lFAsJv4d)m5afMl zpOhC98gCbEw};=pD0ImLo3cwF#Dr>PdDBfKEV#5~{V;>@O*dB!L808=T3+``z7JV; zU{O5)m>?bT?Y&^EiNAKNV3L>TM)Yj!+T%$Kzkc|zRpS z!q*BPo=`_-cIg;oMHHa60=ZXzVsosHrUo=5>}+r;LPu*m(wiClh=`^y<#$?YuYmss z7m0#+-MveaIp7)b2dR4iZo$5zEp6q_>2K>RvwO+9_4)aPZNKtI>=HZ-_-t9t0S=&u zDP~5MO+c+BlK~(v%$gM^+AHJ#Un?qlCqoMVFULr2$z}#5{eRB#G7u(nEMZ^ZOL&Js zfYZa#875qf-#`qMxGOo`KLpikU8erkbVF=#`GZ!acQfHz-x(PeGpeA~^Y6qaC)Jd$ zu9=5dI$a=u!0DGFs#87=xA{_PX9Wv5_93^4uUBn87z@|*v^?T%wb#LAV1{m#;o7zu zQRhS3wu)zNp#e6XydK<&wb}p;bH^PmY7T)iAq)TY~Kh8suaBLEk3 z6)D8F07uGHEQRuq9K6MF>PD3K1bvIoM2kx|nbML6*IgfV_0`zf`h1 z5g`bonkp0Ch%KMr6n>*JTh{UPV@uWnn9eC!GE>=8%y;0#6vPs8C@j zN*j>@^0!rfWPK$1jMp#AAnx4cE-N9LXWdnwvXqA{F^w-g8-HM-4X~g_wALEpiQtF^ zF%bu*a8#32GB&=1JaLZUr;^(=bD~Z7XjF1`7P7-9(ddV0s)J|aQuRBrm4g7qVg~?j;_t_0K~q?VrH1Uv^0=mPfE{3sF@js|4Zxt{Erbg#UIDG*L7FUS4zj!rE{7M1*iUl@ER4;mRxt|t zeg76cIT?7I=rzTClj?jDq$l(2I;%c`RLvd$Vl^Ulcf z9Gh6KhDJ;NDD3^UW~qh@tZ}qfx7OednV!hf(IO7EO`8HGy626XfK^ro@}E>@Cx! zkh+TZN}JMWxS*|r{uoDHumX|D5`??s>m%LYSF{gTJg1mjfhzlU4F6_D=np4pw{34r zR>g1u<<9%WG^!5O1~Oqtv2Xqj1+Hcf7 zFSXzf1q61l=&*s~+^>C{R%{;16?W!-dq=026jsT$#i!oj>6>?ZmDg!T&FE;J+{eOo zC4tmEXt+)4hSl5&*OK+4^yl>N?=T_ZAK)OMZ@kYJKtm|XDm^eCZiTcx z2^LtvxI~O7cFkTY?-X=_Lb($s`mOv#w6%d(3YKpZ9>uj&&C$JzyUcon5&)Xbh6tnr z6S9QxJYP|*>7q%r4(XL%R}TW0Ti2!9)XzC8lvZ#{NUGTVBg#>?$LI(i!$>W=hd2G< zg;pJUmyb$D%&Rx>W)`?{{_w^qJ2+fZe*(n{ChWz%?r@`C=|%|!luFhhy<@N$AxEuv z6qlWgkqGhsEePq(WD2@AwRhGcYaK3Y{i8xvwpK}S3id%4f^P;IAs-I^a)t8Zl;NB0 zcB{PaS*9=VgNXz7ZD%~3Fy7_HXS64j0SPT<-&1myB&(e=T}%_YC^2?hysAW`2ut#w z9CrupbkjDG`Jw3$x+00XUK*t}s9BO&g_LN!3{!$X&0jlnDH_I4nJesdKV+C}_1(VvYm-ZS}iuF)?g`JWT4`akz}S>!@l+xnM`ZtVDf?``caE7X~eO5K_gY;cCE z=juykx46|`I(BuB+>glffsD~_4ft9<^yb&2A}Qo}sc3YEMeJKjnbmrO<{+WStn6$t zeAAE;T}Ex%wQptu2Mv2DpZmQ9P)fQzLDf$vA6)j$J5mG?=sKL2e(GD-gw|Qedd=G? zEdE@<@WM4xdk`IR0=C;G|GLzqH4@qHzVQdgr_vy&pZ6x!)&hvoP1H|4%hYO~w9vjw zrh++>DJl&ln|JxMQEZX|FPi1Qe!5Yxx0L*&U>v=ILJc=PH zc`(mqeN}6R+U9rz1*}R#=e3Y<@T%QjSJe~57gDE?1ju=PZFReASCrzoPRiGpQe$OQluQu?;bU>ZS|uc&&R*3koj zcvM*9T22TBPk8SaDw}U&P=4DFoaocWlYYn<%er~_h!T=^5T41n-SW_@(jh#-?8Q67 zn(mfF0ZDKo7@lymMp9R>|Kuvw*rLf2jr0%s_h0P_vyE?5{oKnM05|!L9fG35 zEbhc8bUXzVSUDidEJ(N#%Kw_|O0l-?kRFe9dikDRZBpysxca(#QVfEBT>BSNNW*Ym z$0G&PQxL9;(@M3ha+TU?I!0sT2b^)Fh;MAr7U>kWv9GUZ>FPW1!-i}Cz)i%+Hy9RG z`yb<{y3Up{y9|y8B2jVDbm0^qMQ}E`1>`R*CKCeRMJQ(G$^9pv);qt{TxiYkRXeM~ zNG_K67GUp?!%|6o;w>+;ZkTZ;cNZns3`e=?Aq1eh=iQ(=;X+>LPqbj4nM2Vr{2zKW z=rfGkj>adU8*N``i5upTQ{KRmr(+>QOEF<=K5T>coWf@@?!&a*9Guq##Op@~<0mO1 z(V8kxkNwH+hQN?6>{UF6)IhCwy%oXc`3YAGP;!m;1~(5zPMdZ{TJGC_1u<^8na~Bl zjGsv}dkf0Dld;)aR{uK~b9EA;E%byeJxHwWDP8Vkt$mcrKXr1j*VwTn$jJY9UZJI{YFqT~HeW+#_Jh_< zt8~_iJq93STc+PafvxhKiv%+_iiVAd=QB;g5dcw=USo(&e4r7-u85R3X>8%YJpIanFTQJTj**7TM zfVu~K;#>Vae+X{`BQe=GvCb3UD*iJFx^ zoJ?Z1m_EUoIGh(61pHPq${v{iP={#$LaVS)cevnN-ShKiRYZ&0vNP)^cad76bn+|( zBK-ZgM_nN4w{ER@81KcGyqMOw&pI{w6sSJFSnXJDpc+12P~WJGY-k3~9h&0+U_N{f z9a3LSjMeIiO65ulb683hrv8QiJ%lk_qiIu;0doFDheED;ypiMK&Eh0X7=KFN@EkuN z*0qYOxFqZv!(Blw6T7%wyeC~E1#4oD_23r6Us^=uB~w?wnT0C6fRJ?USP*m9X_h@g zBG^YvBfE*E<h?fEFMbx<2#`)l}_ z2)0ydl_PfI1+oy_#IQ?iLBK7;zq#fRump@VhvNSVj1M3 z6#R_oh4C%U|Aty6n{RwK>EGfO^t_J))rPAGhJqu-2xiE$9>FBb)@aDu@KaX%qrpGL zNB1f_ee-78E!fd(!dy2l+u)__UTmu=FZ3Ksf{)RTR^N?NJbcLs-jEYF$g;hp{0LwC z>une3w!73a$e+h?52~G>y~hx+MNEVr z0XBKZ4QFwFkDb_Y&v7p{?Za_=pJt~oW4}-K?aRqJZR$W!bdm9mo%N&w%6r=No%L_l zIwgVUyQ5H)2&^JpHGxSl+xl-Ceg23QX`>UKJ)7Z22lIq zrg#!FV>^7Kr{S-fMt_p8$l}@S7Qa;8Ys*3@tXT0*atgY4XS!dN96xZbAC5^Zi&-0hxJRfCS|;vWX3qi z6CXt3A-f5C6zT;#Ubw=@kgr_8@P$2@LZoxcK?^`DQ|pSuGIK7F|7j5|L$-<+$kg~v zef{OfzqRFvfD0FJl;n;;={3JMS>s=6CVibKlxnO43R6Gy-P60X1x;SR!wS?DB^M9F zhD*6XXqOc$v|pkpl{&@BWS1Oq5a{wrqW5>vPOSb(6-y)lgYac;}eYg&ajXT z@Mxoxk-txM;H|wmRaQtMZ=z!2pRhTiQ}#|V_9r0Od^*3g zAUDlWi6MG2i=x#?Nrr6h^{g`!}{B^CKpDj>;` z%zfI&3%_a?<=Zz>Vx$Ofy{N3otN#%Fj|oia&vBFLl5rL9>x@?q6lEWTfEgC*+fv@V zqm)&&*!jvEdY=@Wa&|m#chadtZ5AiIw`0KJrII%R{RGX8iG*slX)?IbzL~QO75p~j zKDl?aTSk(LUK5r z)q~2;-U{$+Iu&{Ekm&SqyJ3flkgFJB@^F*_#FhfHIO*GFm1C?uON8tya;}t%ow#8$ znp;tVb*PIeSd6{tF_!={Wf{pRcN)1IL+FUg4kk|N#xlUDj;I>7fMp04B+B0?)saz$ ztc9Qje-gK{&8w*aTl}@U02Am30sHnf$mNbVo+i3yonLZbck{eP*_L^dYT;RU#u!zi zuyj=5fsZ#6cw{_{`x<9e{vHB#IE%0-Ctgh z3+jLDEqxNbKifWMeGN(HP+9-R@~uvBE!^k*dmuX?C*blUh$qIN2kH?g5~HL_tAMjU zE~Fv#q+$h0ODgivQ!UJalsh@7P4y6cSi!fB?7AMcfGj;3j6I2vXSI!ldUojANr_*N zLa+2LlcVuVTpFXx_LoUv6HRj3B-_{1>?9eEJlYEIrpVTv(*N>JTcVek zXGcwH&9>cv!+hy2Dm7VZa?s$_fsznLFahZ69tflxUOzN%WLa= z`M3M}63l6hOh72(%8C-QJU?rFEmh(axn-UmH&O1NkI%+O!Ye1em7LEE5bm7>II%Da zuwS2SBGGo0M!j|Y8*l7h;-83|p{yD6mDNnHXUZ(&GF$h@q$!>;?{0YlUWSIfLSrfQ z`u$RS%t+%)pcFvtk~KKvIUwMu2U;XjgN@jaj(LEb=rBcRn!mNn#s6~Mg+4AWa%W7G z>J!(-e$$rv{LWNw79*9=6VtHRMes!};dJJsK>Mi4ta=FQD-B)keN6TPIZOnaAb!wg z2G(DCuJBuwCltvR!Tr%lgRhr7nI=p9UT@!&R{(@sf}_)UKSC>*T#m z4Ah(x1+Ztx35fQ429luMKym}&O^qkU>K>0!Xp8QCTqnp$yXHYM+fe_>E-*h>ecZn3 z(5?Zdup1y!yl^x}4C&4tzs*gJZ&sY&`F8I+_%G$VN7fo-kz}@xlpvJicRxiFOr36Z zCZs)H+e>j>>WF;-Szn7WxPy zV6bpyMRr0I3pC>Q>9KoZ{BZ?SD!ZSXLr+tJwneX3-yl(v?K-BdJ1l=xU;7^MJU2*N zuk%?CD)=wYhx$F8f>)n^AeOe!I)P}9i^ef7{KjgGfw^N2 zF@PGNOw^RH&gsscC&2~di4;H1f} zhJuK9%X3bK!~qG(rxUS8CO_sQ=t*f^^VNR~08rU)O`WU*91Zg9Q${L?qfJi(!B>Q?0y zx6=JHYy#6nX{Y3uARnjS6-O@2(k01}EXdeD_0^I1BPU-tZ#VeyeZWv~bu~ zN>ISkkYU@)lYA$KtDh{C!6c*aFYyR@tk?*|_0a10B+N$M!!Cbke={wr*sNQ_DAITUGq zTp?B%o5xp9!t7B|b;>6wChMW@Xkbtzo)!?AMiz6BLjI!ZepfE{ux?XQPgzrG-d?iu zMk5pVOGvn~RG+JnJm!w?#2Fm4?<2O1s%&cK&Dry#$C&gzE`L%^i&aSRoQBTwl<{W+ z$9$DUe`7?dhvZ4zNwiiG2hy@4TO>LyWUwnn6&}qK3&(lx?+d}QSU*&~@O6#ev?bY< zE0hxQAPAchE!$a2^Xv$l2?tuDT>^1^b%|BX{Wd(2%r@k68WNuD+w32 zevKDM;+^A4F3_ie46ZsfV>pO$t7e#DJU41e=g5Lh2Qr-k&Fc)2SfUYIste6Nc(^z? z3B{L7Tfy#L@kie};b)xJ4I|x~d^H_Fi@A=UH^({9b!8i-+QJe#qa;yg{z?o)O6`T- zVryO7zY?gbJpYQ8>FqjXL4XDtG%(BzK1(>%4GK!@#Y3}pPI7T5?S;PcQO!w!W6?CR z*?z$Ux0oLO2>7oqsc+mv?KYz$D=OqmfEyBD$0PDTBexOrh%vaSZ@nuGa|$>!xhQv= z;zV@rmlOD7sAjjWtV^{WAs@Xf5tOl>?pfOc-bSmC)g8(95`vvv?I81}`5mmQ{>e|X#+v>P+d!LXS3E%4dR5&PJ? zPPNITl(ab?K&(}i^fSGRKtoryH#qHzg3jf24p&4Ej!nHy`YlJ&Dx7nzQrxZH!J@wv zwC7kKbkpgOsIg^xD(LZh>!GRv8vk3+a-C21Fw^6=;}uaPKNP2Y=f21y-hcZ&owiz{ zteqec(G*LReCqh9HYXI}4tITO^czQ-W(150k=*uR*WoaMp<{8i0iY!BUP+RsKWsTI zfvHJDr=9B+$L1rXjcxZZ%~~xb_@&R6+l8ZR@jmRRRN=OnrxnD?*_6O=^hAUVxYi3J zoMnE~IC4Sd7JM9Vxjp)K&y64N((*Qw`tc8=tILEgxmQMLR;Hj-c347oIW`<)oeg?!;tGU1N`I~Nqhj)WSAB4WscxIgeZdPf6{(_af zNzo$I6)lY}TsU^NSjCv78pO5~*hS)V4(66nyE_=KogP;~H!= zR#oH#LV>wmg@63=HA5}V4;6xis9yg(3WWPgFneT}Eh~Ar`(@IzgDZ&f#bAoPq+#iS zVP0vZB7p%gFvnS_WfH-$gn2)rU9b!p0nj zj4l3JFT^eU?Vsl=jX8rN`VX32d}~c4H72AE@($N+N&UF%bUBQd+(Sb|9sbxvXRHR8 zl$bt|ds*=pCpM~n1++yMaHE0|Aj`rNbVEPm+EYCdc=irP$32>3g8{iHfqNsop(N%@ zS2dQnIe_GTBK@APK675s3^@a~6=qiqy}+Saf>-XmQFo@*k&iE2cn=CNq;dP9`NOnN zx+F>ta%|+NDc;1Bf{;3#a+;DH#?1=~rkLx4&%DxJDEO(GScZr9wslrigHYc`4+4_P2F2w!m)WdtOUVzshpmM~-^Yv#L;`ukBbv6f0QQTKM-9 zM#R&aF)6U0z$~Sk?;0`4TB;Qey!RivE*j+PF5Dh{FW!zX0>1Oh z)oan;PcVmqp<1B|>Bb+3X(?u+ym_{3{7JPO6{mxw5nr^6DNt}^J3Yv(5XLNhtX+J?n!C0fdV!McDX51CP z{XFgQ7`AvHzMkpcIy#(LJ#*n8KC*qzqkmte_VgOjqzXt2%ulln(6SWmnO*X%p9m;8 zYfRokgZ8&3NT(#?f(q`VxF><>9yO2;|K*CMnx(l212Q&cK~~&uwEvj@zbt^4>cW$W zDl!L+wz^>{!oJIsR=e#XJs2-3ot785QTr8Q9s4@eW!j}i#7IDJTQv7~JTG#pe+)r4 z1RYFvQiXLuF_=*6LuTDs-+6P2IPG7BKk0umvg=$oj`HXvXn{cxx9DaMKRY2i1z7Gu zU$$J=ld7+DO`q}vWH6>Y#4j9!qVm57uSjk~OrsPglp8xsqA@a4?&k&d&na3@{i zT1cZT=5w{5QmLP5n*mX^17-ijjC!bFGj;}oH&QB^UbK$+{UiJd$g%2NuH@MQ33Pl* zDVRHObTv(uWE{R#ey|p#U0|RRP92;VkCenT7_3^p&WCLt$Bw(!@adD{NALYk@hfq3 zd1rv1Q@q%|9O7gIGeR*A(6Ehec8HqAHK5$IgTB1xUSY;t3rW2ykvbtI@)1O1)>KEF zxwwIGi1IDmF|&=5N6$q=Y>DrVrEKAnSnMnT3Az4ZAQbp7O47R;K-@1g*!!EWg4j#H7UO`u~Eq-x(xe5!t^katf5Ezzps zR3Wj{IXX)5NB(KV4MvYx^;LX~z;hYZ$iL{8e|D)~D10*Uat_nx+1|y@aD6QI9dkZd zTbgTH|KhXJPAr;%3&UytOCM#vAx+QUapnL>{*@Tdme~wcaSD|)yFstZ0j7T<$-5lKaFI^1 z@rq1pA~J3HRg;D{bI`k)(W&5C;1khfI(9F!-#GZ)=dJOVbJ4{D{*5Fp03i zA=^G}r_pgnh%4UzZZUpGG^9RCitVZ0zQkLKV`F|z_TeL{%%2^-&2?c!*?!zD4=VT` zG~BxDnQAtCKUq}G_wK{H(fc>jZKB$3(2Xw4hgWGCXc&86P-y`AhFSv?9&pMLP2|u7 zD;tW}>c6Pmd7AL%Yg{?76`EeX z5!88URJpo|tylbD025}M`)HW`>03~BZJhQgvSLBqOOEum$hAG7M}`C1KbA3iVxj71 z3Wu9-3J#~rBL+i&D}(@ms)8b;ZfJ6ZpT|P<;6h#}6}YSp zzOqEhUMpp7+-hi6Av6^3@KvqM7oAQ>E)Yr*CwY44o{xDBsxAnq*IiUrk(#EAViuMXFQmx9Hc%TIc<0;KRfdG~_aet0u6@<*DY0`RO ziI1li8ySI&^^CuW<|CV!=>Y^p~Wp$6B4)RkvHiBHPI`ZY#uu3Fhy(jF)G$ z?vK@A*jaEM2R6C zz15k;D2H>2F_5T17bu@^|eMG;L1TBDB$PQ{*5*3fLk{Kcg^p)rt|<`SWZ&2G_v;lKL8S;{B_ z+y27O1pxeKOQ^)FsSb#y?DTJv6Q-4>owDZSH3mIc4X$DhZC)yyqsw@-cG&tLp0Wn; zBqmCeBk(kZZ$S*kNpc%`KEv$`7#BGiBQxvKMK-pU8ho^Q19-;_2)ezN=+CG!+s8fr zQ(0q&%1GHMQNqS;aB~u1&pDdIR}A0UXA-%#YFA%;=o)*XGjFiSwVQ1CE_(@FFmGYc zsuG(LbdILVlE@b_T|nfRUC}hCU-LA}Z&%1+qA!7i*=efR}m(;|MpYOJyVE989ty*o-w zi9O(!gRgnvr_aOR;U#=9agWA|H8~EZutUS7#tD%aJ*e&BvSvCzay7zS;It;|UT#6aE_HVQ__ z2eEQ~x&){gYk=&|Y~vta^4i@1VO^30;n3q6^VUXFf^T|SNvlf71$UTIFidom!6W4C zCJLU7h80TEcn-=4cS_77*cy|XCebgE-`DaDO#*+bc`k^s%I;Li>Ir6FcOXro+V~Ha zHd#rNio$hx%FAVA1$t|K{Is^+>)&c)L^!CAkZQUEHaG_CP?q=DfHef^up6}6Lud_# zZj69RoH>*C;e>nIAln{AEMvG+rTEzzP2*r?D1K4vl0ahqTXAipU}~v1GvLvpeH{~> z{7+;+b(7A*+L_`ucU@#W4PG*$ndJ1i>az$aShU0ayC!9a6fL?OyGGzda=EjZizML+ ze<>@@DKEXGd$`wl@JG+cd>XEeb>}RaO+bt$J`R57Cr)T(+%5zY7Or7t z3OJxhUD++A>S8o6dRXz;SOAC%f3gq2BHn5wkQp>rT2`TVXdYKmk4iA99)0`&&bfxE<@uW=c?%?KbP+CqYCF`N$FVu9w4OSw|c&_e6A$e zq}-l^1JPyO7=(JSb5+T*KLYlCBs}ijRP|4y0}L(joB;w?Ea-D;x={@93^BS`R(fP( zsmLY8nCfaarAi{&pKVys-h6KlkD)Izi5~Lp$Xm|5w!Y52OR9{}$zJ>^w%3zUkS`FI zx}k|_6K@$@ro%|Se*9dwL?^A49r88?E|6|riJG)_=6G3y(#;4r(0!UgdUWh(G4dA; zb9)MZUNF0|!U!Q;y#v4D)^F*#*Dp2cA=B4>C)|7W`kB`8;pqM{1Zd8{lMI`7E2noG zYE-oJvww?%v)G$irSbV+u{j>lE@<#SVl(dl7n|Ay;o?y5B;QE|B;(^1aYEEL#A%L% zJRf|}{(uT2OZ(b)N$E(9;mctndoNH4LWQ0jL$8Zd6#UVNx8*~|7g`F>d<8E2ac~bX zO;Ld(#I2HsvEmsxC}=1o2@>Nes?5Nwz{Gfen1)r6$HmrX?R;Z=BFxH~6w zZ84oE@5;0Eo3EFSxESWU>+=5dPyKPJa<!4 znQi$cvrJu#@50*3jrc3#`c|~D#$J~!z*}nWS}1poUSd2A10f}%R|8sZF}lG~@tb&# zccA|}lpynj+k{mN>`E;-CuC&u9{-tAG69ZQLCZKH9YGHm@r|DQletFiuZcbe&EZtd zAGj{$p}tsG8r|e~T4keFn8?lTnOB{4yxsY5q2&Z>iblVjJ5Y%lzmwH zZHePfGLQY7ZQ5iE7DxG;ER6CXBdcB+yNyS5m~F$!pY_y$_{|4!_OpRr=h|AP`W*$i zqXO!DAYTj{u|J6Tpa7Rx^Pd$J@b{JvkULDj3^Wu86jG$|%H%%lRR8nX`Xmc(Yx$1* zmI4c-JqR%EaVEBGoidi<;J5>7!e0d7Pq&V{eFj-h4%vc;O zhz^lAmfouKSy2z>_MED+riqq9vh4kw;c_?aASf?K#w*iGnyPAg&hIt9^+b+3OIG(x z5NA#3umZ&N z^)RzMEbV8NS?GU^8%LDl_LXMD(RgA{e)P!;en6(uJZPDz)tEIQdeOR23RFp7IA)Ol zW}=|Zr#?(Ms_}LyJm0}|RS@o-HtcoIrO`^rEtA#FZMy$5@uPbA1@3T!ZPs#-F+yHA@;HzAO1J2&AI=#kH&x;PR^brVwqdJ5(+|* z2p&o>5L;daTMG6Xf@7)UxHKyzy+Y>rp~j8arC`i14g#DStX1I$89ep*jy|8=ds!}& z;c4ST?3640uvSH;g;6e|U$D-zl+gE=j`O+`^sUB)ZeE;MEgPL@Ync{ZB<5sV_%=lt z$W&W%^TZvk2nSN(nKF84fT|jJHvfA%;+{e@yP5B$C#jtq|1%5Y+}7Uyx~8gU#ToL9 z9FZL!8{bZ<_zdl*`fEe>RZb+5i6r(lX)QtRPz7lv!ph zm8)(j$R!#A4ZB!c0h0oin0#Hv(lE=!RN$Oz*Ez(-`G%4>Lb%XXQAw$tO9Khb@t)Rz zgDf)zO>!2E`3E?_yO<2gKkvZELldc2K+SDRz4dg^*Q^Jx9TGY%lI9%&u{01+Wm`;j zq`8+A(}IH>C?l4bOpck+7a$H|tn{TPSa)eWU>ebEKVPAnbEJkt05>Zgt4K9Y7Sny$ z81(-5O4naByG~jAy6BETU$hE~c9OYs);z|QjT8RnMU~B_k_K<6Le;OXq(sz+ObU!9 zHV^9zs(a%5z`S&&8tVOCI>Z4PSHN@flYz=d0EJ8-s#ji|?$XL5XZ{^Wcf*=gh4K%J zAEZF~rf?2JC^jO1?@Gw)_w`N{f`)2zCTAs~#X9MxulAiTs)exHI2|ID^(*skxo?F~ zkBA6ta)v8_ofR4GpGc}~{gg8Ze_f#s5HWe;yK#*uC`4VGgH7H5UFBH0Mn@FdTvf%u{KbjZBj4Xd=5tW-jT!QN~z8Z zvAjGtH9v-Lxu7AufQ4~osa1#_)Nm2x6pO_&wOu0(2A3A+Bp0ku6rtYiq&IPcL5G*^ zjm9PF$p9$2Yr@QZLVwwckI``DM^St{Vjxp|@1O`UScI+#>Gjo(qU7 z8|UYm*N3v!JS3F^1is3i!DN;!=-XFrMn22r5YGp+TvyfYK+v?Ca!`7k43(fqw|8*h zi2+FqPB91%iFGmkJ_>tH_>C|LH_al@4CBV+rb{&u7t*}G`960tV z7mMM1%6?CZ&-)@+6VHpVp{3(b_)cHrzksXzq^PJ3fg&_C#m>bDAt~)Qtx$ra61@pj z*Y8>XNfhML6b9xoX^!zK4h6# z$eTZ**{ve_X0~bZ0YTuHC-5)*U|D#P@>d$E@skkxrNs%n*0uUQdfRM3Q4I37i%ruO z4~IctSi~cW4e!LLHrP-`r{xc@cTDE|v2SpJn%B^geykymm6WFA{Vw#+(UveRQsM$7 zFb(mSjD#u*j(ktUucPi+=bzDXcjtyxcVwLbda-Kr(BT_$ACs1WHJN!$KB>&ZG}63U z)-U2&e9bG${|E9w4ZoFLR@r$Ct3t1V8_S%BKA%H^2hzo_$^0yqXepM8B}RF4(#Cop z#DexI=IUzezTnr1*uj0qttN1CiqnZ;(H!3IA_C&|9`$~uc_2%gR^khN(tSw@+;fhr ztRt4|yV-hAJYusmW7gTR%_>%DY~oX>u$Ff$bG4GH5YY`^W*ro#uKuBEKh{Jy+v%O( zLoP^K`_?O%>fT7yEtJ4`fuwjT9I0QPA#QKgUVL;$>ZaO@sRZCNo2_DO(J!O8GJ>50 zkUWh?JtzMx>9^-(vn`tFB_L>#tXmo=i)7qVvLz1u3+I5;Bf$;1BBt{}V?sDX7(|AU zpGg-i{PVJWm`IKYUk%T&ML>umN@$+oAT7RmJaQU=83jeoW|I;eXZBfn0Lz`BTTm>K z=j80Mg|D!sPSPMeN+6UVs9jOq$|3<>>@t+n?k^E3UT`eUa956wwRLpiDI4DNPY6AE zYuWH#z8GGFMNl~O_e5ma7zjDux&`)|bw_Tw~KmL1XHY1@^U=C`9D)VR{&aTOm%2ndoxTU1nC zdd+kv^aXBkSLHY@T*)VgbjDCyU@yv+!`z59%79F{0dg3CplOsffmSTb15r%KgreL- z1`pZbj&GvS3<6eNNZWseFTkBF3pm49mA;TL#|BR%>nv4LhsYA&BdZ%Cip(Duv>Z+$ z_EV)E9loNgOJYSL5OefC8#?+a3>4VO2Ir;C8&JwCuct0+UFFdjh%H65VnlXa;%&+f zqfmc=rA80Hhm19}UCiz}@8yXAq|h%EFYsTfRCb_QyF#fEuzhgalLeLprT1EK@1NMj z=uu17vwPVV0YNBL)~ZYv5$MSPo=G`L9=pSO4&80j6MeRY$BYhL@Su!Avx6YU}$H|5TaRIYjp1iLRMRQw1C61PhZ z1VLwVkL8a2H=79P2n|{^qh60YP4t+7O^1 zDc>%{@Lj3OPosc;*-jtAf-gfYlUTv6{S|=w%ZRX?DyvUYkgU|)zgX19O25DmwF-4- zmP^AMEJ*CsckE>UgMc#CwtD?9Q|`r-Q_rfdv}IVfm=r)eg0<4fKFefim+DnuUFTE1 zc4(q+iigTrJdsmxUN|KHK>xU*uMUMB_~iLK&Y2&ld#0_u`%=Jj#^n$IqrKr`C=-X;-iXkkSyfAW;S{|mvgjna_sJwwEs++H}Y!~qvKV_U-$Mdz< zoA}~^NLHUL@nTEk_&$M^&Fth8)_07L2UCaWC(Etl{Erf0EinatMRir$D1GdMMsFe2 zC>)|lN1D8=h)ZODL+FzU{Fh}HOKNSF_wws2sV!qKG!$s)?1A_xdVSPVcA5?cwUkvO}ZKmi&V z?zNWY*W%9yp%A|pa=PnFO(;u_Jre*yqAkbHCzX5wmXJFquei`1OEDr)<(#nG3ATM^ z8B*QKtC2C+Ssp<>m8{`eR0Ty%9O6sx=WY7r_YhLY-72VJ!*3#)Ujz*(wvuh7(@>a% zc!3xabSP-4jr>93+d-g;po=u^r++0Z29k~#q4eaQu;Hh^ z0e_FN^)KK>+rOi|x-FBPV@k+x0e?ked?;C1`XEJ3K>!_X2CH33ii^>&ZlLK%*->oe zfl5Ps@m)!R`YwmON%`@Z#M$}LzrjMIpJ%Psx{-ccbv+;dyND5SOeX~49)dqrOv;V` z1l?$ZDAe-t(YWG5OSk_r1+GIu3qDN5?NF}3R>4sL_(}O^TWv-jVkA+N(-rK%xAzk^ zK5`Hvhz-`TRY1@yIaY8iCeT`iX_V_>#>1mF$dahB;Zs)Eu-cY&T*nHpZO{WiLDtxs z@K5>i**()NA&rJ*Z}WqY_q<{#-TTs_+IiU<;K6Ed7cHlh(UVs~XsG&8K>k!K?+68& zOUid>HT?!lq(DmqEcV@F#U8f1pUzpsre6bWx{ky++hs>9-|l<-e&)$fvXri$@!Ez( z(0k~huZM4dFk~#iTKRkD)3ih{F1w`)7CHhD%UB)daG=jJzcNTdZ6kAR{T1AA^7I1Y z-S-T1I@kkD7H@PksdO^HuPXdD6!>fIVCZ0D>l& z#Rc^(k>Obhkj#IdHn_)zCXQn{x*C5^zd+rgA5eQ5{x}d+=&|t=-@u}WrE~bpTHdnB zDqCptjNT=U98rGC6w+jQBCrCoxu5}O9=EC9f3&{7-PW*t19RqOfK8W^tivW@u;OV3 z(Ef?QOeErlCJTS}z>LEmJcQX^*r;0O4M@D>5=bZvG#Sof0V3=4=KsE%PF7s@LZ|1 z>Ma@^mO8+gFq0d@Gfs%fL2S6)kbw2{&%ftSHAw3q0I z$qXQ$_*0+{k3DPy$G!wB%hu3zouyW)jkP39yEW3qS-x4t`y(ozJ1@f^MtHkNb&r|h zzv`FjJpiHnleJn>)^6&{1bw`csCO=hCH?kXZoP%mz61m0Z}VmUT)46Bp#Ev0SB?NtCl%g+Eoii+S}q(w>VOsIQG|AyBw!aHd*^700NwHmvJ1e1%lFN+=(#1 zWz0qbbg1-4v0V5kJAL3DD4VgywpUno^}j*@UxzNmzF?5)mUpC+ML__9yj2)8JcO45 zf^=UiEi2N8SW5CIICS2NTaHe)U4I90E+uWd=dkcUcu<*T=PK<+1g-gz{Wdv1#8QG5 zt7<&o5*b;-1Yc80mTCmRSEVpki_8no&t6D>&<6H=9tXC=^ntb3x#>-osJj4yq04=# zpoqH#j(Vjb(f8>t6NnWUrq(a^ZNe`rg9Z+oAurx zAV@8wU8EA4$J9mW>zZeD>UJ8;Gv0{h$87A-pJEi#$F5-jep`MP0OcxLrk(WoNg`To z5W+egF1X>ypT?2$Rr|vZe#IIcNm-SVgZhbfd-Jh#@-CY_!M5c%*R9$5Z*ZJ{CCO{y zsT6J+dKibm$NrYf5!koZnzz3XLSIK(fE<;fouEXpD&U=z`4B)vTX1`i&L6Pc;N2|$ z*@v}H3coCuSgQ4%BxIf?zWSZd$;4J2WVu+xs>%DJ=Fl0ey9PdMgDhD}VU^O@ibc+f z50iEqeVcLthr<4Xs`MG~K-n!UXuL%rg9c;b7<1W8Hgxd2Zduj5@&e1se^R2GY^#~i zfb(!RUe50UnEeME?SBkkHPg1L^8%}Gr>!csQAg&Yc;_=UK-4g5CI^DVv>ZU>;4L;Z zbcDKHh;(?}sI{0)nQ?SueT*AZTjz5i1S- zz^d?lmu-SC_%ou>qd>ks*Xoj+EHx9Q1^QHq_gGpxe%S~B%`wLLVE}mgO5-ZxZK2Fo z4%J5obtSoK>UsNnAqIkYCi74|)ImJIjN;2;E}_n)c07HD4fNbgv|g)kXvN9%RaoOKnO;qUL%7$>Lc2h0(t@Z&V}ptZJjT6N3&nR8zYc>t!gilT>izgp^L z9OAZ^&jK+=2XkMsJVhI*Z}Mhij3=?g^5uK#oC?uTxH$LzF6p=DUYk81ikE<(MRIRx zpe&McOUafv@Ur886bXbyS16ENWxid)T1Nm$9FPO!AQ>dcjS@Lgm?cQY&YwM=?sKB0 zLoS@0;w#^GZ0OK;tb%0=)$CZ3+K2!zvwoE`i*hLsza%Lm)M^PsT25(WVaM}OUdmT? z6iI|ZmSI#Vg6M|kvaEnASsI4Yi6AWt7AM6ePrwWOljQJKRP4XcCMIXCdHn}0t)&^V zO464~iT;$M+6y$0O@;^vPB0~O3Jg+t0)ha}T*XriU<8EeG8%^;uCXEK&KGn^6@+!= zu0s_P(8iCdq+cnQ4#r8jP>#JePnLUiTK1xak z!M+-0BDo4jwk)JTixR&D8Yp$(6?`uowCP>{1WoveS_X}4{t!T9D_@Jfq{aUc51bEC z7QS3Cs+*J>ohqnuenbizOE{!^N<9*d4jIOAxhDn3qf3LcotE!`zr*`k&Q@m~+6KP% zTI#%pUJ!trGeD3p81l3Z1dZQhr}y50LN*2vwB4$^J_^2vLt3_`7TJMUoY1c7&kp)< z6}HkA5EOc_fS^qJsM*0kvvGEFn#tgNdb5xkW<3>Fd8zf}W`-BI{BLARtJS<)q% zp&8#2SmY_NP?JM_PZZPca|~ik&*1-Q*Qa47yAdTfS?g8+s_F~rzAFO%VWfC11x|e~ zZF_C}$=?G@8L+7o%g`1L1RY};)veaQ|0b(t$yL#sFqHZj!0u~(R0=MZJ%u0`SANvK zzT^&&l4@u)`CfcJKk-n@7Y}_L{1*Twx5k!jeK&IxI}pk*4l%Xjii^-Obm6-w2^ghb z#X9bXxl7SB-N+@4_$Gy{03BLtXyrjG9>1NXNne8>X{+4w9{`&!=R5;AL&_5Qoxaz` zdp-?)Q%t8@tZ^GaQ0fw{0jrg_c4tD-_bG%fF1D6gI^?^*$+yZlfL1RSGed{yYZcbf zc_l#3FA=dj#HB49Gw^YvGF2^rF43!HJ)=Lg>HdGPN&0&xRcH0`MYHVvr0>K+N#MTV zeHE;XI2Ik$LW0O3z=4Rv>@N8C)_3R;tTk8JvaZXqe0w!Cuc4~iwjRhG;3dh9U*pF< zWs~@FlEdRwov#K+;XPvOy&cL}tR*zDsJ)}0C01e?|A_;5IsLdzPYts{-a1QHcL7x5 z8wg4;ymKH(wUfs#51PxBI9xEp(Q17P zS5Y4H?(j-$hSyE%BXE( z9^zdge`8p=p6vM%cw52RyDqh4Gh?9K9gLBP>hBeQr^oH0vR{TFZl3s8Ebw;GjcK?% zM!Tr7bf|?SPsE2Jp4(wbzdg6xZ=uvL0YMApSQLM0pe&McOUafv@N(e5oB)BK5IK{~ z&m03_VcX&=6rj{5q*=bQ#_@u*H^-T000>c>ARGsIL=nqa?MUUaG-lt0y$E@C0>s>d zL+8BJu6rv=%GE^fLSL#6!fBAgU74CwSjfkNEIJ$r3Ib~oWmGVSY@MZXBEFVnRm7=; z`Gl4ONIK%HxvW!)WA|D4#EtkX8n!eRNlj}}sIg24)-6~&5LF^|8Kr{-Y8=X6L`k7k z{)(cnq&P+ffC@{JBveZY2trl~pr(jvz#I@167g4gi5``pyhs5hwocr>PeJD{NAv8Rd&Tyux11C>fEY8 zic8=LOIE~xfpqwc$nXBDO|eT(wxJEftv{xO3slVW3r_sJEcp5zc*~F14`LKYyz>Lz zDq!grfFQSVu&gWdy3e6_;=g`fe%^ym;=g4(@272Y62B#z-;DBpJ#jkWPw@Q_13_AI zBjrz=OxrOmR=#DYcijR2Hf#+oTdcPGKa%H06zXRKLBWp5fgosbAc(qX({q800SG#7 zb_gJ7@F|;2H`)qz_Og1$4@;L87o>=*KZX7nKs)86Wos2E*(m%K>d!HgRjY_GqES)V z1<=OswGp;M&)`fu#rEylE$?F9cm>S>uhppu4<>K1-n}q7a)niG_+5t71wb#V zTYzufkC!^Q+R_zZKuQ!|LBuH)=vmWmroV5!hd#khQh+MOjQ}w3ffdSYrCJ~?rxLq} zT4w2MInmGfqD`hz?yU^~igsYBP6_a(h%+u9`))!co4NwEN71Fu`J>;WKYauJ7iaG0 zeayio^}>{vdI|{Y#hRz*Gc4P{dM|r{HEe%B)xH3F>xo6JXcy;;>Z57Ns~{jqbWB*O z|GPHQ`&FBr?&ndKUGA>NH_NY(cenRzVJ_Zw-mGfK2mpaa+9|I%ghkTHf5e|m4@+}f z*ohG(zKS_A(Z;+g=gYIS9rKdXlO|-w?}CH+yue~A;$xNNQiuKuOQd~P%WhUxYoS}d zjnbVq3qYcZCb4Wu6dz(Is{d_;u_NGmjn=sOby!usk>^z8MFv9aYG-0h6bUDHGc->{!G1^c2f?%R5oHT z$^3PsJQ!lZBB_@-;eM=La8^Cq!)|7+)+C^fT?k76x=Fpm)WMQ+F|AotyPe7ARQXSH zPh%C(kiL+g0zRyQZpsN`SNv3Z)kJ~2A_*|acf3n!zUQ_Q$OE;?awj|7j9#>Q6jFzV z)n^Y6%E;43>2YJ}ZXlzGdLuinIA&pl;JZgy(pSF?yqc(;`%W9m$CaSiQ zei><-yj%&a`XVYtMZ$IPF(M!+1SdgClO43YzVa8?U#6nbDzT&pLRK}u&?JV$!4s=O zLGcc^5zc&>7x8e~TAm(6#zp@G8%0Nrz6heXglGdgB&>pyxfL;5{j{i4wo1Hep zQjiqRvMaiOgRiOUopnl@bb(N{uOTZ`3t1mXFhuf~EUvmr?TCwU9ugzRy;&5dEY1Wf z@cl45@r3ms#G+yR5teC?4~|@0H@*Ww{grU4*_%#n@75!}1B|}-)8?g9HoNCWo1D4N zQnigJm!BZ_S8=Gs#Rj!M^^o=wFV*l0(B>`(!<^Vc&F_o%0)lh_5ad@mxBy_Mcxo2i z)MLra`c+8nMY;JjzBQi2@oC1^Yyk*ryn*Mk2$}~3DSLd!JOc>IecJ|}zR70tr}0O! z$?CLpsmxAXSdYX-Icc6sXIL01A1OL0JX#tiOBx4)QYXxg00a#@X%p;1*0%0?R^+{t z$ekPu4+7~z|5mjFNE2Wd^#!$?SRh6OuyB3}fl~EFlni!x8bA1#R)g}Iti1%Ey8?E$ zvq2Nq3>n&odI$&-2&t-N?SKvM{B103*djXFZOgVP{;SDrp+L}alk1 zm9mEW9rD_W>Z7`8Hc|Va&caUh%K)-s+2(xZ8U4n=Ep6vCd7qs){Bf&F=jabO<38{G zo>v|pOj5?(uMW}FPvj)Kl-!5a%`H~Uoo4Lgv#ISu3hbaBjex*)?)$}=NP+@mr~(kh zW_xY=$j$h;|2oTaQ1Z|FJs5HkF=QXa^Ac8B0Og}SpT!yrqN^{l+HHZ35=)nS!4E)? z&%dgVnuqyv&LRj0@`aweunznu%b-+i8Bu!G)fj$!m`JOAsL%{x8zh#QisoBFp34+| zoKgVgGXvkDe0;Oy2CXi;8mpzBr3~^&v;bgEP!=F(5k(R*RCcJNa#?7Q6&zL}%1BF) zb5Ggyfxo~%Q?E6zxE6f#Du`mKRI;6TwLa}70qLeESX$Tnzj2;C2pGN5s#gJsHe3N6 z?KT6FqvdS!`6Wx#1m^;B0(>P{!)?Ie4YYFjG)QN5AcE<_`-q;YZaxP2)r(7Ubm&rt z5|XdLMBPidvP~ifg48I4C|^H~^Rpwo`);xR{;%@5V6`C`D@m*I<`X?F^v==5W~Dp@`4 zb(asb02b(7r=VF;BZs={h9CMvA_rkY{Xx-q1P`#lN@@vk;RiN(>~6ldJZ)KCPU&T@ zVfpvf^uO0K=hYZ)ych>`d1WQf=5DD3;EAP~mY=ew(Podce0$=X0K&XcI(fG&e>(u( zW-LybwW)%GV)7I%izZp&MLgl;WftOwnb$_*fHyq6^>_ZLO)}3;uxvNQhnqTf7R|B) zpDe*jfUij{@1E;1oStK0NxwbE8ti$Jy95L+l7UMDWs!_qO12;l=#?}-1fk^FcS8&p z9HPi`!pi)_=hAsxMJf`%mg8Hx<0jD5Cn!{bE2^H9u<%?0m$;WhW=!zBX0k>MJ7s}!11Rv zXIY%Mr9!#Sa(ljlpPf6|<)@CV&;NizQU0l$=7Te1K$TNaP8{-F z3Kch`sB4Z85Ty3NIE3BUj zhcrNq9TZHjKUO?Rl(@K` z@>l;l$PqZTiA}_CKwK&Q!DY-Lup{x58QW_^J3od6(E!eHyRBJEuo4$TU#oZZJj?N7 zhvV+ohg1QSRZWO0{`kpJfFP9WJ>RmLEKA&~yRjnq_fWP0zNzo24gsi}1A+jn4671f z%Ben1ySpxmuNfP=3;$(*LBGa6CwY-IZuubb*3k;BUf)#cFmxKtJEwW}gdN}i*MJGb zR>ktj_O5Ffvll@umNU$kNq_<;6nX`wrnTH>7Dv>FZnD{d+bmnvXqof=3(au>trA%b z6&YhVz8^dOd3H9W57fTeYPP(W+G@+}CU{Q0Ky9?Oxbk+36ULcusV+Zl#Z#8+xzol@ zf6J;XW~@5f#!hwDGd=-xifv)6XT?O)qD;FY$T@y@*YGn83%od26`k`Y4BZ;|7-!DW~pjG3iUnN z(&(<{u|T#Pmr`%XHQ<3e&gI$z?d1=AH%)jQ2jYc5zjh!f-0)>&ZZ)H^6$Kut%g|B6 zYnkO;mfUUmgE)}yzuPLSs_;+rcFW3ICcDw!7s=u{OK#Q5j4pt>Oft)S!2C!aMdq@x zD9?I+Q}hT~l8I!E$1vJ;1#Nz<`yxOGwbuNmUtJPJn_@eSo<{G47)auMsd5$HBY6t` zsL>Tq2N?jgX;-$SmUqblGWRX!f_p46f-~xh6_#F2J2qYl!&kG+jp52sL!YVSw=ji& zGCp{yWqc<%8)OXbwuvLR;XjKH4b`<)-}S3lqg_jkR+hQJCW>+EE7~4LF?Iy#t6rgw zA~l>vH2QmvyNnmT!!_>pT>SK)3lD*3;oM_zI`@!sC5UrBbN@^>O0N*w<4jD>)Grk1 zFKQ+I4g8DC6#e2~#B0tx%oP)*kMGa@>b?%83z4HA%FtLDvi!s@8#uiOUrWa8jO{2A}{Q&iQ6>(OC0z_&8aDc6%lkVpvOEF;;y0TU6BnpKuiL|cB zp)4sZMI^b3^f=eY+#zc2=mR!Be#(}2V@1&ZOGMnrmhmE*1r4!uq7I^4afcBI<$hpL z{6UIh1zLs7DSJd$new$$#++VX<1;uj)~C;69(5o)go6Hv9skkiSWcMVbPVdMgHgba9geH&SKWP;TG75F#ddgyn4SW|F zs+O-`IAddvoY_a7IKRfyAlG*vOZrfL>fdb1b=vxRB`RhO77l@Y?P{b@5edje|01Y* zqKru+68h%gN!$S3SD%tn>%t}NH*voW?foRmpsXU;+2?{^=K1TXFG9WNkAPpKeF){0 ze9Mpqp>+1d9X5ILMysiW3i4IyI?!%t1tUNTrbP)@% z0{Vy~%PGZ;$>!8U%x7KrSMPX)>IO=TECvW+X@@!)=$4K+T@vLDt1l}&2B34NRTYP< zx{W1mtA7K>(H$uFp-6AzxO~cya*~u{lY0p3moEeE?Xjx*l_>Rp0G;P?Fe?BkXh)+Y z)@!o7k_uMLb05V@4rvk~6q*}EVaC7y_pmzT4jbHeyCvD?y=m2Uv#x)|)6Jxnb`R*` z^DXHe2$QR1fDWFdWED5lhbA>c-2ejeE2VMqPxo`uqbKU#8|0*E8t}(ubm7%MK(xM z{HdGrQUx@A9e4;zp?L1Q;N=F`k&Ugq)3?|NmI`g1@3B<<4H%WI#qglP(})YcqZ2@q zrA`Cre1nhfx7rvEwhP(S)^WjmsoWKopKh^Cr9kIEzsmLgq2);UrkUx%N7YYW9C5T#|3h__l^ni^#`S(_v zdD2G5rmVT`?Uq>n2HNy|<{x;Ah zCjkg6`G6y!XU4&^@b8`G~sHPq6i_s5cLLrW-DQp?igk1ovXCFCt_px|?-b3{4t9-@Dj`IzCQaZ9gZ zxw-Ni*{r?3+Kj*a#Fz=qigv97ht8oS?N$;yk7idJ9+ z2#<*$_oaW9_0o+c4!p!Tuml9XNDZN?Z*p6uQLgz@vBlVM!y>i6MEtj zyzYjVrK;#J%X6l#&mvTn)uA8iuGh5$wU`h3(iwmtiE;vhf+D0iCB6;{K1m~(JYOKl zc`o6Be6{7dQ=+9VF@6330a;3ad_NL0N(hFo=FMW;z>)~<*fD$ZPU|21hTmVg@s}VQ zWum-RnMX1Z@vtP2(k4M!wUF>5!BZl4_@2ol1QhwnNnv3l+@e(E3vH6G)`?-j1b~ZE zKeUPdAF!Qx7d`~uk2H8OscXD{q!3zNK0}H0uXt3;uVWwx2bU^M{m!dLUHy5~9z5cP ztXXDI80c|{CY}@1wO^F`;z8@(`FB=dxZkSNHI)A`OxR!VK+puOn00_oONPitER74& z@(%J1j5uhv|C2T~^aMHx{XNrcnYMSEt-P8zwdA5N_z2;m&4qgbLHf$dro_rmK|oLu zdZaC!y4^+wK7+C~0?+ELspAHexDUg}m5$Ab3{}f5t<;GWTrw7rG;GsHZ(;@3m#7bd zX2a!X2z{2?OfPH}uHZpS$;7a*DX|3U@P$0dGKvtyO~44z>^GoGJXc#wiIDKhcIqSh z{|Cl3Y#ok|i+cGmNxzG_WwB6Ff10+6S$IkwML-Q@T?=cH9znkxjNi4z5~i*9j4Op6;+ zF;MUXP7onD+SLLQSx^B2s%%0TzgbB;4iL1@26te2GJC`-+qRi?{T52rD*CfWbE>_a zLn_i~%wye=d%{Ma{vrU+<5^Jv?^1XL1o5NB^X;jd{4Dq~< zuk_bZJfH&AjKLOCE-)~sNW;axk?0b+dID=C%q#L7qQFFP&)K>>D5%aUfM$86W<*u{)xQ9N0;=0lcgcoPOs zD{|H8RCBYpcUJkbbjFtYuOg-~sKSF`#w;%n^Ad_#w+2 zW;*Ic-zYt0<4=5+C1rc47q&Q^AM(CpRb8Z{uY!PhpI4{x`bCXHUJDJPpI%L_Becfj zHV!{?EIqAAF0+Pi=HtvobbNss8mVf7KK2B-*-rP|hvnlS8!E20mD@go61^E70~9!; z;ei7|8Z`o|7|%|s-cI2SC9=a(y72x@XaH(%Q$%kt`bYv_OI|_V+xQ*w;i>#nyu0LU zPH8me9Ds(O1kX3hqD=Zg5b3F;<8G+~;Nf4gp`-U%CE$Nm!zN2?{%wZq7Ek}<{v@7b zaC-ZZNJWM>p*R|9C)#yr7SRkMz^hD$)DCgU3iW$AFvk}ca*2-*&qpId|C9}tRaOda z(K2_zji{2)HVbH~{T)~<49NAM4WDB7$_YO1U>RG}`DO^ajE6OrCp(QiXCYZ>2Q_^( z0H#sPLd6L_4t>vNPJG$MCVSZ>Y@OAvyb>1Q02v)lir$=lBHDD$|5?VRKvem{(tAO0 zdY1OjSf3S#591H;q-E-wd5>|HVuw z)Kh7(FsCvD0EZwWf^<0Fb2{O%gyV4Pmz?^SCoG#1SZ`Q)0A=N28{&)f@X&y*TmN(6 zi!xu?eMc^DHZo8i`lHJ5N9vvGsi1nfXu{(H+q$H)@`u7VNGwP)2yO{|QO~0!k37s0 zh%aDCgP_`cEsmS7CSf=E00wCXBk>ZEPGFN16;&hVY4A-Dk)iVREIt&?nJb5zIcSr> z-#~ik%hN6uC<|;oJ$2|tmbKiL@y8lhv=Moa$d-8ffsPY63u0+5wJGPV39_G|e$$vwe5tKjL#%i5W^3McW#$ zAVwq4$=kW4_7))uYCs)<943$C(I@;;NH~Q{mA4Ak3?WhB-+}uL5}k zgy<`>Zp2$}YhKbGVrPILe0E4l5fJp$EmoP^Z#Au(%+~!5Id+EJVN2XSLf+7Tl9Uj@ zzz#Z7d%tSalMi4K)MC|}K1R_fxY`z4ZODJ6Eua|%*ak4bMRYA^kyRPKX1F7FG47bT z^q7s{9Jzw8<~5CLaEJ3-5wLBe2zHLi@3Vn}_j1+4*ZDdeu)dQo z!&0E7h6NsZf(89y9ORiV@`r4gFVC~|kCs&^f8<-90jQI=WI3dzkCr&(M?^|Z%AUgN z1R#j*(enlnbl$tD8{iRNsRaZnpEPl$o4X#Y`f#ZC=}(vkbPwm~`~J*kCXd)yvc=lA zFz&KfQ)dA|*$4#NU_0ST{xK`=yU`Mp_(z(Vv?5A<^Vavk%FC>fTgIHH{6pKS)&U4&z8JmR z#!uYMvZW&qWYll|1LAG+7S9L>VwtIcpc$Oy3b&~MR8FH%3oOdf7obG73A#BvDUwoe z7WZ*Q4DE_I+5eDDP8}c)R#F|;kqP}3o_I{hB;8`^hc>+HtIX4f znJP2ZwDmXP=_Pc)Hdil|Jmn3b4yhn&LVkX^fIrGXqq%}|6NS6&G`^n7vnOm>(*_(2 z{~L(ggw+&z<5WB8%Qh!$x)0~;ryj-vB#+On^_E=?_$O!SS{f=c+~SM25&$HnTK70) z`4r|~jc=8#WpHFo|4%sJtTbvd?y9fyjtcKIfPA70xS+8)_5m6mr##~0oZKq5lMZE` zWUj+2Yjrop^?;=oQGM=Ff9?B>ojmdomZ()$*Ks)?4StDY*F|yv`Oi-V1nKhv?+~w- zdWgV?01ZKjm#q9TJi)_END|TZrXxP`)WXW|gP!XZ!kxaIAmAmbc;Sa0Pi) z@lgcJ8#SE+LGf5nA|HXuNtM$L@llkS+>$Jk zO7l*DK4Zz&#MppMXIiX&`37dIR_@b}1PUoRp~yU#@((>KSG0((c{C{=JIuLN6MeP- zLrV;5EuXX5BLGeKdffX3G8$qyGy?=Nj@#Y}-`6tls*ebS3qG?rT?$Jac*%2M2?%jb%uX%|IS~Ml4L`sPMxjg-Bo+-&s9P}!e3A!?oLMK5%0$I}a?kEC-LO+?;pH!x*83pI15=7-XD|~5~1bQji05YOkjs^srB>Qn_ z32*{1k)NKi?DE%JX03peF6gW$BP^XTW6DSql^mvgRh}bG;=4j0e0vg~9=F*<-~BiQ z<_mh;b(UNM7?j0fZ4pPU@?$_ku{Z=-iILvFD5JumWhCVLLelBT{Wt>tEW0(GKmcrJ zH=Jv+njtT3+e}^5vT^S*d>eU?mLdl-TGlcC0P^2wY-;Qj)(q>cay7zl!&?w2n`8Vn zxQTFnggSVR@I~3gb(DY}^EN^M(pJ?Dyf}Y}h=5t@{gjQKehQ+J;|+j+GG* zgc{-{RTPSYUjZ_gPilGOOU#2hzx%RG2BCe%&tOUZ>N0hghYCR=ZQTwb?{~kQofIWloot4{|01Fd00`2x*0S+ER#}H)z;dH7NAa`Jpt)aLQOnwB z;xViP=p|DAaPI3%sARh0^q_jv!OC3AL2k0VgI&X95j0}Cgn*!*BMm^1FAa-;AmS=} zZyVJ|JQ98S!x5bI?y$n{KePPI33gFiX{}q{%CLPMbzVuN4E-KUK=|UL&l7Wd9uUM8 zaRmhR0?^!V`2*jy;lduPY;Lm#mi}4Q>u3usI(%IZ83;g8eYCq`5sSt>Uxv*;w8;YV zS_{5>*1dx`7qJAkDf088{zKr8kJiLd=A4^t=)}Fye;P}LZhS`l4is$i-l{FaZT6Vi z!CTnA{WhwQvZ~e0N$odyU&}FPXvr-9sT;rWMg3eoHVvo=ibDB4^dZVAGB*KgTLuuQ z)W*>uN_ftp3<%!uNUJ>D16uhwz&Oi-kKD=oq1UpNt*i+9Po&*OI$1c%UXA49rSnlI zeuv+M2c;G}wYy$v4i;4)PrHLQmpnI>?X}m1& zWGo5fT1I8UeCS{g1EI{=^6@}CpUc$$$Rx}M%1chF#g6FRBFhb)>c4nYrhclg-W;lL zg}<*3SbqFIn;hB2YmYY1thKteA0$C5eLM7|&_76zza`O<;JxExw?x|(9>U_~Q`UEC zpEc9=b=r-s`Woo$Adep(ei9%^^Hxe0AWppGfUqpl`yN;7ADY3n#98@?AF8dEPHL7D zA2dqB-*DzxapxI9yop16uHV#A)_8s0P9C_|a+5i0Uv+_H*SwjAUB|;_xDZ*z#%U-@ z?-(^|@C|erAeQBfhuN)eu-BRzR$EOM;BcK}fi4arJHo9wS^=uDc2jnK@K|+H*G{U@ z6Njuc^i?}{tr*nVBv6!Qz zf#Ztp{mtX}n~1D59u-&bWcs9*;Sv-#;dAm4y57?);eN>a1_x|7)n#p6msm@~dSUhuU_)QEN(g8Y z4Si{l3+~(&Ph!4sy09RDLuINFWEw5OHNZVF%aval1tAF#&+le;(|HV{D0B8okGk9D152?Xa~QuLO{w9xOl5TKgb~DIuq_Xc3BlRw6D05XyT1 z4-sY%m@6G(jv?y4&xKxQ*0OfI6H)7t-bRaWO@WZ1nVM>tHrAnimF=! zNw^ZRlK50Pg=h0Fu5^4K$G`y;5JZJ=r9SBzlxRkon|TPOi`~P9Pg=5(uZHX1h@d3l zlbvcLDpF*H1jV?#xJ>`$rnb5*pWp)@ejj>nwCU+-Yizo}GF|T^pQ{kenkZ5<1n5s> zxr1HQ`@kUqWQc9~X>>lyncZ!ZIDPKzd)g{8%dGQ!l)#Fsi7P)p0yk6-8TrFIzSal2 zAkxi6XjgzW185oQ+i98lWmv9YQ6x*J63RY>i*@qV5-b1$`}EfVvLKmqfUYQqp*-nUsIEf$v&2ieP^5Q)CX* z*7=Jx^R>i8NhR+%#H2F$M{2|NKu=C2c-zS=^0hD;|C!!GQ zP`DCO>`Mpm`Es)j_TFw)?3Pxw@`IMZ`pwEH=F9=U42tpLKveN4E3NLZ(V;_DQNMz( z*snyVyO`Vo^1KxK8%lHj=*@0DmcrUBz3sPLVUkZAjh7@qr+fIAgc)+ z1#h(MJ0p;dMT3&C9o0axHu) zZ(ttNTqWzW_yY#>j;EHQIzQ7m^Rxe|NpvJ_pH20A5(|#UthTDvnm02KW7$>C&tL)uz+jLAvqVu0pcq6dM~V_{ z0M$S$zbaa5$(Chn<>$4Z_S?5X-t}kMPqz0-UfEuYmL-`viJ25BFlP}2Kq99BFqoWU z&vf_u{ZI8BKoChS>3tu7rzzl0ci&sL!l_eL=ltu`Da}ctjRO$Gm?MTG$OWF)n^+n% zLL=&yS|;S~Gp0~SF_t3JcXcehU=n|WKM4VzSjrCf-DV?wTkzS%79=c8s!#g{?=1m` zlJzOH!2z$2L$35Iy^>%}lsN?0_%K_c|JjB{2H84wu@$fQIM1=36Oi>f;f;Zy0Bs3$ zz&j2psI&rtu!f@^p>0F;#kxLr6Gi3A!Yi7SHHL=15WWSf5&5-(l2_2@+;`@({EGk^ z-?1Zy@Pmd$Z(}=vY~3Z?2Oxtr1inQJ10t{3Ma`pa^Ez93hNknF z8?J)rjIa2Ri{1%fy=n!G0sg!Q{G_Rz9b`NP({N)m+hG5P9q!y@Q!{y6xadOsx_yNV zS9w}lK)$#ZiRd?Rd;xkwdUvi;{D|tO+x{%#cl{8*i=v7awtH(HSI`!*V4bBop1CI< zPP^0Nn8uClidx84!#p&B+=-QtU^9{EauSw6>@j$EcNF*$CfI1~>-`Eeav zEufpw9 z?L!l(R#t+7Uc_`Ng=n{p9Dc^e2VP;)XKi}vJCFsJBA+d%dNssFIFMj;RMRd98gHfc z5>BSMB-Bdc4VFhDchoF=h5WJ$2-|a5CJIlpwS00VDuE>;QBX>e(nHXmeT9|lU6?PY zY*E`;xV&j4A%qeaQc&Dw@gWI}v;z<%g+Blr+?;FPEWS+=1@Iw=;({`C5{e?BpmOTZ z(Ef*U8r@@!3(ml8#%IxXmVx<Jww#rQPbxbdR`6*R|)BXl!_6-dBW4X4q?nyw&6%65!@ALSce z`X=5DcY>2`eiVX~81gBUTQ^k=^~C@JML-a%(f&`=R(%CT5K%yyf^J3uVOqX36oN&N zltHO?D4%Spn%H%_d$&S~2 zls0)E1+C{9K9v|F+{cD^VuIu8_gv?vyp-0mQrvzSE|e~(KCQ$R000e9oU&M;ZJb;}RY2VSzVSN;-Q5l7@$6xOc$81c@gehY{Y0YQP!xlsrzoz!F%NI}1M zGY)(o{ z77pU$a*`U#(!jf|rf31bIEdR0%?);Wb4j;1e()Cukj&U!xo-wBmLrGv7)eTw-T+>`5t1_5`_xPQ{@+%aC zDl%U9*iJ+SB8@{4&>Pj%tM648LDaj&9|2tR^!O!;Xse~>Gu?CRRssHFPhk0Zn~e|d zcWzou%*P zdmgr)?)z+JY7EPmRaVq=Db_oe5q~jpi4rOnGG;#24b|8KKV_(=GdogBTVTuBqnv#A zeH$KUfv2R(YFp@+@R4CC)zqNP} ztiAa`sWciO7kGTOq0#>oE8!M&d$G8Cz{a|su<4QgoS;@>4X1zF(wqz^%jW>d(_cwN z{aW-aDLxJenj;3$3dNbF@-y(1wuHrXr~vaw?#K_UxA!G1gSB1#OiR`xk0ejyC5;)X zEaxiHeu?i9{iseaR;KJFO&v(p9Gww7i;)_5-NPJW+Q?8Qe4mxwO0RSJbx zA_EY_2Pp{bn#ECfG5N_EYJTux>+Rc){#jzpD>m@bI`XR|rw9lNP*7YBL}=?gbcjjY zQQffQvH`45_TId`}j+SJ#)DOVH%5TtaZw5puqHJQGX zKko$)PCzJi&e0DAK;e@n5J!=eTcD5ZXmmeVYK-%}(=rF{@?*cXWu$V=*HKp9NjehT zMY~XK=PkYmAP9v^exx`mx^M5la1tC!LD>~n){fnj8)vA`ik0>7?9$N$XoA9y?Aml#)5cEU%2Cq~rzsT5fF;6Qj}5?PkkP?gX4Dv6^L{M#+c2+#*Zy-+WM0h(knM1T?-$fezU!HO|680SxV< z(`?jDBOqvOQ?LjcPqbUzX#hd72na&WCsE&x1t1h1AMcH*L_Jg5m($8(`Ip$P_iZv9 zg|4Sr&AN|Mm@}Y5JrVIs<`zM(1q2C9h!Uee<~V_hEvn;#yYQP*W({Xho-}PV(@1(y zUZ51s6mu`h6i%l5t0$?I$n5~W^c zOXWY}XColvedB4#3MfLO|%^-zY(X%=jfX_H%TWB>Zr_;(ZFId-(zlW~$ zX=|_sZP|-mOj=lWBxONBAEeJn*Nn6EDefj1h5kd*Z$7AR)8A&Evz~2#4zFMVQFf`7 zt-6Z5n&2KRD&@P5e1!t3N~(&FrFvC`=ZAPpinIEX`o198u;ojBjS0Sia;bkVf0Z5qV0kma}Bp^!jve#EMRaBA+HBc==Q0hui{XN{IUYRYH>A2In zp-p8~rByAs7ChrJo-ei;+9+8p`jgTe5G3Y-R?HK=6&5S2kg!94Tx^_z~`y6jA<0|J;e`fyl^huXNCxE-$n#(h!e6&@NA=DQb z=aD36kKL9#`~YLw{hYu$!YQWftf(G7E53qAjAx8iauuL~K_}lO-DHm2^I@I>rvL@! zfuIxANb^9@2_pQdkgX=mX!6wj#C7bgPz4EQ5(YGRGT}YE4a+2da_; z8#$odWrGJF;6RASxHF2-$oe$GNP6LinCH(TB9k%mu#-R%Z8WdH)ylh+BmqT&3JJ0j zDrM|gAV|!tm<50oy!#ViCg+oSI(Em<k468u5MMtS$d0C(bcDVlxNtwV7VFSCLWG>fZ_52y@g|G}G%`NbmgN174TYY&?mx z3cS&Jcm9)=mjf=ATwvwP0W7rIjqoqt%FUuwPmi%H^J(AGFgAR|Dgc6F%ia&+1eUeK zY2FI_9cMcwK+vIouxTu-N>+TD{_-y3R1t?2=$SY`P#M2bZ5a|AtCe%(*~e^JK+yCK z;+0xO`{x62fs^H+fbj7qgW6TREtW3Q5BOsS8ffg%6M;Ty2g*V`4HpgsVF5CZMNk5z zbPOP<{?%PO+w%}b{ZDA2a5(0vhn9|eqp&;^dgn2&O#qCX;KK9>J~hI5^tRPv-O3jkxM zY3Fni+ZRO-uT0=O!52;=ZYyY*lhfHGppAxK^^#e%X7Or*^7-o;i?bc%{j42&_3r_g zq<}655c@3m&*q|kq~+EZS^``M`;NuO01_Y!^8zU;tG5tHNLEl&Ph0n^e~m>4uFK0l zZl%jUM$f@ggE3gPDk`Ms;~NuKxEoM1oRNi zBLYlV;9&GstiWVs#NDvHhum0PqjuL+&t+;@K2b-O4@jp8W6$<7r1I&4jg)?pb6&*YJFa*VHfK`f#HLKegd0&Bb>=p)Q`Gd&yGD)|&Ah3&E0 zx`o!z3{A_{@r+ZgSnNo+bt9v3R1j8EBy$D(r>NDSJ^dlBLlyuPvwQEff&S;M3}C8M z4yUUxBfYb{OXkG4;Q#UvC4Meue$Z^{g^em2eX9Hl{uwb`bmQoN6qbYnox)rpPSre$ z{T^u*xfK(AzwdFI-1m?TvlYFnz8OPt`hU%Ps7niT0P-W-)Z#2``8+b0XOypQM3)LE zg6KEn9AjkMU+M*{eAEVa-;H(EPAjUY-!j=9UE38bstXAk>5Xq%%N|*>D zS`aOK);mRNd~7jQlTaIWWFT0pUQEWhZ8p=532^UbR^Uev`Wx`0axn`smk?n!@5pqU zX&fObn%a*|^-Xwx(}1+JJEOQG1!2pl*tPaN6?$yjI+>J zEIy`_M%ZdoakdpN0O*i)hlEX)SJ6cZ@-JXd+~B4PuS=Ct9BqflzlyGYkL~Zc$Li|p ztfGXx7rvMG*~XV8O?*^{qqQw3@Nc>QlF~tjh>+s!J|xSZv*LS~b@e=H)wQ(oKdU#8Ri>_gG=Q99bNmV~a}?v-r?MX@Ah2l&|Vb zA<|um_ywhjloXsyg-^-v$s9CG0#xD8W@OJDmYaUYR~D;luL9WlC@~jvA`*7W0cCQFd5L$)Y}PFWC4C}DI(z8 zD!1*=@QpKq0m^%l#qlrJoHW1uqdkGb~+W#cO{T z-UfUTa3=-fEd;TgdV$)AQ;}VfL>~)d8~s}rK?y0M5Z3iTBE|qQ;s8NoFaIan0Utrd zZ0TBmH7T4!JS>Z26sm^<`(72H}Q#g3W=gQ*u0Y#2eiecE;OahvM;CmZhXw(9EjSXl{}x|nBG--)Ec6fTG7#iRq@ zQZ|j#R8|~f7R-bbCbOQk3wbZB8DHpW{Z@;M^n-*-tc!zDf zvOG}*9DP!IPI5sU0Wt#bwMY=}vRSOr_Uzqh6_st)vhGsuErDX3s7XnV2ZBUJaax8k zP4b*tIyZwqJ5GXhUxN6go89-%HrT({(lyJlio25Z&Lh$y=mHR;Xkj4bO@b;Kr!3xZ z%&n41#x~pJ=pGgtMyB`E^dFu;2GSPTk4kP_B2+8eYJH|qSP zO-JwGL`zQb9P7oXx5aAD{yN=!1^k1rL4O7CjCppFzNwApF?>JC4`4#PpbiENwP@w@ zOw=&`DN2aIQP54r4>B)Y1rMozgb^{!qam##=x#Gl+srF>+DP|ytEsKC_|l8Py53F_ zD|vGP7t~eqQ5I41P$As(LhxNdWzj{ip2ZeSTUYbYa(b&}4&P`)$el&SSgkg$w^*~r z*5$;mfPSK(N-EG&ZUpGLBztVi+?o&b6gX)qFb@Qspr)Azf=&?OPl0TuItBw<&0b9W zg^5fPOS}LCNmOw~$ETg6vz)I$`9v-ul8Nk842Ak?u~$|C!XUJ{CdM`rn|i^8oUzWA z5b9^GykfN_+ujYCur|R&H$!|Ga;WzIs)=}xq!I`T@*P8h!89E)3F*|ubhn_{X_-SP zgT1VlalCCdvA{}C{~EH#X((G#o)D_h9(@&E&R!%5Mor^s^1D#jpbUh1OBr#1L-ApP zm>#l(7c79tU1f|ey)VTo7A#x@r6g@XTW)T$t^-e_Kqak7LQ>_&smtOJSA~#s>3k)JkSMNRMISvloJm`g~YT4mietUjY4OF2f_(e@~nTdRWt{gU2K zrAn!mN<=H?@Qk-3$`e9z0o$MudWwSKC(8}nEWU3>`)*-1Gh;QF-^bbRW%*SI=2(}x z6LDU_qACDEq@CM>;lbZp&*5!WUU#-tto{)Bt>UUDXDPM8iAO%I~Ecxz5c(IDdp zhsw$|*Man&C>&ZzmQJoDWDw4iv@^h!w!R$Re*=I^ANoCzN$Fav(iX4WN|GXfUY%9B zp}#h?$tQ|$w<6E9R@0}Sv+14RMN#gz@nNDP?aysO&-Qp_rlC!6JzJvRqPYBxDgpXUu9zUu6N!io*xvFaKYBAGAq;pt|(} z#$*vx55JHm@V4Hvk*+w~e_->qQ--YJRRNeYgTg761$KogHrd#ozX0Iw1fVFlrd8xq zP8(D2Fo5o7ECP%<_y_d*OaJjcoj5-59}y66ci-B6tHz=0r&?EQ!bg%FCY zz97h1Z>U_Nr=Fk?ax3n>T3)sMzT0hN;wc-Rn6cKjPg#5c^vo|Mp6V`3LcK-b_AhFA zae&}~W7>yb#|FudM;D5CqW}a2`T$PQC#O3f#8L25Sj;W7%CCD+KPaluccqa0!E;3gpe=HXN@l`l!32>ZuqgH$)@&<=dkQQt&4M|WRo zQ~2wO$?}tTHIL)}p0^J3>j2w2pSRfq_-o1>Z77!260|i@$LCATr z#%NY3_yfIh2JcoZ0-*7YHr@GS8y`N552O{AUUY@e4KutKwFWP}=@5V*0V65;A7F-> z!<$w>klKgT8H+hWi~4UyCVABcdS1pNWy%_A&gcAx%iu9>!2=}V#knz-H{DW^yUsb# zM1X;Clthkk(CbLQ8N@f<;oGoGoCXMbH=sK6U1B-0n2W{qLe-+JM=F;K35;`ULHBWo z%p!nlh7&?(X|GcH0Y2ljC0tvfW$ly#1j5FVnlRIGDWIph5S3ds+ ze_#WhIAoqpSxMzt)bT5nrJZu9PP`7oOU9Wklq-dGD7}D$H3m{c<)KSK?Wt?-=CKcS zpGt8{z|pMc^Fmy>j0I87dgO6hvVrZPU*Bz0yPv>W|FBhXoV_h(%&tHdbRfR$XckIV zp^&$4#rnpBLLxoBuOUfs>m8^FYuEYM*%^=mZh|6v#Fxk3kiXAQVU7_ld=47EM-R zHq!(wB~}6&Q)Z!N!9k(aCH*@kgX99gsF|wZ${&-fgdl-Iu|1YQc#rk>?4X7ztCQpC z+KYJB#wuGa@g=0XIKkh4O^{Gf0D@SN_7q)MkX1l|x>6wQAVTR+QQ&{dHi+G9b*Q$| z_Rk@dUWzosNm&#-&uTmJ3qm0xc+`aaR`7N#G?j!h)za(Drz~1x()e{(aU@l`WTeyx zg-8C~pTh@y%Jw4VC#~Udav!H$Omx_ShE-Vkd>U!|G^zrHv^6b9d054r7`g+H;}Lx6 zbfD4=-OGfKJjOPU1K(%M1KYaNYpi7T z2aw>_k}s#1$%LAhwe2s!6cRusR>|3Bu;&5lz`q6kVBk^f>ijMW`lvNGUdn0eAA~S$ z>p;lVDJ|+7acQ~{UAYm&Iqr*GUPe9C7sU=i0-GzL{FE{mE`D$`k4aWc=JR?*39!X2 z+jE}{c3h9eMaC*?E=ECqKbq5NL>EvXp%Fp4;3U$WKU1I?1X(2^j+FTCpc3CCAm_B2 z&O>BJ@=%EpZe@W6*g3fUuh=~?WVH?FS-g$<#?Izlcw34H@8nq7*S0cQnZ@$2SoR=W zV-9Y{Z`LY67|Nw>cnGSm1q3PgU!;o^94-MtZuv&NCD5Z3^M^FB+7JS$U%c$}RJV{- z$Lwx^oTu!_{(q*t1D3#arMz;DRp|J2Sv~NcUY#xYU?F8f%2g53B`vz4v}X5w*9L|T zvjt*^ik&a+Y-Lycua zo|SYd>N)y+9L-I~xeJhwYin5SY0JtYXjni{jg_qZD%E=%_iK1pO3<4R;#95LYlI2( z3hJl&1XpD5eDR>N>g~5YrtXUN>bDA_h^{c2`TKdm3Qm=q-Fcgh z;jDTho8pjzFR<%Yx3-8NdSF9gh-wY;7|wi5stAB z{tR&9pe<-R&C-j%PSMsd!Z0&1b`&WKT{vHcvXnw)7qF%p=#e;3pMo7jR6dBQZQ6>% zsYn_?Refz8!XMN~H`}|0cQDsA*y2@R!6IlO-vcGZ6|$8`NqNt`j1|Xi?5NsJ>Hrux zNt+VjQoG(#ZC_$+XWUROY?s5_(#PmrVuX8uo$yXfrg^dbzR)nzc^ejd(^!i#FKD|` z*;&+u6UB)A`qbm$8wAN;GhY92W~l=~KInO;pj@TJTv zvY-`*G4QG*J7niKC{B<8y}t06Pb#v&)STj(%Tk)TlIS`mQ?03k5fndgtUx5TxN|2j z|55&gXX;y67ux7!oVItJ4GkRvdfjqm0((5q=%Kyq(hQf6U5)@U>%_r%XQohL_a zZ_aaKS=d5OHpI`cM>Vbe&`tr>O2HEfUzI;uOKuVh7yeOmerFMkiUDYfWZ^pwn79u< z@7aq*7}l6eHsIHdzMotMVf8X;>O)r)l#On?ELq4idhS0%>v#ctOX&+(RsRg%VwMQ3v=jvrQQaayLUrW713}6^B|%w!10qF5H4}iND++qy*g%@{DIy_7{yruE&HB0? zx8hW}EoebGthOOFoEu0Zu=H=h6$V2nrG5;N<`SKmbWZK~%X; zpYj!a6k+m-A#{p65!=a;OrnAxo4?AVGILtabSI~Wacp~WqSmUHUjksqh3^M#w~^hC zP6Kg4NFB3|x`ua;@bee`deIBhA%@^$zh?8t$iTS>(tt6A}GFo+Aubs_P?ioAMJ2!U^D zM)Ky8f;HVqe?qB|71J!`sUV+J6=jiH7y&`>iGC5q=~?I&7U$jBr)+5N-vjvda{O}= zYpHY0+5kjyYj^`1QopP#xN@#8x^SW!Ew68G(J}inedm90Le4HrHJphvX8@QiY2>j8 z2-yaljJ$m-5AP*%SdzteT6V`@+sMEk0G_1)K`3EyKwE!}{MKj)0(Qr zq}&egzYXBzekEbepBFwR@3gL;UoGOW!3bu*!z<>W^{r=enu zO%4Rn4jPAwmHo_1HnQ_uv|Bd|0Zq0*&Y05|@t~e-$TDMW4eY(wa%1@SVEaurxfmZ% z{|C>c%xM&&JvFaL!3Q80cpB4p1t>R>(=;e>n&Ul8h+j`E&mS}A@&KANH0C!sSSJ81Wtoq3+NI~rozNv#NO6aFiEd%()eSEFO86#to zOOn(Ru%Po0+a$9?_>fu6>4jg$M;<;}NKo`r5a5xt?O1(1XyYjGWmv8u+&KG;vDLJs z{x+bpvw|xO7j<$ z2=!3TZ!W0+>HI6Dp#JAu!=iQ(Ux*m~_>fKa-^yu}4^!`9TikpWTXR1H@2%%jZ6m%W zz7H~iUj(#dkO2ga1bR;r;Rx3uupsP){;$B2DLSEL7}nTa}+*ta*PGt^5KRL zvD&6{t-SR^M7e-;HO4^*wuB{oL5ZJib<9jMesVB|wpJ&6dooV5eJe4~2^khy(rO?l zV#FQ#Jm$OT%g-G1MyQ>Zg#v%3Wo?KxX!g+0SZI2}7mMnll`Vb`6UwD*%j85kbtfgK zx)kbjZ1QtJQ1pyw9(YG!r^SXK*e-T4{uE2w=V{+@t6Q)Zx#(IjxVIr+v5>V@k~=v0)b7tx`RVj zgdr)|S}Du5@QI?P*~Vw}g5XxroTRXwxz_tKERYKr9st7u>DG>jpPTPv(Eib z+r;>o)v@YX+x{+Sv7Xh}QXC`)C(T5B(?KARlne;$f|@6wA}P4W7$71C+_b>veuPk@ zhd2iJ(9KwGqg)raTkXn^P@W4B5-RyEVT+))L*Vkd`RcmTQcj`01q3O`A}GP?e?mvj zOJJU%?X}#LY~X=FoC;zEA=zK>tqm|j;e82!;be@12;PrcPsh!ePmkEb=69JbeIKu^ zBn^}i&xf>UUa)-E{gxeiit@8TtLz-BUGXvEEhWtbe3m#i64NOz2!2U-3?KP}Q)UNL50Ww~-Qlb{+ zYN*p`fI%qiIO|n@It)1U!B9-`sN*_bZt?Z=HopIFZD#V2mEj;d)w}^6oOZT$A_6;5 zrCDAGz^0N6TYL0+u@rD^J?Q!ej)LDrxtCd;EOGJ|alz**KJR;Z^}%nw7thIAIrZNC z*KBFrjw`DcoEm==f>8GuW244QUdqa;d7>Yj>s}k`LmB5(zlF;$@cx;ntZs=RLej?a zH8Z*AzcIx2P~K%$x%R`PwT=g}-T(-qta0j*L8(i`1U92A*v~D4v*@uQR*Xv;c;{=- z^la_}^ufJvC4})O0MQOms10am)my~Srq7rZK0+>`v5@asIknvifcSq>5B#kZtqDMo zolB%D-vT8dD^24$5abpOyywIu2{mXO{=~X*VE4^z1p&ZGmRM2qwXCwgo9Fe^o0Wav znia^UW(f&IiKukqGq!iKO|ZZ7CCiO&wwkI6OR;6qiWUP%!C&%0rg;joYr#W2BCeDb zk#${fgNGky#eU3cm!3yI|2#csDbM8|nm|2CfKvm*I6;ZfVL9b&$G6B61vHMu*O{NB zfQ%6i#`VA-PvWcS0gK_#x1y9Wr)-s_al)P_T{a~-J^TbH2Z91DBPs{L9_5()D5{4! zSjcbiN1sjz{_tNtOkV^ES#Cdu7WdiMj=LG&;FVIgXe~#vFFJ>OWnt;H4soL#d^}ZJ zO6T>1fFOn76Xk$L+nl0Azeu!LgZfh?ZHV*SDg4?bun5woppYfy?=_)`|- ziSIg2ZyVZwCz#`tR-vs>YSbAp_IS0G0j$RwK25AvZqvtTkC^zB|5^F3@_WcU`ECpt ze`dJ@Y<(NviJ!oBtXKaHT@GI7lt}sBNdf37&$kl9%@oOlitl_!-p&sqgf2zmFoO)f zpAH}5Bvbm&;?{T2#*EW|k&a;%-VHOn#v@&N89OKjGMy~tY0C#)tOKTItLx#7cBFF; ze%2bSaq(r0haV??4VI;R5R&vQUq=uStf2e!X{G8dsFe%)7Jl;m;7_;EA&%x%IX-ra zy6}qAC+6cakySq*uNb$Kn1?=OnvM9uzTXDq%c-n997a(0ZmQqTB^d-+z|ma#C00c? z#p$j+JNZ@wXw+^srAxW5c$&xgP+PJMHQ_4}y5SWF54=QtRp61jf^4%S56dc5v`YAv zunxwjhivTdvoK(@={EW$O zoh;XepK*U>Lqk1SxwcyE68ccN=B9dIXj5?$EVenEhi^PjRE2a)EY<6{w7D}M<|%M8 zQeYkkIzg>64+Nbc!k+@!O2)`AF>B>F$WaJe8CKFVhnPhtkSCZ}(-Invuqu?9u!7bz$Eo)`AHSXoXZVk1MM|_>sI7ld1dY z0~i_IK^mP_1o%%0dtgTi_ zTNkxl152Dmf$B*|{&)Bq$z3kxk)A?yFZ?R}R)!MF6(E31%i-7Ye-%@-bTC$c#l9cf zc;~aYh?rrU-5Hi%{Ku4aDSeX_Z1!o%xccRhiBH&X7phNrvaZy`Z>p8PaNb}WnQjXbS`a*joL>QReu&mtazV|>_yP;dDhA)e`&tKO4}~R zYV3USsV9=!LnoAlo~ZQ1TDYPL^w!p^1d2F7(Ch>jOl&DMUaJ<{#9Z_xAmFPV2+D zYO)TWH~=?AycZ{5Ux5!+G=7}&)dhOMy$>wlAHZzs|l z06_x5w0%cg_u~D;KVZGvZ?MGZlK?@bR@C?zh8o&3UdNaWy?hUy=UC`kY8VkPj5`4c z(mm3{dALqfvJ#X)whO@&+?BK9G+UFHr^s5zPOJ0Ar6|ts!;vegG_9)foYDxW*0c=%F5X zr%;LXL+}YS!J@zh@34{W4}ec#4Tm*jQTtcOV;%iLP?78^0~i#b2NHA33DQt9ZxAFu z>XKE^vDV|WfV;^oTjh5CSDPL0vJ(956t&YYQm2zzjRUfA#t&Csy<+@{@**v@q<$Xz z&7&2{qWU{+-13CjawMGDWJh-0N+0O7c3H8=QZjiSEmjV{=xwE{d6GGB;^)@8`!*|{ zegV*U6d;S|%#~BcORQLyfTi!Fy=8$Hx;{JCyg*q`haMo{*!HtS{Cb=0WD$r%GwL)x zHhr10tYA)q?|9h{Q}9%X{w9M;t85hud*4cT10ntAV>sKLaM6=wSh+0Lf*&E{SYRmQ`^RWYT3T0Yyd0dJlo>y znl`ZY@O_Z@Z1Ny6@9#=h>G6Y=w;=QIQ?i{~>dj^9InV!@r@+Zdfq5Y41hvdO5OjhF ze+p!)DQXHur$~M%5R2rnF3<6mW5XysQ$y%LIP+cb9%j2W2-!_cJO~9kp~P2tE5jsJ zn5a&H>i$v@CC*4}alnTaE?;>>5R@1or{(T5HmDbpLDTX8) zh_RIS z9cO&1Xz|=m3?^>i1d&H=wgle8dZl#fH&F^!aDWT~dNEcy@J2R2h1&}$s!{>uKS;tqU^V8w!;po*sTmaO>{esJE# z!(!eM5QIuV-w+U#u)P2&H`tNgkCRc-YFkkL7JiO)SmFvxsJ|3AZNn>ojq;K^i=tk< z%_cdOt>?&7R*AWONw(gKmm%=t43p!HD2>`%>X5906attepAg_iJce%*o2`G}-?C-y zpjF2ga!fVvmtM@n7Sezp90(F%Nxzj4O&KzjU#dWgKgsxhR-S)oLp#|@#5RwGI^8ZI zp&PI>=nlx%%AI$lbMTD@$GT+?Sn&U2qn&`ISjg3{Ly;_bFUcec`RCC}kLPNj+NDg>5o)2JV8 zfTQOR@Y2ip$PGYH5~r-S>;8bW1O%0F6$;O{HygaR(l%uQ>MP7t+0$c7j+jJcrcAk{ zfFRYSGyp+c{~b5AHEgXdSofPeJD1;;$5;f3`n>EGMXD5u1+UtaTR_kr>w4vSE1rBF z9xk@h1)oL9rY&%KKLZbd-+3soE8j&G6$oMzLaS;_(=rD4Q6T+!9A6>ut=dDJP+YJG z%F9`}^Hd4Ev>O2QM>c$zqpIPL+I8??#nn)I38@JPB3A)H6ni?U)3!K;O8s|yll8y) z=a8u%BiZFvcNX>5QQNeUThe9#=J9_v-nR!w?^Vnb?*tRMioVVGNxRDzN=*GhM5h{g z&tWJRL- z5m%ChS4uy0$LAw`Q)Q&ohT7_>Zh18SE5AtGkS`j>WlQXL0Hb5yeU^lmTAGkcbc$z+ zF;So)0EBoVFN?J}@v}Q^V*lNintBc}x!V%->l|B@^Hq#-%RWH)-bs7YZUp6!z+t&U zPFwcKHX+CTv27em`5i!YK8wq&Vi|l={b}mo$UMVok3KMoAIbkM1aWi7Rn4kRa~eC9 z7UO#%%>a~*!gDOvD0ZCr(6?Hv?8#s;!neQ{N=@^Blq%cCphr@E`qal~I}!L^u#rRe zTV~=VD=p`+iIy+I`^*j6f&@5|N5<2962O0f!6X-5d{vW#Hq_k456J-vilb+7Ktqikjt?YPyQKg>eJxX!+{)JVa)tR`^s~V=x`E(GL}3KFm|# z6rjL75OjhXX&wkVL4-dAvek4o&6b8Vf)oc?Gt+d~SogiG+CO76R zWivm7V1qz_@{R2>Z*YneLQo9asfN)MA7*FOSMbu&x`uDZ(4rvmYZXdw&k0=NRsHpe zUqFxm3mq#hJ&n`Dkp)qT?J?`xaU=dHwpmHK2EgJA_>sAQhX_m(6#dv|qWQ|RU=x|% zOM0Lle9Osyh6GNElwtt0Kuo_cd}8u3R>&W=;a*I$Ir*z)(K~S7dKq!nbKxV0GV1*} z&(GNNxa>wY{>ru!0fo6_#pSap_oPj3z1@08_FF~6GAzM9VkOlm^`wVb%r+&| zD-_riT4Y?O@buqqhj#r8FbqqICRRune~D_e%~eI57C!k@SrOY9lPf*|ju8ZYDX7Xp7BM1=yk|%$(vi8Yz>2Q;H0s^=KW%EH!>ZYeQn8#m zr4X9ss|SQs__UM;K4?eUfG;xziy#Tk$;3g-@Ncoc?GIXprf6AD{wWk#w!doOTe-T= zB{c>hpv&4i+BmTfAn5OHs1t|0`0S})i^5y_A@Xdq97oEU#7cd<_&_t6pto;au6ZqEbWyVJ|-+@7WTUrU6rarqF zAm}C=1>{SW00gc5L*4;A@{{Q(JjqAwMC9Xw+9Xib8BLJ^K%)3!-2emyngt*Tx{Hl< zsp$9!l42f1F^_R-*yxsT@Xmlu`PQ&&_)hurSl?0KqdtP5peuerH7M_K2ZFe#EfKL@ zc4YI9tpqS3MGec?s$*IS2MEf>7*`8O5LtT=Kac?z{Ocu=lEth=`80MWooL)+OPR0} zjSwoY`>5fK9Q-4`)KS(pvxD*HpRhpqIsG|}vupA#|0pBdBDhDJEXft$G@?-^$@Vku zsW;mgRwmp2(v|W=@k*;X^I8%_wSluBkg%*d%BoMJRi}DFM{b+>X_<}FD=VG zj{({9)MqB> zbw191Y47A3n*^{Dh9v$;$g+=e=EQdtH?GsdYzsr_-!R^ESptib$~7OSU9W&=02^n< zeX&DhWT>B4r$8gGWvFZ6j*~D{koyXvh5BHSAH-uSzj#*L1$DnbEkGFn4FEKq2CBC7 zR@Xy;R(vREv~p0;X)PL4AMVHxpPwu#pmcUGJiL)H^b!25b=v~AP$w3BmAI>Df=R}C zXwEiG@#{4GwFniFb+Y~IS* zg0;WJHs$k)fzxdFA0!}%xa2lDHHLHN@cn2Z#4P^U3*w`SiYxj9mZf3bxPbSO$1KTnd>lN z=6c0?H~%?fMjyV6s;#Q!BDTlEWBFC^VVe4c(Jl~nq~48F)=JrkUsP>JKoi_x{NVB%>* z0Af`Qt;x5?XaYh`^NHw}CL^Erc^G|01U^3E@xP;Z|KESAWKroPY=jUb9<9x(V&Sj8 zAu?$DgqxKpwk#I}pDDgXCn)GE>xC4VptTV}aTN4Tg5FWn36~+ksHt%UQ9~@yoJsuxV5m{%6sERgO6CI@sjz=_ub? zM3ta)OJ+}L%NC~h85}nD_wHo1uoA%pLA&~cq{pf&tJ-b|=0Fg(8xAy4P$5&KFGF$+ z@AimTyF6tpF_Du znM9z=7ld)iv|%folv1piRCj5oC=F6JL>XOzMdGu=08B4>x?KlfwPO5aRG;}No^BwK zWpBT;)x@X}hM#SWv)eb)}|c+{%W_4s2!Q7`)-eqh+PQZ(sp z?JJa+kw_L(y0ILBcJ>JA?+rI{ODSs$4*(6N%f!aKEn|REvJMfyP>DHVS*|!-c_J+b zTyoFZ(91VjQLLM?)m!rtz=i0=x+bfIufiVJTi>3? zthyM%Hr-~aRli3Zwu;bPi8Owg$U8V829&^8O6TEcAW1R6*JW1S{7w?&#I<9rP5fjR zoo<4kp26++;(llkN6xRY;uZgvdu?12ZYAyGONnyiofo9cg|Zr}@|N6f{oDSLU8jej zLJ1Z-C;&P7QykzbJHuH+DFkOs>4yjIu|3yMcU{~1h@N5b32x>Q>ADTBa{?bdiY{Y=(LtYV9FGX4px<$Q4^ABB_@c~ls`=qp$R4ehwz5)+RR zCuya1zY$JjqQ5y$^EU^R#!>22CcKI9J}?b)j~o-Huqu;+tFj+WSF982pjzp^j;7bq z;$kWBzMNQVdrWrcw=FZi$0qSlRePp@xJxMGBHj_0fIkue>eP7_I;pQEWEI-K5x+v$ zF%1lJRQlp z7sMMr9%|6aa@;ms4JWXa8^Vfr(V5o-i#1uwDMJSk3ickT9hX4RM;IrIth)6#{ZzY|c%zSWcnE?zDCK@ALrBB>YatyKn~HG-NkY<<{yE1wAO}^p5^IxKNl_G@6VPRlHRS;9Tr!0vl=jBol^;AJ}Sy?^qV+m~WI2yd{c^ zPqPeCq;VL)W%MbV=(wH}-i}yp-Fhop!T6azkH}4hRFsxdj4rfN8y>W(iKHf z`5oHwEsZ>*>@s4KA)MlQ%6!o%XF2ARBX`lZk6YIyC$pATSz|MOiqpch-8aZ5M8*mz zrGAiQ4(Wf?2KPK<@v>2?YG=%;Vg9gXT%_nU$7BKjw^mI#k2z1p} z{)GGs(sF>+>7;rXK-27Qo9MjXCI*p#5X?%;&%%Q6a{4VY7jr_e%p$F*tezgP`of+V zLcAq@qCTqENg96L4H16b>wi33&I3WmQ)K@4JOxe)3dr)pAqs>cO`Q8I*N@Z7o(FAe z_yE7-Seqd1E<{+4v%)#s;67ZEI&a*S@?$0;&8EK)q6t{Dn8NW9^!xaG9`Tg;BSA}B z5H#!ibgXK6RVDl)`fBBq`l*HyEacB!`V1n3KYRlcywOAwLz%MO-?NDxoVTXyY{9Ba z5yme>kXeM>Sn8<8EX|`Lsj0lBeC0ZW7=b?kgcFq>xdtC96TG(_LF*p2@34xBjp*r!ineUV?QyS%4k+XIk=Amyu( z0)kW$iT?m`()2Q~AY=W&x(__bYHblNju0qIKY=i|LP-52X*(B52Fj`&gCG=zK; zVbnoCKvC_#&U*JeV5OLsm$jYGYWHvOU@2Qgq|zdOxu8oLt|*dbu8$LgaE3gvk#b_B z&av-S_fGO$-~`SXtw;aBxF_9Pf%al7nUUkc2N%z4&U{{gBnAXyJ6T*=m5G^jQd__*-Dr zS9FuI7stQS*a#LL{Q$qbUyWarbj4bpE@0)Gt&b={B3-~gdqcT)++{NZTdlfgnH8-D zkg%m(05!7K$O*`!NOJCj0!^lrhZ_KX7Tae-yZ;V<`nPKWwLRatc}h4c2q$WuDhrllZh)3RxqUs7)zm zxkyj!kyM}M$o9c4|4eaSLeH+Tinc$7A1)w{v=Vv%uc-(MDu#mc%fK&!VbZR?5+ee+ z1h5EjEyQ-^lQ)8`U8J@u5$aE0$a`soX^7L>%6T?PYQQdVsk{(1)>itpAiHbu4$Pj#z*XDwp$h0ILNE>z=%} zsh<9bPfs(%=CAJSiS7ef=nE$hfqX&%%0&{z8U*wB{@D4KSYz#l>uRm;jE|A;MWoy6 zIb?~LRApi0tgP*LqJCoi58Ghp4R z6vqqav48Q8H(r#OK6RrIIePclPqoj~6E?H|TQ2{ZpS9M5R%0Fq@S8ql~-w6xWT6zWJOX>N% zS_UuhUZLn33w*dGWzW(36=N-VsT2-S4DQ7Ne2=9nY5VdO+^r^eS!MuysIl|gnNz-F z*?}!K#v~N4I*V;uU!{vKg$D~XrXu1!@sfs*Svam(!0*f}V5hgR1#>H4K7Pqg{|`Jl zgK(586Q2qcl&ERW>p&%i=e&m{?UFHxQxlHEO`< z=WBe5Rw`F?DNA)PT?hvJ(H+f80geg$BUy09W7uiyu(*~*t)N?gWHEqq0xP;X@|NO%r_of4#L^4n(e#8db)SIrB2;K@~ORs{1mTiJH{dX9t;2p0MfOC-4ol#j307t)%WsK&=hLU&>YKW#@KM+))NaFj+g z0rT}}&;wns7xdC=zW91CoK*KE*l6Q`0>Mt^4G+wQl%sa|Vk2RKyWdQTODp zXZTqb`);(c@oogR^?*TFAkDoC!A<~%1Vx0c>8Ejq`~Vh6FHp83E8~=}lt3c@h?&_k z;sBLUSn1>n5_sKcLz<+URtG-{s-FaGo%~|?eVCcwY<+tlX0>WoLmQVvpG^oz%=XY=h=oEo-@2nYf| znhRn?mGf5uK@#8rg7CE@AV?0Dn^)66WZmN{^GXCd%1IFbk3{~I6jLniMt9s`Gg!UF z6J=Ng{Q>V>KZ18}Id`ZGRGz5;?4l0GzWAc&MH^DLGcF?b*m>j6i6 zm=nr=#1JxuMbMd6>=r?5$hC>MimwtBg8GsJK?TN;8G$p1J`@pt_un+mFTBTXzoDDD zoT+s4XuMoXg9_hFGMx0zXyp2LN(VN+}ML80(v>anT>G%iQ>oCR@ zjh3#bue4A{WRWnQQ)*}`KFUL9l~c1@T7dfCMw{MqFLKNQc&y!GEB=Uh>xoVQgjfPv zML>`!%|psf{f6$fo&)!>1@5plG_JxI&F@mbGXV~CTsvR&mqm~w=C062%0HT6Lo(rS z=v`9Tb$Q`qUB@O1hbV-Cl~%Q-uyI7;QXK!UFu!ZW8gaa4sUw#uVE z8P!XDKrpIG&S~xr#KvXem^;GutLH4U^9F!^__l1Zl{M3@HJ4MSh0r1g2o6{czmzIb zS=$agZX*Y8vT>|*>KZp#dg+y+4i01;UkbgXORcKXMJ437h{{iW;DXM-yXBd-Rp(!D ztE1uGr)_X(%oeu3iy`S<3`yq^vD}AGSw_w!=kkbpjnZWHh_X_;fHrbcFF8vV0 z2odT<`s`g;scnbvC%ipu;rn=D6&G_ab9$b4)sEqmL2f&r@Tsvw*0TIlOZ%2juP4t= z!th4&tBN}h1c_08eZo8t^y|~s^EEwHD4%IE$xpOKN2YAZok^c3i# zSzPOZzD6C%E2?&M>4nz`Z#0p{WMYg7dv@nNcKFDXSfMnaAbteE;_al}%rn3b^7BQ= zxVFwnd?=hQ<-m`GPfAV``IZ=b1qn>a;ag^Sv==`CrPj3S1C)%dH~7a1Tf?+cED@9~ zKM37f6iYc(mbmBZ{!%n_@?7`z*5AE_trZp4xD0`f<7sp9A3>cH$|tuI%QH;Ecd_b< zJ$_ls`#Fv6L*&&=O4SHJ;S?P?MRtKl@())`h=hO_N+3~5;*e8TikP-8O*~}7d$35- z$vxGJtbFCQNW@Z5TAaf2*P_)t2ZJKkFbe+tK%8xcnH994W7 zpc0p@#8D~$i7ai%9m+v76x(T?)b*$h^xX$oF=mam=i-Qy{*p$q!G}nml|WHQO0H+` zmLj|_1reHP^2+QjjyJuPJp^9D_Vl$RDUTE@rQ$Tf-4PJ+N52o9pyf>^ZL|NrYhQ6 z_FX7? z3cm?}`6)|f#;vqwy(LzDojA+5rg@ha-ExAT`l|L3u?YO+kK!CcIYmj$mea1)ke?Hq zoUY1?d_1qh3%-R=_oakUHu2qzfUJ9LW_XiTR<^Na?%#8NbpZ$p-f?119JQ4S0dZ5^ zbo9rq_vKpw#s;mTZZ%sOf1k%FQmU8Yi9RaiYXU(^Cn(-Agm{Yy2)Yp<=q27Ov*wkT zqhruEc>o1xPAaX=M!%9}LsI=5aDEUAjOhtht7+kurC+jGE&Rxde4=pxg49z2(Nq+L zumuphSs!)i;Rd{_v<0}}m=!dMqHBwZ-g~n^5YD0vi=Z<;L0Qk_{bs6pyhTvxp_AI? z1>!0oD3zrBVtZ}2<2J15?j=__IKH|71T}b>oEMx1z{|XoLrGKL7kBIE?l2Yw_7IEA z)feh06h>R>$_RbDMUcJ9?hgS$`ze1tK+shb>H_kJfFNj2UlK{O4g>*kvqdxC{gCw^ zxgM4nxAKZ}*!KESa$3m+9i;>+h>QvsWOM8T8@-l=2&V>uHKHsH%zawe>SR2NZ)2Y5^Hksmj`FrBAqm zs{n9tOE`yH17)AGzRmcin}GUD-)_Y%7xGj9)rPW-QuqhZ?)^wyyX8yN|8mDrEZ#u z^KI{+T~9MsPExM(7&|{ttd&|KAn1%wy`|X`KJo9K3g1c7gFcV{PWg0CQ5Ezl`sfz) zRZF>54{a6sw40fR=h+e#qvK?;qER^$Ebyo=>ANe^j8~d=C39p*M}1kRUll3+?0$yU z=WMnM-)=`bEM2nBT9z}9R6s|LCuffpi4=I3=tqNI)^&V{?&(uh2$TqNj>aFPoG1!0 zbc&dOAjOk=z#?Zj<{F$<&vb2M@#GoiQWk zBuUE)tl@|5N)U6AP^Y{|*y+E`dOJ2E$PHUd+dD1R@I}&ZCmo4}IgEMEZ@8mN=ujM1IQ4-EI<}17aS376EEB3fg4%1J7`r6E3ITX zY2`0rbs4jK$(|~QTaHl1>@K#uq15!=V`HNOR#Uzn@aD3xRgXG}wi1S85zs*`J#ztA ze4mjYgd%O#V@m|b9b2r!W)I(GLp^sP^yjRcZ3*et57Ig1e72I}vnr@hb@um=U}onD?9BQ#9irS@Dqfb9=t~WY8o&&Zz|sQPm4htfinVvBy{s% ztKdNqz#<4?+<*EDqPc{0iOXvALEhV9QwQ$1$^K`o2&c29>;EI^2nZ737}N&`f*d_n zMYx+p8J&5;`ZnE6f9m6ezLl0-`uilinl}^_FMNd6TBW2dMLco9Pn8K!OUzf0cf(#c zS?}Q&uv|-6i-4fY_mIXyUJ$i;(=}7|SSipd_de^{2535tQipQXxb!pl)wzUhc!w5> z#v1ify&vjJGQ1zt`x#DA>e`G?=pJ^&z%^CN!GTcV1q{;P-ZBsrTT<8>b{3gwYnc4_ zKu4;q+{FXp`$@)^qd*XR6x(arj$19$dq43gPs1kwf>;$#25`!m2qw&tUI1=U3}w+I z(qh3d12FAP1F4+O%8u|WErP@b`K`esX#4;p(SiVErOt;AEl!85d<3yoM|sInY#aqH z2H=uA@&G^(4*CJp$~i8*%z>cgBuM{u1yJqA&$$AHANqSV&`(_b)Tej^MLde2_vV6b z9{Zs1FuLXO1kUWY>AiQ_SkHaUz1-RPsbnk5vd8polCdy?W@HvicI>jBUrc@Aqxs@GCgXt+T2nmy+j)Nw>|T7Is{b z4O^#aq?lV-DtX2MeQ{}N(#P;cz~d8(n)Fn4$54X7m;;VjPWMd@jd+f{G2g+#!45RPg7mXyDN!9 zbd^x!lD;wK%WefP%9QC@P6+)Wiy?bBB?_Q+Ipr!7xYky%;|jicL{A?Z3u%SPT{SCI zQgoZU_*(exfR%pfJw;VCfDiGmwh+ncP3_{(1!M~3cd$!#q|k*iBCdKXXuKq@hD2=x zpTw!V5-p;=i$uSfXW0^Vm-Y6seGm)4YMgABHc_8Aw39=0{KbV1=BX9_s9?GjqR(T$ zN6+aa@NoDg`jZr8_i~3HaGv-@fT#Qy@l{|*Y$w)rx7#2<+wAn9m6dY>r1+=)5}vnG zd}g<_PV2+#;7r;$8{z+D@4dq;y{a?cb#mn#x~fA}SG77wYDp*|q0~x90!%VsGRQE- z+<`IJk3E-}`^1HFW4dGpe;}U72iCDoX`&`rTq9G=Y-RrZsm+c*A-(1nb}{1te-cL z3Jef1BkLOLy~&0TK439;QZ1Xj0=HbB3pD`jFO67JuYMJXN%cSY-VPM)i-on zs^NE0b}vLj)M^)NadM)V>qR$z+@|NoEmC)eRn~6eO(iRzI_y}A9?XIs3ChMNP?+m40LVp2jGS$m z1-9NHC(9?2+x#9Ua4$T_@$FbDW%^KDT5;a`pP+A(66c?QGAc$a@qYoH z;HB5Q>OP_^LZZcwmFAOb4?vLmg5oa)f=bpGN?WuED8xU^VcO-;!^FdR>|3B;pebXS z*q~MvfFLyxCxm2WN%Oc3zjzaU=crZU8!6fK2fRL2p+h*)q>J_%08=SHqFY)6>CnfN zenj;a*=M=In*oCG#l?P!_6^i&Eg)TXb&-d}R6N4Us>-+PW(REIz(W|gyl8VYx5icP zw=(J!52K{&$&-FiW>wly66Hvrz`spl;z{e>|FC7}4pS@Gp)_x{)>8mpD0`k05MLJ% z#HnGkwgw>R17s&4sGV`|1R#h$EGr=nS937Xw}!>0$#ZgXO zJoEuwpy__y<}*>oIDIaUMU(gtfFLrZs&ZImMd^Q$Xg@xSe_}&@I7ntYY-Qa=R=wea zq}4^aQL0JbFRx_2`FN=xCp`BtTi~_cskJ4E&xbA*WbrCJEIl~xWr!ok)cAgx*?pVM zk3YlsL4VxvDGG^VsV&_64VH*%la-zu20|e&WGM$vRbNCVKlECcwsJWGG&ksl1_@a{ z3JgxOb-3prZEo_YRhMnDsxAQP@=FMg17?CN4R^6bt}Hc>w8n4M3D4C}#MinJ9dBAc*`H08RVv!`Is_fWuQP zglw>ywe*wdh0qMpsj|Qh{&NFzX}lsSzx7asb9zdgRH=(R^jHexF_rzXc<@!Dm8?C* zeYK2eL2aFd9xaB*yd+k`cRAA*li89jYtG_UJ0&e}Psj12I(=kl1x4!OCq*9XW~{)Q;1`&GX|KI zPQPe1l`E{G`u(Kd=~;<2AxrTq`0#Te{AYlmK+&->73mki%+_vWPMg4TDvd>NQ`@5LFBAEM;`r;+Eo9u;Hrb1 zF4_n24aB2v0kv|-YoX;Zds6?Yh%D|&w3JveO?@~JZz*@W0Ff&D)y4G!`Kt>SqqcQf9^+%EAQK%PPr(oHW5be!%MM zTUoWeoNWx}^Kvs5M69L|E&virWa-V%f903>rTICEIu!A(H4;V<Fg0}?m(bw`XmW%Mv%b| z2+2!WD#;SA?7FnU6Q={gR5DCa311|qNR|U65H98Xm=Gn!Hr!cO``wp}5>vVo$`@Y2 zD(D`z7T(Qv!!j$c{s7Kk5%h7qsjV$h_IpHPC>FUxv_X^$PWj4X=_33^ig-c*6|1um z9my?$6TZ4SQ7S}S8v4Z4>QZNk=+IO!_Pxso2*0b4h_s6hc4TeBUsHAMtiBK90 zN7)M__!byFiUr+9D_@C1R4$$1YvQM((n8>bcmnW_~F|Dd~ga4Jq_zW zNW9BzAzjB2 zHsSq4rSK|yi01AwMKv8ki? zK!3S4ocpI_b}B%S=oVC~GV@2g1)%Wl7jcv^wy=!6cq2*nT1D+zOLYST#ZD)f!qGlm z8zI^+1cH<{)-XdHW8eD(bv?`0ur26!)N7`L`k_Ff;Lr~zY2WVoNy^Ib4&v^$>@0R) z&BQ4~fq>#t{|;cRR}|0HXW$|$-Eq-B{iqG@`zbz#dT2|)jg4no>jr>9I}84`kVnW= zJwUY<{wWFg3K0C7&Y~R%S`Cl_5X4DL0SE$gA&Etcpdt_y?Do7$00~qN`)qp8jTm?V zRFYewlEU4}I~phSXiSn-VqEBv9RH?|SYdVua&Smqz8)R41=^Oh4?+d{OC`_) z0YUO%2DCvpEmK;YdY0S$HJhI~0uZ#)S_A~eFQ5unI3IG13vt@AaA;L+G|%`X5VP;c zHrRVB?G<&s_A;E&{|*7VxEb$t(G>jhHXJlXA7AvUSS`M_)q59otKybkC;TM9(znI$ zO9L_PXP(2C*pC4C_HasLlU1JjS;EmS*~$|7vHGF@RdD1rkF{4&t3Lu%sn@`3K4@#9 z1%&i{d=#Bd0?*XWbBu9vnmzp(4*74OY0R^|@)E09Oa13h#nKQys9Q2zD3#EM^^FHS zQEmm5>@3^-u|v&VFf^y!4bAvn|FEUxQGBB2c3$2Rz>w&jFv2* zLMR3$F99a}dd-XUG>+*22VH^^qT0%;?QLVsE7@{J6{ERQr_QN71Q$Qj)ME

LzN65+uVv?0nc-N&QgmVG)KeE&!9RkCW>2^ebB2f0(Cki0f5b&zne;>H^wL zSpoqogRh{yx7oAyCnX2?f5bGE~l8VdjnhJdTb6;gto4$Fv|Hb?>bO|L%zNZAcOFXG86%Hir@=G+M13%&tnA@li9qq zku2MY`hH}?{m)xVg8+c9kjd#TeCDwdlF*r%<4AY)9n}MZswZ!j`d@DbGiLwFgp>dpU=yw4_G5{##arSt>@$-+uSuR_sd z3z|$f3Q}yg+UWKhQA&5%JiKW>=RXi`GfFp#oxmVycb3o^LJL!+LIe*B_%w3qAK5%@rs@3uhjeI@+G<3-cy3OB z{s4-@h-iG2azAOKFMf|^c?fHeP8^kfk@9XP50#5p&L2e)l&H9(QVOQpF@?gSQcr{2 zdk`S#R)C;KX};t5;kpbU=%e)EE@kG$Ef$9@P=YW}3N+4Sp(73;GRwGJiLzfj?Wd#& z1t2KoE!ve~PW74q9L=+(4Cl9*d5$fn6C`WSw(7O-Ck@&%78s&c5q>owXvAhC06}K} zDEaa6vIt_6EIbQ95GhiA_ZvhGYHOi3$N45D9bj$tN%CYtq4h)f3A>K6<7bF5R4T1_ zFaICW2<1(`YLoQAxrrXE0a~oGxc7FzDJZPF+UhqlrsO**Bz;_k)6Erh zV*$Uq!d98Ze(C@LG$@YRO)-uK)t?i87gHhdVvu8BdTBF{+Qjy|09zS90Mjc^|9zfy z!)W<+6F(S7NHoGx_71}2XhX7$i^EguN`9Rj4Dzv0xwy>(F_fPwz$<|la1%c}RyfEs z_lWiN+=xpu`hVSTSw#oq%ED^qBI>GwAjLAMHHAwL0%*=D^rXWWo$Y}*PAlC0E!qlO zSJ!`z`RW`DQ?X~vv$09zu`pjOBh<vB~+DasN|c4XxK%yb-7U05DNaAWk0qWc(BL z0SMx`j@yfEv!ShDvGOF=y0J}GAt%~}a|lyy^XW9edpJx%WsRwy%36i(LALj9wuQ0n ztzo4lyWwZqxnxsKyTHmuS#akWU!zG8NIm+I?XqMcPc=Ht8)~yok9f>ojK>cy<~!XQ z?5G31QhQfBR&Q783HJ-uM^!yekD~k(7${>P+kAcap-vS) z%0fak16}hkk;RL4bo)(KT~%Qf&6i@$eFe1XL`W=8U2c>7q52llCtk%$Jn`|;-%HEn z>8V_Ls1Yjw>k6*SogmIHEq2Zt)?eBgS_?=Xny&v0Xa_U2(5#rKLVhd}M%dDR-r(dK8sm zD`q6kBA~|K>{9^AkJ!NBSC~VR*1GC)4obKhayF6Fbl>`_GeKMc*6R;TL{@(N50VI?fM!{W-zQeMnFstpFQ)@a14x%9{K7A%lV| z6ew?6X;oRHF9T@ZXQMbsUYIS|idEMaeN;61sV3we_@jP<2xr=^p@^(%FKz=PzdUqk z6;}O3j1Q_R!NqXjil=zue^4l*QcR+p6t(|rHa7IKr9gL5WnEUc{y&nb0$iN&$-|}fo$aj(2laxh@7vdt$BFINMt<4n; z@iK!VnWApk=FzwPdzP%Kwgduq?TUBuvXQZfIs_>RZ7|1bFsJgc>aYGGiu6YO4i}Z> zPhI5ayJAUf78t}=-CmyyC{7#;A45acc0??Cbo$e9&$m(Jun5}lCGcALhrvN9NtbDr zU6ExLN#B(LMJ!6+%HueE+xKZ-Jz!q#mg@Q<)p!PB)J}*~9PhO6QczH!1)6nCvcMv3 z;SkAw9bw$K-+FOAT~|RFtGn6PC-CW!5UXyXHhvbkE|n`I^rqA*8+l+KuB5o zWw|u@C|j#`{TFx0J{MgDkOB}C2MlC8lAOw`9}AQ%Ic66(Ld$2gBO7;yp51Q!+rDS1 z>s02*-q{VBlfEEA@6z8xuE{Xtv1t8A7WJh-V7{2vTo+_-U-iMo$b4j^{H~}Q) z2dzWpa4v`wToA(}xA=mP1i+xpK7k|kuk&!srt+QEwwZA<#TbF_JLdr?c#L+iXb~i^ zI=hFhY_|jYa&pmJ##%c+LKR#~ovb2Gv67S>m+C{d9lBi6CSPG6(%UUg{mC*yiv$i5 zS9&P^9J?0V2|*kUqi%iQuF6LH61c{{nEK-I%{I$clX<}C`W2hO(LO{WPb0(N*G*$f zfiwziv56-b_vd%e|6Z{X{GdduR-lA4CdXEaP*N1f)cDkobSXdLGS8_TzCACp$Bw>y zgVj~-=Jck#HEjN4f>8JQ7DaGBH8RH0RqDxMehWa58bU0=*gn6_j^cl?F#epaSO+-M z^l8|*-s7via7bCGKlc-Kl=|t@Q%LIOW^tpKhp$~x>v??9MH$Nr07UsY4zdtHfRp6W zyZICiI9+?!VtM(?{3|)o2ap{|CY` zpK0s|tb|Ac2Y@aNsiHCiFXc2}+oS}J6x)VxdmW}QYAiK8l|?P`0uc)=kj2zz$UK8A zQh?WS7AjocQsbeX+=+Penn&UBy0}SHw?N@O*0b1SiSI~^CfqYbv1(-Ux z7m6TIvw;68*n)wUz%R<~b;*qB)`#@>{2mq`PTsYMD0S)wCegVT~Y=lCP_hzO1R+!F&q2_erjH@it=`=?z+MOyF7Iy zGUe+fI9#P-IFZ9Io{2W8fG)%!dX!`hy@ztY70h4gWigIQA;Cq8kQV$@v>b?#uWPyw zm;DGpe{WL*FQSZ>qjX%3z>m_1U@g{(Eh1l7S%$c3FTOrnKvB@jwYC~bxR#ZQ!g2+* zU%ZpRNd#7q^C-5Fq=ZN=UPWZVQ9!tR`DWe?T5H>Slr~nalPDanIFgPdMhK81Ktiho zJY90StP-PvhblXa((*W#O*h%}*r>I(T+LDP*MJzTr{sViUXN0BLYoK9;+dEf`j5)w ziXr(4bPzl8lh4*5l6u0IsXm9#mNbYob`Hj6SffO6?00hYdkE7McnDA+C0MFJUMEEffN=n~KuEs^ z5H*AHlQ@bp@SqLsBz^_kep=pPb?v{!%XY%m5LCJHmA`2O_%gOOh9Zh{qD+@Q6-s}d zi^bos4Fn00ip!~}6o&i&^t0uz=bK&1$6R@NwJo#3at3Eg+cig=u@&3lXXix z3f+Y#ZED+1$p8D?w?o;wFY@9nc&~bI!r-q*jm$?Nh3cW2BTKX^%>5bjpWRuROxhy(dV5Yvijn2u}D zKWlT_zeD@jiQkO~zE#C;by3XaHa;$s$9ntcsJaK5nVnt0-~_2$Ch2cq!!%WorIe8`|+hKKD`X3Y6jx zf*mr>lBfKhskpj=8dU^>yc#qxksWoQDJ~&i%;J}9&tC$PjbjnC4j|~m5PTl7X~P80 zQRy0YeM+P*BHB`z*=ZS^7B9>_Zc|veHFtcukQ~NBX+dqBt3W68cI%bI z1HIO1X(;#O!#!48i4|6=jd7%tz_iU1uVR719IAqN@-3zVVdO*KWvggm0)Tj-58ZnubJgddi}0MRrkYV1_(3#{1EB`Q zh^S-&Z40xPY~+<2@ePEd?M#`~pU!xcryl@lC@(oIE>Wu3O2w;zZ=O0}heb&TOR&M6 z_kf8VwpJ}HHGUd8+Bl6=HGrF7+NipLBe8N2pQO$Bgwe|OVJ!}X%jY!JdJYHq(#Az+ zRti3KHui`O9lU{}(cZPCtmPVrTkB(FP`ouJ6NfEINm-WWcVo5j&o*`V1$-#iS*jD@ zrS5krPbL0>WU0!ymZh)H@8@6!oZe6F25_jf=ElvIs5u|{S3wkY2_0DO~=g#gI`k@nGq=Id@_|?is8n86soeCwSRPDWhFR<|!ZR9Wx3e|0J-_spQWkt3FLK{zxq%c7Q&Fv-+bC*yzA^wlC-KwRW0Cx<5}~ z+Ml;CwO6%mwH*2%Kl3cuNG4Ki*H~X9UyvYS2l%s#@&a_{=!fN<{BGnsZ5i-C;#R0Q zOP73uwX5pdK}m$6xC^GtMT{$%USx&QXR#0~x0aS`Vbj}T%x2O@w(x;h+w|a(&tvLP zP~q|Q9U3Lfh&qAC{y?wA588QtC-cp-mhOAT<~bCjs%EXlR$Rz}*rmK*%}oT7(>R`I zlsq5(v`tg_x{)=$Ig~ zXkv{ZsmU2x!(s>>nddoC;Q>23@C482@Rza{Hv|Yj6&LfqOM!f%*0!=ly!`lyOOx2r z32W(hUcG5A2>?YPC_nmRJAC*V1ed&Zu07u(Emy+ac9>g7@hGs$EDhZ+0Vw(|u>`)M zFiV(-qJ%C5esZL}^mj4xk`IZ@hz>{*K}13z8o$FP58nqMH)!Q`T~@aC{~-J+gh5Tz zO1BgOoNgjDyIkXR5kktlQah#$gi2D|aMD$WON9}CDD4Iz+`$I~HJ;`0;UbYO?#B+Z zS~v9rn>&2JO->J4bK7Q%uKWZ|MMBmwXNqcoN=f2qRNEHjj#y!OAA%fhuyPX(ss&nu zq7q<=kT1cZ3E>OV^N1{CxPnCm!f5mHnTZS7~zzzsj0oZufh@m0HS&e zictf(usW(N;d^k)N_!IEz_X}UXW7;{zWeJKSM9-V6RY=ZEwGl)^M1W&tojNfHebk3 zNeNF3EmQ9#j;ns*I!c(R2HB&H-ET8{|A9PcEsgI+VFCz{e+Plb0D%Dr;wK431i%z& zM2m(c6l7;G)!8i){%pXLD;I;_eA211hGo{nDVB5!Z|;SCQ$ zCh7^H-V{b_&i~1VE6h3iL-TrBEKU zx*L;&+yd>1Ep3I&Zb)pfitc}l&UY?(sC=}Y5>k005LDc{=s=?i;$)&AEIedKw|?Jh zl4JO50$5-FhrDCk1}1f`?-qxOd_obZu2RLgi4Sd-KCJpH2J?30eM1j*@u8S*SSBkN zwuYr&{Vpr}oSKHyi^f$Sq4{1-!fm7>t1S;rZ7W5MCSgSJ1b!Y66l=#Ki27dyf+~Ii z5TxFMQlHyl1Fv8alzAD;tV&C+`Iwd0zn%Q)>-3w_sZ|1kVp5E=0CC%IVO@ePu=KTt zbswhkwm@oUk$%YLQtMOU)vvs7@I;&lKoC7kRseI41t2Ipi5=ZWYuyYl5@!<*C6X(r zanjK^emFa6vzhIdVe9PzRwlD-&1vlXj76KSAZf;T+N^R`e=n#}=^~y-4cYSmx?)Ex zJ$A1h>UqxUDjQMm@j1q6fS#|&KJoGd^iVIQA_`T^g)u{U3u-p2PMPEKA_DvJ7LE6z7nWj|1M& z`WW6GwXvPI<7;UIE14#%IrUG->omv<cGfF9|V(ML@4svKGSrMh4a!Gg;U z-(v#<58}^ByrI3+UILw1c`!ywvb>r_ zE)R&8RJv)#>G9`nXzW(DVILx`CTnZE5Nj;@QnDMO0P>kz=GrC7IQ87jOwMB_nA zvjr)iIbwvOdghXNblZ*y#N>Ha|;0xyB-umjQ-dssa<9n~ou%G6UG1h#s@1MsZ+M1sncR@%tuvM z(`PzERK;TjBv?yRk0hJH+9rw;{cw$Bf>dzT%;IHo6_nLbOG%aWpCu@XvemOqy{aME&M83;OQ zt7e(7H5sM~)n_<`x|D zo`UHwtJPMh4W(0=ee!m31eONzSSI&Um`fHxOM#zX1_%@a+< zY2fs*HP`SGA&)xAA)!WD#dn?+fgsW0O1RRN)}aUfu*U(m(fyC0NY7i-%Cpg*p)1}+ zNQb=$CICl)r2qhM@K3@V8@l)=K0+9w19%~oT>wWhlo~)$!Pn}g%Bi>sIWM&rarg5B z8yb3)?+L)P>j87F<15Z!NxK9D>8u!6x1ihWi|ivPe$)6EN{_t6R*MCcp>wbp02qt_ z#KCxh94^c+mJ=$8r=Pk+wQl`(Zqwd%e7em%Vzaydju$AGwO0U&e30*JxhsjF(_Um( zM8#_C&`K-~&H3tm1x0-RNw((v6`Y#19H*-_%XbtCxlSEYcvYuXfiq|vNmg0CJcL*z zOkcfvN`&iWxSXd!vL+GHt@;q4MSH{vw>ylUe#E8@{0+)M7I5r(^zbWr&M8y?I`WCc ze}GiAkEGKQcYhyGTYBeBxKi4VqFc@OSom0VA%V*wMr~c3;-c8cKwi}dKzVk$@^iq$*lGfQK;we5wSG4`cbM4GaD=1PyIL zVaTV{d=)2(qHBfc@YDJ|EJt1h2#Q$~Td};{I7oi|Ku{0IRSO7GUr@hVg;G;_0uU5N zmb8O$+B~ctLmR?J)Zi;OSy}oebXlD6uKtLXH(kry6<%9zCC4`bqj9%HdBWxZj`B0R z;b_9@x<3Z}S5df*BK?$`OHEFfYU5{sAZSPk)DsZ27mJ|ml+Cm9-+cNA;(i~*`AUBvTtOZ9ub3yh2I#_{}( z)_deRt4`r4z2$r>TS?xwGUTOrOE0w-zeET<+}otulqy;GHo(04#E$2ft4!{5yIQHb9;?Hf&lGQPrkd@}TKe255t(+pL)2Or^MdOIdj@1qM zdlx31m=--E2N?%{#OZYp!beX1V*XE^^6v=00YzSnA`3n=uZTL4FV1Ldng)OX*q|Wi z7@LoN-v*Dc)f@|n>ebXEr(EWASb$q((z3B=()ou@00{|S)7Z3Fzp%vXmrwbSk)Jhf z2a3dzSp=YKjM~H2sHp>1*SgNiX)iA|N>SYn| zB$d~?3Ywd^TwWo3uzrCbfGknQ=rHGL)b*Msq-avjizYsVg2{?BjTPR(`|T)O63elK zYF~9RSj#26!%;t5=o#k1C5uwuVkY2)EpI%RVQ>bnE-?QjkxSiAlNKbH--izTlTA;J zTQ+g3wc~53a>b>@Ya}gb(Bcq0)#<2;3cD7_YY0j*GAW zdoS@ducw%Ql!ST%{8Gaft94j`Z}lyXy(+3M@l%$BKB3ar)mNsGV-DYCvs3-F=Njtq ztuzt(s4Ri7lx4%R_qdRN<|$FAek5LM5lP7g{`-K=Z>Pauh+!f~VHIcjTIRsX&w*ti z=;W`XWeVQ_4!n^-kfsscy400`|^z6;{DZWU#jU(Jf4`ThY&-xDS zw@OyB)kw& ztDxbC`QUdUreowKL`Dy|fIWA=FCo#xnC20i`9Ldt#T(l42lXm**4Xi*8Sy|;O zt6fXJRool{EdLNO8n%r1CA7-&KxI89Qib$9ZEZ8iJc*ObyKQuAE5Ijypkz@|`4-~h zT%EWAZ-~JiRJb!={ z-XC(T?JW?;vETLYx7aF#Rkk5y5dKwufqi6d3wP`1uICQfBbQvk9H^ z3n(uDLR!(J&J>r-!mV^*fSQyZ`>l6;aj_FcASHh}X?U^wZ*j&wi7TYHT8*~p_!02h z+654VIX~`yi}ixQ4C3TR9qULq_+$AOEVJ*w+Vlb|xnews1i3L?lN2tOr7CjV*{ zK>~u>*cwKAbbxg=^)DbuC;dQ*)5<3V&b#%2oN=pP00eRR+z4CkD)9YNz*%r~_3v0& zD@qd95wfb$=~{}ezL1b5hCOZzJHErgRj-m(-0Id{k2M*689@2?tziV^5@!Msq*Q<= zHD&;|CbUw&2n0=oi@(JhPyZO{oKCnpZt5NlFr0E1Xpabpg3kG!w*U-o15d932>c@b zUt>J&(`!IVocxm%`?V^i*xa2M`GlE!3V{2&D2Ds23`?@|nzPs$_IU!X4Pp8AGndlw zgs?r->3`I_MhBJ2a?jc9w!g5*`~=(U&cuN^^-z5o{h~U&C!|Ub6Dbb>hCOAI&;Dn? zM?eksDvhUW@Hr-npz|q)%C7MWg;dGYrUfR_dcAGMrO-$Apwr)AlSg0V(88!yv=MLR zCrG}F<|vL6jWIP(hf@;zLlY)Fp7A~Arzef0AU|cffp0NCar}Ji7953NP1`>U-pb#N zwz$&&af0lp6?#g*^&~G2YvvT}phFW?zZ&nQtgEr*@z)pC7U5_QyQ{uyV+S4uxX%OJ zpNH=KAqZGcIQq0$hjSruQv4~`>0I+qSo*+^ZDQmFOO(|xE&u|t^{-Iq3^RnlufDZfw`rs4l!`lzEg?6jY;^l2k-}O?rxGnGp z7=~MZs^W|LR>RxS{x$ljrb7by>oTL-jKC?|M}7Rn`VV1M$+o?w*7a7~el7h+Cl=}y z(Q1p+&^)&M>d1c)K7)eX8IoOKfl^zAD`GXYNBFexvZZ@|$l+{kyIO$bl^0m$>US-I zeGd9-Fo!ISAzmjWm0~Q62}GLT3Ml&&2eQ3jGn5FRWhZq7af{1VoNKZDXWAHMy6%ufS!%Td;t-1bR**OuZihpoNBGvH@}7 zM#xcvrxGR;Uue_UB7c>y=Lw${!-u}dgXL?P11B{HmVuy?x_Xw0d!sn;Mgl=z=F)_w zADZ6~Fl2v4OD++3$ zRVmRSf#;aewd$sJh7gai zq}+nQ7;<+dQp}d0p$I2a?f!e5+U`MkW)*++Wte4ul$RYSh6=CE5K>G9f2rLQ3WMPCu@c#b0@exx2Pd|o5!bQBRg?_C93k;G1B;i?UqLg^boYuoX9&+)A zbX8t9E9rqhb|9#jT`o33Y~@&MWzr32E~kx8;^n+P^q{mgC_I;# zD&AK_QHW4L)4Tr0(j4WTtK4k$o1muRAPG7aL z$^AAHZ?{#a2?#omLIVV`{F_ICkmJ`p;6c=BB$fnYX{IGwT~=1x(F5HfWz~RNU}kvI zzs2UKF!P_+)}VibkC-cYUPbn0(5`mEMFMI8qUU%Z2n#UnWARr2Gi)`R+KNR??jTAj z#}#k-5?%8wB9nmp4$+O(MDp=8We~&;SR!I{lT6${jyYpKBLEEUtxYcxj z-lEOdkdC%U%IYp$>N~nr8$SyKG1^I?pMMmKp#MgDoUv^3JgYxdV}ca-&sC)3w`q>&1<;E& zs}>lnDAkl$Ah2g_ZtGVqg=1w*fNUYwiL0}J3!~12Fy&C`a|hXCDSVzC)woya#% z`I_JVx0aba!0&1++d#jmc?Xnq1dC!~7X*ONS~WI{|EdSSlsFEQG2_5b%#WEWzr&X3 ztW|2umH<6`<>bUW-&#tn1uVfdL}G!V((73CP`AMjE>3?|`fdzLb5WoIR*w;#KoH$! z`JS%>ro6(|r)CasxE$S{wiQ_;0s$Ft+fNqiJ0h#x`Y;r{-NyIbW9gZr98tgC;_Zy@ z6*?`9Qyk%jwvRDrLHDaaIf+GNu;IsydC&mLqP0 zJPLbkrk5?DM_#eo@{~2MejCmA!+_4K09XiT{VXOuXmf*)12pYpjS0Y32Q1VRuFwUb zgggO%WRT*CJM}67Z42L7@G!;i9|cEX&g3ikHJ zLtXw|>4|73oE$V?$--5$Tj{wz!_$b$Ox=V9EfGc@B;n;&o6+{GNvtXReqzI82eBf< zGG_G!7Okhwqo)9fsNJz_zy#yjClrSt@;N0^bU|hs@P}m*0Msge!Y6!IPWJo+OQJqY z0o=vp*Qc2~vVjNyvaCXCzKmkx8D?YIm+4$m`ZB;&28*lFUYy>~&sbCQI!ns`62O$K zx^nbQ2l2!nm4&CeoE-gF@+<&yJn%6~VBulL3arEXA7L>Iz!(2#^^F@W*|r7Ics=jg za)!^SJOg$Tzgz+e{c?Fk>CkvQBcA%?uDORx+mFSF(mS6F)FZ_6Vj6r~zLq&~GIL-V z2s)W-XPLG)i~~!R{?{Vn7XksV73r6Krb$I}x-RAt=}ww#HN8j_3@R1VKl`ksa@^|k z4R5vjG_MJYo$##GL@Ts<$I7@1#VJ0+WTs#eK90Leze}ITy?k^15c|X{vBmf2XAlH% zOj(p@upD5Tj#ql2JPhB0FeU9kvBhIS89{(jzy*X^9bYU(M9z3i3W?tR%vGvCvUEL} z08y8~5JtujY6sa)F}mC8YP%4GKkHi=a;%cg6HkJD0%3#$!kq?c%s~(bRg`Y&3S@>d zd7V+IdL{wJKlzSun#T`-co6}>kZ|L2il;;P7|PSwKiSa!r)e@(SR){ywo3U&_;*!< zgxRJLiweBiWrag`+VJp$_y(x7+U5^q7Jn&eG!T|;L!gpcl@tIV7$?fgp$nd#J9&8< z1(czQ+p?Y{NNYqukUECrm6L4J_31D22UO<%x zZRF55ZEhiLt?eHK>$?iNR`9Zxl!_;v@Jm@MHPyNJ%FAO91uzM*f%ej4rytqZ`(S(w zF<6u}qAc=AC%jGEYx76`DgnaL? zv8}gQbYjS=s@g5K7R3{vIKG_;K)^K@PeBQg4qI3P{YB*(B30Gi+W}^(Wl_WN+Y3AY z+UBPFEnB|M8czcV5|G1+xPYK6mR|`uBUb@wP&wLjR0^7k?$7oDssRLzzG@SIft~U( z6S;uEZLkGsjgE$uKhOv z7jNge6c&|LF}aRq4INTJhzkP?I8R>$g5=1X^yapI-{R@LC_{Btaq1sXr)Tq=^2*Wg zJmrC9c>r4hL9%Fakg_=7EZ z%j8#n5izUam=rms^?HDyR)C=QLBP4h7Z6mk2qHzb9W??>^yX0dwarflE4zgafbRrO zhij$*f_PfM0wcEaJw)i>h6fZ%+nUmlRf(StSp?;Feao^_FWC&%RW+x4$>I%IY`7vC zwowqs%dAiFMEwd5`W-BS1O#DCF#m{eO%xE6FT22MH`1Tj-W0a+s=YEQ7fo4Z$r6fJG1oH$(v4HTo@ZnpS!cOTQ!Euv8YXvxc^~hI*(x z&6WNv5K-4_zB;_yzmb4UQ1uX`8c^0{BQ_tWpo-S zOq5!#*(oI-JPVw{_3GCwksSt>Y{jh-{XY6OTKFpF6JopetQx02Y4e&(LLHER${|1x z5N!6~&71{r3rcdiB~}AWS6{(PEN3-{NnlW4Wx(;_3F{>-Ol8?NCN5~3qrm&Pz*mLy z2`elH6wUr*rvDgGCKcZIO3;ho5(} zRo?Io@QH1j6LW0EKNW*c#ty84w9Qf_6Id2;;8BOMi!7`?z19!W6_JaE?zP$R0s6tp zU~$!OB@sFZhs88)Q1l}*819LD>QS1`JN}5?aM*;vc4TAGr1psAV1DX8n;dzVQ_+xP z==&|L7t_8OC#p2IH&I^o4_QV6>?=V}l+V(&^tZPq=6}D`-pRT6zTlBHma2D(qUCFu z11CQRmVuy?zmAqEd;>Ue(f~osCsIE(9|y|@mkO9fIo_DbM&`tVEZjnZ3DPGeCP~v# zu&yXcpwO*{BvzWxN}oLSiGJy)zI(usm;YS+qlmg+>)m1?zG#{!%+hU4ilRq+l(P3n zr5`+By!7IAUJ?#wF+ESQoaff**b}?43LI4an()O-UHYr(I{XrsgL)^2gh|d74hrK8 zj(t(CIbA8vvzYw)Bv%ktf))v_ zaeTq2YTio=RBT z>UUeLWeaI^5U$1@T!wx4oCYEuusupGPVF-g10cg!2clxVY)ku&WkwME(t`-d8`uWK z3V8Y1-dq-ZtBBfcspVt4gL2_QY!nqp3OuL8_+niG0X6qL#}WS>j++N;CFc6^_RDGN zXA-{+;kdY7s-ko0L-pVd~wI@M|lGiv(&W&N}MIg2TBHWc^Qt!we@iF zQJdZWpTS=z*pAtWPnM4&TwXwlF{`IJ2rL%vp(GtY;f)}On6@$)&Rt((^?m#xKANyR z>HKW)4U@EnV_%i>CIOhEU%ERM0KF?Z9 z$459h@ftF0A;0R7rw9<4{!d>;1h?7-n%Ls53R%fT@B_ke^yT;r(UzF9Q~w=`%z4C= zuPNwA(>y%5}|(z~K6Vs-PNfU>Bd0$E}xU=cvk%>EzX zJL~~KTegjC{P#tR7Fj)MWDk*pMUbGhFeZeW*9J$X8Kv;kbnDo*}jAIgRO;V zDOHq_tOQzDrque_(zg5CmYd}C9UQmTt^X31f+*1d9ReN#{o=MbrGH)({FUk@9s-fl z7UJ^HNA%LJYSmk}0 zCMOF5zz79YIVp$0i7Hb6hdH`U>9+vEfaXrhr5x84UR`)=ZQcnXTA zrYqWuiH0w{P+f=Zihv*}w7E>5&Gy}IsiC_Zyw26W%MxoC<5Oz^7NHx!OSL$at*|PZ zeR-$F_Y;4=?E9~ICGos+xRGMAZT zoA!km`_aEE&!%iO!SV)LRW9WvA8~QpVTFPJ&-(X0XXUA8EF9lO_-m+9`Kwav)J#LV zX|^r*{TP-Rer}jGN>fol_DzhdYu|P3FYrMb4C;7b-i=AieXzw#V9Z`EoY>kP}d;+S;kZ?Ouj1MGG}@=&!jvyVqt0?y$jrwimL!t*&;BRds&^+BcI( zn>(40AmhkylmnS6n=aB{yu^N8{tN=;TS`B$Qu3-PzSAN|s3*;PbkyZ*nFDVE4lDyf zud|YV5m4}plKtOmQSys2Uw;1!Iq-(p?~;ip2nw2Sj?GLZ0b8FgUTan?#Zl={NHk4` znM?6BDIJS{T-YU#3B*N05+FT%@uh$0nbOsJJ>V|B=11|;1Bu7;yg~@UqQuG2TfIU^ z3X8EJq7)@p%JqKfrPm?I(x<=FcTuTZS4c*`O1yv%{Pf~^h{Zr2Cis#;xk8|o5mB@- zjf#rQz4O2Y_$Z>AfSOrSdLGOAA9I{93P9azORf77O3PW~uR>9O z2=#vQ%WRKj#_^vraVORbz1Gs+ZMCbRJ90VU*4j*(b?zieHI^$u>0=9lviIWih4e(K zD`RreqpTq25RfMkBr9;_loA-SfY7@CuQ`3a2LPas1H;a>XeRzSCUR| zDQ*9O@T=`0gbrUl2%P41fEULT8;_d{sn|BERp`a=t;nkm%2)uz4`X(hzJwMHA zeHjIeJ3TL1?(pB?q;rqW0b;C>MTqJr*NIS!7Z@VC!*1f{(B>nUz^5@U(9!IEYF*(l zVIQ->mw$wn;k=bqueann06MmA%;l#DC%-l*C+=iSX#IPQTRyzqP z;+q{{YtI8%1KdoxC#->Ofn}X2T&Xj7*Q5p%E~hDQ(Z@^pxcH6`>bnsEL2NS_+;h8C zjy+&y^yApd&)~@WN;t+*)vhW?8G@YvbV~a8VOLMoUR6t2ZY_POhq_Aii1q?)Ewb09 zcHhFORgV&>%9=KP1!ebQp36U02?#1}3YINN2?(Mckycht#khP`y+Hl%`5IeQ25lBAD)`@%P9%5_99ab@o?;k2B zx#BvDcf6M{oosnTVK4GcLrWxv6_4$Q{_mm(J`5ld!&&q1ljc?ASr5;o^=ZsgOI5!M zRvaQ+3mIxRd4P_Dlx=)6W!c_2F@WP~ENQB+1Ssz!-{?B;cT)HZSOjrgke6E?V8y{F&)I}*A&f$YEd9F@)usKE^cw+UQQCsWsDy8C!O`uDH(JH~Zm>~&Jav8C z${VjGd@KEicmT>8+k(A<)LWc{ZwE+AKhGG7A<%l-o1dcCNML{no%^m!&U#f6@)HRe z`ax3QFJo!$$lbOudJ|*wxHWgb8z595NGI>=`4rWpp|+@t4}sI_OY+l|%A-+72f!5W zvVm8BL~ow7hBa78wEiA(HV|I%ig8P2_jELt>Yo%|g$Uz8sc$K$p2+^KLb5=CJbLi; zbL3XQ&zRMm`FX~A#%UH*^0LAZLZwJD8FASKkY@5JEPcLf^PE0ahu@}n#}xnrrvo|F z0T=0TSHxywb1sg;ymt6FsU3q(+X3JLB$2BJaJ^5E3h%j32U~1 zmC`GmVmYLD%=Ay2%8 z1C|~?V5t>r3BQ@7u~<=uW8jH1aRJ8>Puzv41-6}Szt@IzqFU2w_(1$**xINN0A4YW z7o99AfK3kfV>;0+`znC@H`p1s)25-Le&y*FS@}s~oMO`~u*BoRLAh#H+qT>U4LW6s zrd%~M`@(^+5Psq4jx?XKi9@$qbnFT8jNu?1@Hq80n87$4WgK48j1-HCAs)Pq_VDEZ zhekeT0|$4ooiYkYc#4&8{4izf;9ZRZa))+HF_xsIM4*qvwLqfrc5#kbfYNv$uO7Gg zBlpXEpy;az=35T=yg`o8x9n_PP&(){c;@m&8}Z2G-*3N6BZ{sO>~O_ zh~DeDZeI8VsYy_`E-9%cAgDS>4|=TN%#Au_M5*iY#jjGd@F-;K`IR30>Ysrc{Vl;M zO14OIcp1o5KHNc0mSC$5KoZpBhzO93wFizX6M~3(SQqpDuNa0aH zOtTTLB|6CwaS%@gJ1Bp#AXo@Q-66|CTR8F^n;gYaEP`2cJI*Pa5kL#45>PATkR+*u zh$TJ+KRpscw9+TFNK^_Sk)Vdq0q`TU^yxC$E)Xh6`|#VT^Y@~{IHg8P62{=rmP2UW z$95o`Eg!tql1WynyFQD#{w1VIz2P|36#=c><;GCX1|>7qc#0YM1)I-v#yY+~#otFErcBIx(R)~E!6pPT`sfIuym z6h@g^O8{2=d8)iSrgB6Dtl%qT;^1BEa(Eu6(JL`j`UgSv=C~?_x+8PM{&BGYq0V5+POGz0~A(n;rNETNv3&o5n$D zBLa2D_3)hI#&OQ8%e#huEB?_bMOp#P57^wRH*qq`!zja9tExHQ5;_(+auxF&4PB^1({LW8T^0&LlvqI(%Vezs zIo={gtpkU8K>zmwXgd`bZvrnANk4Q^ooTYg549^Pe){2||Bgk|9!uk>x!Je2z1_0u zDvOn?U#96VsGd08g?tBUS#rmJ2irR6Pt%iw)?9yvB|5LAnlB`S6`oDVFi;yFh`D55 zq62#KlrPGi#VTeP%eSiGJFOfrCf5Eb>i!yfb`7~}8-rRQFi%ObBpGq8l$4HFS1X09 z;h|oTzUs``QtXasWW0d($N`(#f171T9^rcx+o8U)1PBtqpl~H1NO=d}LqXwCI|%%Z z1L|4H#j&^*4=N;st{zSjT zFN;n$%nt!BupPF%^%@lL_wc@xF|ih)h;+QKpoGPyJ^a}2n=CSUpYKd=(D>m%P&47- zfzJbB3ta#Vc|>YD##>fX1qXr{UjU%;06}9oU(aK?R?W#{WdK3>$Xc?iBP1i9JjG&> zAwEXfZe+Z6Iu2u`U%S)Zb!%E&@Tb%!2|kl}AFpYI0b6ZoSnK^Zk}7 zW7|;o^;TJP75%1x$|?rrV}TnOmS>NECx4rMup8e%wbppb7Z_77CO-jpbc{eS#G?K) zkSTwnvIu}RA3(Lh#QY&FI>&Cau^D{Obbr*!SG?3sRiew}m=H5w}k6U;PrVbgP+YS)c+-*hqdC>mPRmus?|ppB77= zMmdwG1D0u=gooM^r8&!iAlier{Nj&plzBIsp0`GT!Pu%RXwPeC=@rD0>OTz-)I)#0 z-)3f?vHIqAt7-lqVHo#SF48Mtxe?I-1Gkk$PU8mvT3C>w+@lZL>;blJ0d&`OoC6Z~ zQMj@R@h6;A=!+oP?Q9#n4U5A8tFAeNZP6Ez_F4+b94RnPb5b@L92sNT7`Fp}(+?vv z;Dmf)KMtZBv2MH?zeAT25C1!&1KN`g?lEsOai=sdMbsXjW}VBDXgD* zZicT|?xZTMY9(Vt!^fzpPI{%rudvXhHtq9*TYEAela3CaaBD3+lZhMu-KuWt4tzA- zZOPfg901YCxN<%2?%s+_&_Mv&ApgTjXPV1M**gGbkdMFF=WXaPezhhhthIWBrP|;x zhaFIu5SJJ#yWixuIF?dV$7BOh%MBRqs|5Km8sApx;dVPZ%$8|R6|Jr7uo`W-tRsDV zo)wU9LidvGqU0$q_dQ4^>eMP*>2k{@QNX3KU#M8=QaHbrn%aYY&?bCT;A8n(=D<0vchAXeyBz>|=M`5vne*|2^0Wtlv>6EKzQ}5!1R`z8@1$&E2xp@b`f<;gQ%Z301 z0Ze3HwxL&UM?vgiyFmZbJ1CG%71EXi(W{drI#Z5F~22AWrn@oi35DH+rTr z;I=9}Q1N)+KoCi4wc2u0?El^-Mz?cnRJ}ECdOs1~iKF)#whF0VrfFjW;^h2Qr&j42 zLXmjVW(2H`AF;+-9DsHLewAOsyLN6RED8d(eBn~&!Lp|~W#!=IE3!ek_*HySD!+FUy$}!-fp+V$`GY9C zBM(7krB$#0_p~z<6)b&z)*|R%0D?#=t}PHcfeauBkMuS+TW>9Ae31Hw4}~?n6QR`a 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 z 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∾$$uf~9Q+I8elwb)H{Nt3 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OXUZ%-F9zGy>C#PY*eAiTT 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�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 fXNgpqoleLzgtc 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 literal 0 HcmV?d00001 diff --git a/images/getting_started/routing_error_no_controller.png b/images/getting_started/routing_error_no_controller.png new file mode 100644 index 0000000000000000000000000000000000000000..ed62862291d44375df857c582580c98818f61029 GIT binary patch literal 4186 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 OqpxkORipVR_J05~$wl}8 literal 0 HcmV?d00001 diff --git a/images/getting_started/routing_error_no_route_matches.png b/images/getting_started/routing_error_no_route_matches.png new file mode 100644 index 0000000000000000000000000000000000000000..08c54f921feac292aeee8ec18349d8f162d1d6c4 GIT binary patch literal 5913 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�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 z zcm?eqd_jv`v2(8KsF-e)&Wx%;4y}TRDma}Pa0A)_OFW(E*n;#LBKF>BbBWV~5l>!Y z)g$fp+iDi3+qg6a(kRRJ4ff9WC`bo_5a;^hktAP6P1^8&8ZR(VkiV1!bGxKncf+BDF^u8s`&ftCNrF3{(Aw_z_~^4pQa)sahkFxOl@$Tf1lk;`(BZ|8t1F3 z52jpML}2Gx%hk2^Hr;uDbTX5%(ddOT`Y#)nkyFdG299eg(-}imZlm}C z{eHWdkrfR~=;J^@u^T$fj6(uPuIW4jdc3Tw1j zaTjHFmJH~{DpmxUYydE@Aam3+8N`xlZ^Qa5bpV6KB^ZSbqc84?%o^X+smkBFhas^5 z`;6MgRHdNhIjxqd?T9k4eVZ?LZhP}mkp?ITOhAbit~)GEo*MluqXH?+b$PVNq%?=YHnfNxRDLJ`s(>BCJO zEvaZ@V4D8miCKU~FV2 zTq9n`<;;Jn7{C1=Fo09joL3e>A6U8!8A{O7sRdmt9S@11c@u!k%NxT~^OjBrrd)9~ zSfH7@qW)F?XxBD5;95XP;}lqUr4{50kb!WE_W7;B9fnjo@R3eG_KXo6U2%)zkv;;< ztCU1|!h7-BwjbSuM_z@O+1+yY4s@JM3&FfUV+H+OsRXAxEE^3*c_((FI^=LK=*a

x+c!*2H}0Q)8r`gVv2Um^~a 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�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%0Amw*wwxdgjz+`n6(%QE2+&}TQ3f>m5cD+1iU%L zrJAKa6**0}6sT^70IFkM!w_lX>1vZ;jIcAWn3S=Tle3bc;r6nVceBmInJPpA{lwk$>G0Hn!)W02t@DEDm6fZ#z6g{7;sE0%Qpq`8Y;nmjd$1N`unP zs6l+Aj9!wE;@&d(g^XTuVzRa%Jd7pry^NH|#V6-P&S~(T9$hJKgWWW^m8+j?ClBm- zo|b-CIylWZRPN7RN$I}Tt}a1;NZMGJSO=B?b6|pv#FEdiC7TC~ zN>93#p@@g6&Rcw-Ccf7nY0(#+&s9UBH&BFvsl|6f@=v~S#7RV7@R#?EJ5o=1YE68x ztF0J7pfJ3^et12>F`?N!MR{`V*Xj|NCI0j-K;p}T47@*X7n@#nggt}mIdhZ}rh)@# z>E{Pm1COh!$}mL(g6ZtDR+@Fg^3UpubxjwisG#1E-%OSa%F`J+ghT5o6|34dN=ndG&I1#ZQZMk@M!+d zKm|{0qqD12i4O9*`$4>HANZOhYii{z3FnuPqj8$Sb|`I~TE-FhmCBm07@~K#T2c_% z(G_OInH|X=M3=lefR-aLt@bt0$4g{tcL&uRCE0ilt*Q+*(h>U96wB`gg;E`~d6z-Eo-7u%Y@_?uc95)3VjZx%f2V!6OEm858^b$k%d85_`XNKs zF3{IBZTy--UamzNY~-lT3NzGvrhF!M657(mQJ&>xloojLR&jRTta6gwk>g})&F>nE zZ8!sH#(VlD8FI)y@?B)_EJbi|x>w2VV2FOU`wIbp)c-ee{wC!AY&1asr#L_3SO`yk z3_aFC4o;l@hcN>^c{O71&p|H~Sz~+(U}BUu7H-S_drtcGXB1VCn8(1mMg=2#x>pWf z{?G&jlYx|0Mh!0z($500CA4c-%ti@PvE&5cnQpKtItK2kaUWk|y|pL$&~{ z5*~KTBEL10t8tJ+Q}ErTPvKEA{~ICRA?H&&0cva|%Hz)+;FLuWk*5LyrVQNSg;RjJ z*NfXLq!6vFtdO1=Nkl74nW~KVlW#0l?`0|l&j0t^m2(39NTW^UfyoB&dc{W}e=lJf z`tZ;tio@$dpH>nFyV_Ex-in~+(Cb&o!#Pr^!l=ox{^QyIvsGSc2SyW_Awo)-%j;I0Xa>p2$|kWH5*b`nE~U zpX&+=$Jo<+7|aOWsauT62tTnWGhO<`H2wdQ85zELCU3rbYi)eOZUa&EKJCuC=AWA5 zZ{7-4J=5ubm#QWlAGFif{y;_4D!u&pyN~8PVWv#4V51>>XBNv6yw-)em9z8+K=Hv` zBg%-Set@u47cMTM>o@@RBGB5-oGhvD5ZX@p#CjUtN#BIK7_7~DA->PG-YVQ4ols^S z2;_KdFfrJvz-DTWGI3UzmxllQ6d{ZIOb0H9Obqak>th>6g~#TJ%b#Q5A=S6Q>*yWA z|JCW+q{>UQmg#CX=h;k)b=du5>?3~m!9@JldBHd|7c=wqe`MP-&oQZS`p4`dqDoJ!++zEN3p13kLcES5Hj5Td*4JBFKXv_iF5+&B|uDHOFJ`Lj!Qwd?cV zTrTuuD-C)7x|*MB7d7>1B#I543-~Rkgy8rcqxx5_b)RQ^a~34`QI$tL$cLniSb&3? z*l{hrYTg*Fo~#1fw_tD@F-xeae_dF%r;WQ+YZr#8eo8BUzo1JWOeC)fCsilqu|7M7 zaJ!Iyu@7F%AXp4c#_2;m|0Y{t|H9RW#0B-a6`vC&g#u`9jBXF45nGIOkB17~ebx6a zIYVi5dmbb7{XRjkIZ6~TA+9pwX&Cho5gUUIi2g|3HOFS@@6`91#~J>8IvajGpYZQF z7?dWhxOagfW0wfpK6HMnxaORZc3{J`flUu1iZ_?ugW2GXVL&*hs4c_M;r10Z~)JU@^ovQtSck?W$=~)Qw2t zQ6tKGSjTKeZ^|bl{XE-*7dFqPNUYVuu5;AJ#~nWXeJyhb`9403)_zCAsi*X67l~(C zMq^Jxs}mgpakH*bIyT9wszHC5d5;rl57gAC_HrASY#j{41Q0 zj|eDg08BynuC($1Ipu3HD3$F9`=B!C&}w_mlYR}o^3_sv-0r{U=$z^fQCP=1FVu=4kBv`jzH?&8V)%EZ#wrR_imvk9=1uD>&q@yhE6Kio(y zQ`~muoh`M9KG-tLcHFWVoa!r|&X(=+@SZEqY$|4HdY0Asv*_9)U{b4p;lQbtyK9rXpL1KLWnDk;|tEge&0DxCEz0X2C3&4wAD zj}LCy)T`ig;A7UYw5$szMWr$`O37w@QcDF_;6+x3Pk=X7xG-d_+gWL%G-(W4g#7oh zs9OTLFfl-*%4&NxfbN%GooiT~iFW2uN-bkgsf~}BoVG1cB8=DETbLuvV#2hP%@~=; z)#BWaILw~nsT2WQ2g{{_R`0(1^17Dd5?k-d^U_EjAf~bLs4 z4+NlYJ@=3=K&b_h%l$i0IMc(kvTin~FHYU;v9Z856O@B!tZ?6x|&a2x@gX|;HHJn(W9%{T>*(8Bj0n@qr( ztw|Y7e+r3;?A?uu*bQwV&$f2rn%Svjv1_A@T{@o?c3FSv$uQjQ+FqfFw_t4Tud%Z6 zsJjRs3e&y~CaNFB5_}mK!tO>)=rLuY|5HD?Aa2=CA;34CCxa=j2d^5hS@f0>$C@%9 zI`NS%#YAn{@h7N{!2;Mc927rbwBE5*vu6zy7o$^7mc5_+^c{Ad=J+en($vw?Rg2R3 zOy_?^ZslB4A{*G5oPA{4b`Y(4%eb#u zqjkWKpO$w!c+RUY|C#K)Z26aO-x2%3R;lro5kQX=~#xHgE^N)vP*Yx=l$=jbEh2GzGeCYTsrc+a=Xtd z7&|N6b&)Ntznc2=-VBuAgR#G=Lf(0;B5ZH>xBUKHQ{EAw0=Bf3^M4EO#Sv}nsc;W+jOO?%TjYdO?V+cCNHu8g+ zmH~wiEY>IfI@|fbi!FnDh~#dRGVEFAVN3mQw#*9h!ln-4C~kPJSt~E?1@#OD?|A>V zy)}M`_HB~3zGP4O=G797qK4+&cME@n-16HKRO7tISq?*`-Z zQnH-he15blJWEn&#Jym_0m4ka2}L{SO16WjX+LzNe%?W7t0y%Qf^mWICzcpDiJF(n z+Yrr5T`lwFAa{d;@Lw}tFk1ks-UVQYc#Q!j_J-&5B6d|k^3l%#U?BN!`VhDK1n4ZL z6(i1G9R3D0klhsAvHt<`>~X783Y&L-yt=yU5hy9|Fo=9sT!S6g`?KkNtMF#-?^6bJ z5pr*RQ^r?yqacp3=n< zA%9@<1@Hb77)m)-qfb;m4X&FszH@w96ayH_6DJp+cqW?&Wm0ZU>gMIRO4Uv89f>Yn z{_}NX+w+PiPjDj`Bz{h$MfMsY=OMxT6ynnEnEv?m{s<}{!sw{ItC}4nPz*aK-j+zlDoirkmF?6%vxM;ut6cMy~zT zxzztb?+-dG_Ney!{1y@jPm*vi+hPk$H%ds1@u7}yIT*&uPF9nAH7ZDcR~x2ebK#Bm z{}#3!@Duc3`i2DJ=-gBxiU!;%S*l@mFTGpstY|#nRO6*XUBRlcsPRy$s8vvMs@8xY ziMv78*h?_t}pgZV4iv)$5}CT-HvH=lCZ+ zh`7z1aUm%x``C8gd~0l8Ni?JWv27g`oRw8plT|a%P{_Ay>Rvv!wstiR-L(Gty0oHupcgbt!Wk5;U1b6j z4u>C;|MVtyV(9|iFb1o@p6ucR2D$*e-X$P94&E~Yr)i}?VWke+ZRSnK&M=C&ZPlCY z$i7$QpP4xO_Y)cbG)JiZ5vfNgEuB4H%re21F0s96dKS+&(5BZ#)W(8Ynd;=HP6kLT zsiYEfP5GI%IPWmPXHX8T>0!XVIMrTZUND(wMTG4Xy-Am3W>c5K3cMs0sQrTIm>%t} z>F=F4dg#YC>Af>Ov^wk@|3AI1L9M>m<@iiMF$6rtWZSOL!EX2#_(6pgua>@$$1@7!(?Lls?UhP>a-eeH>!NX(r!p!26hIV|p3 zJhCc9ds44`|A5hXqeaVH(YrZV%rgd#>3Q=2c46`+Hi|lLHdnn3yvKf6 zOYJQKvuLp>t~B?bd=Dgl4;1A9)p}*s+pg@|QwR=RKK2cK*`|fBSPxU1uK#>Hw!)}I zxIQ8|V|{YqGhkVKF#ve}_s$5rxX0-LYKR1}9BTlJN(2SYkL%$^m9zdT_y#c3`Fel+ zw#^IHr=?mH&uI>sjG&Yb{Xz^F&Px?IZ`tGx{ldZR(N&WX1|nW$2X^&aT3{sRUeMS!E(1KdNO}O1&{yfb3^yb{W8VcbHK{==2Zv zw%qaRg`gooTneUs=L#Z_7rt5Xc|a}gJw;w~L{}O9zJc#{zu9INDHP!a7c(d6j8mw3 z7~m!NA3k_4DuCOQ9iZ8$4+o%Kqspis|HBFIWQTF38uymn_M)=y1&d>PRwMQ9HSZ!m zFRt>+-`1mu;|K zny#`3Fa4JQ77a!A{y0HK1B{dENOl85{OMCO?!V4DYr~d>mXV2vBYMk!H#3hHNyk;; z%5LwIdBM83bz+y?OeFKra>EyB9^V=2#5jgsTDIxVZ_}SK!s-NXa2jLgPntNe)(V-*e?AT z9o#yAKm}`oyj1qp?WYe(5(YD21;O7($@-IxLwj($X_c>O3fxNIzF9}o-S5XJc(znQ zQ>hg^gztAhe%qlx!!tmGTDuItpxp@y`|BWX|SpQDf(tO=}|2=K~9%>bzoeLekwF^k49E^OA6eNI0g@g?1-xB5RT{`lGjQzb!v48|U`WPdfN!{3sqmHFGI5#W+Bo*;a z(B?_|j|ugwxqZugODbGG(&poDw3_L=dK|4@`tOKs8MZ&?-$!xc#oW7tlz0a7om}%) zwx&azgV5LOj{KVP{;kUhKeg;6HDlcm1!>_h) z-FHDpu9hnBr%SVQ8mmTbov9!LCuu}1rBZBGASEzM)rLN0G*^+fTFEj3@{_K8I&RmD zt&OYB@8tV3p!p4So++`qPNbI{Tc1_qJUZNT4d!f_4XXfWzE(P)VO)o@#Aq@&6OTYr zvgBuL?8qOcaIX0nOYwnv-=$+ z+nrEc9?m@NCgu+9Oj^9eW{9&}>=O5{5cvZu`QZ#O$-B8 zW67Mw;nr0CD=TP-{jVOQ6vnUcT^Xn&nYln6sh{-%e&nA14JHX&yAo1+`Ugb+Kfl1~ zj3Z8#Bn;T}YSXRQA5D=bMa({cpCaD%H7Xl7UyR%Kyuq3}#^MGVS7E2hasa?6`7iqg z&Q;dtED5MrA1W(h)cnp%l7GgE1^n{Zw4dvjAvMMRDs|y&87A1Z9`I)+at?6iT(|$v zFXf@>2gJVPWjq^v>l2P~nfc!K+it^du<^-e#@pTO?CKY+aA026>{`14I^VTh#XJQ( zbkil~4pe{|Ie-H`PCrm6%b5*lPfiShim4t%1b8)k?CS4#1DJ|t9bal$g1F=8C<_<6 z8fC1Q^9M@-uMJcxJ@ zRCFAEWwvAgP0;$xt=ElygN74V2;eS5|KIFvOCVM>2dnlO1dlPTnlUmU$0?06)^s-- zRIeCnZKb+w3zL*Cs&Ex1u6;7!uN)EcN`=1>b zKcR9K@1L3;3^p?yx+UWu#TslD&9q`%u9P7SrHngN%7-rUn5s!KtZgM0z{$0GFH#{> zP9yJc5J=Ty3`dQR2g6zdtF0j-xvRKY9s4hsH_Z;4(}k{z%R6s-hAxyF7LrWOOs$Rs zVJtEP)h@@g^J-?A1Nu*fTC$8y^P4gZRThmp&PKH>-WxM083qW=3C} z4>$g8p;QOc%pg_%)4cuWk6->$_-PU?XHc7{?P028QEa8&ZyswMA^3PS{-$+C@}&Ho z-e6MmCJtDg-pA|RzIceFv95b*+YHwMRK!+HPidvjWJOxZ%dggqkZjLSRq`|$OY;)H zkxtJqpJ4Bk+3#TF%QW8so1if1%wYKbNt+HiM!!TW!gDuZ~F;O=fqc?#>xUfvj0SDE>+mdX3dxy9?dx z+Nr2<@=TSG4%$2PUm}u!cQL5K5_(u{oPRcoIyLI6Mj2;yRp=#SFL>ywGip38U9U)V zQs`;r5=--m>9NfL3A}a-%3d>69@1+te?W@uu|0+W8F=Q>CIY*4L%a#uT&?A+s$EIA zhUE{yWB~Zsn{>O2(5IwkSHqa=P)QCg7{&z-WmHRT1bXI**m@yhR64=g3Mr z&f-1_+)V$*fxJ`GagEcI_fM-#9Fy*m`o;#|`j$|znq=tEnJa}_C$wRi@0B4~98AyR@ znhWV$%b-}s%W+8dC!%w&)ITS=#2KSsf<^IBk)cF$f`i5J^L3`gF^Vq00x+lOT#P8w z^?Hj3&0bHEJxNlQAZL;MU$#fC#ZKE#p;BOD{$1H>d(3QWSY%)a(B>@LGIPM{`Eh<%sGA6 z%Jlo*F9PXx-g(@6qt{QAAoK?Ie1AcKZP`!XVUPAxa3?v;=&sk05VrX(ZuX!KVEUa2 zaC01>wg8G}L*qNuw12{`tmFIoEgyS{}+CJWW0rH|NyKoFsmfMbZJ zcz)aCERs*d*>7h>0{^!DNS7a&IvHjfa_d;2o+9oRhQy^^?Oxo@_qOS&tT2+3xAZf~ zQHJFf{hw7`b)Jg_92*btWp*{vv>R*lvMD6vvMbu1UNM1`yMp-}I-)vOr3B0T3eD?3 z*Epp81o^hQq%aTZoX^m+IVQB+xNI~rQ7&U8=%v$k%Wr{LoO!d2L+4FFRi^Kd-f-aj z!W7vJ<+iG$MmUPJS+lXqD%%b|#0deHG+^-2m5A}F@Pd$C(Ycku(1S1kzuIir@x z`$u^0NlOCYOW1#BMx|QWv!lL!Iy6NkE-z~DOZFP&7GPqKD{|}mNI-~gy8xWK^sT-? z!=ERGDuDPZfpfg-#wda3z0m(sUr}@a=Qat08%IhdjHvTTh5Rr1mGC3xt`gTF)u2OC zPq{_#|4)B~1q=bYWih%Q)G?+Uad*M*Q9Uq__LE&?7`)RjJ`vuVJ*9!9&_qNls`>pZ zLhKjPzpdfRinkb2FO=u4jsh+{?n&VIYLVI%akm4dDI_u4tio@x{IqGfWcbKi!H=J1 zbx7);9me1o;sh@R>Vaa{uf{jaw{J{*c=XCsI4^G6T1FO#^o3O24asQ#vZ1mOz~(*z z+Lzvc0o?O9x(J(qyj;aV0zkpn>S6#K^#!p@SJMwAHi7BtIvjwsJ=TH$eq|>JR>`;U znwlOHid*P9j+*35XymRZVECC9MDBNu3cqTO*VCn+`5h2W8?*WZNAwj?8zS))XL?aKgFEbl|u#<#D?c4EBCsQA1a>f0Ix8 z1$2tzJEkAQ@x#(BW{9_PXq4sRDLl<{qTQW#+sqOEu64Z0BvsB~N^?Zo(Ooh3c-+~0 z_ID|R)t}y2P|(u7{2`$Xs)wze_mRi5;lP*Gf)N$d_>N#`V3Z2Je%7~{>ZN)=pcr$DWqCBIzDy2f z%s+OkLswr?*3_1{OE9)`x?3ooyY+)5C~<6j){OJ+ny)(6rZ-Ce_MZ8S0i3kG-)k9_ z0MWa5nVWU{se6qR6M{O4`!d2Vra7PMnL9A5^pqDM&pk62Jbu0l=m54^f z2Qs>cB=V{G-s|;+aw^3Tn;eOZ;H(Xo9BIGlsUJ6sqHKu=TK~8xFx995_$3w3%rVp> zD97u{m*zYqeR-O1Pbx+Ty1FA8X}$SiNbM)#f+08R-nt;_wz8qJ&)=t~?28_BIT~@7 zdMeK3qaykOxYIe&r-lrX^d?^TU*gLNn7e*T0MhK;mhpybf`RJ`dLN(ih$_Hm@3XAM7Z~f!#$oMdDAN^Yr>45bjYS&b*(JAT zc6X;NSrS{Yen}OY9A0~0kRI-JR{MPQCM!N(0(7KERyl48v^NmpO-k-rf9WKAQ+l*R zduqKRo+$SHz-m1Pzrl<U_E}? zUi71a{)DgX(-QY)Fd^==``F>;Cyslv6O$+UzX~5u1*G8CB=3E|AktP9J$>Q^J8F=Q z8pTP(#FJx3?unQ;YcLNh5%Hbe440jR~U9GD6X(~D4QzVYz(Y1h-kUp zxN2Jj^?WDaW>L8Y>Hj`fyfLXB-LC!dAb_v+K*UO>dsV&d-MSftkJnM)ADjACQ)xc2 zTu+=e!BHUA+fGswBds!T(=%Y(OBO?Nh>Jc+1Om#IclUr%yZWq@4SI}x3sefe%jox1 z!`+`{TRKnTnxaf-8hX6+&an$yx9Fc7AB)UkK~o960n&~*ufG*ZjVVJ_dm>h9cRXlH z=A*+(pF!%;15m56Ks$!IVVDmkz z9f7b)x6MgHDmlcw**U(-_OS8?l5Vm;4?1R?W#D|qxLAhFl+)WO0Lh>^hKBr=*+t>U z*f6y)Z0U)k%{_lthMRBWucsgGv*5eYs#g92S`o?QjA`vkfaLO} z^?hw`1!wuJFf?=AbIc|P_VVEE0!3%zCT(xaII5^Nq{XKZjWep1V(~DLJx)^z=%*Au zABw1HxMSfOl8N0|b zrO)j(@g?mw?p^srtx2c5O;Pf?$Rnsd4QFL??=6?BP0jD=Htdp$chNW6l>{fzdF%Eb ze>dN{d4H$8BPt*PjaBWT)*nJhZZcdJAEpLZU23=*Qo%rj)@WVVP+<6|ZtFDs(?oa6 z=om#W>nHJa>ZHL2Zv9HBD_8sHe+9!R|xS$nQGTdwiEEmZ4H+^o&9L6Me;6 zTa=67RmaEgiiY`E{HH4ymOi;ryj`V^U>s$8mF_tQJa%jFcwL#rF2W<2S${`a#B9si@{ zJ^SUEGUVXw9vz+}EZtC&7vw|e{^^tYj+B45YQ(E8%R1Op&qH)3^^4BY4Tn)<3-%fi zl8xkJ?(}rZ(%~r@Ls33GY?bja91l9(@I8-TlNq;jUF+nLvtAUwcFo1^3;cYXl%!&8 zNfn0&yMaR8q|uM)t;yasAOQmc*CByEO>nqWa9_88a8YA-f3ctWBHQyND_vu#A-_t% ziu2VPK&tV`b=$JH?pY1g+@b}xCOT`58F$>UPQQt2T_}5P$e3Z&vM+*8L)ZYRN9j(2_= zh%Oh-`92Vy7aB>LOYnoe3PJKRTM|MH@zj~bKI-Olw$ml8b1ntYunX@A#vRg;Hc~d6 z;4s-cHpMQl{f)t;n}%l*D`SL&XlZa@@JEbQA>z3wnk5SbT?UX5eh(%damiDt;=8$B zdkg5u*X2qf{~XaoATHk3@#4!hW;TbhU6L!xQmywM?&l#%S0qS;^5) zE$+52yK}(}wz%!#Bofo>B~}xZNEofKqIjy?+!!QjT9yWm>5Qr#s?xKl2Bk83`X?{{ z>$T#Bj4x`~*nNrfxIoCHv~eb~)Mz9bT0mmqB=5~1{W^2$p#zO$qCUY6#cd{{8*d9V z3NB6B*RD?;5X<1C>tX*_BIF2+_n3g;weCmgmu|s$ zLGJ;Jur;p6B?SowRdT;j8pVwvxJfN`&_Lmor2hb(H6ZlqHUc_ufV)PjWpU8=6Iu6E z;+uSC>7YK9*g}nQ4en28%0aqsjh>V_Gc!#X!g0FnY;}8d`rYY0a%~un?2EU7+ZzTX8SUL(MfOVg!D+<40REkTH!e&N1qhnpEk{?8 z^?2)B+S}gFguw*S>HXrk*v36QX9M?3DJxxE$nE$Z?uBo)t`l*Q zDMl7j{jAcxfaQWLYA-pHwZHJx-W*l1CKxx1@aA|d2+L?v++-5Ui1^VEV+b-p=Q6>- z?jr<|ehAE%=lhrn46Wmcv*gYzm}|^#YAy3`y{l-q9hzX<2Jri446ODnPIEa)Pnq$1 z4z3BKQn}+GJGR(ZVBWVc9Eo2C!9KR~JN0T9ou>b~hGyl)z5U#xUVP;1FKyTFkls|{ zn7O!GuUWx9;IkyjhgemJJ#7f@C@3u@u*0Hc(PQzfzZkj6%-Yxxl|A1Wb>eeFj`Wj4 z*sps_+zG+emt><5>OCur#}D7jNqpJdN;>}}&r{if{JH3PL;(M4LdO@$WR9kZV9T~6E& zJx%p7n$t-2L?Or%KB_Jb^P64I7-RAF1(-4ZLi%K?S2F3S+Td54co4s#@K=Hre@umC zC}0!@4nbte+5!SU$767*2Ulp<6kkcvwOBZ&1x!~2|?W}P~)!(ml3nypoX=jAudw4 zj66FF{PnCvGSCEy#-_(Y8t4|qb<-I7ylafRF!m9$X>6#*3hAc+Gd-zxfzrAc4~pVjNhIHKlGo;A*}VAN%< zUfMmwNvN*7YdLfE0lhbSBL*w_$@^qEF?##$f;U@jdSm9QW7PF!+qd;VhwtzajZj-D z6d9Ju8jts*%y0IDtW_DrOCcJFcP|$zqtPbZ|D-wqiWBszm5{}>Q&x$kDuHE4gX2Fd z9L6$I;=LJtUP&wI7g{3;k)k-C*#33x(zolgDypPJ^4FKXKyLJEk~dW~B8om<8#|~v z-ZL`OJKZx^o5HF&O96!7%S~E|UEU*nG_SpSIvoY$YxMK6U>49m6Ni1iolEI9I6n5$~pr@rxia4*)Az?AmIP|ok93^t^zqSlCE+>7YM9)0P=UJ7l z=&lB^35RH}sNH;>ziE{w!ylh-BR+B58ey3(t7AnlgBRw%s*ORKjPa-~iL8Bwt%5FB zgZLlTWivxG327f&6ZDEHugsv(z(aLO>+he7G|1CAx6dKABM6cn0RhQ<5Bh*~`&1rh zjVNG^!x28m)<$QtFQ%T}US?0a{FY7~>zl{wGU28Sc8p&Q8bJ{j$?MCe|Db(IXI)$L z`w~RgE1tL;J8rXlKGlgtD@1Rb8>wJBBy*}f_|n?&Odh2?+#gUniF`w zTKTZSlp_*iYK!a12C%pw4R!o=J_(%#XQQ!mM->xmeN)A7;d~E=Q0h<8T(d}uc zV~6**NR544d)#7a$8$@a4{XhDvVTV{-Unb07C)dVnLI1QssXP3$WtpjCXw0_Q+qTs z%f80^L6b{V(yUFws#$4HQ+%!@vg8UeNroA9|*rR(*C7`f$Utie%v+z1SrS4)XU|9OS}x3Z%1h zrFoft-N61&Ph@rok`5`3Mk`BxY{mVG;2=lbUh__qQ>7>>i(G`Cix195{4?b2>#y8s zEA7K!-p)9L6^}7*h_D34dSK0lyQhE~=919+3APk)$zP7gMV|~e^Id;d;^>IF{J4P$ zvW=gV->+tYYPM#@&6;NVvIT#%nSDzt_GZ|7k8g!+MiTd+9^Ghvxq-T$SZQmzU3K%A zLgmUAaSQ8JV>^dr`B8}XG}ZiO=v0CBWQm2ro3br9i%l2UI`4|ZDi{m=ev9kXbCEe3&9UcQcCds4>ypUP;0e$ zaTq71Kc=Q^gd0%fcTmhUkv|!R@z{pkwX6_hyU590t!c1DudCTkENt5(6GwGklRwP)(*?t;7O{l;^Fz!RnT&Ei)tw~KF2S< zXD0jax-hR-YvAggb`?NG6H;}|$r4ClUpQjajIAPprsFZ-_aRJSdV@Had3;jnkPkZP ziHaEbDomWYy~qelRiP}YPiqty+B8lzcHDMQ-O03H+HP_AV=gS^jvoni92wNAlRFg% zi;t*QchKGtFq{V>xKoOw3m&_v*;PAv?8(#A0K#gutGSRv<*NK(heLgnoq^;iE+gts zY_5|SB1R2ha_T#KT8-XZ_!^P+G~okcC>Zlvrpj;|o!=ryrqNp+TJg3roFmb34iIlU zo=aD18@p*>nzk@#YoDo5%epexk86@kY)oGiIDXPH*`$)3hmG-~;v`wHuCA%j-x*8U zgaPgGqcd*D>8}lw?hM;Zj{f6&XN6tmb_?EZ9L=wem5lp-+%!sRwn%M@kv-qbeOJ{`4mf1QSlbH)FqsVw@y<{ z0W8*690D?@pKT;vrx%pw%x2o#QI5m+IoILW7t`+}GzG;EPV7 zjJ_$OkB5IP2JiEU02xi`*Wf!%G`{guWtz^C+~jCGl-O(IZpCkyv;V!@SW=7oH`B4d&o;02v*x!cy1QP}&CxEod*sVaU5rpgxl zFu8cuJRs+5zM6?h+={;h3CSN@fybA-9qcYP3SC^E$IGePIVp=LG?LdKkrhBh1AhvI z_C@^V$CbLG=UvTk)|IZ~%}JOqF0o6p%L{oPB)*Bg&aA~Th#xv{(usJM#G4&GL56fK z%?RTvRdAe51NvW-IH|dbI(AuoC?Lu!pyKh5@GbW+p|6N5pSQw6c?`pZ&yMgU#=B0V z*pnGa19#}u#U!#@-E<|jYPyC279b>&jNeqfKDEuucpvr z5|}a+#jQuJpIhR}1N|d1*Wc*{rFO5s3l~sMvjR`6*&8?~_e^)ML(Z32#(B45Jir-1 zJ_^BHus#eRm}tW1y@2*&4=B&)f6|F$+$WIZdpdE?oeCFa*7g<(GJt>!dRfEuY}oNA z(T{)?sE2{Jr1pYYj8`jZl(aa%)6!(|9oE@288AaE|sLo5vRY76= zt_-_;bC3{n`^Z^q&)c8?yljOX8Lv(77WnEPm_fAZu`I1H`B}of`s7!%{OUI!3ik5D z3eQfV^>+p~*`BZTkcv~Bk~Xjks<#^h4cgm=3-Amnk6g9v;H$Q@R@2x>>Au@3UZ_di z#A>2%9|OpK^boeUrBI29qdSt9g*9p~G1IfSQs zyr!exPTW`K6^FWA%);8?`qpD@Lh!3wVMg_v6+m3=s(Z0cN>@Soxd}c%0Cy#*iK>sRwYz;S-KOU3JVnR zg2t2lywuT#u$8*E@F(SHlO7bw-uuNsm{M(m=IxXglk|~5s1^+?2h2LEBdV{g*LEwd zdTFlu9L9Kp_lqzodz%~)gglkLUF|Ig5C%OIOirc}S%?#mhxT;41u1cbb%3usWVgij zK6-c0w?9$s<+keaOYcVd1lg*4a#R8@|6ruS=;4klLENJ1CAHXCId>dc2WaK4ygwd2 zD}?z2>9a+bq0aOkdF*A3HuD*c3Zs;_2hqC*W-!{)F|-1KzZr@ySKcz#iL{;jN2?)3 z=X<4{xq3vR(n)W*zJTNBn@^qOsQZGC+L5`dL6Gy`hlSMzFu}cR#}#)hD3b(d*W#3l zq~z+gi(vmtrP_O%()OTptH{Ze?&ZrE9vVJIo@TF~f=;+P=mZIlP!R~BhKK+`n600i zBbs~@c(ZMCI4miaIbcY+YyG8|9O)3NGQ!#8xkFdBRUzl86$aGK1Z)emStzDj8PaYm zuZx09z{=7`lghVK!}FZeI-U{-LlsD7yH^}3Q!6v8Z!><9NZ$yKHd&;Cb>3<=?6OD3 zXt3#=0ugez>^6r>ocwgKHPs;y+h-%GBFkZOXDr+3`|_9UcOE~mqCsKOzcKh?(ES1i zopKk+?fN8WR4gj=nX?iHG?D$F5T*#4m2kzfen9ZFeOeofJyEl z&I1neZfogACKO(y`>j|1F^;(d3_Sf^=bOybDSDu$>D4yd%gmTwt?-P$_V^ZevCCx+ z-nKn=Gw-0T^!mF2FJb%xjO%Fs(LG8%5_xxd<~kXnK- z;_$Tl>1mJki6vNxA%QoQK{OQEtFxv;&E@3#tO&+Ub`P_iYz2gj2@Vjbb^Xj2zTT&N z(MY-j`~nNoe)j6H=puG<5l5D2%)FP|lV@{Qu$_@SE;I_I^&Ism7s1gSQ3Z=Ad$b8^FiBmYa_K1#{=^8NfV7y*JY`Wb7yGX-Wjd z<9MnyonbDo$%w_K?9t3}bVF}mS!z(kzeAPRGs7ah{@pzBEUvoasVS!Evs2~gGCDXr z1lXmqAbpSKKYG18L{0Wt;8*|oaJN(e3f(ra-bkWMm#*ELJ`T=$JVn&0PrqHEZSV$v zmDPV(euDVw6!F}azDjnO&-c8SUX@Tm$u~iABhT>+#$RbtbOC_}>skjjg2sE=oxz&* z^TTG6O2%V+l1f}Qs$o9URcC^8dtN`kVfApp;eR-mh-*&hSx#77?q09&ViwQ?tQfjW zuc%URtLBM4mOFJ{WbyG9X)7?)jdI?$iT>1$e|%) zDuE?Q0~7=tz1tm^#A&Qsj)nrSUF&Al!fxWp@}y+6qPYxj0-j+Lyfr=?G~OF!nI4B$+8#D#bbOA)72jG^XKlQY^RHj6fqZSd#&eepM)+C+_Hv*OFZ?Kgq8mFWvkI$>c~c$?8|@S$mhNQ`w=2b-d$7Kiqyg6$dp? z)~qlN&ChqYl$~ZF_PJrx=_Up9-0-itW|W+$^K5j@-~c0|Ao zSw$DV#xgy z7^+P*6}b+36ENw1onDyZ-Yxk=(L;}a7$ChYM!1B;6(c0rwd*#n#_>9$!@Qz4eKv#j z)8!MSk$;Ge{4sqNuk9pFL%5iDIoeFuF5p|rk&{U+!4C1Gfk_P+cWKpFkL$JN)W3A} zR9{H33f^B6a(GC8Dk6I*#L!_HeY&ZesXEAZc#9NR;yiP)Gu`tT`+>6wi6#f*#)?Qf zl^}qgNQBv^fof$M43EvsVJFi4iF3(UfT;{)BXmT_C-Ws%ygqYh#}rz?FM_|1%qf+m zMR*-o+a@;^b({k9^Yghtzlqub)ngNA$Yhx4^~svf+pNDQl^VrDQ~%uNg_|)$R%Y5- zW|W~?()GV_MTts9^R@8c#3vOH^Y6CVKQ3`r5m@qN5g#aEpUd_5y zB7qU6HqlGlg7YTQB&m~y;$rx^%qCN1PR{tML_*F)tvLGKS%?r)#2mk2$eX~L20ni} zaL|>ye1ZI=c|Bd`k5gTyG#`kG=wDn)SarS*WJN9Aq<6;AR5+PwWTOeC005PR^@+2e zJvr{$+q<=cnA~p^)AZBzEo%}mDf@DDYKn?pC9~xyj9coEfxr~8gg%>+6rv7*3y3ql z=>%hSo2yAAV<+}ve&tj)2zAL&qAl1d;Se|RY3ue1+lnfE??XPWVC?G1O-W%b+1~Nt zoA@!Q-1VPW8IjZ~gEH|>tK8MCr=W5gimIj&G{oyX8)tssO}@zmSq9_8d5$ek9RobM z=%*N;v!eg};(umkKdGmRUhU0$%T#w}Tx0(}^G(B9MZcb|l8BYw4$&en_yf7_r1qea zZA0sp)>qIwVUHFI-sRj-_I2qzQ2f}M4qIuTyH4BAMy;dU@4+i)YZYY?#sxQA6&_Y< zMF+8&B_lk^3EYi}56pEy(m({qcLy{BF67LJ>d>VKHT>{rfM=2Zj6}xgKHx6-sxfKBZW+HWq z4f=w;7qilJ)K;C`Q`lI0W|IbBT+5<#N4)$5eX@ z=IhSKS$xpZcI4r)QTDHF9>2SO1YGg)na)HQe_n@pV7|hzs zhhI!}pJ)jgG|Ne(5TP~!o+Ucj^1YKOxeaj+mCy~?#WPiQx~PM8yqUhLlgRV0cC8-m z+6ly-pI-wP3Z2d4bTR?&toE2cdR@O`_+~3@OX7Omyi6o4FQ1IcaK>aK-9Za{pMZ$j zIYz*7_E`+fqv$uZ`6qZi^XL?Ufza=j7G9VMBi)h!U3Su^ed9!#?mj4{)KzWQJ$Oz_>iIV5#9wG?fnIh13DdqCf(INPhR;KiuDAjQS$2^M5# z`GL>WlS(GG&lzFS7NvjiIah(<&Jh=J$=O6I_o0`iw`Dbur%uiGJZs!^uMC+h;cl_1 z<~4#B)@=2}-14;(CAtMw|YA%OR(@ z#$nlEu~F|PBOqa|{ib7S>IP~k!Z(g<09^mqasVy;B7>8EH8}6*E#y%f+E+F*Y?KzxY9bf(6a76mZq3B6_BiPd)lh-sGHFXHaih@&|~?1-1|1L1YOR3BrQv~<=jFg zGHwgyw>j}!r7|2hq02xh(<+?2IFO}W3_SJ7xaF`^^Bj@>~|_`=lH=AU|#zdzA)qE?PNX`Niqj-k8v~2 zXK7ki?}sK|_nxd(C+l~YKfYzj=fE23ku2I_8A1C>Bg!Amqio^CS%$G4M#EwDn0S;| zzo%mn>5oH3X`>I$?CE(4T-2%?p3tYSEr-_5FIJo-Wf`Y=<;}!q+OGF15;-hywiWRB zJ^mDO`d96?3@eE17q&GP01mou;rw9#4|#9;&UV`Wjn7=2R;{TLdzn_1##Tiw4f(bP zgQE65DQb>**rIKLmwbw3DRa+&L29fLcneXqo|AG7I{m|h_ zIL@5s`~6yheoeCoYz9Y+rJ-pV>ws-W`~i*PN*SP9#@&0sRxIDq7wMeQH28a4U%QF< zuuxm$Y!)dpVN|Zxs)$71H@l48tl50sh6fKss2Axw?A@LBK`D7q&tIy!g5iNwox7iWtr=7z4*0pltfO6jUhyA;`**Ou19LDnea<69XOfA(*@k*C;o3pMP45H1?z}Q|mHfUTD<%&iDFmy%h$L#M!kPzByrc-YX zdkF>U|1qd_n%x@ry`}Yi4)PHBw4h}(mMvbhvp{IB2kJ5&Z!z^q#fZ30Q~IvG%$Y|z zAava#cl%k#3-QLq?rvIZzd$#>DOIvFac9gxrZ*DqXSs{Y5Qov;r*f=oZ@hzFhn`6J zdlpdVhEXuyJfEokFy{>2vIIgty$h#6PH3rNG>1J}=YCB-bKVCH>K+2|BY(pLF=TbN zH1LQ$MVp;xa4yaduCHE0!a$mB5~p7RB`I2nE8RDCe&j@UjFB`t#t44pzJI!z{Ab=z zq#(VSxuq*oiu22LepjYPTwTTtB4XiAA5h;UhHfzPI@%x;n{RLr9hV~fjO_fi>?{1N zt&y2UKK9dJ$;CPr&r*tdqVN9qC#kZ&RTB$IW>~tS@r}Vd=m)Q>s;uMH@8bRpIsQ*J z00P~VjU~_Yd-|BFM>Ir)uoQ+x(@4qGDY8|Z<44>JeQyO8h zC*!;*8yIcGBGg9b!z&B1YB6p1)!BN-3_pmS+SRJsSgJ$lhD~~tl?7*SPxc5=>5!%` zfg)vxNQ?e~dIJ;*o9Fq=94cTvedZA}1kXG3UQmtprXrGZS}+o-=QW%VffF#B{%oC~ zk6?==97~>80fBNdiL1YK8l1t&D(Br@C00}6jW8bSrA+{li46?`$_bJ5Pj$M$_5 z3hi*M$mmQLt!k_7Q%Tk`EhElVufI(|kM8g%y(wTvx!(&If*P9G6CNSo?*N2mL5X>` z_v4DK>Clw4DC?~DH_@5ap=YumWa|4isjIA8qJQ*wW@I?OL`n8PUj_Z$*xvT8)QG7$ z_Xj!(hl+VT*QrzMvgF%QJoXnc?cUzrCA?oH(ocX?;p+bavYkVGB{zaFkEY#TXK`^+ z#Hsp(@T*hw#hd2uZSvy$&9mu$|+bA^p8Hy zMXJ)iJb@}ivMB!D^X`Jvu`!S~$k0g_z(Ku5a#XpG3QUOcO>C<4 zu<0$P7iei;{WMPRCaQh_m zUQZ_+X(=#HU%kqDKOo^6Y(5;cNlJeH?-CRdp@eKWIf!jJ;bG_5m z&s#h7{)oC%_>OJA4I%GIiL5}`Zn+^HNe>N)GtJJ0$w8q+avJ2Z4T0OlDgnlSuFOe0 zx%McS$IGcg8xhwQ2Ks~YRJ%x(cat%6XyPG#x6Yl9s66xxYA?$j|H0gSIRNfsd;y`> z@2Lh>plwg$l!6pbufghHv$lYpaf)SmCd>AJ-Fb0+pAW6ZxOwlig3FkxH%BQ=;s{N3 z63vZ7CXW=0Wt^jBV2?i@%ME~O#7?PLfv_x9Z9%4J;xaU7!OIiga!ulN+ zpM;%gBS}dF#&0oE5WWeq13*MO+iho@M7BH6pU+a)IT(^u&os6I3r02cW{bT1%NuQ8 zVo@oAbsfGPD$4KOR^s30S7RX})(JK__}IU;ncNGwqA;S|0Lnw+v7wBgus*^(R#}SU zyVuvTS6$G*Ot4=ZOMF{Y?74~-ozV!EWQq1apPguEnkJ#;Y78}we{^6Mf@;4nj*GCg zexLn5Tlm-wV%yvuRR_5G%gHM@8SyHe&t9Mgcve0WHzIC()aO<8y=*FxejB77w;^UG z6py!;nzCI;UBaC+Gnj9_=C0?M<=U-x!VM)@l5@D+&~#Dp%*`l0(@fKM66wg;qU+Xa z7*jhn;kz}f;23JvV^q~pEtp5T_6+di_5ydi|LTI|dH_Nc7P#{&l3c=5>h_LlnO53g zqR>3YQ9#?bCHsC3{KXLO-%(liw<8?a=y%#pBrW@Cono>k7J=sYwyzC`q?RB#NFD`_Lsv#ID%W#CCxBj(r95|wNvu)kw+ zU7aOxPvRA3Gp!wytc#XT-d42dpPrwIq4k(pa`3#tF`DJayzo2c1GDut2h1{~U=$_* z7RbM6{>5y5rQyY++~b^-msML@-M8n;V60;&ih%eefFc3SCn#o&nj;tiI9>DLZ;8V3;vTIpvrYGc5x1 zHuA>ZlgQ^jTuIb19M7slzZHdEb=ZsFWeO|Iq)*{5wOdvaS74ej076@e0Gf9w(SKGSmO6+xl|>xpJ*#nj{zVXe#1lb1K}WR^*3c zTk~Y(!m{Hk!tdkiyK>~oT#}Sr3cZNPe_ph9$oHj6AZrMa)vX+pLwe#3n2U4f90SqX?zr~VHshAW-25i+Xa z)t)XYD)GIE?>$KBsjnU0+5b+T$JSiMrk_ohbENf;_NVPp9bw}*#2=XJD6i6xW3PTq zmX;cQOk}LlwEekiyf$8=_AmR95LC@YZhPXJ&)JQ;Pkj$3sU0Y27+%-%Q%8M4LB_Fj z>PX^9n&e%gMu2T|fRU-1(NiV-hMaiTU)dgaTuxsFG&k)n4x4Knzy{iHR!nAQn&afc zE8a|+nB2ZOTfL>f6@dD&C&=gsPV4!(`z~9irTg9FzWy!tU1n>v#<|5&ko2(mbf*bz z&%kUdg7=@j%k7zyL#JO>zHBR~-~978W_3eg?H3=Xm!r>8$CXppEgadG6uEic04>lv z6UEvVruW{Ydfoh7PBg*2${;b$l4!l?h+ejvecU5EX-T?kp)M)@?N;@tRDHL+$5gt4 zRkrO`f33gprbQP1TmLij7VmX-92@w`M85}n!ygfG!2$zRQbN=Ng9FQKw2 zpB7pgi@>gWeh*Pm9wDDb8pC%!hNU*!F=c+iSqLQ)EHuH{>*8Sw|NW^}%3=M-gkqnx zbnlw>YT_NIlK&LH(7`DYwf;eo<5g8hJmZNbVP-1BH)e07LCpj7oZQt=sd5&6Rdyuv zexDr>8*IbjhOMhE;1P}IWt{&kef48zs`74is8T^cAsz0$kOR2)UBz25#$lxnL`0h*FiJI?`5-Tw(Nf6}fTfluZtC)y1)*ak1@kWAp97nD>8D)j8 z^h-5YTi5Jah*kALlIXk#%?!{&vm4B|wOO8?N?e~uH+w-q1AQV#qVG)A zA1-qKR<&E~f$)pVjD8%Eg}KJ#COu=nvPx-1Tp?*Xn*WHY{aes^!B?w9rJaH6iWQlC zH|yu+7c7M+GP}*R?!Nd`h_Y!jJZXy|S>wbe!q+Q&%_JcyrTk#u{;YH-RVOCR;sV_W}4ewtIf)?g%V6&=Cs2YC2|hZ8|_R+IWtD5ICddJc~# z(g`9;N2OPHfCo6|bonT;^wCuLByFnM>}&^F{O}a$at;<~tI(d?vPhX=F(h)YWr#> z_r*DHDt50Kb>`uErB98im)8itG z&r$V)$2mfc=P*Ql3;zf_w~_U^8StI$=ZvgM_V}01mwy20RL*}`@*JUYQ2;TKgzC}v zjDH7c$2Vks(KA>=4O)=N^?S#({_48kOUlC2Zu{~&zvn>MQuKk#=9xp`HDWJ6wI1`D z9%N7$DqtAf`;=u_=i%p_6{?QkV|>Cm-ys9iRy3=++3&qYt>#e0my^1;(@$w^%J+v% z`RGm+rmXHbYe$zu845*<=Xq(P5y#I1^UofUyTksZZ@HhxTfPPW<}Z}B22H(MQ^9f> zF92OFqH%x4_R3(rd(vQy4PgbPb4IED$<{w3Y61=FZexo zsI5Z5T;{%Ksl$B>Qaxr!eM`v8nZB|nZ~ejJhO_1yK>Pbub#jj2XS&cbfz(>-ycgSYfa4qAoNX)*~&@>{Z^@7K)GiWK`uMy^6U# zhRep1eNHEo`skRhoStK?ybjLdCndxzEcWEQwDGvdXa4Xd{s=C+b$yM>NkcF}>-`q4 zZa~W6^9+DAe+uNE;Qsp)?*t7J^|T&_h>{o%lzJ8pm)}{n@zYJY^0hk(;9X-B7Z~{YiUuGSKKPxL0$Ay!tpIt>(7-U3ug7bj1sNxk zqA{R3;1_$5bPS2%0!T0aXog8i2FI*GuNdQ9S$Okgvz==OvPzLs*-#FGyXi@~LA46Efl&bh%ord}p*Q70oP zoaF_N4YY=cP+L*P-@nN*wZ69WLH!EXpynSKV?wEIAiaU7C37i_^45;YQScj~WzO+F zM(Ofg1zr*Iw`a<7zG&JqW^jl?WfKZG@$`_xoeykj;jBR%ko|%k*k2%0n5YYsQUT3H z84;8Lt>v6kNJJ6)IFQK-0I#E*mUIdH_41V;Z58yjqj7ON)5$*)u~<;cDZCapn-W;D zq_;OP$&iV6!a>LRiMJIVHo#r`!YIo`?Tl;L_Jj2@ zuK0NJ91f0f>2*Jm*PY0+Yj8}yo4p>1x-HiPP#U9{1nGM$Pnv@Ov+_a)s_={pT@~OEXLS zOarb`y0)5LdKs$BSf@H;5^9hlqPnuEIWipRSLa8NJL=y5JzTTpeScIIFO=D?EwYDI{8>S7QU$_798jKq~Skk}LeA|w|ZGAc`5of9yGNWh}aeE)XM|)d*#V#CbT2T^y@B;; ziud(^0aucBdCG^i?Kz4A-rx!&Sn%=$D#Paj^Zju+OB~=@o6ietq2>&iHHX*wH_*Bt z(JnQE*t!Ry!Hg6uMs0VKCay9+lC&kQ$$V7MpHaSSRyn`0=(-ITo89~TK7MlYH!aZ| zU35LhJ=04X@;Q{0y&?7}h$sCPvDi*7XB;F^rxr`J?(@*Ag**!ZTCP441-!&sMzwn> zzza#$*E$ttr8p?Bs{jew*u>CzdjX9*Hh7zqJ100-DaZ_U@`J|#x~>Eyo`T~ubOt=b zO;9PCX@oyPHyr69tN*gUhhZGdQuq;rQJ!Zt{l>VL&z!P}v1M##99bp;yNWRSXTMAD z*Iim0nW{;FEtgnt)>Q>it#+?y0U{M@e> zPTMJX`g?ljJy|1q;06(b;^!~H#zNLsq;c`tV(l~JOGBonjDg%K{MEH4jBst%dRV9B zFYZ2ZBhRE%9@xaIZ#RATJe?iTszLx98xD8T6bN~;Hm4d~^(5p|`zwRO?X(_`YO^1n z93JA?b++$$E6l4W-i)zM?!e?SvAz1&Cp%wa8RKxKQ3n5_aSh7!hb2=h8UO-?`%qBv zNIJi)edpBV{j)C9VajQ$uG{x_FFq@3c1HHpp%N%gcrb%=VOtwzGg9BOwJ!fhZDIuu zfKVucad8ovamD_2a=+jqf0k=n1c4niYaDnM!Rb8dQ%qGu>gPlZZ^x z9Ubqxwl-w%=1}pVu*6}xhfaM;msEL;uWUTb5vhZLpmt)jy@TYMDl`D;|5AVcZ|EZ) z(S+~MxPaDY5ot1Dl=`vdnQ_Ju;7;*Bq^@2*+80Rkv}M3sM6z{aEaqCqg_R;po6+R*0v%qavVBnYMC?!^p?SEq7Y%w0!M|@JTAf z{7fcd*hx-QOLeh3OZxh`1lnM2X&**IFDi~fZI7cwByWxQd38Fy9+4K}Eqbz%6kQ^F z;q|Z-!K<PwtBWGL1W(0L#;ShCo?`wXph@MeGTr$4qa3XB9ckS7dblw_}s z3mMQXlUFZ)+bsFAf2RHj2{bevEsL7n#U&&h!9f14C2~1qmJR-=;vzOkU3?m~L~QfK z!UsAPr&lSxOYwOk&ul&Ygf>%_fqV}*?0i#vK3eRKP-IQco-h(xkcl6lmF4s|zj`Mm zab9!B5i7{_*#)+qi?QeJXiJ)#`g(2x=EjO63XO{|u3^%ecQ0ShQEx?wxLh=_k<(ig8`(v%jPaQW@h(Xs1Mq&1jV;j^|!1OfNb=hvk*RAqhT&GHfO{*@6P^vVOyfYn_tpk zvbJu2Kf-{+r+-oz8hK*?ZC}hkvunIzm)=EX>tgic{i>w93l@K&En^+| z?A@rY#?k%O$EYG{ff5;^%VWj9lQj*d-Ace8_1~YkEu-1W$NVaXlnl?{ zh~rWTRtn`^uFJQ7QvPWyp>KqJftp=W>B(i4Q`*M`z2@Ec3b~Gk+R%Z{EoDckDl(Zx zRob`1Jcw4QBzdIaklFLv8Z4lG1HNT4ajsVV;u+GLJ)azv=6(gLg~2_IhpAJG^r|mv zBTTzz3AT*7+S;#8l0@Fbpyw|B>YX>Nz~nyNPLn;>t1NGE8NMe6 zyFl@Us~3bdI9#&jLYHpgf+Dw@ynjAhLII9C1-%(A~as4;!P%`HRic-R~ zTst#=xM^wyKUZPGTF}a;rYvPj$DB$yta)z8Ele)#xioh5Rjv}wZ9&~&>I&p7p6wNgaKYQB3Hs;P`l~L;d?Ju7nlZbnMLVHax6EevE zx;;TKvIB@+Ipl0PBqC7kaPYv;_#8CGesBr||0NEia+B3D7e(<7K*&F4hGo=hmEK3$K;AZo$dP#@#sX&)? zpImZ~ll6PXoGda)zfPQuJgg<&KM0tVHD8BrC@CrHO`L zxOT0kUklN)Y;BxR{Y5^GZ!w9Wq$0x)*RG;LX7Gu9o=m|^0vBR_nkW(esuu6EFdb2S z&|#68=4203W}a=ud|(Cfk7&!1l{`leA1$g7GN;EFj!G6zZ$efa?1667yp2^S3eBH> z2&%?5Z2+2wGQLYZnw}}?_v}LId*{x9eJ{F;(~lL#1_aLoOQo}MZ;H9R11pZPIuO(M z4kI}e@$wZn+wAR%uWn^V^_H#?o?sdH_u>xBzim=Au&1>SNN_iEx&H|eCDh*X-P_0h z##D?u6aY-c(+6!+#Iz6V`b`pGNVQ7WZ7YH)PS>WW%+T&jw$8w!X_1tt+@8mR4af0R z4n?6zUkUw&Oj(y`>%8@V>Lhb)?mEC5OGrz1NiEMHuit6wgiG>Uywj}&&D-=@5soCZ z3z!7w)NZ0RPZ*BD#lG6~Z!dFn$-mpEB$R6nmMksI^ofRfY1gq|5?KS3Ica&8N$pob zdPorz zmr6(~Q!;XKPA1y$I?S6uBK$qB=3KYNwoeuQ@8Gk-$%6lSF3vVw8#&aY6-`0LI<2#% zGPtw6g%8G*dObIyDVt(i$rT$(AJ!V%b)%j#8@l!H7QEfC$m(h=yUYUepqn_{g=c|m z?D;$WyJ%OIA>$FMiME*{^MU_wRxH|>W%Bo{o-<%Lj)Ce`3stZR2MYAt0|Fyn$v+16 zHS;Ou5ujV*a4&YYu@~BnxE3N0-h|rae{l-3J1P>nzIL7+O!8`uI?v(aHNt-*0xF{n zWz(>Xu8SBKVjo_n;Z*z8%}&uZ)r&0S*tRA>@X**6qnM6v_yjtNOlEQ@JDtWwo{ZH! zry#@BUZ4r^ksVJ@J9Yd`>HPEtQJf5$1Y%9rf`!o!&a*l9+4mSZIht5;*7zEXnsEsg zY^YTbkvQFHMq+^+Cz^}3&J1iinV*5QBU=9@P+GOG`;3Ty@)=;n`>BCLKareqp$v`m6 zI9urO`2Bef)*l3B8?u;;H=HY$T>glQXe*kcvL{DqH6AX1$bL}8qI{6Rm6Vbk78bBl78zS2b~x*@_dj>{>RgIS|BCQTH}R@+CdClIk&Br32iWftpwUw~bOcp4J;d(#& zNvPs>dxI?rIQx=sHhNqs)Gl_y!Q zGMZV1saddz)wiM5tT1FyNZ|xP3uUV6G+K)_;Y<@Q#DF26>(~_(6n9yiziLcYm;JJeU&461b*-w~) zkE!mBodOcg!sVL4Tc1U+&45bAw)=>*zg==8iA=S#Rp|nuxtrZLLhGnMI9GJLI8|bt*O==w$=~FjSA1S-fXK zYzfwTrsvw<3=*Y>+g}=5h+xXFl`>)rzBZ;fvO?F*xgLd9u!09(bia={u641W+WVj8 zDS2Pa#O6}Xy^rG%j8Lx>S6>tiypf;dnf(fJF`-0lmUOiHuJr~ny3e}uJe$wWbi4rf zyYX^t?P%oFit+C$TY}%;FkI5vU^?e24Xz%Azw#vyoh~Nz9ta2RE_UtxRTvC4kz{SHj&{ zP7ZNx66_0ft~ptowS4de)llVSF3sxim(?-fbCjd+j2HL=y{E!Z8-UW(c{M(5gC-*UkpG zV&qx?eMG_<6NalX|b>#7YOodYXU^rL@?B%oSOlQqndfE{PXm^83TeQ?{lmXy*2=jY}49e|&S zscZ5-#kA0|f;-Nh%YN#tw>xG9KYp8R-s82N{=TgB`}C0_arxnnO?PYaN30=ZlTu@E zn9Nxk2Wxu^;&o9{eDXZ2wsxL__FXTUmk7gxkf3k^IcvkBSZ55_XDxuBC*pS^K;x~* ze*W)IOaZn|38aT_mP%u~8c?-U_0XW>#oigmRB5N&Ck?h=>029F4R^{@`#jW|@34w2 zR6z+iV~`oY5zZA8%oag%xF^mY0`<;UF_QlpW7wK_*6EHRLkcU<=|B^tD}yKnM->v@ zJ#>)ZmhO3MH)N*y707yOL;pt4)PA5ci8ixWccU>!@|x+wHa$=U`gpBqCsFN_)ZDEy zzNZ9t5niGATyc=hExJ>)AB5yrp|LcvZ{bY0k~^u|$iAa$S~l z7J&l(3J_#Hv8xO#*k!Z=YoC#OjGthed98K9)=CP2+Xz5lUH~UmU&24carr?xs?tR47+ ziBG)C6(*_H$B(lm8VSOGf9=&h_-timYGSCs{_jtd>dD<1`K`hX7?_1f8AkeOr>j#p zJ74Cl-H|ehC&06q`QB=t$cd5q=8zePElKKC)PQRF9^T$2i_mWSqx;`8W(b@yC^kTK zKH<3TJu8Z|CbB4W;H z<($?Q!c4US6brbAoXp}`vMI24hj~m3tGr>Z^B8J-U_B7q;bYMinK*h7(8F^gpI9#A zO&n@&-{-MT_0fLS0t^c!{|8;@=0`;W=)x7|aVrg$s5{m|`h+Fhtc~+ZUIVa&Ovm2m zDri5tjKI9xrT2^6(PLj;;#6+>{_^w#nXSL7F6RN!p_=w z&}&u*c24!$_w#Kxb7=|mWc7U9?1Num5R*|9we_W=&;JKn0LIM2)Cq?^s}WClcvp#e z?iWphrs<(gt!c5A57?%-YS`cye4eeZhXyXLXg{>ec`4^6N*t}jjO=rE7^u>KT?UpG ztF?2)UKneN{A>#@o_2K31)qVc2SnUoZrE>|^-LdiHL239=2Aq|@6ezm z@Q0@UFRSzU-9qyQw?;jaM=I*Yb}xzEB^>!{WfRsmAfwtJ?Yz8HQ?P3pG7QV{h5civ z^D3wVQ*?a*m^2?iuMyB-K#5ud)SFoTTf(^~eSNyqbB*76+)@G?gZ83dvsTrm{5GSa zKc|`XTp*M6tG;Z3f! zf(uuk6zPa67g|_-IsdD8{jr*Uh*yB2PS)KbsUN~AR*oIbIY`{%CF1%rBY$PTwNSg zQps?Y!hTq?0Yq1-YQuMXYM)e3_8Nh^-{(H=tfCQYs=7*K!KT$4Mb7V|Em6xF>)%(6 z5EVW#7-^QypA5VxGiFGgEus!1CVjvXmuxbQ!-13-b#Q!UpI4N$78eZputjGIY{#kCz4yB{eu$4z54dDCz`kAL4KC(uQlhgnH2djbNK3Jl07!>SXKH3kJkIt{ zFOe?V+$B7;^Ijjmtkc$y824dcRpoH6pSfd3U@foas6FY}%UIeah8bItnUEml42cZxkAQQ&E-9kqmJVdMah8gbBz#4Co=OAmPWNl8Ug9S?7vRS(EjC3l<96$a+3IkT=m;&c>7i{;s1Ne;JW4LX2D zpsOzM9=kI^(fiOa`h4JLRth7`g?TTAmePgj6R9`Eo6td*woh?0=}DLHH5DS`Bwx5} z=S2A{JJqAMh{cp*tM6^P(Enk4sYB*Dj5YFna-uU;RIlaOk&Ho*w#2>%v*a0q!lWGp zClhG&zOvX*w}E)uHYB6;yXUFh8cQ|qfb%m`RdvkwbJQb$_BF(Z>O zlI)*Z+`vRe1?X@kfbL1eiU)9ReeHNEEx@QGMfsEiw8~3buoMb!Idx=~xVJv>#BV%4 zpk_CM8#5U8QUh7BjJC75xSpK<{Du<;(#<75$Uvn&bx#{v&%l|xhaAaCI4X(Ah&mU^ z%YjXFUS1{(p&JX~V~8G_{$D-D0b0TvS)J-b&sJ`%kLiv#F2&c$Cb0BL{D4?k9X-Ws z^iCZ%eh7V|O!c@kyN{Jhb+eiuAt#}zCD6$wa7BF>Uq`t$Z|x|_3jDHVHDq=xTTI; ztv+~vf|mv%7#+YF3>p4qQsm&UvpPO1YyF_;Hyn@SF0`uSPZq&q+qSyTw_*!miJxf= z>%*O#l}o*VK)Wyc*Fs7B%y)LCIkJ+J`D~@|kd{(qB`*P|$Ng*7mYL-^DQ}*4vOGHv zuM&(G&YbJtg%fJ^_b|Is@L}UO*7C_IHo4hRhYtnd@odp@l#PK|WqW4|uxARe)sU6&<>h7dQ4M4n%VJ^9zSGR{sQCHNlEJIs ziZ)}ah5EomZ3($cY%2LJGe5H|4i{fOIx1&;;i1OnZ8L|nYC${s;XVI8XCF-&sqPg0 zpF_s(t1>nPbG^Z8nsVvshGgrJuvBkkT6nhZ-4X2sbwYBPY4*)BZfKC7ecjd6>S3}&3EGVsVn09in*XJC}Uv0>A!N^>O3lGek$h`z;KDd$;1Y)L~H_R*){_=Y-{ zg+%M)acYi(M0Rdc&0eN9Rk!&^K}4rR2c{qpARWe7@)rsib&~NkYugn!1CZ2vQP_*{ z1~F%qEXa(NiK*uLZE~kaW{Zhwfpw}B5Mcnq{8?ns3s?8%D9w_s`|2PgVa}a)f6=~t z{n)n=HKyZ9Tw~ZlAn9oV9W7A3fOjnxQDL;(lT?dvBpsjt3IH+)13>3MNd2dTKKRWR z)@_<<@{8Y`_w(`ox~;wE4u;ItXto>DcXGh9#=NY2`|$wOs&lj)!OErR8YeYZ1%2~~ zSJok^yv0)PEUD8GJRXVz5Q?|(j0-v9?od`kp6ese3P=a6(*zf38u8VdYGdsOah;6q zndn^X8-Ht@2ACopQV-!`ed8B~fk0@~d;YY44vQ*rcA_p^e8_kS>sXwalDCZVNT^c~ zB%Cnzj9RUMmoYgnfc>wT4TxO3&P-pVtM0u<(qTWbBp=W2b(%0QQ1$OK_3GX;UFbJz z-nxtmnK#7P&$M)DSx--1Za(Y6_K|S6QanSCm+wxwwl})Toi(cRv2vj!>uGe~xn7#Q zokPDvzlW^LodN$M!b3r#b&b50iith7!?Z|l+yd-%(G;dbH=f)lTMDoq;z1~52bJ-# z4l&*Q=MVn)=U}K!T9kGS#NJ6JlAtP*7lA(vr{i(^$+IeY$=y!9^jq(Eiv2vw&l9!^ zy#MWX!=zO>x%hS1zwz{|^ec!cx*hD}j{oE`fb{b6`^DWeeqnY&;qPd%8Efso1pnvp zMeHLRfJvsA7J2f7(lU=(i%g<(i__3Sv1yC^?XhQ(Srv=#y|$Y!ocxRCSN_Z2V*P{DWLh?pyYFzu zWOy6~^slf|Xc;{IoEzOK0|B;SB9zk=83sA*TLqo==4 z5^q;MYq!gM@9)~PEjkgirAJG+#4^ifWF!_@A3R!2XoAl1=6=jErsfl=pFgFVj^07# zCJq6j3=o$kIKBS~%?RgfkGJG9waAPm3}JCHd@y&CxG#+H`?=5YZ%nQPWm#4iT_%HliU@4IQAVq0pK7XGtvlcsIk|n-S_O5cdOnZZb@;qbSbi5Y14JslkJE~^O&V747${kE@sV*w+{XwEot}^^|1`Y$A-8Z92)ype%T8 zY(@tLHjiIM%~2(YmNKcAQV8M&y#e&rsc(E!74hKQLkurtJ?ReGEXT8{rolZ#Oro)G zsJwrJl`>bxJhiVg*>(z9V&v99;>l zl#?S-@_;)3EFFva{PLSmE?*nHO3(Govm^9+ne>Y4s7`3lQ5Ax?qB!JXAPhoq&_RPRLe44hw8;Hk{AeuA- znK<$sA%QxDg8~6S*?Sj`m4Rp4Vufz(7e! zJ<}g#XR3{5@Jsx8<@Tz1Co?!EJT2JVujS$-&dhAHVE^PGgBSINEY`ss+*+4Xe3?ng zp2j7UJ<7q~#!xSk+Qvk)+?6aOiXFquZT!`r<(|g;zidN-krdpMSHx=9(ym8eo)mLW z648E}EXOSs`u2~izy9V){2NmB(@#Hv&u?ZXTbbOh2g5D1Ptt%O8X$_q-sSApC) zi9Gbp>-uPA=jkIrmFys=IUFfmZ^mLMR{0EjGVsRdDF zq&QMrKRS%^IM+>{e1t~Q6yKNbfmnu`#r9*f2WQ4z6G!5zEij&KGh~$ewOL}#R!4Eo z;~l}B7Xs41GGyrs+GzNtS|$C!*Rcefh;LPN#$+yRW_vo-NB0@tYOGQkuk<(0x&~r2 z^Qu;0|Lu>-htk}hhmUd-8K|Z4XzlneDflg&muZhM#s!nOU0BN^QYPUcrP>!Yce035=^O{Ly_46`C>_`qy~a1`lfCF@aCuKj70--nhCdv{4ldEkApmPB6Y4TW;fov7y?+*|yGMn@N zDtIpf!n5cwR_XB~0~-za6iaQV0yuZrkk;AV@1tDsE?rF0dIsN)B{C|qEX{;oz%N6+ z=Wxs&N;_NZY4X!jeued{U0!&gT#3VR{ODT0(6veYany~O+Z6TTY)619KxZ|CLk@;) zU*QUH&g#+OJ~s*7QRJGpMLwV%(%algNhJnCYwQ^YLh*nw5`?FF?WyYw4NODYpt_O- z(J1HsHV~mIc)$$X>M?N0rygoge96Dify zGch`5<#Oyi08L(S8Id9tgClWDT5gS>$Z{k@zr@vr5g>&bIbxEBh~B=yb$T zy$00zpODr0JSqKPV_t5PhpBg1&F(`9Nt>B9P9!S^kTZryIb(vUBT;=9+yCQH2jC{G;ZbS0)KJj}S~8AJ8(GAf2b z3-P8!vPY``kH+DCa0XN%9mjoy`HwFQ%8+xV!LtBy@7paj(`oES$0q7)Fjs2%$KTKq zqAPxL&Om;)=fxF5WZjbFxgXn#fIO}@CivydK3lR3{a(aHTZuH#EvLE~l}J0jXbH8g zKSK6*Yk^a%aQ>`(n`}q2V77@p`l!3Xy4eG7dgobIkKC!rIRvUVf`$#STxhocAA9c^ z)%4n~`#Ps0B0@x@x2Z^P(xj7D5fBg}y%PbECelQL1~Nq;bX1!3i4Y-#7O5xh0v z4}%lQ7{B(@keA*vR%I#!3O@1_MXJ(po@nOjvbvsr72;x$1Hc=0s`WnWfLN?8quZ3t z$pJ}e@0!(sM%Ae}UO<`*Sqv^i0v(e}(_qS7mNI>Q%l=mUp^@3dT9+!L<#{crv1v4p z-L%(|kN7T=ADo-T*Cv!dKs8Uh}!Z|p(b4LA0EpsM;v28r1#uDa4sk!re=-&QX!8 zhW$X8xveDby&rk@q(2^u6@>78h09JDs&Qn^hP;$=FYEacsO}bvU2->d>hcE7dPTLI zIKav$3*qK!DC=YebYgm_m+K??y7=f6hNvH8I8@Dg5~&xl*Wp&SlEfmTi)b6Ejz6P4WvzP~Vcl8Cr? ztj&^;A z)36K|S7@1wdyofVQ*giy&-AG39TZlRjtq324d~nDWNLOAZRa?H#}xa!}Ys~Xq0-h_ZeE9Ci<)zzoKo1 zJ}lkH65o^y^%EvE>o-=3nDG^h)hvm2^XxhuI(>ux_R@~N(p%V8tOi=dP?f?~F5Dsd zsE-bysT&S`J`wnFt^^cR%uuXv5}VxPLvK>o4uJ64^SI@Ny{vEt9r#wm`GI;d#>7$j zsy2r(Fvx!1gt72!Bz8LrkBt*=aqV+t;2Np0ayewU)!UK zmOgj5q}O0?%Q`3Y`z&|i+_eZKVED{oB`pmte|^AwsGDxO&6N8INIf$EKUpkJI&Kuo z>r3Zt#=@+KlH7D)8zOivLIudxf%zSM-&<)yDvMc|UA%WF@yL8Ec6 zkB#U;sd_>j^q)w)iSkd5=R=K#D@KSJy?Mv8!a$a;u3@>m9ywyhIcJR)>8gXw2pDhJ z&*TkTX3^Mn-HSkCz(^`02%KfC#MGfX!d>b8q%wZE6%Bee7|oEQ2qp>)m8ET0GGvB2 z)+D7F%Nf|2cUjfz(}y=?_VXWp&+~d98P!zpVZ{))rr-p8bf4?=`o%z}t_s)2!kr`= z`u&<5DpK-WU+p{AI|TL5*wn5)-K8$b&|n|+5GG91-DWyeiQfOL;hh>y!Oz1gJ8a4` z`~GW@uoXey6`ObVW_nTjSt9x0Tm}XF(})y#pSg+@^u-N%hezu-9?{tTEKa6-6_B~C zM6aTp&LOLm5kry37wG}*jt)9M^?5S_y<^dT3pn0BMD6P6XOKBOe+t=kjlSn*i{$vx z2O4VMt5ns7=^7df6+MixMG4zfw7O;6M123YV9%hOu{g2w7My9oH2J`Oh3Z2LFTFuwp z+!SEKv=}7r{UhDWd9z{lK8$s<9_&S~amxsx<|-VCx}c}w!<9mcZqb89W(h*~dDxhL@-{NNxq&kuH{}jvJBejLF9o05(9dGYfq7V}5BB;Ph?FRk zdk)3&^Ji4cY&Ph z#n5=b=_Nxg`NM1NFnNq+0<=Rp14X@XRlsdCP$&A(bNlo5R#oefS4nJ)Z}`$dORFZ~ zqjVgG*mm2D^N){VE;Vsv{)7R#?gLZR0LaW#MG^{dJgp5pS|RH;4{;5EU@e84E+slrWA7+x1e|R(sZ3a`08~^NIX5wx5`S#$Bio%6JCi5+aeV0@%j7d=* zR@Yj$|Db`Lj94sywrm5de2z>(kf6zB9L|6e&jSR(ag#*n8>vyi@L!R$m8Y8BC%mJ- z_u~%ZG#c;`@p*6;m6#1^CoP!2T30hP8p11F91@}wD*&0wdErSXwMa`|{lA%rrDB}< z0P7S^ML#E;FQGG6*>~509xDis+2n%@eFR=^Tmh+k?JkTyqB=>__(mn8lZ-o5sE#VX=FODQBKs(P(ON2lk0_DzOtuF7#`$2Cl( zzjhLaW5Ug>KB{VFW+uojbPksGp^oZmHyFXP5d#%_uhv|sNU28Kk|;CQPIWo3mh;Zb+#aq7aYP4k2tMzKoojB#ioT{bwY)Z1Jlhob1Kjt3VypsYYC zSewLh@rRzN8Rra0-htDJaOE{Cp#&h5+^I{jo0dfkWy(ae1bllBO_4nkPY@SaN=%-b zdG5}K{a#Eqh3!t!E_n}?MTMim#F5{aKpXO7?N@U6d%Fg~c`?|-?J0%tQDWx-(qh^V zaS(F;(sb3iw~e^`B>|ZsCxOO7ZH>?UCDs#%rThZPj#n18r5_mBl@!;Qu^7i)R4@uO z8minkP4nO|Y)#eO;I^8%i@6H}NhMG_CXEv6cIo6~%`a)HFn!yq2il>51!j)|Ebmm^ z=hy+6x~|P`HCMQqW7qV-&ke)sgX?Ev->lB` zJgu4qQ0`)nJKB$wA$4D@>;66lpBT$9HXM*2Men6Ps{i~qp~-ikW*n8+hjM?l^UXdX z7S)a#D0#OPxow=SJKI)P;V(|B{~WqGXrqa2Q2d{&B9K`v$D$z)X!JrNo2R+nL8wKwUWf+@)la9ch$s+i5~GvSN-Z#r!8X~7nI|(?f{5ovmOW%_y%AG*FmOuIHpsE6{(8C4-Bdx zzqcVp(uPp+Z%a8rufx6zy1*MHk{u}L#HG$tDvL%sL-L7BK7=##(Tc^9kQ2YXEn5UAJR@<$?q;>EK!(sFGCA%9OWD|9 zj3u`i%C}}LU4Rb(5H#DUb+@GV!Lh*spP1ynd8tDB$A_8AA$qD?FUnnIo$omvA^v?t zS}bSkV*@}a87F!xjlVl?eMUUe&&G(5uKgQ`PT_rzrO|v#){l`-E2NQghVqo-Yh>mR z;9gtD(0do1@6)iVoSz)2ol5kkI|ew`ROR>qk@PzgInJ_|Myn5S!dgXOD8g3?S*pgg zK9WBkDdRCjRAz9J=Fc!4DN?+!3R9uOht*o0!PaAx_~ZT~b2B_}MH&ye8jvwu5*zKW z;Q7hJO2j$zUw|cFg(Gn%e%1c~SW+OC=2Y1{j`sLe{N|^1#ep12^^XBy`*?6td5D|3#432;Ys2fcbG0mmJVJ)`K?o|Jx)M zU5<58r)NQoP~zD-r|181WY`AR-({EXXX~|1dxUDGDQ7r(6=m{%?HqCyS z`#aBewaV7ys#Th#m}sa9_cI=WPANwQaV&03eJUa!3jd%lWU_=7i6~h94bjq< z!0rBi5KrxTYuWwd@lR^aMw0YoRqsgEvTD!kd9yP2ow$GErShpe??gWCuwvD`(+QN= zk|)Mvxln&_u$@QOSo*qM-YYjkgjZfYYlPOy|E<`cx*`#7&O<{qMHsH=9!|Mu9=51) z?iK6zPy(MqFuv8^;g1k8mcg&OBy)D($6HIKEYO`tm~yx+#L=DONqul{*)!-FWF}rH zgpMQ_3zxY{8Z*5qWlEl7tm`x-^2W(3SU)LFYSN`AxF+yNY>k0X!wZj7Ny`>KZMVQm z45jC~`N_ITc?R<2xYoo>*CgTqZu+Y5Q>QAZfF3bhAhp8&*5vc$JKx|_*3GKW&0i

wm3x2{5hc-9*u?x`rv19(}tRRn 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 literal 0 HcmV?d00001 diff --git a/images/getting_started/unknown_action_create_for_articles.png b/images/getting_started/unknown_action_create_for_articles.png new file mode 100644 index 0000000000000000000000000000000000000000..fd20cd53dc18daf010eb3e70b094fca6851bec2e GIT binary patch literal 5327 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 literal 0 HcmV?d00001 diff --git a/images/getting_started/unknown_action_new_for_articles.png b/images/getting_started/unknown_action_new_for_articles.png new file mode 100644 index 0000000000000000000000000000000000000000..e948a51e4a113627e6170fc54a91d0be89e719ba GIT binary patch literal 5481 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

^m-Cj68?E5Q$MEnB zw}%(@4Bc^LjNI1yz{v~ypTZD<03@U)n?Y*vR{6@; z-GTvtt8hqe4o3&^cOAJD8b>DQU+mUcdF~|0gIbJdH1j`m*xPQZ8>^RT0M| zuEz(yljEe61BUd0+x#NgR3?>9iCy3WgiKk-NzGQ!4l2F@vJjei}pg|Py3#H!Z&{kA9}Rf z>`XhpTyZc86@zcpa=5AeBBN>zx`g)c!iay_%@@jtObf5xPH!Jw=}+ah^8n)iHl6AU zdoAyI8|rm>eR})QZ|HT?_w<9(5&@0q&CR-Sr$uh+CPFZxTj8}v>>xRCb3-mrb(+XO6|Hg2Q~Sr!izVLhCF z$HGGYXRBAk^EYudX1H76zU^-w_(#|~8!$RCzE}_7%^9vKTrSm^G%WYk<*f{Ot8B9A zqu#d3A@=<5S6|qTW|dy4Q9);$2$mJ=cX{u|9}HHM&9+-DvUk@Vo@ase!y!#4YGFiD z-Af(fIk>jVl|HY>qww-JY2Q_`*yxn&r7uPG*EmmMhZ9JiFq_>^w(s}1Lab;5AI{%- z*@Xg*>%4Tx5Pn~co7F0G+%pbHtr6cjgfL2<=kIQ=3vV4R_YWUUJrO|&{vrz+ zsG}O-bJb|J#8bo`7O`$fr|97SS}sMU*R2^S51gJ^Pi`_KS#Ag@$`+$4ud$RzUT{$x zJSKOEsfaFp1P;mMcC0KQ;%Hzd%NaT2NHw^hvNoYGYEhsvw&(KPhan1ZceuOhE-Ehi1w&k-n_DCTXd*#8zuN~W=EnyQ zloydWY+c^_s4D>$yBdbjd;>&*tDfr*lit4C9bXv#I;ugu15*NJsJbh)1$j8#^rkO} z0ehq*q%S@|a!KSq(#AVc&&BG6ASN*PBV9etPD5A2)p=$qpgu@GMk^A2i>dnVQ-Nt#=fNM@-4%>DJEL2fXrpK`!)l zzB_4xdYkY1&6y;9fWG{X=s4eVnLRIfSg$5?xC0^QaFiauBRFuQbzP4mm55$xXZzqh zW(R9(ZVVy2j78^NxkW`?E8Pb#mg@;ss$~jUZ06U0M^m^Rw_f3QESaoI2M5iUlNfcI zp)C?$u?;99(Uaq^DInRqnyH7kn#67klZI%Jj~Wse0&N4g+>SP1_{O*b&G$yMQ-*t( zNrILj1KfsoTcD3P?vj1&pD8Rz1e{RrkG_*Ud|g443U^f0W^tKuvpYp2UPk7{X3uT# zdKEw4PaxvcXqhv0@_2e~Q8hH>U9|L(BlRFoD-05eKLzns;fdp@FI8!etJ6}siw1u* z>=vW*Pf}BF{3GxylkGrO`a9)>16cW$86JE`{P~=p?(f9%af5E~nEm?9?B|_`p*QBB z3Pj}StaMMDXMC~BKwGjfXFe05d$9e(tAoSb8z@UOl-a&vh$46{9Z)nzrd4{viV5jheoj2QQ^DI1-JC8azb22 zeX?Z;WMVrXWhyAI@I$pFPP}fD$SrFk&D%zC)#O(&=~{hy@yX?CQO*0or;l&xz!wMn zq&uq0E$bJ!y5-P>0fy*eyFq4J7_jxLj}$aVs|C%`3Z0ST`)pV1x3ujUrsb&p_Rfzq z!Ii0eEClAw+b&T}h$nH;1R)!3!0X7W*dUfSyO;7cevjLCu=*Z%x=l?wIQ0#8{Eyps zB+E8Eh&CwNXpXj&;+h+~?G|4dP-5;c#pCa$)xy(Jx_WiYLp#`_Ui?X!vuLpF$TSIA z{HikAyG`ABgXY3Y;&U%%EhN0i+^Cx4C|WX9oj3K*-{?Be0zP;;D=znPdeEdu9!E{! zVy3BFlXk~+^DC&2xGq*Yxq6SxnZx9wORQ$j%6YM4q!pBW#H#`(9%U9hrB$J?F#O*h zL$FO%DQ8B1IXJ>qmDkJ9R!56O98zaEy1+S~mF74D$+174(v&@{DAjIqAmeDWius1R z@TD2*yr^?>V!lb<+jO&O(MY(JGfZ|EbvC^o2Jy|RK}6Gmy^+7YPtncizDhYyn7hE# zTa)J*u&!0~4HuNp;VIE|VeoVr@x3V4^8LL;AFIXlP_sIaS$vN5d!{8oG>cA3im=P} zRJ%#d+52X1Ypck~Jr}FZCcSJ6YNN6o)w?@@hL}8DlN|D_X{u9W>r&0BhODJp*R;`L zb8tUY;&J8%yg?(=B?JX>t)|3(D3~>{-f1 zs?B}Q%~%$pWP=m7D_Q2UquWEO@ZduexPMT;YgX z*;?L>u1k`}eDmv>oQ1?%R&J+QE4V=&JH;*r{q8!nI``Ln%rz!XC|_l&(U<5zONfx? zRo?;W!)qb^y)Dx(KJR;#IqY@SjAW*MQlbK4MVCr6n-gP=b9`@&V4L2Kp6)Dw7zQ$x~N#!;c<<_Bevv61|)9jiG=cHbG)fJIP74w-AS6G*=6z@QDYAm(yB@ zX^-ry;c4>&7M;q!2tfo7yX_aX764~$Ui;y27s8t068+V<{U#q;c$ER(Mzwe4(CM;W zfa@GlE74r%`w|OF;LAN;l%)UNB$-t`6_q{-r`g!N;2KTMdbH%Z2_48#cUmA^orlRG zZ!U6J-BNdUYmPJLwULv#(ejd5rs$e|myLYG-PR4DEzZOts>jG)>FlFWON$=KCbLQz z??LZ6(E9Gl1$yhvP3Y0PTdXSzoYH^fBeEle*eyGpF9&p6kCr(e#g4N&PN}qG>CYKb z1^B+caz~(%5VP$pPA^S=g7?4Nq&nx{-fp5cAhoOGAUXD{(T9f2{ZVibUaUmUp0FCS%FQhiZaK+B!#tQ*D7&dy;m zSbbHu0*ln1%iB%+fP9-XyDHUMcsnSfl**+=c~p9o&wElfr^a$1S;&WWNrhpzg&wX< zpheM>f{uAbq=%Bv@|-};KU-wq4=LWGyt9|;u`^Ivp8EY2Ot03;>4iH|@X@&);-*D0 z+$SwxkW3PiN5Q;Z=kCz|O=hOZ8*pGC1Ng^+wp+G*G*8lKwZ8BHV zaUxJ}x@|MsTk*V9^zULKtEpTKya%ifB&}M%IZDQA&}0Yb#cMop`&U2)9J=`CMX*>I zb`%7@NO_FT4MH3@HGcozJ(_+A45Re*cyprzBdyc|z7S6Wg_(&ycD$zRjwcYXJ(ZwO zLvLly2hZL<%A{L$m&hIWNz8rnD5bavLyyj@pwcN{ZzNi}F1q%Wdi6 z$)wSH^l@v|0E3?i=*m_g^|eo{OK{GMXg1xEYEYg2G;FxWpCWl@bJ{OMy-&YLU#;H+ zj_7*nk=+P5&e#^xzo)9Vm|R;VPM>5&#RBQPrQ7Fto;1E$G^EE7Z0j4cMp!l3FS|VE zFK_=66fJ&I#LzhPZ>i2;G|&g9yO@uque80r2*Cn*J#G`gs$1hZ+z%I*0R#^xJvVlb^G~5UR-& zNsK{{Ggqh@oDL5o!>-Z8QRs=jnY8}gZSfD~VQblK5){X%v%T0bo#OQGEzHrc$5Qyr z?R=}(jFw@nSD3rsb*Wt4d}KtZQMKGD$Ye0)y%X{;yA~(+@kT8y+Wg-kbj>i_!FkBI zOsFJV$Xzp`8V{SUn)CcnfFgR6ydEqgAEj7O-qe*{{&6rGF=%zVs#CD`&;Z+~NKk5*|jET70ndi9mG{C-CPt8h>y2OB0W+ z-erTe8-KDQ(u7~uOjxE^Z51Mt(KtgEqHLc|EJ?slz#SHipLE8)SA8Yu;?%S1@)tD_rx&iw zQm0+9Zeqy_Kkq-G;7bJ-MfHLKuyl8^G}+kzRcfV@)GHnJ46iPG zJg$TauKy<6CQ?DWMOlrifbNduRc;v)ddHQ&v23Z6@!*z^n))uM^%iheB>kit~y>-`BSJKCRUC0tn=cFyOWQCqN=>)r_JD@g*1zwi{Q71ayX&moQipe zH)KK$PaO&R53ah?6|x^rxTY`u9*{>_%5mkFmXoX7dUzBjN|gXzCVjP4oeeIRu>DKj zpE$pynMf?u%fElS1qTks^B~dA_%)Ouj{`tZ1Bwjp-`K@=*{-Jd{$_6{5p<*GohFf^ z$~95F%35Tx|0h+U;@(;7?@A+$-g*{!o*m1)jX*ZDscRGBzN&o8w)cMI_bGLO5O79;&NAAI(;>1O%l!_v>`~ARM73T zu8w??($+SZ52zx}Dx;rVe3=SxrcJMYSYP$gj1rpI{gDh<`}JB3Wf`#1jk1tRb!x5;ogrQrJ#z@8~{Tk|w%h3v&vof}I681--ro|<1r*lOfUD`~#*X!ecei-3!fG~#KI`EI&gx-k(etj)krkzhG|r)7 zz5?&_{H zvmLU6QkoSJ-!$S7L5;iDLra0KZMBNJrP+Upnr% zXdlW_Wm<8dx4Hf-jR+Ks?i{J}#W!*W68wu*! zQT{kS$S=L{Yx8$GjVdI! z0&sB;M20M+kJ%EF5T`9O-#AL~Qu0PYfeCfK4^86+MuQ9P zwoy~q7OHI80oSiX3wiX_>Ef8&QB%eVcyKi!P^&oc*FKO?=`;Em_y;EHe+B$A`FrU( zhmmF*IpAqrE^ByK1$3eqaM3`PU2Kk8NLkZ2g$gD#c!7hV)}}nUe#P&ZHr=(8(R_z8 zK&(mXSZTfTsnjyqG`>l-UH1cejWH~oz?K`BGVLet4MvLkDYFITY@29=;*vV7WZl~9 zl5wc_S|%?nQsJn?06nSy@byIcB8&Zz+*v5n^*|Z5Yt(jE~-I?@l<_k{Rx}Ygy~`tj0*S z0|nX9T1+w(Qlg{%vYZn(Y*jX4LA-~9k*YSTS+9=XQglkpdX&$3wXUd6xjTE_+5S{v`|81}YpR_2*p-XjTeJYD6IPdIu)*U^|t|c7^ymNRXal<_{ zkK$xYa2<5;7+1q9t&Xbot3i$!F&-p?lOg&`f!0?SW8mSF$U)aL1`TVHn(PImOQp$5 zp&dZ7aU#ho{looWUT8iE2U_LSS5lc5tE1SIq^j`Pcc9`tXZxzta3g7pxBMyiG!Jr z7YL0-68?}E&}kcNnRUbc!|UM1R?!fhge!Rj`iM7W<;%KekFExtP661Tc=mh|9(IFOdfr(E36U(?V;`L6riYAt1QQxrnw!f5cb{D zoD#^x26fIig-+OANYAB>k5KD!rmkj$#H7~C+0Yg*+d=(ehv@lGLw35i=g52#>!d)1 z&6fbf^?hh$4@Fn#<|tOW<>_A1z{=PEqWZX7Yd{N#zDnz&!Qrjd9-F46dbQ}32Rk*# zxy2y@i%wRF&%j-oFnbmcW4JndXgTu+-IA)Ac$z*T2HRD|-fIi2Gn&oGXj_Sd3{ztL zwAyZ79PiE`{e7(X+YkZjuv(`v85B+_lF4IB)n8W%WphtB(t;hs^#hUrwNc2dt7f0% zrcvmw#iOgdNmBC@Y-YP}RC|VhUff$~y0X-&l5&o%8Wm`yqV#qaoYhjZKg>x^N1ajY zaPGHO4w&2s$E1=ER<(`o{b!0{)kk2H&3&Q9x-q^bsVIp+95w=t)tHMDV4#VJ0k2d% zM(-#m&M>SBo`&ii5`)>5yXw!5>=#RiYLW2ij)O!+hH838>a!WBN*sj9(-|R$d2<7q z>jM^2j1hMx@;|yy?`pMm@q;S|8jFLn)S)?=Z(`-7f+UI}I_5RzaJCr7Fo&pVvhPT0 zmueP5NgDpDO(3qH;wn9XW^t#uDsn!9^lCg$ z!%a9lMmf&X+u7UHup#qT44|}t32P^}jI+2q_Md=kL1lLWP_fQ@&gQ7Ket?La911Iw zLzW>vU8o}3OnXZBzntL;UlhU>0b)9+uL!2TJ5D@SykVzPMFML~jBqQ*SU3hCc@$HO zS_jQVSR6m{n+Mtg`nBD;>cXTcfB>~R6nFLF3pI))^0}l{UOOGoruCm#@z-Q?`p?@+ z4rFm4eC%KM2i$(MBdsd@Nr$IK*G6#W7*>3-iu$)0pltF-Om%UGN%8&v?hYlIc0R4r z{7;mOu~TO4L7DstuISI-j55YI+p|88*@rA2x=gkKv~SoU^@GNz;rQ4(rn5cuUwMZ- zoZ=IQjFA90HUeL)=Q>|k%He9Dt>j^hjik;D&*}D-0TwK|k@rvvf>`D3evX(P`dWCj zOma2wGjz`;!#%?ve0H2@vp6JT9hvIIwmJzQ=JZ4`s*ba~NC`Je-Hlt~m(zj%wv z5|ky$e-=w37~bO~HI|f`O8K1V3~WvRyH4OaW~7A*i}g$R{V@be{5<1}hLIm=5PeEF z-Hc&#K*pwrE=fwPI3e-pca% z_a%f7K&=^UqW8`arPF~N4*y)e<@6W+|7al#<>)a+cpnRM zD{S1y(;2^wL5UyzN_5Kc*kmUOZRxvPcz=MrE`N=P2l=2ZHToav-&M5ORKACybv$%^ zGJuQ2GPJ7GLJ1F)lv%1?=qpm-fk3OoJ#7T5jgtNV!B!NhR*_$3GJhp{U3qC~BfE7k zgiR%2@MP)vY^)^ONWJ-84=0+T>u}iADV5725%h85v^c~ed=bM-N@pztTZAMFYWlZ) zAB!DvuI4G$O|=-^8qBNIti4!kLe}!w?)LZkJj1AIO5Nfh6QIIIo!tA+5hJpF!~JA&;?p#{5tC}DYuh+kwbVl9oxBGP{@6xr4wYW61Ja2`?C^XNuB0&Qw0ZH~` zV~V~cGcQ2&X*a`~NVrQO{& zjb1%>sz#^jWSBHiuE#AV7FoBh!s~pE^J_7$>tW~h7z2Z54V04G%KcdjP#2HX5igb^ z!p0NQBy0+c(ed~AhItIi8Ku*x!b3Lnavmo3tkP|n0-v3&HjsMl1lcTtN`?WL=Q`IVW8NM9tALVa^M>HDzhxeLuK z@+0GXf1D9V>$;iZckH}^*PE-%=bJA%Pe}U)AOfj3FOYe_BQ=Ckvh-9;?)oX*1f=^|kqoXS)x<6lkShKA) zCo!gl5|*GdJ{A35R4zvl&HbN*isJk5)toS}_tw7leG1N0ADfJw*baC(AB@4B&gF$A zFkUEEzB^eAX*boDBZD?Kp!Ff~0}@F5FS{NNC$eCJSD=*H&``J;tbERFPTQqU?;C6e z4Y^z%XXq%EY$}vI1&hd?d%oQh2-T0_SbTOUbL#2l$n$jRe51|vTQ76Z>orA!0F2>? zs-j?%-_y0}a6FXvaym)_go{!Jf@$qLeIxVzvpZ8`B~0H z9{2Y4qOs_b`8_Z2*)47_HapZSHJorLy+)I%zGckd3Ap@4JU-^$_PZ%c5DHdx>J$q@ zf<^ce>i^X|(U*gEH%&BKEg%<)Zq?(D!(HrseH{*PQSMl$v=44SVt-&UTp-M9#7jJ3 zU}8eaWU()(1RO?B$P^;iP6(8E1mL|2!+*iP zN}n*(p=8FAyFdleDpTofds-MWag8hW=$v{mnd7<9>b!y;Mxs;x3KedWFRG?&klDkQ z@8$Ku_!Ve>IN?9$b~QHO1<%={rs3Op%l23*U4v0? z@N5x)l*j3t4@nvHkAv|H$JP3S%O1!VB=ohm;}+*W#+HrbT^i?HXdYaxtH{b!Z%MhT zsIb=)!)bRtk|zaf3H+u7AJnRKnk1qypz22YLs#PC1RS|;l@=5v;XxQ5YhVIE>Xpzs zZv(XN3$;(sVj}Y+Ec^!4FgVde{R9-+7wav|zt#S)v+s_lI(+{=_RJ=GZ;nl}Ws{k` z3E3+vk)6GTlubrRvdcJTLfLyuQAmZ9(R1nhdp-M~=lP5Ca-7fo`P|odzu(t&U#CBT zGBYFN(}zN)7-FmePwD_xy$JUBm^9kY#%f*5CT zNOBA(3%gNZV;B*Xg4Xox)GtEUW3Hw!NMnD&=9+vg>0`fO&ZR^27#yzIdA!8`>&)0x zzXtt$?Yn<#kx~)%Yj5h9>ll1y+2+e1Qxye2#`%<3IGNs8>X&-H-ji^);$&wR^H|7o zs^%+Wqs32U2{XWnH;Txf9ftt3{5lZh+r{Ce?nVAc(#@VGp0=m|EZkKyqrHgsUR}*% zT3a?LM=q4{Ct!yKZLC{7mpzx;RciesPy32=igDn0U)A$X2(5olSO10w{-zY|QSXNH zkj-R{`CoZ3H3%X-@1_4fjI-}gINF)ya!phtSjxa$96&Qq7qsa#mJ(`?M5P%!+tsJw z=cHt0=Tz*JM^Z|pYF+0{Wg@^~+vO#jZ7gvaCMk)XCk_v6qopY;r9i3m*hX8a#Xov)p!Y*D0bWgCoHhQuw)Ze}+F@ma8w_EfR`YQEF7Mc8wFh+GpWNGM0p!PLJ)PTV%NwuyrQ3 zRKLjVdkt6)$E9&=g*MJ0qeyEcg{keb_zpnXp+c!;?jSM?MvUQa9 z`G`^90h`Q3U!f&eQvEPBO>4<{ygRkT9beqZ8zR*EEbsGKC8*1*p0$=xUm(qC;na0+ zobr905^EosnET?C(V}MW@=>^n+>`h}OWwp!jIa)RmzL(b(U6MZAz-kF9;OL?l_35x zq0(xtxNBDVbxqSRwJj^{0eg9VZw#vp?*H1?4n(Rw_tPIC2(%Wmobae;aJfiNOA~T@ zM==-SVd`|)G|D9>$LN`bW{sMuwRmn=wc!^qU2O!2^Y)+eMLMasyv(A^b3}qIcRBB> znKx=EbUiqSldh}`s}SPgT6rmq(b03d1nCw*N#V%m`qLXJjIy*VzC`qr-hU2vXpWGV z5eJ~@T`6hE@UR2rZeO#bwe$K&wIjV#UQ^yl`&H=mM8YHZc=tNY`+%&_b+VB-mv_36 zC}@3uuSqGEXgT!PGQbDb;u|qV#W=wM5N4zUcEbdU04nx< zaYLD0N+RmS$)jekoVFkurp#6w5wK&wzi|tm=K>t)OG!*jeAraS{x!Q9HNfn^cy_$# zbs+8|YpQ}9Ufc2$Ds|T^Vu_g^taYQ!#inAJdPAzOwP;aA^`3KRWrzQXEG%l`HLN_C z)Rm8*X@_tL%tp|%wO&1)6`;=UYS-TqmBciywOf&FDv4Avm}!IpUaOrQ)9o=!;XZcK z?sGz|&2UGJGoitQ5Sa;iol%ik2f0N<$TJs_K^Dn}ZwWnvdX_O}2R1RPt5+cA0#(HI#`%$7ic*Qfp4RV(XfR zSpp}5Lt^f|ci^I%#RDtKm-N}V|E;6NWsU%*Ud4vbpt3U~3OD z7{kuKkJRV^lEcZuOF%>uyY8ZJn4(?#;wy`Sfg0UE2`&t~`0cy(F7$M-1+qD2d%k>_ z9KBgb@KG9zl7bk^cZku&p7MZ!ygGk79ju{>_)EsxjYdkBB&9wi0IZLq_LhytW>(ST z8B@o~$9O|BAXoje!9FoptUxs#sIb}HK`4;p;8J#=7yU&^AR2ZTn)nPwoWH?2c?q`}!Ufjm zb_PHF|A0aaRdjBF$`#lXwBgRPAH&^5-5a{HM^gY$QX%6V_h#zK;nh4fmeRCze<$^j z^~{e>$W6$@Z9CjG5_=eM0D2>Sz})n6lj6}E0x@b#p%k=%^%&YcVdr0M6b23q^&WXU z3?$Lm_QKP}KVH{XxFwu9iEO-3&^`lxp_e??8s$ajeoK;Q&ohLfh@w64n}Bu3H7{#D za$#X%Tl}cKM7f8+2WBR}?^G13ewfq%PiL25^F{P#(FUleT@|pz4We|ehS1yd{`}W! zm)opBktwsS(82*-^uSk$0z%hLTG4;V>g@uhuwyc`1l}oX&4G~`863;t{4Tr-Va{+! zITfa_H9%G;yywL@=T=WFgT6$_iD@iYrm;2H=Au9-OgdQ5 z_JMb%D~A&^lcpLw5DdV7XM#hhtNY`Z@zO#0zh@W~_*Vsz?r1&YjgbbQtu?OAD-nEy z$Rd;m*gXse#igBxc{*EX^>Y%VPyS2e8%f&(xFz+3;3- zUFQq*`1X-6;E)tAJYdHMp4*imZ0BLbLP7;NACSVKLV0;_Bz*(}p=^W$I1|=G&K~K| zKaI5|TH;vcxr5y8-(FnlX+L7>wI|@oI(+`3GkC9QR>Et=@}+%0vD}I6dQVLA5c@D; zCuXBFpa=er`kT1URX{hK&Q89MJ=>psVUtWN&KPo__&j3!Gm^b)XKoHq*_A~B@GUin znk9qn{c~(Z&8ZZ~MZ*dNI zWr-n(91>wn%$4-Ib1;oD{`cy*nk|2U_zk8ol$QG|h}$(lPze0}V=HJH03X~kqY>+! zCY&WbhrX`$(9`3Hkf=1Pt_Pujmp$KM4$zk=2lk16khuj*GO@nLAlz5?FTJ@No1R`z$IC{t;m(J6ZkD0o`huf$;sSZRJ*2CHjj0afD=+7n` z8DL&QYj7h{;R&>g{Ep`;K=da5u>rtayRCm-R0UvNH9p^&PK<235=L6sE|JfS*<1EFlfLAZhja%R$B`*Sr{K?!9svwGKTp z5+eQ|(EYZv#i3SdSSItfS$SlW&_at>*vGf&QvP3-0v0_2m;J%$UK`h#uK&$|FrP0M z+78@r3_XUyH^RwWfx&a35l{IQ{AFwmpf+Eb>NcECEza3Uno%_C|Wr`{dLWC3U}AaIkiXeONhr<5!#%c4x8tt z$5!JxkP*g%Lt1R6o!i3Ng7zRV7qXms)*|vnA={(=_O+Q@*- z<=8y94%EpxNWfgnz>+BLb_UJP!e={+YH}`})^8i5K}DW|8Z8(q;DPvAbf(>Scz9sT z9KOghwqV+TiPI~nZ**U+!%gv?xyhU#PL9n$r11d94)?U9<472~t*UA6PpB%UPJ}ao z69boy7=HuC0$5kIcS-t^PM8Rvr4Jc&)?iKw7E#Vys~JAxHAZBmsiyoqwT~{Mx_9N# zA+GbESV!Y8xTxwZXVqV}F{4IdxsnCfitgv3a1%UVZ6n%P2ew=Us9C&`+JD$|&U*2bt*B1wVYjpfw!`V zaEbYkXZpHuw>t<({9$%#oHf&}t*!LeeQkwgMFfsE?OU+!B6~Yr5>Elt+x^oNTZ4~y zeUaJ%1hnzSIIOfpN)94C()jcc;};HhCSk1HH!Udv7$T=KD2@T)ui}VY(jAo=b;ECb zl0x4gR;JFKU+31HX~CU-O#LKDhcbgT!?gv-RS6)g@d-4cEQh@{S`PKW))3AAC83(= zP}eTP23*Qb;G2)Xq=O2{)1SrNgR7dSeqCm!c3V|d1uuy}Igy|Pm93sbZDM&+VE3G% zY#$Cl8Acm5q}!)^RtZ0< z4AZTpTk&5EOnio2sqWGy#%?>70r9S*PO0pC!k)qiZ*zey4lSRbCgHU~A`A`m z2`d7OdxrLw>{ewK;{#hK4yw3$=~xd*uM;P18&Ea*QP)_Ac(6!6-8cA>rPAInVDZu1 zhr`;_Mal)!#g%Nsyq|iAIY13XI&Sr>Y_ZdVZp*18#E_^|h62KnqCCw)8R zDOEC~$CWL;3N6h^e2h4wadHm3jucAwbKNj}Q$2d0y6V!esjztOv}aEUw( zZE>)TU}0V0HaM&?WqxMy7fEe@Yn<+x9Mz2I|x8^FK%Wr&5=y2&Z-) zy=?H*@h(JM;L`xX#sA*HA*4!f}Qx5;q=Ctka_Ia>BpkJN6HA{@SD5=TtzHd}8V z9pmsQDd$)_6$y;`!dp1Wu|w%>IA?vg^j=EJsJ`L7Eh9O)tgc0|w#JkpENqxS6SKZ@ z`(v0sbG;smVxe59&^ds|HD-5>k-kvGGfWJ_1~nh7Cy@F_aFWc0q`vQhV;(Tq`o6mJ zfl(cycBvB1#j-(W&lRPg?+kq%wwP1Hz)fel0#We_orLmw;7hECwM>EQ%YPS zHPZ(45+2-UbQ{K1R7qgmw9RpI5>oc@rQrz%-U}^%A+Wg$RsdeSH6ncy>%eahTYe7QRjHiHX89uxCDSka$+Jz z9%fS~*f}VIbDUp+<&ZLf$hz|8-Yex6TxOlQNJUk(aQpAPZ_nml-uC|39f8q}U#}Es zS#OKxxbpJ0+S8Bo`0B)G38$9?{b9;Yu5i>9WohRz<~b%ITZEXLE!QQMCS)wA9wJWiz+E`iNZxZmA+dmssowiDFkV<{ z1FRgaKO6iKw#Jt41ypJPaK=T8K295xcXsaI)imm#nBv2~g>x}jre6(yD_i;ToDjZ*Q{J}zT z*C_;g0I$-G8$BQtw|K1*y&)T&zAUj^L0|F$ptlc@4uh7}cKOqA&ZX2n!J&|OU};;` zdjZA;R=kmQ52{QQp-1&1j_+)>2L=XuI3N_EQ`OjX$^EA54o|TZ)p>eFsBtIIo{eR- zM)q+Ub<$L$bJUj!bQNMwirq6%M*+uBUOuPy?Znc}0`I_y1*U`{MMF*Dn%m4s9yVbU zM6As8gl#~vj{6j-L`&(A6Yu&YrtwRawK9~HlGkt!+-U!n&@2co-H4dNF-(`m=2}0z zxlY>`Q7Qzd3IlUj-3Tha|4PF+*kA9BE#AS9U$+L(rzKuB$&VYvqRZB8D>QL!6Pxa3 zgDnbORz(^HOJM?7*^}Jo-AzBolN1?gVUR zAPSTwxA_JRZ=}%WwB7Gmz!5Cl{qO?vu6Ysh2!0I$#h+8RfWN>$3icp}-;8XPbIJ&i zZ@H7Ux%kDuA;D}k6}pAk3zy|WaCX$lWo>mkn0X2$Yq0jz40yNO?%Yd|ALwO*gaU*U z!U^DmCP1Wpi(eO0Gd7Tcz(J{>L(pcS(G#>pZ*g1glob*iy9=6GxL*Fdc_{m^`>W4@ z(5}MdmuU5N{L?-`>+AQA`AH7q zNZI5d4uG|z5)tqCEt>gv-yBY8dE@2#-@Uc=2{f`x!Gd~a>2;vj;>FQ+#JlqvLTtA4 zyk=0w`|df6>!1@r6s`p!2O?#aKbqXrYV_NoZO4)5)LW^t$8%6;Ip^;V1Y-rX7iTP& zTOD?OWCDle>VLdk0PPDgB=nJr&|YO*`|5{w{y9j0-IYlF5@jHWtl!_lX2eRM&20n0 z94?d(i$KSMd4vS=n|^C2s^&&9wHDY>>B8xD_O#C2^|*(I6>M32COSVVF??8OOXLxO z-Dl+-YJ58+g2k@{(A-TRkk{X><-R>*myqB%RYIrla5=o0CL#QsTW;*cR$ryq1z5SC z+jjDF)Tnx>X@xiOy|=8F6P@2mDh~^vCDl*XN|v%}m-k!_dluoD)s!YwHC4zQw*SVj z%}I%W_pXNsbgG-Bv|*)nd*-B)RnnlFoqlWc?ZK`2 z01`ZueK>B(iquuycsbZeYmMt9@b7|pWr>?|P>CF!CJPvuOs`_RE+9aZBiKth66fPW zssGDKAoVpYeur9e|9Bvo4!Ca{0A_c{SB)SrTvpcJLyZ%(0z&DaFL^{a1(63mX$qum z4kL=<35htiSP6WS>$>a(euMlJ{z=4%at>c=sU@IYlZacNGR4 zzh=Xv#`~|0g{hR4JSz>#@k#cuE{S)JpXE5(8-gUhy6OS{ZRM7}R(odwBWXhhV>SsJ ziqP8j!`BK=xm6nTq>)NQBp#MNM;+?O?m-xkJwDXRDjeQ~=1Q7G%#M(W!KbLT2yfMq z>v6!eCuyTHlJ`ZB zB6FK1m)S%xEn3jDWnX%_yy5Xh7I0i^XynzAsx{I`({mpi=pUjT8c_M>9oVEfJkOeHFnL9m zL%m(Sr6ifoFhu0v9^pPiR%$&xDp2qvc$dyvraUQO^~641!b4?)!b7sswNh!$ponI= zc`iVsBD95UbAVPMk;>hY-TVg^jyU2!_aHVvNy+W3x?96h*H5%;Ycez%o#a;QFrJ*W z@AzF^YOks35l6z{GnBmZCrwMOm$%)Q!NNvvv?Q#bVR}?jzju&irDE%Y4f z=lxMRSM>6Tv0}B;VmyzF&ZNQ5WeNG~-#@7nZ?7o3VGxpztFj~-6MnI4_n(Yp5fr|c zR9okylB+CgHCyfPDC^@#qe!1lKXnOu!Dbb=vyUT;$2Zj?^qVb*{piwy%34Kzm`Xcq zDRWoyhl~fxy&Zk{eR1z{{;V;8$Pg9oOu5_-GjYeCI=-Hf{YBDd|44K9#+}KXn+Bfh zCc=>w%E#pl9J$o)|31E$+C+FD%KY~uoCT4{Ei0bmx!~wauSR9pxxZ~_*D6L;;G%9# z)jpwNw1gV|EBoKKVamEHwi5nqVVa~k|EmBYxVe9`M}u1NFMmPV{?|nIOB?yWOl1Gh z+yDRGb-CpKdAj@m@mcFckdyR{{2|=w8x#P(<^FJ4jREN}O%x<=A_q7zLo1b$l|{kC zM2thsAeAMsLLk#wjls*Fbc9F^d!7Pm?BUBsNV&#)2>*hN9~GQ{B{O}$dspMUrI!<% zkw_XV7M_rYoI@|`^>Yms#cl;Llju5AE0ymyWMzi=j{Db~UPDQ{F?0aZOW>EOp)EG% zBJ&<2V$)vlv%Yxp^dPrpYGHfjtS~GPin>dB7UL~t-B;c`rX*q$tM?zq6@_|R${`}e z8|oP2`~>*k9u#s6bN6hGp&cg}P~gR_o~T|n1r7xxy{71LMyO~Y3imJ0PZKG4$m%|` z)Ucwh;25akL_04kQv7zZdEV#cLr4~w}7S3ClyG7+flVWx(kLh0viW8^YaRv;z! z>U29%MWOtjbfP`%henj8KsLqTGMpPw0O3#~_a%8<#T+&iqNtTZ*8L$o`lahMuh@=) zc8l{kddf(yu+kS)%xl}!qFlNF`QE$Za*VOV9z7y1WTqZEDgjUkKX>wB^OPa4n-jYT9>b+l# z-&f!pv}|ySnCQNpFw-2wrq1L(>ji^#mFJ88#L~^r6yy#VKd2;CV&&aZQp7u;(xYIx zGDGaZVeMvtu+YdfkKHdtd+_%>Q03QpVvg2oTobP{&D}q~w=P_%cQAH!Qy;+2%^xqP zcWHfjeKh%3dD*=F_LJ~-Y93wEvFpC5s5K( z(n@WA_UJJSUN&r*7>>M8iduWsYgOi2Y#e8bSQOh}$S*Std2~p@I)qYeO*g{cPGSFe zIHl9kW|#>-jugBS%HB2;PBgK*=#*@Knidiv%=Ii~I4~-$i$GSJNJcJ4^ret3mykt> z9rpL!Nqwx>P4I=&AU*9>Zudfz3jHUpoAHK}-?@2s^hr-EEH*@+|0qAJqAvL|7|Vf$ zGq{6Wj*?E$Bw@2*F89DC+`09Vdf$d-nv%34=xQ)MH=~?51;#h-hq-11%;U%{r7~8^ z@QKOASgixqtXk8S3p&@sXWKj6VNy3<4ivCMy7sO1L=1{ zyZ%a9e2+_nhD?D-`9oQ=UXvnG7Bb|scQ$t#y8RCB!_7a!-?(+%o>r(&@Kjg`Yi9c@ z)v6_!iV?-xe7}*NacBba1oBblgdX|`jTgI0 z{4JL6@n>U%B2N#Q4T>842yU{O{R|?=!n9YbI^t}SQ0FZhAmMoBF;LDfGB3ZJkc{zF z>*}5%e{NGcz89u7`MKXuSNQIVB*VyU$1Az2Q?$(~niJtC^IDdy^VTIV2*uEy(d1XV zGFOuXh}o7Cr1C1U9`Va%`6I~W2;}4_jeM!4c5F6Os=m#1sV(Cf#^&-fZ@n(IkcxcF zcB&~5%B9ZPFkQ&f{PL{JF-t)cgN(9Xg;gVq9ox9dyPDjBPoBe%ZwOmLwcK^Exn_I2 zIpC&xr+pfSe$dhzTGfYWv6_ww?Ck7QppyW`Q73fHUyHSBay7bnt4uu|8pWa-*cPu& zKvkSN>Jb8jeao%~vLr(6;cmqAl4C$epz>5BZ|Soan2yJd#T$z|_4d!QhJy5N|a_HsJ^*JOkkerID6{V3T^4`8$j>=HC8<;ELGizXH z%)-7Jdhz?Sso~$V1o7WnIW`GRjbVQ;rhc=3D3IlocoML`6mMe|gHL&oWlxBX%@X~M zV!_p$Dkx_pI8D{P;Nh7oHT~leT=_mBbNolFzc|~&IPQqV80&{)m*)h}D$BF{&SnYw za+jkvAv8hfy{=n*Qq%2Jnb;{WHM95!Uc9MIe?KIPUa!=vO1o3xn`fl?g+1U$ktXR) zy`L1kDk>b!%`;KckNG9sYKV-4Z^k#2_vqC;%_KJp7N4QEl1w2}_rHOz(KhZ!lf_x7 z$5W94j!JV?$PIV-m6Hqqct(- zK^NwZ#1Ce1+dFOd_7VLvB$~&cM0xNrXc41N5&7 z%ofkP^W=>THL=mLp7y1$sn=LWtel%X?S#}eH% zD&dWNm0{dtZ4rNPR*96yM}JgW>AEvReU_A%Oi{l9+GPML53Tsk34S;hiW1_2gf+ioUXch>(Pvb5k@_+THi2$Ix*jm>Y8H}x=e4!wrYRv&ST_s zZ+Ww|ihmkwyL(5H=nnL%C|$F9<&!U*<+m=$b`|En=3bVTxAGa)-ev!I8ET`G*aLvu z+PWY;*iY+SUN$~ggCZ~16@faw6qj(@KL0oCTvn_cP+Re)Y$$47lUT`_An~xJots!# zYn^LVmoaWAHrm>`SL+@f@~IJ5Mu1dTh4MGCNnlQP$ROJkYs97jGTtHeCf@H`9$Hx0 z+u7Av))9tyQ?y0&?iR#=?{~7{!ftNS@n^gRlx=zqr150oTH%zDO`bfmKG>8=LHdn9 z`*0%MhN{{2SuAE;VdTE?A~XnzrXRt@Qoq zy_^1s`1F!q=@ae09;JXTLhQZI&=nI1im`4-{8Zo~WRR;iA^N+u(H@`*r8lneA79le zlO$<2*h3Rn&Og=LWp`KodM+d@-fbD9T)NN(+PR+Ti(bZ6)gc{m6~Vm7DyAlmjG zgZ^n?BO)WRzoyQP`7!mqcaS!ut^So&sNi;ibi@Cd5Ia^=xa8`k*jJmJ7aC7gU-*_4 zv!^>B)c;6-_2zG_KAUS9CnrIR&ZYH;xMt9AyxHm(>unwQ(O+Zsr*BW?U%$)Q$Ov@_ z%v1Q1p+=4q61^gY2;6A|1>L=1=rpkxGK7Nl*q!iC-=NO1W~CslM92!n43NWi4@fmW zcL06w`G=oFXO`J`JC-aFCq+HOQ>+z^ze2fBO4cb=5s4V%CC>vu_A(Xnl`NEoIgCpM z5B|9D??DB!JB~torHJ_l&0Y@Df~pzxOjQD-n;5zgRQI66$j+j{K|@AhRO-j?&xNIq zHVl5Vc&^&GVI&BSk8Teti142uFY7>+X_d39N6X@%TMUnZrJilz!H zG6eao=9pYxJxFn+-E�b(Brmxp?JLo|p@|!?SH7(?(jAmip3xu@8;5u~YEG7sSEr~;hB z=J15^lo{Qb`NgvAE-HCL`gp~j38R?~NRzu%}>=j*mm zjM3DuO!q(?;Kpd04dSABcv#Kbm6LQbdSC*#)J0TTBrUG8qJ@3GW*T~ansjZdQ}Red zviM!vR;+o0j}%d;OI%SMY50mlz`_j2<&Lf8#2Ur7gd{CYo`CHV-$17MM0X@nE%YJ3 zW$pX>D)29JvV#wOH+k#(0Zl$SjAx1JB)gc%n=U-fQ~{CA7gZF`x#P+^?7MqzQ0Uj= z&16SP1nksy1YWcbTF$&C57^uakT0|kl78Qr^kL)4HBqkzFN-(=pQH>G<`ShGBxZhC zr@-;c*HHGItgz-9XTQo+kRNseP=zZk;;F6aNr$MXlh|0${c>bh&Og=f5mDJ0_gOaa9P35rh)#2xkxr051`Nj(K+5z2LvCo+lf*bonfK_@A|F#N)enB5#K_S% zDPiyL=(u%s)D(1ZbmTuJno7GfG%%nlwy+mq*snoKXY_6}cW_WGig3;T$BX^_eF0i& zX=x=TrK-XUJ z&IJU=s|)|-J+=Qh&2D4|F)#T*l_k)8!e}X%iL;U^4VKH)YE1oU#^B+EbbPzK( zF)1x3JUT@omMhMejFYiLKw5PWj=pp{i1@#d%-N^sjI6iuScSr zM^1J&Z13&5r)7t-^71y8mi&|gW*B1xTP-cuN)ZUBe|!928xBh6zYRyf+)#KCXMs>y z`u7410$zYY{M+jP#X8V0P33?8&%>xyENX<`>$eeg*cE2*O@;^!6&>Ze8@7@E4aEDS A;Q#;t literal 0 HcmV?d00001 diff --git a/images/has_many_through.png b/images/has_many_through.png new file mode 100644 index 0000000000000000000000000000000000000000..858c898dc13ca0b98b9ed2715a0c78577716b4e8 GIT binary patch literal 79428 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%0D_t4BE=<1m*2 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¥*QH`hQ1PjhIf0JB8kU- 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 literal 0 HcmV?d00001 diff --git a/images/has_one.png b/images/has_one.png new file mode 100644 index 0000000000000000000000000000000000000000..93faa05b07f0d1dcefd441526bade2c99f3fa717 GIT binary patch literal 29072 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 vH9BQz=c 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 literal 0 HcmV?d00001 diff --git a/images/has_one_through.png b/images/has_one_through.png new file mode 100644 index 0000000000000000000000000000000000000000..07dac1a27d5b32d260dcbf8ad4d48208ceb598e1 GIT binary patch literal 72434 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 Vy{d8SnUB$EgN?N#fpx$m{@-iHiXs32 literal 0 HcmV?d00001 diff --git a/images/header_backdrop.png b/images/header_backdrop.png new file mode 100644 index 0000000000000000000000000000000000000000..72b030478fa9fd4ef7409147080435ce8dd88e6e GIT binary patch literal 224 zcmV<603ZK}P)7I*FdpuIsqwFhVk zG&V3NI^-H9D;fj-uhWPCHvuC#w;|Wso4F}yMj?7@$}rMgGHs~SK{AE8JF2=)PX`m( zCah(Yf~}iE@Tk@;T8&zn)K4u@nW+TqCa_R6W+UCK3u94sciMpB9nkMv1Kf`}-MseW an)(Z+0SOEC0HiSh0000e! literal 0 HcmV?d00001 diff --git a/images/i18n/demo_html_safe.png b/images/i18n/demo_html_safe.png new file mode 100644 index 0000000000000000000000000000000000000000..9afa8ebec140678c1d0c898b0beead727efa48af GIT binary patch literal 10073 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 literal 0 HcmV?d00001 diff --git a/images/i18n/demo_localized_pirate.png b/images/i18n/demo_localized_pirate.png new file mode 100644 index 0000000000000000000000000000000000000000..bf8d0b558c09439737ee186d12b1033d95b82bba GIT binary patch literal 11485 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 literal 0 HcmV?d00001 diff --git a/images/i18n/demo_translated_pirate.png b/images/i18n/demo_translated_pirate.png new file mode 100644 index 0000000000000000000000000000000000000000..aa5618a865d3ca8e7cc1012e12bb0823588f29df GIT binary patch literal 10202 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 Ae*gdg literal 0 HcmV?d00001 diff --git a/images/i18n/demo_translation_missing.png b/images/i18n/demo_translation_missing.png new file mode 100644 index 0000000000000000000000000000000000000000..867aa7c42d97759c8a5c76b0ab6af82eed37f8c5 GIT binary patch literal 10260 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 literal 0 HcmV?d00001 diff --git a/images/icons/callouts/11.png b/images/icons/callouts/11.png new file mode 100644 index 0000000000000000000000000000000000000000..3b7b9318e70761dd5be9a5c17533be3c1937cbb8 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sxu=U`2uF1C4}O+<`Mpem|0VzZ z{~xJ-=)i)Vl4pL3D`g%(AarI6$B~)Y6{&Nd{MybVv%OJf^2_w=sd81P4+QW&`CuHj zHhBwM(V+$z%eGaeJPLkV6DG4h&S5K>$7R^i_&I)p?eS2DHwX9=y#N2dckx<1<0~c> Z28Mf+!$K~|q}PL-;_2$=vd$@?2>^)tLfilV literal 0 HcmV?d00001 diff --git a/images/icons/callouts/12.png b/images/icons/callouts/12.png new file mode 100644 index 0000000000000000000000000000000000000000..7b95925e9d0931cdc25ff4e33523fa8395bb17e0 GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sqo<2w2uF1CkN^Mwzua`-NveG# zPuu_h(vl7bUNLuUo>&~;_wTU&O+|-u_Ggv%f2vyEdMDB1@BD|7%`ey4u+95>T4L8f zW1ED88&i+h|Jozq{JFkuzmUVZmip-F25%UoE}VX_>ZOppeDW9Z6F(pGn?-#xyD=|* kbIcRo?)i>7t_&i4483(xXEpRAxj~NdboFyt=akR{0Qad(T>t<8 literal 0 HcmV?d00001 diff --git a/images/icons/callouts/13.png b/images/icons/callouts/13.png new file mode 100644 index 0000000000000000000000000000000000000000..4b99fe8efc36b3a4bb15cbc0ab4f03469683cb11 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sv!{z=2uF1CkN^Mg_suyl=k5Q0 z|No!=@ZaBrnZxBTV_{T_-tQZGYBKM0JlXTS?!)c%dvi`Xtt!Z5Pva(;nLqz*RJd&SqPh24J^!OW n|L>%!reFQWnWHJ>@Q{I_rZ#GNaEZVqkh45p{an^LB{Ts5TBB0d literal 0 HcmV?d00001 diff --git a/images/icons/callouts/14.png b/images/icons/callouts/14.png new file mode 100644 index 0000000000000000000000000000000000000000..4274e6580af707bfbdb14f48a58cb7e6930c2a11 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}^nXMsm#F$04T7&G=L?PLcEvX^-J zy0Twl7361DSWz*@0w~0k*`_FXgzvRFF z`?HRoIH0hX=gdx3k^F-P1Rk34ANiR3d-j2ZKZ|Gm|6AYYzovVgYC(K`?AZ-}><^c+ zwe97cEI74Va#R|bi ooJTJG|GzHR;urHPCKd*U`0^-*4U;~b1D(X+>FVdQ&MBb@03^I$;s5{u literal 0 HcmV?d00001 diff --git a/images/icons/callouts/15.png b/images/icons/callouts/15.png new file mode 100644 index 0000000000000000000000000000000000000000..70e4bba61532b8ad6e8e9f42f1461311e28f27e7 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_So2QFo2uF1CkN^Mw@8{OuwukZ3 zf60IU_h+6taNxkTPy9zJwO>mg3kaTnpXX6Z%KsO^Kki1KE&6MJ*#6%w+giu^dcU-c zf9F3;ZA=WCpSt%X|HhmJJsJ~&%PxG}?7$x2FX&u2?Zma$E7$Nh%qj2UNw~nd?RlfU qF>~`1o(;ARAHJP85G#Ng@b=d#Wzp$Pzl%u-(f literal 0 HcmV?d00001 diff --git a/images/icons/callouts/2.png b/images/icons/callouts/2.png new file mode 100644 index 0000000000000000000000000000000000000000..8c57970ba9be47ef2654a40ab785d0acdf92e091 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_SzNd?02!|}|!G(;69C#QGOxD-l zIQ7JdbqAz8R5oevak*y1q;0??B;DD=Q@-oP1u;! QzZ&EOPgg&ebxsLQ0J(cR`v3p{ literal 0 HcmV?d00001 diff --git a/images/icons/callouts/3.png b/images/icons/callouts/3.png new file mode 100644 index 0000000000000000000000000000000000000000..57a33d15b44057062cb3308b834ac94b0ad2b043 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sp{I*u2!|}|!G(;?4g#(R)x-0o zPw20odcz|nsw1Y;huh*#eKE7@?Pw5zkiEsCw^}l_th}5Jl3D;oR zIU&xG<$&G#1_g#=yTdtH);E1-2n^^y_PKSD>$|(v3yu{xGMMzSbjBRpOGT-G@yGywq1*gHA^ literal 0 HcmV?d00001 diff --git a/images/icons/callouts/4.png b/images/icons/callouts/4.png new file mode 100644 index 0000000000000000000000000000000000000000..f061ab02b84be8eb1c24766984bd7e37d130a8bc GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sj;D)b2!|}|LBU0b9VFNe9855X zis5<2)qV8U;r8m@gpE>Xrmi~ppg%rc#d7}IugaYv?z3~lmn=@-Fje^T)W+?7pLei_ zaj(x_*Ld<#VSm`~LrZ>pPm)=~7r?yx)`Q>v+B?k`)GDt$Z{`0w?j-*!HnYBW!MCr2 O?Dur_b6Mw<&;$UU+d#np literal 0 HcmV?d00001 diff --git a/images/icons/callouts/5.png b/images/icons/callouts/5.png new file mode 100644 index 0000000000000000000000000000000000000000..b4de02da1127c2c9b1a3d96010bd59fbe4cfaa02 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sfv1aO2!|}|!G(;>iUO_&)x(uG zdZ-jdFKD^a?4opD>9UvCfq5~Ve`Y#fdTjY~j}X`PDDSOhEi&OQC9hJOPczIYDX6VK zykO!%(_gCES literal 0 HcmV?d00001 diff --git a/images/icons/callouts/6.png b/images/icons/callouts/6.png new file mode 100644 index 0000000000000000000000000000000000000000..0e055eec1e3e692b8bae23700a7ff97e39ac800b GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sxu=U`2!|}|!G(;?1_Est{pYRe zadmUM$2Bo_@g&g+9x1sh%2$+(nZznTJ-PpVLdm}Dx6VSR_?9-=JIT7)On-QiGkb~< zAG_?jz`G4@jq1FVdQ&MBb@03rE3M*si- literal 0 HcmV?d00001 diff --git a/images/icons/callouts/7.png b/images/icons/callouts/7.png new file mode 100644 index 0000000000000000000000000000000000000000..5ead87d040bf68746d002501902549f0a80db2db GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sx~Gd{2!|}|!G(;?1`I3*CQtMT z>*zTWrldTRGxDaWmU3jX=!B^g?^}DituOt5&Lu7WT59aHx1BQkJd3g~vtE1t;4Q=B zL(3fJ^SU-yI}|2(x2HXr!|HcalKIt?``j!1Ret6yy;7`JZ)aw>|Bi0Z4v^KJu6{1- HoD!M<+&Vaa literal 0 HcmV?d00001 diff --git a/images/icons/callouts/8.png b/images/icons/callouts/8.png new file mode 100644 index 0000000000000000000000000000000000000000..cb99545eb652cc9e78c0cff352fc602a737b1620 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sxu=U`2!|}|K|!V?1_Est`I`@B zZID>Q#@=1snzVj{`w3CD?(V&A8>M7;{{5Dlw60cnx3^Q`1nwN?6^;AP&s{0ZK6_@N z)A0po=R9gS#q{UcZxs)n4>NZkW#nYu|8UpBM+L{Cj)_}kEwNjq{>mkhVMFVLCt+U2 Zp7o38Tkc9_QVIn*#naW#Wt~$(695f=K#KqX literal 0 HcmV?d00001 diff --git a/images/icons/callouts/9.png b/images/icons/callouts/9.png new file mode 100644 index 0000000000000000000000000000000000000000..0ac03602f6a590146987d0a0d83ac4672b229216 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^JRr;gBp8b2n5}_Sg{O;S2!|}|K|!V?1_Est`PrK< zCK*cbigj1F9zD9($uOLQPw$)5(JVuYAMdL@KGnvS@pHO1Pg&r%koWUz$pGf|^SPFB z7j7n4#4u|~?%V#<;^2u1=YHDQ8%QOjg|{DS5Ien$i#_n5>HQ6CvsigFwoka?y{V|> Z3wuw1Mbc$!<`$4!JYD@<);T3K0Ra78JZ%5~ literal 0 HcmV?d00001 diff --git a/images/icons/caution.png b/images/icons/caution.png new file mode 100644 index 0000000000000000000000000000000000000000..7227b54b325a4802786d0a2826954c09aa008190 GIT binary patch literal 2295 zcmVqm(~zIJ4OOh7(<3$>&0w`(nhf+rjcMP;ludRp@JZ46W$Io>&Q-VSf>@1Fm;=iaB1dphgy?;jW#pxDvTaq;5C+|$`p0d;qG z*VosdIdg^{Jv=;ugM$MC0-gqlhXAvqId$sPrcImFYPA7nW@ctuTH36E6tkmgY-|h- z4J8@_OHWVF&d&Z`ff^bbLPA0&CnxD~sjFi}?i>E=f5HHeq1@cu?+K``t}Y@Xf(ae) zOV6vVHF04tHP#(|Gwx*uuy5bK{QUgy9H_RoHZn3&5CnSs?XOnVAInpYbx9Nb()~-B zsnIE0e#QXy?%i8ZQ1BfB)zs8PM@MTk8hQ+Q<%POqd5Y04P84}j!$}%xtS>7qDmmsQ z29T1HQdn3x_drxPF)=ZWCiGSB6GwAE!%HGiXz=i3cXHCBlA>Q^0LjV8MMXt(40Pnk zk+85ZQ55Mh+<)!y!&!=vE-i$ui^9g4vvO3}x=I}WfvGn)J#u%X7XwI2N-8cco-?4T zs;aoSIM6Vqj#VBqAsVHnXz7sn`@bA0{-m<*a$^3cD%ChA3XA&o zQPh;xT_dJlyLKrQitXFC&t9^Uk`jHI*Ft?j1Er7yOsTCHji6Rf=)dB&WFf~1lBB@^ zQ{n!wZJ{14Pdj(+#0qB#R9;?=H8GmlaNnxpxA@U+juW->K^KT9sm;wz7!A*J&$~S% z|E|#$yXt1qfzbHirHlzHtgNhjVj%PnyvZKpH~Uo-X7IzEyeM!O98g59WWv~dOEU)K z>SS$cu8?VvA%O!E{OFC6jNsRUo@GqiwrxXQJ^@f`Yb*K(drXM@d1=9ZUan$EP7f!d zfMha3?O?xv0X_e$Eg*=7muaXSfT=ViC^o=_F(o7t$~RZuNI&OwG;Bn9Dd&M@Pr;mdrQ#c!`r80sZ(#3w7l@ZAe(aa8G%L|LUby1aR=+LEP+~Y?l?k zlgABr(kdxKJSS@*$|$~YvpM#bUL$tMF^zI?g2w>QN#jhD~1cF+dK z@yY8go#&7(S-!DHuloIvfE=vNFe?TxVdydn4-`rM@w2vj@3-h=ii(P&o?`q8o0F51 znwm!A_j#M{P4Lns3vNg4jqS8P8x@+iKLjaW3B}xCpmEkV^>wa?it+t*K z)>&}I$=!=LA{p)&4h{|!-@fxOFyXz{FK;5}dJ~W$S~6Z~s<3ye{nOTeei*@M3{W87 zSDg>jt8X(JdwY9ii0wEdK=_n7fBw9alde?z28TlvPqtjTj`^lKkXAum8JS!3s?6Um zz4+Rp&zoC&S$e?AlKNHWgS->Hm#z&Hft8h2Q&W?ztt}30qJcM3)b8%?7cN}DJM=j8 zP!+zXvH7ze%%N3^Cc^;M$b-vY_WU9D;}1_?jXwAVF4_{wBnqV3*F6uaPWPX__<(3k zO-=EEuxiyRM#KD!K*a0f;?myUj!!LOdNe$-`OT*Kv)^!>%)z>mX5wX6^}+>a;12nP zlhQ=Ok4)36*Z)`d$-SDhgG8fLDsi=1vu2GT2)OHk3EqIo5Qy=TcIVEW^Yrv2Ce^qQ zbD*X6qfV_HoCq?K?-?_7OR?|awAGmj?o{uToBknH!`}ys8v1}j#haCtwSN72WRZYi zfB=?0(~NzH@NH~tp!eFfYl%rcDQc-X>N zKBlA0m?6SaOc_C#>KXWO2I(_ZpZTx%!=dAaMtZDeLjVJWrKKf2 zj50*RF`yYGW5(101my{Pm83)f8tQLeUS5k9EyCWx#=#@Rq7#&qB57!1@|1YQYsClNtLQet{cM(qTmz*7ujgYBuG2J#GxEqlfrqtPbG8Y>If2|zJ`n5;xb1k-m0 zs|46=fb?U7CJqQfA#@4=#6)Mo^y-`?5M!E7$ykj}#yIBk|EZ188z(Ss{|5uSKm4Z^ R@VWp1002ovPDHLkV1gg*W3m7M literal 0 HcmV?d00001 diff --git a/images/icons/example.png b/images/icons/example.png new file mode 100644 index 0000000000000000000000000000000000000000..de23c0aa871543ea4e6b5902d3ee34c37acc6118 GIT binary patch literal 2078 zcmV+(2;ujMP)1->_8{6n6m6_`Icd-SLA*rPibkVY z#M)5yAZrNDzeh`1q2Nk~wqc zOk|h@kk9Ay`~5jNIc~T6siPTVPitFSUteFifQE;MFdY{LIIjLZ(cw# z6D>nsK)r;sYjEg;W+IuxqoL*r&@@~&Ffc%`B$8LvkjWAFOt(z>RP}7mKG2|UQ7uIF zVkYeA>6sLeVd7FvO-+<73Ko(i$!@p5zy1APPUoIIdu%ovf?W_q@L-aXvIuD?f&|eo zNW6jDv17-{qN3N*(!eH4etf|MQ{_kS(~BUAlB7(%UT?U7;Ic?-BuR5RolQ+mr%s(J zFE3xee!ZxO6$S?fb90@b{QUg5xHzl<)Vg)+nwy)iR#vT8zMNF!0VWA>aSHZ2j-+V- z8W|aZF`xys)44M?HWs>LVq#KLQy~dv^LRW*j(n8y+l<=U+WbR@{0!!+um0xp<;!LN zD2=dK2oF{Rq#6r@G7%s|a05{IK@F|$zCHv%=9`%b2??+Syt84$1_%X%(P;E~-3XG( z%1V?_EEJ*-gRs3}L89(a{7%AEUQSGa)Sk=Z|)-R?AW7l zMO0K&STPjsh!&Z}O(xUaxpNVdMza|V%nt$*aOhj=M)ug4RB|Cc?;zkzbzQKN~inqSLRaaNn z+S;0%n+w;0$gLo&U^Sb}Mw5}_dGZ`9Qj%w~Ua4>dRmC^gu1!u(`S*Xm;;F8wv8cu+ zy{oGdM!BJ(;r8v@^>^D^{$~aT%I05?Ew5S1_nX;b^9sNgb7^py0#gMJXpvoIsq?61WW< zkA#3~t>02qn*;&typn!=clSemm!WSQE-W;gjCFPYMZMA5IGvTy5g_^iGZ9$&01Fso zW&^e$VFCtbH<4ut4>Bk}7}l&=Q(RoEW1;KUuY=X?_5dkTTxpqVC~<^H#RQ@*ss$F9 zC62McFtkb>z`=1q5jYh?j#os5e%d4FBg{(6M0wFvlLge94XrVFS{`$%2{m-I41nq_ z1OpL_3N}FO>g>`7gj)yl)6a<1kvJ%0zcqbKlQh0PQ2a3Ds)?k42?>h^44;)nx5opq zJfn~?v~lA`xVx(IT4`D7!i5XXtUzl#pI^A}Zgw^SfUMvuKzAJ;F91ZyR2zmMoF9#x zFon#r$f!sZ_@tzyd-v|4-8>QUH*O-Z==5ALqJVd%MYy&nCMF_#0BCXxtzNyFCcVAA zp`^^5Ig@*OgujPyl>nxYy{xmdb1DJE@brjUH~4r9WT!hb`GtYs%Tb?csyo-MjOW<|hX+z(GKO=IC%ZaG60EVII;#L{N{b1!4$j zFk%jf|NQ0(4r7V3y_5AjYE@IvvR|$&_m&;~-xYpEoji`1r(g#F+2jOP1STJHwbNjb;hrOx(J~vIW zIc)d4n_q}a!XfbrX((@qA&ev(r_~1pZru04iV;S-cr0KbHUj0ipxbF~V{gn6wzIxOT}ej3xbSaeC@% zEK*>RZ7`o24Jh?jtB!wq2>H=)@0(?dU%^J8A)}J~py1UZSZLK-FD+W0c<0WYuCA`` z?rwAy6erYzz^zh`;Pk6CBf34)#v5 zkqcj<_GfwsDEbmWx<;j5rcdM9LPm_f1pV#L{!jf3&<~~W0fukb&B&M}Hvj+t07*qo IM6N<$f)`}iRsaA1 literal 0 HcmV?d00001 diff --git a/images/icons/home.png b/images/icons/home.png new file mode 100644 index 0000000000000000000000000000000000000000..24149d6e78efad1a87f17b1ec02696a3e998aec5 GIT binary patch literal 1163 zcmV;61a$j}P)J2EUVw$g{Tw6ydEN}v9{=fY?(quWXTdG2$cdw%yk_nvcP z!AwXR*eWFTZxfRGfZ1$#cb z=@$}p<2%)j;SB!J|G@pl!jVaQRb#_|-ifgpH;IERb}uBqpKHOnLUU{1T^N~mp|rt* z@U(v*XgYsl;3t^2tU-H~^3)OAp_4{5_bs4n%z+zB1eh@`Va4aiU6Uj~Og4Trw2teq zAv@B`M1-aeF0iQgG4NwDmO@*Z3SQ38OQ){Pqp`<|rXCx2)X#bX(120o>qkUu>vdL? z)*IM`j!TM!YnA)rbDkpbHm26t91E(N=TO^j<_^PCPWV`K!EDOtLDBCb;!b<;dj1lW zT02;d_e80xLJ2Hqxv4)?G>CZL}_Z? zBya>Je#(y`zNt0fk1i{gy%HYOmb`vccC3P5JT5^<9G1+eHKjFgu z{8c5Fda&RMfXmvrGuQBKa7(QS%td6e=W!o9pXmMRvT;lwRS$tknmHTjJ+i-QmH(LI>Bt^a`KPzTl*_ z+=qNaQwAK7sv0%3r#YBfAFK6}T}MZ8xY&sFvm!nz7m-_IMqaHMnUx|{7R_^Ioiict zf*GGy@OSP*zH)WPZ;Tbf^tkMX!}U^>rLRe#%oyDY|{S dsKA*9>^~bpfUkLnoT~r;002ovPDHLkV1k9qKrR3P literal 0 HcmV?d00001 diff --git a/images/icons/important.png b/images/icons/important.png new file mode 100644 index 0000000000000000000000000000000000000000..dafcf0f59e4f37c20474a6be5e5a9f3c57a145de GIT binary patch literal 2451 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 M07*qoM6N<$g2|pd`~Uy| literal 0 HcmV?d00001 diff --git a/images/icons/note.png b/images/icons/note.png new file mode 100644 index 0000000000000000000000000000000000000000..08d35a6f5c3eab60401adfffc279451d3a32d409 GIT binary patch literal 2155 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 literal 0 HcmV?d00001 diff --git a/images/icons/tip.png b/images/icons/tip.png new file mode 100644 index 0000000000000000000000000000000000000000..d834e6d1bb54b3f6ff82c4edbb22e49212038dc7 GIT binary patch literal 2248 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 ad;Jed<(|YkX%;E~0000RNT(|NwpX}ea-obW_ zhVt)k-`@4LuU1o!)=)QS?XwNdMDGY{7j#)~V!_XHuHsxmo6APiA^r^(94?@DCfWA;iJb- zo<4j2;^nK?m8`14tI{()KCY2>`nr)pM0&BxuT9Uco)E|m6B13$32dC8!ogq-0F^_o As{jB1 literal 0 HcmV?d00001 diff --git a/images/oscardelben.jpg b/images/oscardelben.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9f3f67c2c753dbe277d8c811bdedfd2d22033137 GIT binary patch literal 6299 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 literal 0 HcmV?d00001 diff --git a/images/polymorphic.png b/images/polymorphic.png new file mode 100644 index 0000000000000000000000000000000000000000..a3cbc4502ad727c48fc05243b0cd44f759e86c31 GIT binary patch literal 66415 zcmXtf1ymeO(=`dOOVAM9A-KB*3m!bU!{Tniov^sOy99T477fAO-6go|zj@yOn{ycU z%$e@4y4AO;x~DqyySyX{B0eGv3=E3YH!&p`nD;-Se~Sq3p-&`Ftes)r!E#B739Gm* zon+d`CYs<5D)>l0`LP#x;q90*@10YciPDvIweJM}aiMV_I?|(b}z} z?7MraH<3u0AqXM!qzPn3$N<_)L%6WOw04{qKG#elrS9FuT7juKol=lXu&cQ7#aEYRPm0O*Yn83yLRM=(HG7?=$Z^iekidgH-`-u}Jj2T%C? zB=-!k_go?5hjzi^rbk$rnUrv^UJ^I&alc8qYN2FB}|B50|?T z2;}F_pV=qZcXw|H_VkzpRNpWelTUED=`)NCm9f(kEjf^3cu#?3!h9>oBAa5zl|z>ENH+d-tv@|m8pI# z!=KBmUqYS9E9A{K^+|i%1i@4ngXOrBXrT>uc6T>HK}bY|cz7jy}SJ`EH$=@1WOT54+Ge?y#~pU=#wG)P%_sO#yiO-$rqStuh~ zt@blWT5-bxVg1C3%018xZh^4<8N>55JrhmY0t(NFHM{ z{`Ed!QGxO($)(!jx02%2>S_fz(!Sb=!so?*RNitlYC7r7?wJn=1OQ4IWeV-3rNd0! zjz&tWs_ZN*CPk%9Wi&R6qTrxC%sE&8LBA;}D%sEA~8W_m3ZK@JR~!kKG)NkEpJwJ3DI4 zPSJ$UR`WW$)%{7XJZApB0&yN6gsy%3t14GsP}f=<%``MLoSf<#18yQwzf|RymP+gI zqN z$+mrBanEn5Jxv8#%l}@f~--;^pNfArWK|nFMxL3P!D%QCH@RI!pn; z+=DylBP&V~@;{f=no}Y+=e$1+`^0G*(%cuA*QwM{s8RNbb09^FatXv3QqLf*sYMs| z3#$VENCXESv-lC86A)q5{XHDBkdeYNxniD^IdLaThmPW$x8qOw;%BM#+oviZgP9ZDSBo;FAS(4C zw2YgXVIz5bRzKDDmkN+R6f4VL-m2rYrB4{twgs= zK_3ocZhyO(Gr|zH&(K7 z-WhkEX&3hoghvoFCJ(D^B6C_TflBk)W>=qYu>d50(r;iiMp_vJxLnZ>gSWgd{y&Z1 z@;!44*A+Wf@R4bE>G$=1WDMbITpm`OuvF~OH38J0Q!Kmu8#L-S#H#?=T$i{B3b=FY zf2aHc*31drA4nTBc)Var)z|njcQ5dY^1UDjkj}BE*Xgx;Iy{r!ZedATpC6c8*8Fk* ze{^1Q@{ zM3o%dWYwxWMndI@aFP6ZP(X*+r~Lp?f8YDfBBFF0mvh26rAz5{7tW%Z6v3aPnLZ=| zWUlb1ci)YKC^U92%Q_g0<`%?z_JuA}U8Es4Q;=}#aH6LU8vRb#O18aM@ z(y@Fr!1t1I=NlG-vpw^iq^K!`-ZJ;Cey>Wl`HkWKI_LS~Kx1ZD)+j56)fN#m6~VtR zrMXWO0Wezrgb`7bKZH3`23bJuvwTd5J@y&(1Bt$0^bcTm{G>dWAsW<=ogc+>_JpZC zJp$kRN*Oia#Bvh%|B-3)-(6o{D|2-nNKQ%lJ9%XpfZ9j$Wfsh2f{c-p~g5nqpkwNujn?AaFek@#eYR>vK~W$UlrgS_nyTH4%pq z!9S;t4s2Y`!9x|`vQ*83q`WWQ#7iw>ri$oKijo8%p+gz)U>p>~#`4#)VBx@Zu(!2k z+5%;%(*8%Jl_VveleUEtPkeV)180?Uuq@pGWZMw&#$00-4LD>{C1z0N4az^MKBf+$^YXSegqFL26zg@x`&?; z7Z;bADd4y_5{QJeq{Fcdng&tq%Rp@rqK~q-R?ynoS}2peb!IviXLSKo!9)wX55onD zg0C(wu^F`j_?|oPBRZtQ{=LtKLRHO-fgdr0Yks~rnqFheE%wncxUa7dnrv#;nL^VQ zgQP&m$=~4vI!>aZyZ6zvMzollvutlX)ei13NjW*m@x%%&*5 z0#AiHKYPhoSXeBiaCqKYo3pUJR&$3su#6x00jvZxJ_g*+g3`lH2}f===6mA1oU5NFN5l0CiReK8Exh5(!Q}D0u2y>03#+S?r9Fy6+n7wnU8Q5_ThkK zo$KXI3+)UO?F@BuK8T0bM5(Tbqc#+rx8+S8S3(`=rKUE(gZl(7frNk)<0%nD+V_pg zn3pObXF*r^8M`R4KcJ0RO?WG?7CIS~W?e}J|;_BLpE zXiBG^6v3ea;(2=_Oc>!<%Yq|^Qi&k+6s~-@H(sBkI`j>T(R|kBV7)60yKkeuvkR-A z`+=nS?LO?BQ7(qk6&Dzn4PxZx>jb+R}1z4eVd+?LLhkY`j7#utdTD)yj(H zOwN#SgpYu(_o|7HzKQQ_y3xSMn9_z|DIYuUs}=lsn;Pfi4Qukfxk-ZHzrN^u;rXep z{v^<{n~rq5Pqw$k979sVB?!x3ApZhQ38dnVN_CdWJfhszNp12~HwV7rD7Q&raJ?bh ziVSJ4D^qYeQ?(vMUT#MCPfOKJ`1_=|_;?4qPp8)1M6W!|9{pihP`l%o^AW%a#{im& zAe-=!V@JP!1EFB$*LxmLlfXm4A1L--`72ldMywCDo3Hah^ z4XCZph46Ls^%YPmQJF1&2(B=b*AtoKi$1x&n=>QyG=?ANVG#3H|36MhNlCT$`mVLR zyZBb0p5s8n^-3P(Td;*B*a|6~+$#OEmAP=4zuXx9QWTrWF z$^XL{F;FBmHFY7Yj|cY{GBN}O*E9b1bhWIG?tgy3ebU9(-q}Xc(O5UWE(zP(Wp2{n zyx=b~krw@Z!xKi-q<@9#KVW7z)leh|8UE+)$WVN$8r>v!jJVS?qs=QOgMI$>7tnbx1-xR+yAd8EM3x@@M&Y^iPeKs+Og^u^-JvPW~eI#l>n}s8k zK7`lP+p5a@cGWD~n|bhRwB>H>cc7y^3D1H&LnwMve~hVwqVhpiICUmsjYRx++Uex5 zj!iTL=Qz$G5*d7u96<5cv7V$r|Fe_R=&wL5o5^qR-BM}&2-fp&JP*t3+k95Ra$!c! ziP_yp)PMJ=ztZi;|LQ2|YI|m&F6%17r3iin->`3Qmb`hD6YYbTbeio^JAF~38gQBn zq_E;le^(*-?4=eBMv%O|$!m5~8DZV8dcm9L$pm+n)3O&VaUXSmYB;pd`>^_s1jSvU zJSG^v%yQI2R=C~?hbF2&Z50MSo=d2j*gayD!=pT#BS*vcj>_Y?DneTa(orF(T$~HV2FTIwb(DQwV zg|txfgJzBtO)=UKcDAIeyG|ETVw`Jf9_0Y{<;JH5eT}6u)t`YVxg3NrsFl{e{_^mB zv8F+#bJj71yO78&uH5Du?(eL{bX==gK`gzTU(NM>xbYVar*u2sS0EjUS~TB}U`$#t zDUlCv%O1S;q#LM!TPi9O!0>4two=M{i{F;PgN>x)D4JQd+Odi_(PTo_PAv}HR7!IN z_g0+3)ZlUjfY!bmeC@H?Bt8M*ncIw~`qXTExsQv0lq<}aIMeyAWjB{%at&Aa>YXre zT0I9HH5ZbjeZqf1ZVckR4H~4AdOkx3>VC&TL|xlAF3xWXc<6XvzR#Fh`~9KIwiDZY zF9fz|m*ZeUc8$KvF^>QgOb&Y|0*cQ=0!MZbW}d*r?f?una0F(&1P^1;_gBb;WUf3j_9Ho#@(h1q~q*Rx4){0KCcgE4n#2&O>_s#lls*ZbZK=CN>12t z{g0`W>A2!Taq+(tzp;x>M*opgSE^dO`Ri?yBL069Hhd|XtmVK+p~86*}YBi_lwaeam6 zV19XBW6E``|ME0k4fJLE{a7uCexwJ4?TdL?O<}$xo+Ei3{k|ad%<puIDMOhwG1CWjCw!?Kj zA9TWKq{2K_f_KdfMgF%2JQmgAA2I{C8YpAx##v_z-p!o=!Y*_lo-_z}7D63aaF}#> zfa}~q;D_j$Z*gVIao=Rf*b$FDLm>90<|DkPHmKxf{O8jKB&srT*iyU;tvO8ZTc+L+-d>DvhtH4u8a zR!*$=fZga(EeB^+YX{fsc36l*cRG-Nwi|aP_E7!u`NTjW^8)q~`Dy$kPdI)acsr__ z_e6-qh(Vo1X3GwEM`YJ^H9knpZyhXYf->^-_^NOXl`0oDijC#Ic{ZmvrQolsMS5<1j#S7*EZIPDdOC zq!8zkz84$ZI=7 z9rU2;z+vB5hjTJQwgw$E&*8Dz5aAyS)MKZCLLKM)Htw;1rqoDoxqiwE%V8q7@9EA_ zh{*mJ)8x?id7vycxCx>(e{Ho#tWO^&h7+S`gAl)t7CB+Vb57!kzcZ0@IO}-h;<*>e zVg@jFVPz{4#^_^7nF%Ml7VB?%Epn=a7|6A#z)-3m$VgN@ug-&a?o@qa&T;=Qj@hB2 zViQ*->Zph*>N4=8oOIl3cV@E~-aZdiTT$Sc5VoTY)Z=Xnyxb|v8t&nJuf3PA&3`(j zES2W8Q8GImZB{f2W>!sy_dL0`>%q{aUFcu7j67w-%^6B-L}H0y+4H9+=#cm|YfSjO zxp4<2dYZ7DBQYvEa6gnBgaLdCSb(fKM1yI0Pja)p&D*upPx|TDV^et+#Hz7b*?lwN zJav?^;78=9ADUcuP;b>l8eU-=Ox_^XZH2IWFgJ_CwoS)X6}wt{)JuD6!>4l zOSP0X&D_7S=X(kXv;Km@*J>fqfS9))M;Mns{a!pN0Fuu z8wVB*sC16IuKX^OhL_pDquy_t7~~v6YbPx|dQoNDvOuPwrs=jg8nE<)ha|&qLHqll zkr=SGQQFpA#nh@pIHk&;(Zck zY)^QiN8O^s+#-Sx8fAKcL7w6f(?S*4Aw!u^3``-O9R31CduWOPPd|S5b+Mp8z$G{! z6BRlLegrPv3^HsHjudjA41a5qqJr+Vr(mJ5l_X0M;V|hUjQ%%B3V+|96h&7P5o1|d zem|aju?~tldX9RtSb&Cd5W^IV)on!9(`{!^7OTnQeQq{drNz*J=nKw|_iJ9qH=Fvt z*o4P(Xg6r}$I+U7yeTs3^wIoJhW&k0QW4tP+Tpv!(3PMPm0?Y@KT>ifJbS<|L~M)^ z!V!{@&k_R>p?D~0$f&4T9$epQ+umcFPa*!M8b!XWV^XS*HRbA`H&;+Yc8R7zm z^ckH6dvpT&86YRe&kx4e*H>R(pM-?O&hAXPNZuWKd3boZxn*qh6lz2GA=bR^mlUS* z5)uGx>=AkvRyPz5Spvfm?nW%)k58Z~z|d@ZoDLL7>B!rE|84=RJ10*X_HlrnwDwn@ zDj`|7I7gObd2WbUw}$)IZaas~%MCb^rOV69YN3Hke^0uFkK1z`=D1gpr{Dg;h2z03 zeQ76M8JmO;jrJ7z0@)le)E1^O*@5pEY~~-Zo^C&qqft{qx7C4xf?FV-TG$-k&1mKD?f~8M?kcyUTuJ$dRg` z=izxpUI_+R9N~_xD>n5)9I+Y$x!v~cQLJZJ1QZZj2YpBmyC6_gW!6onDwkL_(OGg!> z&Q33s3_#QYf6+4$qfv;rNc+!z-jwZkKhB{WN8?!n1cZcy1Ozf|2K)pA^jaF0_L6B? zh-e6?g3A=Nv67B$D(Pv5Nac}DX|_6f{7tRA^W48}3ioPJJko**8Pg~!C6>8x@vGD| zYl_SFYRhG4Z{)rqEm{}Uc{g<~l~N9_ppjayN}%*T!MDk@+0A{~F%GRx)Ebs`IkK=U zBfP6#C1d%xJ~EIK5-N3B#Q(611LqlGa9}&v^YyosoY8dT#Inl~q|P+cL-+wcf#YJ| zA#dhug0#0{#aWPVvrSh0obc zb&G$6^d!LaZP@)(w6FbYr0u}2itv3mb6x@JFHcFc<2m2`Z?f96a6y_WLuNnvdX)3J z#U?tk48rb!pkIpHX(Pv7+*Z-J3oopBxVdp$3oPgveEA-8_cjn>?HoNd>k1O;k(GL# znuNcm;AGh9-M-t@0}?T&FG)|p{p4I>)TwNQVa00^iK+BjPbs(}h2c=haN!3r`x#i& z30!Hd2m_IvBw<=b-*_%O!+@%i)c0Vak0ovH&iM?0V%ss9W?ba`->mCjVfo;KQXej~ zmP%tCI-!O}S5`{g+}+MljRAGK5~Ssj9JMW)+lYJLhS&wqbLb;Q@;Z*ZkhbE4PD8x@ z93dT_VRAHLduBM~)$Wc9D7nxU6#n6-;iS2o*(9IiapLN3C}mB)EHV+7agPGkzT?+g zOljNi9;;a9HpQX(>_^$x4+%}tv=JW}SElaP)JkM^-IOJimPM)&svYE>U@W5f;Nzu) zzTRHiX&HJ#m$=E1k1 zmE)7x4H`Q&32so)II_4AzbSx_<-&PMbZOM{=yNb4I$W+&Fp%2DPU7N!jcEuZZ)qtms_#+h%Aeq-z z2^!~e3RaepBuc}BPU!hHx|LRMjKVmRC%G~!2J&s4>Y{O8^}aJ9if_YVCbOnE6q+ZT zfj>oeCfO&@xpyjNR3rwyfukI1Ww?09@A=>)E=tH~2zqs!3Ht{OZ{o=qXT_4o>T3#T zW=6itNRF;}@L7UbGjA(wn7*P6Dl81mqoru#>odwv>f|G$$t$bdar!&TFr74VNL&E4 z=X>wnkD?1zQ)wbTE%9j&Qou#LIWVYJwi5I8riwWX#7hH zp+;pR0))n=m#RY9EV>52_|o=R{W?C09dm2<=f5Z&zSR_0jcUl*m(JEK6~c)0Kirp= zmKqxyH7u*KP|?s7WM$jE9@vUe;DXO+4Ng%ayzL9lR~V)G&m3U21|Z3{4eD?KS(mqt zin=Y=E}rmdjyN=`Tsla|R}$<3d}GGJf*B#f07DFLR5Ov-G7O;ky+7P!Hhq=S@kNOZ5#D_j&ieg*TIaxVY;<^^Mrn4P$@B)M+=tEn*Un(- zKvB>x<}cEzxivPC1BKUX>)6-}333eDZg+P|9M&e-gUalTR#ZNInJNS_aUfzAn?$){U>aa*VM294 zIPad{$u(Q2B%_%?xV2+gX4Z^N9hEW@aS*Ot;V`yC(HGQ-IpD|1n+@<(41I*>qe-EK1YtH(yRgi}!d(R&2c0}8JT6mqjb*!U z{wVLA^#0a1ujWTaM}QcEw}^kHr=MFx2w6H-Gufm3D`ZSoy<%$Hu)3E6GbDU|xgSLp zr(B|KY=)18lhbH;NCvdJQ62t6S69O2M1hiHWTPBgb7*R(k8>@qEGVJrj82ECVKdIy z8nU!eV#PF2*gM(2RlkZoF!$tohG~tiVbcplm|>Pi)$MTEz10mWepi3wIOg5^i&Kq@ zZi4IGB@8pXEZSEKoubNuQSvq0@yIyC@)T2p+#&|V|6$Ed1{MB)N6R(r^ zXF46uYfXk_<>c=EE(b@u)-P?yNV`$U5=LYPLdqs#{lVbV`uP=$DymiVPtY6-cf$V3 zLr>8|&*2M)AC;lUA7#-riIK6c=0$sNRZ)W?*2Y^;+hJt$5@9Veh4rJVPR#;b$F3Vu zSCZ+c$8F^v2ip31iv`}L>&r(Wikt0tLWk<8C{%~@$$Uv(pd%^(xZUJ+QEKVp!X=m_ zutZ3xShvFIj{Q-!XoUA(VPm5|9EX5_z^H-u#|{GV2T3t83TohWoQ7n~r6CKpp5p zq^GBUF6)lIl$4OzG7%qx_&T5tbi%b^crg%65Vi|}j?mZvk?FiN?Usx9b#_8ew>Jj) zYZFVHpI@W!+nOR^y0@nY=Z1Fz+Lx3lnn~c)72Z*5MZMG$KhrHK+Z1nR}=GQzn+oay6u)Wgl z)ibd^ey_#dM#aDUBedq_^IU%CY$E}=GPghXhetZUp+G`HYA5pE8^QBnL=u|&sh&@w zggOu%yTx z=FOew%Vf{T0f=^^H5ux_{5}NI%m;@$fFXSQEALwSO6S#sFoKpfhj*ddmSNTM^~Z=% zZfZo@v%LCUo>|3x0KcrB$1dJkxjXh+{Fi%jtK_=ptivv)yAGebPeC#mwyt;zqxuO# zRIugDmTE+gqgF(j8xcBe$hI^XE zFBmri0s`K3Ll%HW!hOR=*I{B2H06aarpYleNn4c#KmS`-(cHJahrcFMNM`-FS|h0o z;lW+U&QbU^Ha2!|EbSU>Px8r?oEP}!9H2%}?xz8~Fs>{vK2Y4+z0d>bm; zS^WDD{~5?9@g_35Db#M^^J7b=LLu92%Ymba5icT>V{O3WQpy4&U1edRq){xw+7q z+w2X#5CR1S1Z*UKff}(rAbQ;-Kl`wo->aDiH=Hy{gdt=BIK7>!q3CAisT^JqTaWp- z;2n4co1d`DHIKSQ{=^YT&_tFmCau~<+R9pFYdhKq1#_KlKj`m4=hBinL zh)nPR;DqcppUL$_@BQdtE(za@va5az8su_Ivze%8=e^pOuT9E6LlPh zozpy)#l;*ErE0>`to|z=?s8m_5>1-t1zJghWP>k^TFFQMUfE?l$;{2QYZ;&3z3Ua+ zDf?}KAzjbgj776-XNA+2#eFZcijKJ@Mn4E}Txj!4s(+!`dB|xEGBH~%@Nd=KF{Wp! zw(icmo^hbvu)iUgC3uOHF_L#?8RZX27Wg z{;OE9#Pi}%dO2)3C|a7Ev9$5VdS|2Cd*l17!m97jU{;p{TZWEy>2kwa_W2nJB8dq@ zBoSZI1LzPkGGVXYjE66d#PS>g8Q9nx+c>9o)ZOO>6itIYRT#j9xm&HX=76{7yX_<6 z^R+Jd*suM*d&Nb{9?MzYws&e7)fDkft|NZAy6qIU^PM+Y81a#i4@N8=)gtge938Fj zo+bXqUpv|ymwlS36D+O3&$c?oKXNr(yLuYWufX@JM#Ya9IO@G*#-xH+|JhvM$Qkn0MK!#|s-=m3LRP+nExo+%(4G4*6G%ddk&(DWCB_A${j7 zGY!u#cZZ3<&g$KuQ$&6&JU9MWg5Miy%L8GoJTb_`sflD=hJK}4h3OJ~Y`A4rE|X%5 zjISWArzo3+%+8baD9B~urDm3cXHeS6=R3TGhhNCV59UD;BVp!S%FQ-c5bEUl4D4wR z$tP54Y9Fb~g@MBsJ6Q#z^W;$wq6Z7c4@9i5oFxX;So9b43wZ`C+m_S6ce%+C&+ExZZA

cIeyaL8pSo=WcW2vV*J zgd)bWbJQd*YQ7aZU#?k~)40K+@jvmZoKdXejk6jG3*y} z?U`LB#uTL8S;zyW;G7EwKOc0hFD7Nh`FlNVFAL-hMdAXf!QvpMSw3^W7`; zbSUEjQ2Rl~utynxrXw!_k|D75OVT<>LM3{(aew1lDAg);LWvmw`M~4K7{(>mg>>rh zK_?o_o@o5jQe1E(;ho7-uq#|{yE=+>$dKXD*ul2=N|ke2G@rqdaje7M2G zTMtD~0D%qTo8Y@|&*JNf9M)T4cX85>nrcp0;qnCvN!K8wYS!jZT-i!#>&ZT#=YgW^AX(f1K;vC>UR`M(!+JpeT&8f&)*27#6Eon~4EcS`A^G1iw|KqEKrG zX(fTkdktu?$i2}EPPJvjd*z16jXH?~pt7c(jlG02C1jT-F#%+sBCgM+kEbkGZ5xLzeU-SJ({r?ilYo6i%CsgY;!$>)?cxv92npya>P876Z<|pBvlM7$WSw@E-o&HL=p?6 zT}YzsrwV#|2n$1s74tt80__%S1Bdt5NKFR)C9w7q_07=(?@EnLtC8)bzk!e&@$~^$ zIm#3TwbLYmUJEAVAix#h#t6SwZI&Aw?AD3N zku%E;NB=zBbEAJx&&rbj#4&gLccErm6iq-yP3@La|1yDAS*={7#^dG)TCB!Yt)!iT zukZsv{}G(*^NTtHqPG2e1CQMlO2}7jrzs?PabJQxQnp1guy3+mtqw1B>|dSO{tK@kGIXv zj)VLOT*JD+3JrnRAi&>Dwer3y5NY42<~e28cDye=MT925t0HuocWdgpxl!94^f8z44)zBr<(qt zjO64&-5R@fL1r*(2aPi!$|?35O9X^b4^7RBMM1QRxLv4zPp2Tp<911&)37Y6HE1Zk zUE$=bIiu0xVNvz~Exx``xvgx9G@46U;xKjvmZ3in34?b1Zn&*P3ti|>@*f}Kk$&lZ z4t=10gnJK_v#uY+m<9(<>{P8PY!?-?LdtsZOFCdMvJYnnlZzuhF*z^GHG4yMU({YV z)7JOy-;rCRezP>sG-B}q96+}d`sJa%Gn3dFniCEF%^e6}4JTv~jn?*LxiXeQ8^Hd1 z4MIMvLB9QE1fE{`mXZinMFH9%Rl))JRg~sTUv~IRMLPC>I^ZB10c!+tMZ4as z7T2x){TIM`JuX=LYZU5k>GcsrJoi~9b}Bq}N@kLc?(cD1rQ$#mmw;tT`_R)4TF@mH zi7X~y@eogoMWcnzfaMAz9Dz2c3lWWxMTG)S7o{0$wMo4j+)tNooh*CAqf~4}WQYT> zlCoh*noV@H9L(<5Ka!(*oS z`XuciD0t$wFQ5wD-;WTjw(nM4%?kw}R*eUe0^pU#N{46DC~(=!o{%~95RWxQ`#m(3 zda|BG7BaH0Wlebio#DSyZdN4c2bbkZGD)JY7axU|j^+})=lGAr5uX`nf-q=MY51)h zg1VmbU|WN_ey|K-+tf%6Y)~0iCw;nN!<~-79qDGzF5fY(e$F!qXZm2*M#!s#_28&_ z?OW>M^^$DmD)-MLQ0Ceo1_eNxC5+s9u`3=x58}WCNUiuV^)RkAa?}&$cqX4ZG(p{f z>g{PWsa~a*$cXQ5WPi!VQ{O@7QBU{dTKXELvD9|n^;;X2-KC(rM6ArWuPhYDbKjt} zA~FZ$`{#tDFfQS)h$WYQe|HFJr36)vQx9K5-PNVw=7)nHs$T%fL9Qy|Yt5g$r`3g? zcP3`22Z?zS6qf1jFMHlSMz>#CWw&Eo4Uu@BCF(!ZN&eM%pyZuiP&(!xAMh_U>g3jO z)|rDnzQW1A2X(=jGG^TWeLCA5=5g15IjHOPb@yFguOhrgx_5nfp;||P3i#-V`g{nHh#u)sD;h@hrvICQntz=#hR90R5+B(XMg)L%*0Z*7|&Y@7EdezU2t$#_$D zx3o+LN}{QvsYYfvJ07g-Ui&NPQ5zh`3%S*A44p8b&eE>ieU+GP;LdDcmiC$JAz5)* zwxOk^eePGQ(3<>p!uX2!J{8TEp0VQZ^8T%q;O(>InmhVtsIugA<<+zP^^065`lZRH zh*33`QT1EgE{$m(tW-Y2qiYhVz^&vNf@|AI%NT4Y z+V$^d&*~#T4c?DU+^R!!Ms3x*vZ|xom!tKDRV7wj%FuZR-l}2#_0qeK_jF(()%1nJ zuuiZ4vs!DM1W_xE!5C92YE zM`7V5J-#QhD@)BSCBWW7R5PX`bgVscEY{soT3Vo*nbo|^L$GwyIRi?7yTa>IJ$RGC zlqhmcpy9)oj?BQAz_6Ol<+AG*{+ryc(Ujh1jm9exp3KN6a4Meq9C)_nU7|&2#)swQ<@U6Zn<>K71?uDeYFatRbVEBT)oXGbQpcdJ?JQP0;E zJ{|9SSAv#N^LDc78aw!M?qckKsQ8a-IQnQbcJcyM!$))57Q3-n$7WKT36C23y&&$A z?&vm=(9W4U;3W5BCtPO5>eomA#I>%MzusaF(XWSS$Bn?VF->^J$|pzNDb&iJInqky zv$)O2?0_NXd<1Wi1Uy>6UQ@LZK1GpuyxR7?D=NUNX z9jZaqmdvfn1}r$2jsq(cu|%@ZN_(@$Q6pDf!Y9VGxFf3re|R(+;tLJ!y#ToF>Sx+_ zAJs&0y%bk%S(*#T3ay%`$93kuol@&xhs$X5k33EnFSG=z^1VGaRSwGA;rLXgx}2_Y zeWag%`Z?XBuhP|am(J`DnIQ3czDr3UDR`dPRo0=>78Y9Gw%EMBt&5IG%~ugcuxew5 z5#iyK%xfxSJQX@e$;(Fbj$S#&ZNK<_p$2n**Y&pAGuw&bZ6j5%R2W$zmb-rXX88!= zJPiJfg1aIU))53r2Zun%X}%NkV5jw*{avFkGTj|{L1uUDjpw1*HsA@xp$ITX-yVTvy&ELuV!C~gE5iIAp%SlNRhvCuVs;;#* zS3BG2+NLJo=ZirI)|xnzq==1;4Rrr86ne6z#zCilqrRSl;&xEz6&-%72>}Vo^B^}k z%jePJB$J7Sr<|#-6dxb|kGWD`o5^sJy1sVE~J#VKm{L)exUorG}f8}aNN3xmxUhc^5=d)=9jewFWwRi(z@!WX|sXi^xLlAH{jU~~8r>glKEhxeYvFPk{n0vmb+8WxDk|Mq<4 z^<#&P3!mSOW&c;p$mwP{g19e6qP-3? znCYpOX}2iJr0EZNYDgFO6%}-jV$V_{^xX!RqYKSBK*3lM21n-?7a<}d8vnusfdHys z{nxNRlap_EKArZ8lrxxpCi+F9$R=+kmHP5@w_lhP0U@2petR~nY!1%x?D2`Y(Bb$5 z8yz@}3!Y?@@;a#*ykGBqtYNz~DSsYeA9u=n0z=E2Qb{)@6d)ixApIS%47c3SzTH$c zlBuYbvq&O%ykhR~L(f)gJ(F&BOu1gin@cgx=>twHmI_sD;owHf1DQ-mhgqcZ{kY!J za>dj1#2fB)<=*+1usAc(B=_iQqH=-cnf(g&h~a2CJ&}9sXeL$0Co)VQ^Fl%Lzd(Bnt52k?yppjnKOA%g&S6#=LtsmXt zPyS|fq*Z3o&`zb;6`I{;W#MVEr=MiUsY6Y+W-eb^)f1$;VJ+!`za0F3G<{`QRNvRO z0uCYrC^@u%bPXwuba(gAAl(hZ&?(&@rF3^Xq_iLs($d{s&++$v-!FXNI&;q6Yp=cb zihJGLvYg!koWf7+j}IptW;mOarxAO$WI7P*cRnEnq)i^D)RgEU@^utxA2s{U4i67; zXyktk4vO?VZnd^OJ>KmkF!}z2Aw?yTd9FPFdV7N>4~5jR9 zJcB`VgTunYU{IHdSD<0qJd^531f5Kfgd#KNMH}5R{A-5^!rvK%ivfoGN*P)pSFmI5|wr<+rqp21>*{r9O!HeA@GV z%qa_sgaoeSZg;iYzdvtpQ0-LB-Gl7ssYfff!yIGX_f``~v-C}5Jf{WTuacjRh8^2r zI(#~Ooari$LWe&Eq8@(RE1)@Qzv9~gfiXiBpv^1#2}w#7;g?Te#`BK}{g!uLbin$i zE>EqE$gQiUmXU5ID5Jiw5EyzQP~fDbq-+y|9xq1s>w^&TT+6s{Le8hn_g%&^+Suln z<up9n<0q>mFiCvk!&`k74utM$<0o z@yw{~3N_>{Q_1i%IJK^7mGLh%`AO^uA}9|oC5`n?SydN|WA23xx7w z!rlsZ{_-cGg8qj@sBQYu%XwDmamH}Jvx=Oaa-lolZPe@hT~2JoO2)K6cpU1*S>}5Y zueR5KvJpXNf4$2-<^v79HXvc!^XR%`6`7t{@??8DXDI<88>xB=%p_YK=hN4E+*XZy zklz1B4MNmk5rMR5DKHoAtzdl%M*ZH-Oy}b=)Ag z>1c{W2>f`5aw^^q2Vv~mLiUf2#(A0r0YyS|y~cwx6T)%0Y<6A4P8xzq-voyRLk9)b zlawc_XM&&P)!fG-W=qRZ<*&~e-BWuOjBh-YbL&R$ew}gOt0!1>YpQ1I=vTxi4Gr@O zC(}&VlibgpD&;6C4I3Eg=DML?)X4kS|A=POo+I!>g^Vm2q;TAw@AS}=pR5hknP*J$ zeTRjwubWLL=lUG-S{Tg*6&^-eu;=o6rS#7!HuzlGtFEkLVT2ahU2o`{nZ*J;l2!@GKj4Zghb;T zziylZRr}_JUzwUTTn0T2FBsa(98_LQUd8F#qjH|P- zHgf|b5e%TFffa-Fy=|ov0@s^UrfnH8}DUAqDCO_8wM0Oz{{cm z1|B;66V;zYe?{Xo6*)SehCDnrrdc_qd0e92I-QGV0kux7k~!JGEk-tgRwtr!nw|AG5S$&h7-SS^3+O;%PT zBgKf#!yi(G2euW*mg~JN=((sTazjRhq_XEMLoQAIS!`*QuhkSbHa5-^p33-sFA5IC zpM3uOnyIN8!i1XGTpg&#uEMRZ_|Mv0K+5M9rZgvu8SN+Wa2R^a=Mo#teW)2IY+o54 znfXx(M__mG3inoA$7K(_1Yh3hJl>Xt{5Pb!pmRI*YmC|Si{as`T>cQ}!xZ0eO1qGX znug-MhV8LGHu`VxJyde6;#*9hQf|DFrTS~*`J{q0Gg~!rq4P6yQ?l<>)`b|F2Ds4`Je|zlkj%X!8~ipn z2XB2t&@|}oUD(8$Bnf}Aj*5$CR$WYL6?$h)L+_H;I{}*jeZD22!wtj}@QlH>ELV;aewcI9ImU6(z$pU#h+gK=^;-cY<&tSpd< zC6h#BEaG3317`wb>{MOH>i$fiSPj6R9@@HFk=1zQYNe~sMn4yRnJ=Z~BgW|f) zaaaB@i26A?KI-*|>x{5=lGkCk)6h3J%r(35Y4VHQwT`3XvF~0&r*AKUh0Ru(mURxp zO_qWP!$SrJB|b@Gkw2_q4~5~}1Xt;8bC@C>xH;Cu$Y_h98G#>ynLdWV>ab`l=iB%7 zdm7$*%R8~he>+9jP=Ezy0$(2GiLTT5BzQ z^}G^=m=a(6zA|ci-C8PxUN3)k_A|vC$DqqiLUbt9Ns+276MdhgJcQiy(?Q2`hv7Py zneXXsxZCYO)EL?IbsZLV!h0qiJb70e-`*R^3IXazPZdq&V|7)@7*fN4qVSLR)xL_g z7E!9X>mwDx?Lph$<8DP#HAo*n&ThT-!J=U?qZXdT}2O*^gU z;aIkha=(YnrJ_0)u#>LB@5)w8t)y0M!YOs@u znJrD=MTyF4q*YZ?8QjUSC{y@&hCgziBSg_<6?byPKj!t0V$`UHCMjv>F;OvREHHe& z!QFJflx?k?NKbZUtE>B_A7@C-(-h;4Xr#ilEtfF3f8xQo=%t#DFQj~&P3%YZs}X$X zPbdWu^Nn^rl}J!|pJv9K#R_ojj-E)ob?M&Ez*=dvJLPcnyitI`Acx@j-yn=wx`^`R z?oSBC>(P$E`?Ak8zYK}OyT5R+uCCrEn#PC`qHxTps;C6k(i7LJ14l@6OGUnp7H~3% zc736jQnHYlLd;DMZ4!$;9d7O#cTreu@X%%=52%U}ym*NWP4wVQ7AX}U#L(FeIQAss zBwM#?)@APrzy=4N`BrsRiiWRA_#j~U?Go2mo8L~FW&G%Hkjg2`tyx^pAX52_w!)vJ z&=T7R?#3_4uHzm#X>FapB#rx=#eO};`e5W@)TH9xQddTik~+W@?OQYkik9P)G?&h5iiR6ff1F+-iR`CQc}$O zs;kjexJA8f^REmK-tz=Hq{7lqODyxtVj%f;nX_MgwYQ~qL zduj(&U6s{MIpmQMJsRBS^l8|ZPcN`AjE~2dL4)d$mbU8guOq*tptE@M8RES5iOIeE zC-|k)JCl|meV)~UMP!Aq9raO((sbbYeHF4pZqTQVUH=NrsGvLxI${P|NHlhSBm+o~ z1!QBA>Go|$6^*q~ME}gcuEX?ifwZ+PJ@MZ6k;1bUZ{{6dDb>^1uM-iu75uAw6NYI9 zw6XkpslsD}`2LYWvz;~uy?-Rkvdejn2Q887oN-R0Y6lIfJueTVD^6L^;&PGT-$Z6( z30aCN=G#s7Vx<#rqmkVzLtw`xXgQeT4Mn{EB1`R+UvJ*2geDI}UGla>r{H%?-zERz z8ldrNlU9k}OJy>AlaMK^JKNIJ8inw>C2()eEa-vf9Zn zH<<=~D`-bo$M=%O6|ECC_VR={(DQl(_xhnGUXsmHyA?32eQiCFY(J96qUUAwpq==w zf=*nSLVuBpRHT_i&f`E7kSD!0llS|6VRA{KCK4rSc~~9y?s;{dyJ-5$6sNr60Gm> z_n0E`=Pnf+b$BBNlq}|B3E!OheJL1D`-=b84EO$w;ClS{sv9-z=1p>Ml%02e%fok`C5X{oqnovtROP8%=)SjDXtsYz_LCZ4uf3?0ai zH7MQ1&eP-k>$NON5gb+j#l8eIvRH9+S*+{vOANymVaA{QurYO;d56@>R|buIwv)K2 z^lFP;w-(Tlk(X(rq+drf+WpUl>IM0WVh4mNZv?#M!NA@R83LDn(Y2CN3lK0 za+Q^d|D{NS4Qt8=NCx~FviK*?=l(KNX0*P%=NwCliz$_0Jg)>sr4zmK@N2`RaDhcy zUaqDbwiMcX(J5|%JNc_wTpY#9!6RZ$2k-6fx8hP2E8~I*L&RN1?3V4B4{<vo*D{Q3Q9$M62ET{=%Bl~vPfE-NM_FT|`(`DUUY z`Pa)tx{cgclaiF`TWhvmf1|CPGVUpz8m^rZvuI6m;>isSaiM!H6be0xbkYuEC2Nsw ziBQ+%Gb|V8B(^WI=rbHOKT2Z}5~WrRF136d#oA)cqFfAKF3fUqqjgXdI@p+VEb30{ zdQ{cX=%J@3KzlnrpBhkV(FXV}ZYJWQ8{332#%T@4oj82TW3DE#X%pas)oofoo7P?X zgU@l4l%sB`){dgkan}0aR~*4QO}e_l311lK!2H$M#9^e_n$KY z0>^euX}Yyk>?TyoQk>_#o>3i>qoZ%?38-ms{@T?v&Z*S%^O)B3ai}%Fds6Jhb%NOI z|6K1k6LNlEePT(tvcA4~2-(njkK43m)Ml+Ak=(d;%Vf~hB>zP$2saAuHgzA<4OR%ptn0eJ>?1-}n& zP3}Jicu>MH33($Jc7~|_jW)oI1*H2<_f9&EAv zi44y5Oyh#ufNRxUl;RK2rbp2$7dcdQnt5Cx(VtpW`&*LbW8$zXKNpBm%$Qr6vA}p& z)?@G+5_Vk_UYVpXN6^4|=?mbLr=WanpsRPXq7JTYid4gRCF)Q0FETvQ zcpi*sRr+Vqwe)ZxgkgRSSHT(yHR@Rz2_9}G;+tc%Ye=2{2x!y_o-W#nW9dCZ7n-nc zFpIHypjciOr?Cs2kD4}-sdKDKpuYB!7n`=b#i|+Sh)1_SA*eT~7i`2cI+*+N&v#do zkln)sqh_PXgQ6DM8h$-&K^xtg0oFNEyoG*(3(u23AJUFO7vG zUV+!-LA@~`siQ$lv4b6X!qIK9-w&CJ!J6idq6>)$>YONc&plK!LGU%!Z1#HzgfhpA zPk`V*fHzr*5~-QA9d+aUIRss1@C+W38*j_(2;Si;pJ2d~x zP{iTq$svQl-{l3llW&G*-Qr^2f`yzV;TWHsmB5f_GIu`kAtVlOrnHscnTDNHre!O0 zfy^6_pf(ub&*FOl8Mzd^oOFrq{e+-rwj_k*x$^{)E2)+f`WB||s)9-dg*%vza2 z8o2nJIOh5%s`Xx)Hqp!Z&q=ijRPTz!Rb|r~FoThwg6OQF&SMb)=3fbIgg8=jrrS;H zhuYi)yNt?y&vzX5-L;R`*1!Ih>_fbYq}dsg44 zO>~^c>n*oUOCW7v@{f!QAc#GhtF+}S6;D(9jPjvKP*uF>n|3ZbynqgDPX#we0~Y@W z7HTU2281cZvgS-9F$Wf>6W(rKlX2(o;Mu%sll7(wJZ)WU> z8-lPit6t;*YxdAcg<@6u6x~@kERT0}2HfrWNZL5;g&bXUYjLOwR}iG<-jJT%-Fh3y z0qkzaw3-_-x|`4%%Yyl&m!{P`+GDa15(#6+c|s<&O$U&a%2hoeVt^Z#PH9qBgZ6z1 z0OH`;k$u(+lW_XG0_BP9UeT-PKAxp-GxHre#Wj=UW1_5m>22t!#-H0FPjDpN=phyZ}#yDM0}kGG_%_&dM}2g21Dgn9Ds8vN0BcyQ{iFoX&&s3{(y;OEGuy}9e5 zOkp_T#0Wm*gKO-};yi4|c`^Z1Y;N)#&C~e~3(XU=8bgC0r}K4+S}SYG|A~i~aQ||P zMw^T@1+{A&#=He!3)S~#xp`6n*q+OlB8#-~F&4Wg0JRbd(B|_xT?fFn1i)M@Mv1<` z)01WZ_Pj2~)gWscX%53`7$O3PHmiXTu2re;M0t6%9Oozx1v_`V_Ri=h7h7|rdd%(# z!6k2fjq+F|f@EJ6vxz_+=FEQv_>H?!4u__58~A2xOvCDWEC@a9@L|6JlrKQqhiXs^ zn)g?cS^^q^>auI&h0TX>-PJ*HB)r{4>2Hz^0|D-`l|kDO(?9jrncQ~WUB(vG1v~)0 zaAP>tVX1vbp%iPn^JhHpmjwr&NI(k63Ucpp)V-U@2?0g5k_q{0!|iJUcp*dpVEdDG z7=qBM!V7iUcIzQzhg)LD)8Etw8Y}mZs!si4Pa|GsSjgWM|*#fj>W4aHKy{6!l1tI%|W{ZrK*^L;4TnZCm z`~$2F?>_%PU)%HwGI1^8GrvJV8W&6V3O-MaTDOa*Xk2Z^DE9?uoFW6mXDajt4vIks z3Zef#R;p3<7>58rl%*G2*m`*1900BsKu62ppie=Vnkq%tiE#1jj0r_RM}HcIE!;0` zkAuHCOqOX?H6wf<@8_ts1d0D@5CYOGBeWf^w&lwa@M4F6=I8l6kH2KL`N@oLkS_}1ev624 z!Xv`Hw&+c9-K6mBol^~lnd8UAe8B$D!-?BuOIm=vLJEd2F0g$cX>r*y`2Z1c1vl35 zTaIP@V@;?)KPr?-1YoWd_ZlWPDE+bI!uDTrd9C$7I%0JCKm6&ewLY!h$Athh8^(0; z(x&YScVckb9ynNkD5Pl!Qnty6Wzj)bnB`)9{t zh&il(rsx2?xe$e*Oon=b*=Bd@jG0bmF*_=PRkjlW?61&hb9)CW7Fm)=*ojFsZRmey z56S~p91jJGXsXU3KmoVJ%se5PhbQt+CA1liun$KnDVG4$&iptK8P&{&WBVs23cLdN zj|yO_pG+JR6M=`phb(XnC8v7Lg=oabY(fogn+esEo|S+4HMa7RLf?)!5`m9(mtPrK zV#e=t%~93qen6DSbnxL?%ha(C!NMKqcbfmd=Z9BHu_}4At@5wNlvJh!2M1LfM&6;r zxonHG$}vH0FaQ5jk#HO4TbpKl3=w5IqC=aQ@~=E*_>_F8cQ_nD2nCXIp;_H}bk_eC z=(iv-5hw~?M=ns9S->;ZD8>R>2B2gRCQJ*|{sJ+QXarcY7XRN4_aPi{q6cHb!;%nS zzWWGk{cwbWB0eZpN%KY`lN>liAPfCG&Ca#9V<8A*#~Cagy$X|RQ_G@~;lz`nDEmve z;LFheEOLEV01hg;LiY-^c@Nx(zX-hsTKW`7_7mht{#o5J!mNiCs3+tS9)+;wLS@$` z(Fdm_;{Er5rB0a!{Oo@+y`>-*^j2RJZID4;TLH8=*{B|Ud?U4e8<4Bs5R8lzIJZ3O z+0wohOn)Z*S6IGh>7S-Zl|lsoSu+30^J820N-U3do-{vmU1>aEK*p%_~M;_SX!_S<2UxwB$S;QTlY>0TU->K4+o!gnt}Vk7-t0+ja$(! z0=yk_Bwo``VgiR}SuQ|@eeqGy=AdCll^&jq_!{~&vzD*ZPc@9_qgOKZcYv{cWo2b*YU=jZ z+x)mfuW6etAmEADW%F21`QyyM04+fL-P(FPp4;HKDk_T=-?tAO6_XtR2^oan-PY5S zr)n~2)|=mABrPc^X=rGuy$Z52wohBOHp?#uLn3^R?h@llD zYMNoE#dj7;K$EmanWkXCBgq#FOUqxgv$HR)oU$70>!0a9=Rp1b>1@aF9}m6F3^x~7 zUw^-*y81E0>6$z=J5{Tk4o zNeC`(uM5`RK>uZ*W^8n{Yl2>XEh{r~p9m!Yhk+um0Jzy9Sh6f(IruRKF>7qp0IxBR zF(R^LN9Cyj+BuPtkn#%(fL1vSc&>m~_wz~%)5Hp+E`Pvb!N9;^VPO&Wi%(4@cyMsy zZ~po<)bRB3vj6vZ)z1jT)bc?u>{my)eV4}(8EbNCsvLT-izsLger#3lwpAzkf2_NH84$_a`g7n*h3ft*!0sHukht8rk6hQcg@%^vjz8;ChAek&*RJ z2?6C7?zxEeH?$}ZGFO}H>paA89W3_|SZF@`|Ca8_5`@z>>}=ue%r2r0a1;m2n`-dG zps2t_1?7xDTLID$BZV{(K@10Zu7KQHu$n=ae>VQudf?{%T-~A>6ct4g=pFv>Hz)`x z1q`U}zqQ!k2fJ63E%=?FRT*`qnBw2Go}~cizNnM@hedLxAekTyDx|r0_Z9s4^Jtn| zzW!>W1#AV`F^JtL%@XyYm8t)6<(v@-1XAbjYXiG5;=0`APDtQZ7QVv#DaKMdFb zH1+vMPyw)a{+1ZlSzrL0UN48=gXPfG80wQ4OQM%SQ$s!&bWI3G}-I%i>jaS zo5a5U4FLQ@3^GOaFsZghsDjFXr-s?mD$)yM%ovh7WK2*^5%=Z0&kH`g{?z1nNM+JN zf@6{JeApdTbceF({BI}*AgaN{5LVr_d^f>nT6;oJ;;T`pwn=SasBk5LT946x`ddNw z3KY(&3v8gn2tC7A*Ai%&_}|7(D`V*MoBzGWnjd2MgR$*xoY1ofIBv9?zh;#bM4N_(Ab>r_ z)oC?4kq2zKikt#uP$mg!>>lbsZ}0u}-ud}?;pbetVc_g3WU4Xc?Q~9fud@1`5F#%K zTc~q4%BNff&PE?rI03V6z48OK7B-en#}f{z_=m zAt3>@Ebc`jZ0U8XVb4*Sj@ZgniMS~#gIw<&DFK5E)b>uj+Fy;8q~PGr_!Zw#KqU5rAg}Mn{i| zj$Uu$V@n(K>$Qwuj}j&|;&l;hp#n-JBe=^NH-9qntI^jK~wfngVd@kqbu6@-*Oj zmMZ(%>gSDbE+REBT+O|+fsVJg*0#1I!^3OLBp==Y3}cRCt^nVPGf%H|JuMAQt>NtC zWKbABCK}ur>(kac5J?9z_N?sg?j9dImNPD7`py8MABmBdgv5(D^i)=(ey%@V0Ri7m zC0ybGn3n+FYCsOJiv>V;(9ia!Z-JktVDT{MBcKufKq4nkEUdk~ecOwOKJjyA=KR9K z2-f=Eo*WW>>o5=|Ff$(j@s4mB;%swtEiViey=2v4mqw*0_f7r<{NLW+)q_MAQO5xH z-h5Uv>{HxW0fN8g*mRA|jEvj!onI3Zh3^FsqJjc6>Yz&zqNg zZ+e=*uBoj$)8^yHLN+QYWYDh;dwY9FU7}SMB~e!b*8pH2#a&6PF$E%~umCGXW(z6j zy8myi#DvjuIz+&c_nZMWt($^^f@GoH%jI-^5P%|ef5HKs1p>#^rpqz$SxRj!d-R{& z&X>;BOp%Cz$qyesJey|7wT0MD!)qFEKK8)$8?@I?(MSMl2>woI#hwDjnDtmkpiQU0 zUlyGpf@3ZP;ogQGChTvq))R&R4%BAC5o^dmFn`+NZ5K3+aT%aeH?F?U_o0SA%{2&> zs2dC;e$+6*(+R+C+9(D#c7c@Dk=iArBP08m@Fs_4`&2}l)2F=B(#XJpMjYc~zy>-+ zPEtBNPiYVF(jh6eK%_m7=ps6zR;!yW2}Sf*!w)@kFw~EGiJmx&!Y=l&hk#B$kDWroKgukZ)BiNu&cM_^01aGq#wA* zhR6%ug>6C-;=&08ovQj(04F=PcJC5i^=J(=O#q8zWx+yW3ZFsX!)t>Ves2O{!B0G$ z&d%IUM7iG|ka)K&p*6kO(&kNV;hrXb*~Jcjb_gLOPd4~JcDxJ$wDN}B&PU)Gu?a## z+n+Yg!`On0F+#p?M9jAx7&K-QL`?dl!4&-ot2Kc&|LikA;fRQc$nzNO;_Dc+>ijTk zv(s#-F_OOVAU-O49W(~WK?GGbf8~9;JebEe?L*>VG5^~xD=W*Bc)*y|!^bjZtdjUr zZ@$?IHa>8Qzc5pdVfq1B_v+p)$GG+v-n_zaW4tEGeyO&_zEH*lm?KT4Pj|Cf;FrqE zST}P;DopeMe&(SShj?bc7V%Y<)TqSgC;Ed{Yaqy%ZGz-do58on^-v24FMBXVPSiv) zl{q3Akz!K4k7eO0{Q$dfU8Yt_={=EUVGs?xPEFTRH9b878W{;aY1+eAEYE2FdiVYj zV1&_fY|~lPv|gG-H16IO)dy?U`bY*%2+W$p!sz2o zH>J9e2tfbTclkizvBJUcq}dWJYEGnT`hTx-Q+BL|D1XHq$T=cW@>!+Hy>VH-r2nbOG~{nCzb?%1gK!+ zi}SH|0XsHzI*&0AN3*}PYyFQEX9B~v^M2Nj^MtdP@(NO22cJ8eenSn88 z+tyd)bG~x6s!-s*s~!p7=2Aj^B$!}txJ**s!+XEu%4N?r47UCJYI==cT|d@TeO(sa zc6U*`qB$!8U111S4SjY*w!LzYF*B5-xe{W_oid{^WW%lgH@-(j(YJcr4jikWoR;i5 z@%slXNV@pT1qNkR1pL}HaCRV;bWMAkji--P!1J?DUKXqGRiAwT_rEXTYGy=&s7!(> ze@tOSqYVHTj;VZ&`R+Iy+93GvGyaf~Df1Nan|uy92Yfh()f-?P6xhKe;ZYt*G`}yI z)K9jjex8Q1AB(!4Aa@fPH{1SO; z(;DL`iM4finuYT|gn+Xp*i{ti65@l&R&C=0R`m!c}eY=pKnMQKL7nJ+Chv?K@T3iIo0JL{yb(59X5W2uv?(@r{fR`zYpC#}(uS;7vE)D&Fl_kE~ z3b>rJyg+qAx{avkcLt;RBzD62{?u~<3mi!pu>IfaGM@ZUtwn)LSmL@(AYk@%zx!5j z8DMl~xob>4@k|^%4(4Xn@6bL|DSnWAw*&$bay7H*+Af3w#RY1+%_A#(^u{+s;4yF~ z*!dq}l2^WXEM|-X&<9`>{JRfkfCMLm>+GZ*vcu0bB|&@GK39hu-eS1;PX53-dbTyL zCUrIv$r4YfuXVZdPhYe$5c>!UR8z-D1=-7$k4f+ziYR4D>S@65V288T`fXgqeUnS4gYH&M`+q# z=AC@C*w|eY$3o=+m^J->JLm^&IBow=LzKHTk{^w6O*cMe1E;qMH1~dF#d~-n5D^c6 zTlY|nE=?x%Ra|zCQMF&sBn~NxZCBxe{`GHs&``CWv+yFfi9!HJ4>lGdSg}SXFA5W6 zQYvHPnqcYd&pmz>q{!;PjFu*nz2Qy1|2W7tM zeob(9Kw`}mtHMz6oo z#v_FNGPLuu>w%SA{i#8Ceml$fXwOUGi3NQIyxbDdnDNK_80brJKU}bWehD}z!+c}R z=y2-2*VMq8ZM8744#Fsi@3(B?5nqXJ8=|IO!I^)IN0bz*UY+Nbw)jrOmrd4j_($|f z@6n`RnuD}H-km5dL#(m{nsU2JMhv-m6g|&Zx{Gz(#?xkv!!@wVF6Cr@i6yS-Z9UpV zG2#jn@wHl-IG%W51spYA57BnDGJV9%(kJAyX^drV@xRK^BJ(`>FTaC0#b9Dxkf2i(m5H?eCaYUsq0~Bc9Z*YzQQC%A=~tM;u@Pfq{G4RdlH< z1C>;4Qf%&^?MNCMz;l9af2f8LF=)E-JrGFsucDUGFlbfia=GsVEUK0(Dak#d`Ab_Fg4V2cl6w}%JkWaBA zWou}G3eQy=IzAKh<~Ry)*e&YLRXDCRWk7rI;Z)Y6`KBtZ-GEhNpNriMFC)*@7q<*A z2Dd8(-da!ID5mh40L2v`tAAy!FK)6{qV^5onw{BYS`aD?Mi522C30f#(Il6z8pYUf z2SOKVf7thguKHy7LG6 z%FNz1ZS;uy=HEY7k~%f0Dy>0BHw*X0&-;pXI#*jM;i(I339iIjOa{UX3`W;*{({Yw z8!k-bNK6NPUQW!elNpZzG;q^VB!V%sf7bH+q2H*(?*-qM)6tRK;6k}zv-QmS^=;h! z`Q6~q$DI3HW~Ikd<^e+^qXM8G20aZi3o@v_vId3y(0eAFA~ID_e1ZDiVX6lb4e8bFajDSfJ#Y@YQQd zcFdb3A#RAwk0=g+Mni!_9!&GmlNy z`8eR2RI@Gf`|g%}+lOJ>1*i~Uz&uGT@d-z&iIUGTEEx6&WG>y#9^Ytm!xB2Apt&zW zZ9wX=MmQaTXL)>bw4Baxhq+y9(LEAM2^aQvmEj9?(;WR0ul0>6!76SkTSGD9*Eq$^ zZ0E0iT9>0Xlj9`fyLno}rb*hppAHo+X+vBOt+q>oTo%vL5$OoKXvBK;^e`erS^Zxf z_O3<@myF#koRm3Id+wVOdAAL8_65LK^SM&YVV@C8@ceb&<)0@;Qa;zWg+y0}9al@C zp`alQsuPWIHn~IHl_oE* z_WN_5#WoLu!L=^sZkTt72YVXddxj1=^|ScbU(DEx89+YiKuF8TK09g&GNJ(mY#9kB zF-R$FSA^ba#3PJuN8NUU1F0%81zk>5jZZr4O~~)s>mw!2=e7K=E~7ZEaRyTG2}u~7 zgiI=~qL%K8GMC?9WKc#_?fyB5>Z;-90Q~D|^s)e+FZa)!p-r6@gykEbM~b}+^k-$D z*FY*0w{&pu8IxaMv;NcxdkEwi#plb(pCpvlCeUohtk6Tw@d$+R-0d7~3AkftUN>;tJ#H5UD8erd11&+AT)3l$twEkjWEd zW1j&QAAoZcr@N?4EwtN0fway90jIAPOVrTQ;8iE=XRR`$1&L z=#pLtWIx8s!OF~Nw-uOf$W2y7(*^ia;^}1x-i7|Fn+((H0A&kD3CKtgF-tEG0oPT4 zuZ0{K{}LzJ<7u`~EnpdCUYUSvWjB~Vz*UswwpGmP-2^_N{8`pQh2PLNV{pk2SjIZf zyG1^MlL6vZ_oMaW$~Z+PcF(ogCaeMZ78>7P|BL1KQVPux5jp>yx-qc5CIK^Ti!3%n z2OBD*gLV1Xd zjrGo>Kt8D#c)K=@t5H1AGlDa#k=B!C%fEe}dSN;J^&1NrNSDCGH(V#Cj%EXXDZF?3 zmLSBP)uAB5W8IX1aOY8UQS)e8dIE01{pUzkz06D5a~>DUP87V*d%8!YK<eZhO8Os3^?rkR!DiQq14kZLW0eY5JLpFwad~Qv2~8 zZWN3%C-d7ajwjb~sY?YV%%w9;422)dCxdhUZSYSB=0EUdJvQGLm|X8-hK#5jq8%PD z_h#adxMc$MBPa9z`X`(uuj{sdrD&ToPNdO^=#ggER{cvAN61gP2Ha_@7cJ~gj5{`X zQhL6`Ku#Vl6Zl*Gym#6|j8&E(Ho5C2=}kc$3m?bzD+v^p$SP7Vza!SCu>&Ey2n2WJ z^4u_LnUcipVB+nAf`{a2l&B5IA2= zM>DS7y^=Ae5kc?{7DuBi|D`TfnHqfAh1q3gxOd2KXJ%jzO62cpwq{cA--M=tO12dDW^d zJZn-?e+UqvjI4~T+?rH}qw{*4zfwtn_}*Wi03Onr;~=1*2EjhBWh0he9) zY=lFAM=_f(1VKr4@yZ#zQ)P-20A1 zeF?vEO)}l4U2~`b5MnMdG+7{n_8{0NC~zGssP?C>z%)RWnwKE9bewNrjm4+@FO-#D z=|fjqs)vHmDYtM(@32;^79&%t7)+od@0hpfW10UK-&ITJBqCtW)#rQ=5_}?XCs2O{ zMzxcV5yZ9`tcPDfN)_Vt%O?IZkf6rc6*yf^rM15Wdc~#2_(t9v%xq0MpZJ>=?KrPBRrrdcZSp4pxy-P z!1aS18Ehdf{>>KJ9PxUQJo_zVgv!|8@33dveYQNFxyCal*czK`ttLNt%L@f;^aVK? zjqGss`zDF6%ede(Cxp6eECuCen;Vz;#>s zkv0h7TDu=Z>oRfAwjJWdX$5VTF@_$QRC6c$u(py~yiBKE|NW+)ktuieIoX@;x1ngf zmjSTM7ecH`>y7~2r8M#DY;VI~u|;2s_|>;pY_J5`aCv;NDaR;H8hCRqIvVa3wr(L7N)$W$#vdSZ zSjarfB>-DA7dY%YxqR$LC^)vs`a4O!W5>0q0YgVvUJ2xVSvI@w-qegXorMLCA0qV& z%$wF`tmv2(E9%fe4wIml^IH2FV>gep0r|($#;wPLxcQG#RDyDoOxNKhk!l> zaucG!T~Q3zx?wNF(kKTc2vN`Qm~Tf@mp$(*ycR#6YR6+vi#@N#*P?z#?7{trx)_iz z-RM9nRQ$z4>U3%3Bp)eXu#f%1zA5dp0oWeM!-TD?dAK3ZZrP2g#lh z5^RX;mvYDo8e0J&P4S$zU0og@{cjo-&nH9nU$&Gbt~*>=k`t0a!2pv0>-#GdB|}3p zDp+?!Aax#f-A|NEd2uvLk+qQF~Jl1cT=NtoV$1Hm(2g7%ctgyNq+dvA=? zbDkz21AS`&{owgC@zjDg?mSI>!Tgt^7)v1m>TA&|1(SkSDzB5qjM*QJ5z2$3qvrc^ z$Hzffe&`-|ywzvB6#oh9 zz)K9^`Xe})l~^2+c#p`d7QoYle63oKfH*KtxCQn0f?)ENLzH;8MGxEu9P6TYHm_6V z%rlKoW%vhd0lwg)fTb`k%hsbxm_9vZb{Em%aid0IBI)i1oBQs2`;m zPIi(-1U|CK=QMtfTjdn_U-T2XWHme0d3=Kh*bl=rf~EbUsUONBKAUpCfd*qBkh7fR zqojO8=BWksZ=2-uHMvlgd3t_$iEH?|a_&oIif& zI(S{<4BWH#zSmxR?X~v3KA$xgB(^=})H2CHJZkdxjLy2;Pwm1avfyQ7lI7ztM?o8& zH3N2|+oiZs|H~J(e+4K?#xBi}XWpf>lK#HWK9e9PMv_hn3p!D0E=s4W)2BJHtlwXi zsY(^7rgEqzsJ=XLhZO~=+4s4K$NxKh`}c32Be7Vp%Bx{IQ@akLA-mea0}>cW6v*MS z`T^}Fv1vEpJ6UKoJk~udiXJuN7n>(xNns@x3o?>ZXP_~Td|#TBuj(QeOTQuTpC<7k zW+S2(qu;AxbyKBxB06b&Q7cyllKv20OUQ~Fpac=Z*V{>bZSy7d(3WV;L@p0b@)FMJ9%}FNfIZpjw^WSCg?^m$KD3K%$2Xbuh$_D6F zV_Wre{Eyb4$s)*{!=9`qn4YA!)u>U_^=_3{j~N?OrOsPW2%+_E#Cl3T@VaMF={gtB58Fx6XR1*2rP5zl-8am3T(aXT z8qo!9U;4Hw&tisy)TB3)t82cEuf8A7zHIqm7ys6IB34tcn}Vb1(!uE-#(Tl|bB>{I zXg%k#v{l04_QqfD^OE;7-mB~}BR~IaUClkaBFDj=YwE&V5_fUHLf*%siBIDT+}tfap_5il&W&6uR@sFJt~A8&2p0ysHXS~!frr7Oyaqn| zlmwV~135Wc*9J=SZ=6p5##?^)DIR5>_42-(%;LL-EvA_El~YY>&es8dF3EFiUSe-# zzH7L)JN}re8QpS!+b8No6o~>iOTh(&-NE7zF*Qy5e$Ap9>l>^FcU@_TMEal5V?V9r z(tO-_pxZR4H~%)SU5Vc9D?_d0*sROiOtDN!nC)ccPm$6e!|~edQ=9^)sH6j8|$DnO+35W4lCZfqunLdqEmS!KL(HZFAa|T6BmvXf=XU7BG)3S znkqS6p|OruhsbuyGVN$CJgQlQEZlAv(oB<&>5EqbZ- z$DentrYcG8c=ko1da>8j_c*!4k#H=!_5-XF@$S0+UJEox(GbP6zv?c*YEQq8qwT`P z${#!v+Do@}Agy_u-k9NX`kHg^x2*Hl-s#Y|EVJpTqLL!yuhwN>So;&E!%cG5Skg2_ z5BQQE9E!xx3}>)O43O|XY*9hpJp7187&pn=BzQeyYX3VYMuvBV|jI*IUL}Ln7ot@VDgBr$kV0_QzRX-(auxZ=3(VG+L&3)E|oP6!__1`Nk`43QZFC|`)4BO^Pk7^ zOueL@qvrfL7t20LPR=MfxLrc_Xy!^@btv3iRM0XH(|^0LE!3ZYil9*{+8QHpna%}F ziwzKl?HVy={8!2;nSwj@{8pb=HQ7yEmPfHKjYCDs zOGT(26=@&Wie(0+ok-SI9jp|OUjD_*zL0hv;Fy68t$0TzrI)(h#eJr=(z8OUZWBbB zEcy~PC;N;3Wx+c-Oyq%*9odDml8BUpN^e_|jB)fzy{IYt)$H}39M{f4K3^26<;ai6 z?i$`AXRlYKGR3Fr4p#H3vZhb7DPKJ)?@F%(5C9J6fzo7p=;gPupM5?#eOWb=bz}Lm z*w#eqXkG7K-tfD}Km2cvM0`JK#eGuEM^ikGwH|ogU;nEKWTS#oS())VwGFN5dPFx* zUs;TGYB2T^C;M!N)U7s>J=Qm8*X1jFceA~$fuGpfzkSd0p!pzjAfwv$WNxK*+3525 z=HZy0&s|K&(-U=VRYUhnE~(}9WlSW3hmDfNIx`&~$F@o7n ze7fp^d&z40`NeQ%(boC(Ny!tTy>RFsoB#w&hi+=Go*X<~Kws(vN z9cKK8K3|xA4o}bvR%|?LVXwYUU{Ijs;hFB36MyL)qW_2GNZ03zVALjo!#wn%urim+ z=9QLG!PES#fOYfiO}#k0r^JjTYv$VOPgCyyZ)$9s_f2WKMk0rG*6g)%lKtFYvVguI zj_=bmmsMny3l~PM+K_$ecl@;$Qe>o}dpV!8rd{TSnat|xVLhttuGOmpO;H z?Uu0Z7CDYJ7a@LqTJyvyjnhqZ1Lyy68S1<17DC?-e!lVAj(DkFK#&TYwjly%4$2P% zKW_sfB~pt2p~k^3BTe5t`NfQ>h}W2`BU#0mhRnF6gA;$xxIGP(E>P{Pz4f=#nYo}g z@bN*PiMpW-=8~ef`3&OU)e2N)y**{Gb6Dlny}zjPCMNA9b8<$Peb=VAT8R3pViHX? z;gT%vj1eRK>BA!<2I6OgQqqJ!f^5D+G4IxC+XS+G=TCO>AxKHo5#1TYfD$)$xvdZ9 zJMMV&H>~Q-tmo}`y#tAM$oK(N@Q%!T+w4icp(lhyPeW$~;tuo=E=#(a%<;|e&A=s^ zrTEw0Y921~g$(zJ+65)^ZvT56G(XNc-0#zO@V}bxK#7N13wKne=B!G|ykSK= z`o=M&rNRTwO^JPe)jX$Z^|HUVPV*@fNft~HOh6gn>+xaht1nqNyl@si>#Z$#_ERq^vu68F91_+%e#Q}6x!>=qflw-GU9SA_#j z^T+n&oY>sh+|XWB&#J+h+vh4BeMTq8NscbjrNG|K0n?MlEdrjO2jtwnY{x=1TJ22! zN)~mZreSGf_%Cwne$Y&l(MJ3{e^Q+0?EP_@am7Q?tj)bU1z$*K&Pq?kKXF-4MzioV z2T_BH!>oBT3C&9j!n=38NokvUBKTTQ{n^%6_jM$_$?0F2z<_Y{NhzYEF6@V8c4^Lh z$GKag_g}7ME6}J7ll^*pZ)ls+Hk!&AP$Nk-tkPmv7}%N@Y&XTmxDWs7nK^9cH;pA{ zT>0%Ec=?O80?MMgMPXA_!RvfdCG&bW@-+In7fap7;YOsO6QYe4!tj*yviRH|l&#Ng zAGdLN%=p!5-Z@BND;h{0hCy3;ywDOoD$qq$gH)G4cWg>jwyWZr>DOu(Hzkq36Ir$ zdw6IswO3cPl(1+BZ^=eW+SX`KeRi6H-ojLIB7SLs&I6LhlfQ5H$>w*?tu0w0pMFh! zuHa$%mXr17P~7K(KL&;eFH0ett^BJe`->#uk2L-YCrT%l-=+KQBG?{M&|Vle^n580%i-{^+1_PQRi}92%wZ=)P2Yq(06wlodsz z$RLwlGVL4sk@G?2>|jnaRMabFWhvsdwfUdsg#E6vXYcgmg|~Rm9Rs^j&wN`6DxGJ> z54!`ts-5t^yRpK1*!Jbq($@pO*-EG3tm}+u)0?lv<A0 zk=4^V7V91m$oKq{$r8Eg%945WjfJj-Ki8+ek!|y{RXNgp0g(9 zZb^X?#fNM)nX{C$CK)zJ2z$zhu-mY@hbuf>RPg@9`9s-SbdzryC&BRC-n;CdCHm8+ z^ZLw=#=k{f)GGI6BOC8hcVS32i?jwfAofb@-lUz_zJWACe~qDGn{PM@TGC&Slj6 zG`*kgnH_|4`M6wZxh;Q*Idmm;#A_7RcO`rAGhaY@XgYhpFmq;2dYGsd;(6`031t~E&Y9bcI~H>7fQ2(h>SvsHtk3|J zMExd&y3{>X!BHB|&kGM9xGYK+XAqdK{#JhXF!VTp=WSSVRn4cQ<_O7`#JtQv^E6KW zJReJ%&?99p`rK1OK0k#nVL^IdLHr!sE%P3~Zo7zZ-GqwRO5DYhf)dYUvW*49S^gs5 zfzQdyN7bZs*oF~JneMczG(!tBT3tj2M8y5<~XOv`)Ie~T#jDTx`)3+W|GFy`zg|a zRZr#pL~jc--+W+o$wu7GAJ4_y>7SzzT0*YvqnWcE@f#xl2r~7nnX9_N3mKoOzw=w9 z@7XZC`p%{j6s#`3+4lVsUf*Hf086`Rdhg^%I%yC~=inPPdFCH~Y1T60I`hiD)D!eq z9g`{8R(3A5AX_gbTCTEwE3sM1wzwSbZg+B;l zxqWt8o7$rwW0XbwS#oEpiIM^<;G*(9kE&SfL*86`%^hbxEdQT$;aJ!h7tN?H6N3Gc zuTQJ0xKBhkgJ91JC(g`askSZI_}G5u#{|`j8*&n=hqU4+N@7=2vDR)DB5YiD-ZJI3 zU245fNgJP&dk{r5W> zQfe8@5>l@;s#c6&pX?A+fz-hh{3^WkpozN-Sm?2cxC*6y_)CA@KUb|(PB<||v+;1D zAIT8~e~ar%Y!?j0L)%x)QJ1v8bMBuyoy=0fG+z^u2nY(_nVL2dHzURxg2L)#%1Su{ zvZx;R5E>nwOStYR*Ue9Bi2Llb#DabKpPf0xVYjyzBH)TZl;-8htH!wq?e~B z2DW~k^L^O#&`_2}AvP9PM@L6)ZZ1G@-U_(m$BID_@&<+4f5JWai{cNnWmkpsrwTY( zKK~=EOU*fBEvd%KSa5KQo|B>?{x|U5!t(OyTL-bo1;4}W zkv+T$`=%Q;X7>KKzm(jYfd~OMUJW^Sy)G?xeS{v*KVGgq`MlmFpl1jP36W6acG9u9mDw-bl;11}Yf?5bLJZmzlcnWr5i11$c@&z@ydpa=pSx33n;kc;@% zgt3+gtXGbY8gje^Z+Hi8TqQ)dzYK_7^!D}j&CcHZ{gn+Mt8)gM(#BNN!^0T(xwDMG z9fXD+b)i0thjb*eA>hZ5n-G+is3)LJ2e2f7P#j$~c=L~9h932!PEUVZ@Cc*@OBQ_l z_6-LI=XCm$23+F-Pni}`aW$>a(THYRTH3gNP*Bia?8Ot*lSKo8!=s~r`jCl3mVp|g z!k%^u=xUu>>ISdYdivZc_W>5Ep`ihZL>e0#2Z6Z+GdpLH(v9}*nhtxBMOH(DjGA?E z#pG53;d4M@^ja|nRH4y@w@y}}z!J#c`+!9H`Zl8k_GDo4t64!vP`ed;N_vFTX^W%8 zmVx>HzxrR(<#B{N?iM)0^#-4B7}Wc*b8v*uL_hXUW^j|i4h6IYX#(~wLqk!}klPs) z`M#R9SL`Vi-F~ZVP1M){pFXv9c7i3hmtCiE-!2TT za9HRU9K}Ai7Sw|W58gE##pQ7E@Q`xQ4|86l<9jd1YCfc-B(KLPZrO439)pEC{%S)} zP*7Ch7nhWD_W3JV!s5U#;wRINqobn; zB*@F9)blzTY4A7!b;^I^FcJ_DT+&v(n+=P94(gL;5-Vu|LfQFa6gCYgua9575B@kpl>rZlLb&pl||?rv0Dvf<{!E+NBix;maxL$0-(eHX(v zCO-k?zFK-oo>jO8UjpcaaeAV}F3BSVTo3(h+&CPEpDk=JhydRk$b8JC>vYx+&_*>j zHohb%G~@=_dsF5jMyvkC9{PftoK9;gFxo8Y4YOHJ%*W(U%H(tsg?t~OYNXn%TM*0n z7lgKiRw}YFLBTjzOOg}hU)2+;K4>ib?GiqD zwmmPhdZHiIW-vy8T4D6!KmyczcTt(NQM3`_D>NlJ`GOtmb%XJ>If>h5y~LLguM5^BEZ#U-q{gFDGCaAE+&^eZj#xTQ4GE2e|j|zkmN; z<8II6$yx|k4ZT38kQagCrIFwBC6_93GoF(Gd$KI!qwKUtdne1%poc3@NG=~v5*7`? z$~->00JoqZ1y&$x-WVSF2bAqAC}0g^sQ^0O*Wcf9`Q^?6N-Ql~hCC}CV zvYb(O`WN^~_kwUs_2&1oui6gnZ5YVziUo|YOj7^c!X^KOyRFwET?R1tw1jTh^3v^w zf{J2bVUoMbqR-ZRjEPcvYWPYuS?V#TzELv{wF$h@0@~Ymy!}TQw^+>cbZ&*w{#mNJ zwe=G*D^9H_h7m^DG&A@weY6gM<)xPhXIVqZRk^~wzK5cK{T@dN%ryNpSW@j~HZ}X3 z31yRwg0fkfwXR&4XqUV?f1O0tD+FQeZ@7z0tzqhuVaK|i7&)U|vvcX+MSJH*8=nf< zspX3v7N+WiNqzcE5t#wJ8ar4Jj`Qk>S_&w=g@Q!avwETc4M43Wuj!+#2 ztHfU&zjmn5_3c zOHK5rCn+tSa*k!TvqJ0l>!c z201acd3ok0CT&*HjV5sZe?+qb4Q1nai1mcy4FsPAX*u{jbP<@5NNEV+6COXy za@&gLcoW62Z1QbYx`&({DAW}mkc=iK! zj>!>5LH&wCf)z&6fAx&>Rhz*MJb~yW)E}Z%@482q?Mxqn3XN}cSbpW`$SwS=(a^ zeqoUHHZSe7`GBIFLRDyFETdhWP^c%Trw_p0bUFto0F)Lm>2!Ulj0Fha+-Vq4#lcKT z;2+$kt;@=Oe1dUv8lyH2u+;$X4GH7M5 z_L}T%d{9AEW#zB6mZ}p_ToP=;0O{)a6W3^b7JLi|4hHDGEPcB+=5mO zI9&c}caW8>a&vP7)jQtzM(>9Hp`oJcOTMpfBq4!zcMLdVpcQd$?%%@Yc!@N?gKN7q zXtaX@l}UbU;S5;jWurFd#0{E#xLg4U@l(VWPI7FlDT$uBxq07fTrKP3gV`qFcD3>s$0s%}J0XIx`o zyNrs80tO{HE^YllZw+t<%nSW;3_SP1BywAIvxIc}JrJ`MA~7OO^rNMrm9;277v z^2ECf>4>LnHmGh0v<+5Lt%oBi}kVu}?HAy`7ug$;qUn5d1V$ZEfvc zh?vi{$n^{AT-ai&Go)kWQXR{f2XMQ^MwGI@@%x%iQUBw|kNSEWou7)p&!YnrTgO6J zzoqr55s? zOI&;)ojz;R91C!{YypH>$%jR-WeyFg;zQ45iuhfz4v+%0<4RT4Sy>Vgphdw@th)0# z1$e^r+m=L`Fc>XPA)srCvGkq-DQN~yPBAqO0Qoaq*aCS(dQW~?I>mY69tQeT>sA66T*RYe!|pLyoxypR;T{TfS)!}npPClVg&3mwg9 zjPyxA3~?)20LL@O!`CzG$UW&NOu$%ko+d*^r*rO^!rjjgS<==)MJbfv^;+t=f#=#` zw-I*2+pZg12M5*L8-`qyBi$Y?;5WGJq(O@k@6(#VsTx5=s=wq4->K(qFPC!e4gOjN zRC%WZ|C-MuF>Mh-H#QKK1*41*7Uq0Be0*GWy8!Ba+AZ7Js>if%3(-g~Y8tOI9uWv< zhO~}F;)T4zli#MD>!`tL0o%@(Ew1N&k z3pLtX7i2vpf7Cf!J3T!>N<9gY+pY|OhUOP5MuL8%_|6py_j^jYsujZ7`52H_fWpZZ z*6Yxb_IAwq_vVsPn@4~A$ew!z#WHV1eYNWN(GB+w90>lA6sI^^dRZ!2(I5&n~#xO313RLtxA4Qu+Ct}GUwKMJ_?hk0ODpchr#oIFt8+@2s%_)&rE5rl`n+kp3V%Yj({?n%~=<}DT>+S~| zm^LHrH=g%pqp6a{WN76SBAD9etrmlk*fMQm?z>j8U)bb?-qt=M#mz1wBZJ@m^KnA);-c{wfKcr-l;jdo*RRp*@AB#& zb6mTO*U}pMi!Aa!yFh^&xOCKs4D+NpPnUf0sE( z%)9K&)IQuf+87&E@Nfl-i-hn=;wY-MU|oy`_4xrAQ`tvLZ34!hwOX}a;zsg+045MD z$$HRdcA`=@)~x>KbcEqOIBb#bf$tu=B0CRG?Tg7shAcYv5iMT>Bl=pw1gTFx(o&mw z*dY>2=%$!dq-D~1+5u{rlvv*q!Xmq9a03CU==BV`L)PgB5D| zVV0+y?-1?n?xrfczj{~CT|jS~i@bDnh7BN4n~rzo$zx#f5)2HkxM$-#Co6Sc)(*Fy*)3RQZutF%OCQS?x_Js zp+{Z>txxgY?tgyyvYnGbeQ$uGSIehfMlZ4-(p0vg3Iow22WI8^g zE9fgDTK@;IN*jrBIVjU|DjMePjXs8qyv8u57#WCqtfRUoXJZ~}?wGad@BU{A&DzMt zvkOat=@In1%Cd|^`CWOnXkTjdr+8GrqC5Z%96A_r?j@9Y8F@oO*528R_KwU^G#Md} zc&Bqz!ryfHyFPoV$|hAgU42i0Zh!8ZVyOKB3hf-b#^F*%ezLxJmM3{Xy`AGWfoX;sv=DM7bPwGNl>j%_u#{{(gc zgF{CL7WV(!yZyPq|9s=W-d&rO;A7kYKNx2^1P-zoa|U;sQFs22*BVFo9RcVa807!* zijQ@B&Hv9Uw&Z52Y3Ku4a({B2=|6mb7YND5N(E3j+ZbA8E;^ow0D^n?l7o*>e`t{$ z+uOycBX6bLs8_3egYP|#{S)Ww#Tly$3#|*3)Kjbb^IwmkeSG$a5TEQG26!W&^@#BH z4WbnM?jA-9>YqQ}`-GHy;OpyqT{Z_;jMCsCAi`Jw_T~uKeri;>B*3u-KqwZ7FpT?> zcp-(rEp^90n>YAK1(ssZ7%tAJkYqA2 zTBymfFP|>b+rI z7i5k7A{n!?0jQat>GMLu4;YE-^cX(ZU4zFT0k0SRN5J122IXv_C%lIpfDVDeAMrRM zhH_-fiUG1)1NbvgP9x5pWwuF|!r%ZL zt>a2C$j;FHA1*tJ3UpF|cV@wv(1H2l96$VwW+lMQlVZDUP4Ys5UOFNGSl$V@kx(^>*ZR2Jeit163@-!TK`18R z7(Kp~eGAHa)c`Mv$1*D>5>YA$sAq^-R2k%Dr8?IowN?!-XI!Ojc?y0zz`MY$AO8I% z3MLN0jQu79%nxA14H!reSnPk(;9e<+O`;~@Bnt$^a`&4i7%Ct_+Nc9}d`tBTkk#4J zA;(kinqpaAn}HT{gaMJ)EmLf6Rk>N;!U+f+erh2W+Hf3kpu~{=0r#VI?bm?Sx9#Q) zfG_JYFFOFbGr;7!IaSS(6nPT`2(CbxVr>>esy8(VLyi4X8SwWF9L}#;?GMcWx$j*G zN^UdxDw~N@`|C?LkF@t2qkD8g#E*>>ssWf*;3iXugy=Jsum=BKCAUAOk!gouM{)l` zBk1ty5CkiN!Cn0*Hp^BN_*x}d4LAZ?G4GCgEC=)iOzGchvG?ecg}@(Ow`=q~LmYTt zUnV*oXj}t~UL3oQkju8b&@%lCVQj!r2#9=R0MNaRG0CLV5s@pOXrXYBiMs+g^+ZBX z2_E0Y=-RyugFMcVe*}Z6X4q;A8Flg6PCEUJVF?}RP2@h9ia@GJ#y5 zd5Cnl6B6QjOsrk%c3^gN3eMev6f4MF5C5uMkAY#oKYbF9QS*R957wPAK})O(4&HKk z=~+~=q@FL|f5>xhB=nhtL@OYov>5(Ma~10a%9PWMBL5(v-JHMfJ6 zFaCo{ez*@J#=%~$AjRXdtviCtY23l4lJ!Zm8wfAU*@-)gy4BjfspLRZe zi@^__0ONk|fZ~OK&*|=S>7o6LS)ZFPT!cZq=ywMg;yCov1f$CeQ+MIYDS#0=3DFOabPTpjFmr9=plhtD~>2JbwM?|5`@kfaf)#H}^sBsvGOjTIGO+S0RSfM8GUz6}c zYvi$%AO4Z-BY^ouy=aq1xwm5ZQh9A*ZK|uscaiwF?jPWexu5Q4;t?ex;8;(Vjpx=$ zdllH;qJ_Yua|FkO4O{)SdjPYdKoDSY7-KoaP@Q9swrln=%*4QIft^^HPX5Y?W%-yE zs&>BA2za8Fo#u406p%S8&dm_LToHTI!dfWohC(IDk>4hJ|z z5JsomUyQPGone--W^RS7Tp(2@Vm>rvrFi(miXP9s!%qV|?3y&@CHO9YnjobIjc+Z= zf*IGdw#L>_pG`%tjcKLoAx{84)zD?Ifkhjr z(wYUVtaPV&DfGdTd)NE!DIYjG?J_irj#8Q*9)7Cr&gm?R)lMIMk%J}I;{7><(Kj>( zu=i5pt8Wp1_>gH>$=CbUB`)*XBiQCShRlnHLSt0eB*gMUiUz5^GbSwfe%Imdw7w*`d!Gc`I3~Jfsbee?7XgP$E0;Z-`A4l3 z45&lV@3kRND2%|U;?@K(=Sn6l(WV+C>bqfYo95<+DFa|!r-{hE#~Ji*nuNGNPzEml zLJ9xXJ_P$FI+}$_Ck9l9B=(LMniwLG@SK)GVWMrN)7W;pX0HL0b(@@|GYPxyr4KWqX;${5N5KhPyVUs?@> zN@9s4;41mUG}g_UIE0ZsiwQ`r6t!4UwR1JA7UkINsAjsV+0uw^cCbFIP#qGpD*V0l zy#oEZQYS2WCl5}kt%twfC7~x%`_{duHMum>oRHfOC?f`KWD;|R3)Dk+rTag$S%%hz zS1vuG18ndQ6prXTNM>v7(O+c{YCJ}KNDcv8Hz8#|j)1>1??w_osc(14nv!FwHw5|6 z89mF_UN}!KK1?H*t1X4(s%@h=m+@QZt@tvA3b(%> z^^jS6qxiwHD$*k`z^J*fT|^^xIL!M+zEH@skF!Z=R9vSYk?#-VN{H{+=y!}2aAo)$ ztl0+om4wLhZ|BFiEqB5+%SF?rOjZq=S;(w7iuSR0tHIe2Vfl3h`ftpd>3T|d zt;&-=TpL2*WKysBe}lYxtdyoJ&9-RvA-3sZv>yRdO7UA6qmbDktf<+CF`fBeGlu?5I#!&w|-#PN0$x2@BH-vIl)5qMdPoIVucRY1M3)HV}Io* zcYB|ca=N){dt6Cg8%oiI5~6J@OS5N^XnovV@6fkprE@&hmnywCVjLw!m|kc1Oej)e zo6J5E=Rk9Xe>VNW^Hq3-ES3*M{Y_kk#Cp)$Cfn^E^>6F|9RJ(c;S&<`-`D{g?>4Y_ z1Y`Rru=qc&`d<+SHXfvTEegihZRa)i7y~%ezG&tUHw@Z4t55SCQ(IsHMQT0+&0!fC z89r>vv#)Ti@7Cbgs)(i@w8RQd`eS{f`XfFvcj#9%B(<(JMCH&I#A0NI`Q2#}6r!=E)6Hk*zK=n8PV!OLFYg9}&AZ6Ll`i4Z-aAbFrWO z{BlE>iI9)ltkpszTA0KLr9Cq~x8J|VVzZ#52EP|vi`63CZb5pO#rK@(IU(8$qOvko zWlHc|u}Df4=i(YMZ{)}~%YWdtx+Fc?B+#2EIy+OoT6S$cS~O88P$S?PyfC*gXPk&6 zX-BoA{BA$|_rJvyB&M+Yem4{F>)DDYyiWeamxXgZ%Ph?|$_>6@#mJA~zzd?bH^UHp zaG;wYQ8tq1eQwF=$n_?Y(4plTkG~E)24L5z8aJP8^zwM&-)$g9*RnlcCW$bLtzQU! za>?2{=6Q2p)$W2e3e_@-D`zvSsfnvmLx_#X%;24Faf7z}!_Y^*VdTVjE=W)2 zLY_&&7<#CHVY_j?Q-9DO?D^~S689FLdu<7t=fmlxRswNS(utC%ji*N3iY_u78}4kv zdErsWO8?ysI?fHeUxC8dRuZ4gFx7^18&{I7V|1hMD6}X7a-p4oXylYFbCO91P9L+$ zPrNZveFHLV@)i4CP<6zvcA4z1sWe)Lq=T|qoZH1#bvwm_KDEF5l<(?QlvNK3(vdi$ zj{SlGB-li|EqEMlB2C*rHZYV!+?Mr?e!Y{Heh{rY=pbm}3Y{;m+m3QWVUj}!EwKKa z$G?+S4#{X@<;eK4TW#m(F`XwKL1TE=>hA~xahp*L(a)L3X^YrkGc zU{cqUzxmkIuFdM=Ak-a8K*sLjF5&ySsAGDA#0N!u#=MuF&o6dr7Q+Cw4DsywAz~15 zEO8@caUXds^$7Ku`7PO`Ii3F%jnCz;&E+&)5)?+40FiReesd)loY2-eUN*F)}+ zFHP6y)}|3zhmHfH@l8M0a+42@%kK+&Btjk#+*}?E+<<%tF6u_Ke)`AQ)+A06(9Fb5 z(+z(`{88jnd#%_od*(^;H0bEV3A`(kOhJe{BU;erQ1ZJ*mQ)wQclt7ihYsav-85#u zAIIwwk9cpEb!Pn|%v*9PF_7yJc>ox~e!8tBn!97M3TS6sf_xG=?tXbojbg)*jLt{z z7nPg79+Wg)3$fknd3_*Mf$=lW=}{!tUmJBeZs0Pr$DNnQ|VJFqg`&mrasr%RmR1+rs z5gNE9Ti%FZ#aCAX(e6)v$53koc;lPJ$y1OA2vESk0DeHcheB_4u1pmLYbN|f8|1@W zF(`8n+3=4`Ji=_<9g6xr1QHT7rWBI-K3jifQO@{Da}_j5jb)2(7XID`mj3RO3Mpfy zhkLE|$0Y)5ivrcODZXC`>bI)p3D%qW-8PQSq4H?tBGGL!heKZU*Z>wgLt?^_U+Q#G z6UZ6yIa`je{4UKuRoaa@$WygP82bNBgvdneuXNJ*zd{bXO^^|;47jI!8C_)gLwTc z!Br*{DLHzZq%vekDT0`L_R^fsF=$NR#|sM^^!=xYEqYXk*ij%s3s!QEeT=l!ZDMJT zG$c-dI<@psbUuIhwUh+`k`KF6!)fvpylmbo6L9SG;WGHt@Be(#iqR+b(svGQ}CA&YD0O>akVszGdp(23Bn3oc!C)QBUZ{C+Y_#E10(Ho5y%mNsVM-BxTv zaPBio2dujn(Thh9-33k$2E^mj^&mJTBj*WFTzvc~%@(^ayG7Iwt7c zwNwbVb^0cd(8sFKh(jiwnBo!!#nzGj;$-#-CTDIALkjp+k%DnYdn9~-VHeu^T7Y@q z-$3AMCHbAdw88w#yfAk~a>;4Kj>KtI6Zg@wW>g#tF-X~Zas8?M$tWbf==P>2l3LaE zKRm4FewA=;BFj+3;NVl;je>ZIWV#wtMU!NTLWBebl9R-wRu|Df3JQ7Ds(i%qskpE> zf6oCi$EqFOS?|StZU<4Ta+Xx-=xKfga_Rr z1nG@`>{KwLZJsL4U+KNIv-|>c^77Yq_J|`q)n-$^k(qZp<@304mAG`~;plu%hmWlm z%)jiFgR7n|GCwF#TuE`r`p6i8czwHbnmLrt|9zQmNG?Pb|CKGm+v~*$Q@ZE=a=bq4 z%F+w?U#LC2<0I~z|050dA7@{zn$F{WwZ#U|x$^sz~Ka5}E z3j89%BlR9G5*6{k=dv(D4e_O|0#nR8mqzL)CSd3H)}b%cOLyT;OT{*E^qPbDWv$+T z%ls%?zqT}Gflr>(F~{@G*zU#v8t(+@w|*)P1*G5jY)-y^DqQb4Ivf3k5!?2k`Kl?q zp5A4TOdq<6fae}`3{KHpS{NmVj)-iu`_~qSD$&Sfbl&&5z~&1I1tMFp0ln^eVTn~Q z@5C_q8GZjNK`Wxw{5Y%w|BGFE`=!*MVcM0RN|aVx-WY$u^onjan2o<;!*_WAX6WC;L|>QZ-k6@h5P z#9EKe2l4g^S6#i^Z#(F&d$|Wf$715j3-tb`-`g@AOuL8UAdb_Rj--5Gu`5#;J_(zq z{#rZ7jaGhVBw~o9(X8+jiPUgBZ>HnX{CY~s9CIYm%y0h}i{GkeUZviTjR}ht(^mM$ zJHT*87D;o@2N2L{{u99~8`;zB7@ zTOwPSGlqvaYnAJMOLOsh?)id58sdY-4nO1y@gvwUaCtVT&4P%3P(wXvhjOo~m8>nD+UJ0jBCHv%=_ zces8e)S$E5Uz1{|N6b;JqeqAt!T)msf&u=SP3QKig*gd(#O+1F$Pgsn?e#F-|1@O3 z`^)dtOQJPcX2s)EmZn4A&r@nNOkBlXuyt;MrzhYrc>!fR+bEj7v9ucfDQyNMfDatm z&eUrsf>!?-PsO~>u7p||$TDpyzsPDBkMphjoPB^RdyaS%JTyFe!2e*1VB0NWlOdR2Gv4htYuB6D|kVKg0q-9>JeFufuG>1%C$kQJd zpp1}P07!RbKKPp*{zI+mFX$NR5BjH(l5C9!kE{k#kk|x2-4=qFqL7h?=ILH>m>{o; z5hTJu5gW$G<~O6>|G9ti=A$wFa1MUk$-@#K#CGlKPeVOL{6-LId?A7S;v%3DA}yQ# z0-h16i)sHWZ#@V|kP=p7LU!kNQc6YRc3Z9o@#QB=wFfdE38&KvH`=3S2GDcIV?5=)| zXB^Sr|Nk2M3b3f&tzUA692zNU5Cn1P?oLTbmF`B6uAxQg5~Kt~S`Y-up}RpqL^=co zLAvfc|8u?@-+AtRE{^ELo|(PhTCy)>ruzk2JC(-44H3^D$F5%n-*=sH-MKH05Ss-z&gsO8UtXOOb(qY zGf^ijt#2TbPl*xrJz!Mo&k;QW^^8W|)&X#^SUuy7>Cx09X-Qx_4B$qgi4u>s-brCy z0D^(+LDiGyn~UA*P5Mo+E-pJ>{@t-E?7lwz;r1Z$zCjs4IS-am)N>^reZ+ncim@JG zh9LQ#gf8T|XkYls@xaurHIf8nGrc+LFrF_9-gMZ-xYhso^<8mN6);lhQ4Vp_cL+DF z-impXW<$0HQlj6l0e(3uz)5D;yjVsM0l;^HBhInL(Op9D3~bfo=c;Mwyg>~~Tfs&E z>gY@@M<@%N0YvRHL&)VX;q_?AdyjH8^l7euHU3Z^u!r`#iNwD{gSyh-Pg@@oFcmW_ z)kYUj%(_)}f}{5Gd&Vuk9)&Z@fQ;yIBm5(93Vhzd4}6SS0DS^Lu|zYwK_iO~WH`;A z?^Pp*%RyD4?WV2VHG%}m6QfF#`u^tw6QBU3H;`(}gkcPKN&X#|2T?SN{DQ8G*tT~E z&Z+DgnKghv1MpU|-nXJ&QKE1O9gwy{6>&n`dFmS`bUhwiGxM&du1sn&>ufi)B=?&@#CraOB7;Bo$17$_cz~Z67&V7>*{X{fhjV32S6jw zW1$38=5l|3&fsUC&A}^>AaMM$7}?doblT`RQ+6-cml@=r*1rI}S`GR#6Snm`lWpZS z75X@?DDHLQC|MxoQow#Im{chrn54cYpEdUd8VsCOKtgrFN`P1p<_bDdZoMCd-;C9E zMS&Leq;;1cCS8H$`fXC@hR{prhBQbDQh6h7+&_Vj^Bn`o^1)fL*4qX8R#3_dVCJAL zPWI}?3L|}?^bQMD?gBBdAzMQk)gYp2#H8(5;cFC^AW5+R{kr~q=IZ=tt$M0RRlW`+ zY$xM)Z^2etLXhg~Z9hwbwnjwGqZ|jNpD9cLVYO&~d&MPh!$aGvyS+vRUAfJOm>a~eU%?iV1Qa#}^MbVWDa$vFghpm+w5 zH(OUaTUCG9+T9D}Ly`d`Y6;xv?5l(G#E+}Y94ybl!f``}-!AuxMvwr@eyK(DbI9Ht zFPZu6&9xZ>^594skWhHY-Rx3Y z3gIG#M0d)EbN9GNWim;~KkFzQ;o|TzIF! zq3cI2PqkXweFekEh#rh&erqE1ump(L$ohu6B+}Osup$ID)vP0V8Q6qX)b+D!bUX2f zk3mm?Sn;`{CvC1L3tod<-8zTOz#h}S<5glu65306IOSfVt*m4HTZ#D^i)LG!p<3xorC*N9};3DRnForstp~qrq%p+PF7R4`Ju#{et zCe%iMdA!yKLh7CzfuBQy2c|!EjFd5Gve@tKjw(kiPP{BELh{jS65P8>iexM~1w-ke z#qTJywwQW>PNTCqey>eg9Q_YS)x1FiLMbWnfod$lGmsG$AP!&Z*K>d2Si6k|X4f@H zk~Jlw=hoQgn>JW97zvCy=}GUiu9YAOuI3*tQ}JFU9I#_)_(a9`HcIynLFfnzOOQBG z_HYjkBgA<#dk3gnCc@;z5hOt6XVtFh1ht6DJTsbpjidYX8BU*i+Iv){_ONLgXa06F#Luor)_{ktajL zO*2NXF9gQ^H`L6FVL=5u;$G1O=cMsQiJXq)eiCb{*z1^W_uq?6(@w-l?PqJw2QM7p zNpaTLZ)xJ`iJvj!u8u4A;Npbez@A0@)eRb9qSLGSo#C#4@fR4Ss$;w5%r|+xH?S-u zi|01nz4fnv$B0dC|9I(s%KGbk%46Jod4tqPl55rq^ZW59i$?aBJG$o-W=cNNoP527 z+(TIT-SKaYz9}O>KZ=pG377dvP&%N-NCoBF;3GFiFV*+UT7C8}=*a z+#VOxYrBWZ8FI_D;CjVdCAz=XU1n!`mq6G>qw#1{A8VugjTVb|9{C3*#&M!D@-XpV zP0kF2woHk?6m>a9OPMQ>9fC*Su$vR>WQ`Cuwdoi)XVOEiwD-%9gO%o%$;7Wjb<%?m z$^R%lTiR0Id{BYZh}BGp3`}iQY#|uMc!Ye3=HXb;xXepws2(UINQe&o!|Fva5Oaa=X28J*=CYgBx$RCBoq^8 z;u|j?wwZs&SJNnZU4HB*nI6%CLAjZ1RIvNwrOJajVFl9EBd@x~$PV5Lq)LTg?KMT` zeVB&E#kT{YU4$`-YljQypp!?xXuC6Wmw&6o4`DUvA#4saJIJ&1HwZ{F-wY=WIWmFmD_EVoEdjHIesEVEG$vPpUmThjfxFni!kyh@$)tV%8HGVfGS3FjTjQ zBTF_U_hF{@IAa$5ly6GV^+kie2b5?b)@q_%e875VWR;DwT*R}E2Yy#nRdqg65&wsR zv&ZEHXS_^<-n4KhlIdhUrD-9=^`V?|BmRO)bS%V`_KOGYd{Bb*&N&a0`QnY(ZhVlE zV!vo4juav3#lNRI^7oMJh-fz5;VOroxIzx_MLdNCGGi=ExKCOUE!2Y?afM*{i{oZY znj9~+GGx}d?r!1Sc&GHQ_~kbZSfj08kNo>ph2USB3h)c{KBzmWL&3j}HLFpd(GMWv zPv2RkMnq=>{&~#)j^nmBxbyO%2YbtW*J3yzKTgUl+i)v^_-432WNf3dNl6v#CW-fD z*MEhwR~^6}K2@?O|8?(_m0-hzotKw)lhS>A#i-VLKu%rY8~DK9Qb;-E2isXSX^Zl> zi2L>BQ^m`H+j;Sn@%!l<1k%JFYjV?X897K4V#gv>BDiz3k+=#9Byxu=Bu9$MDso5WFxpOiSNh}Gcmh%Gp>f>dnBdl?ss*{dwp{<@N5>$ynPnY=6(6t z&`~4=lv+6^@`J(DKExq7fa8Dk$B>nS%G@1AyPw`N&OR832UT{ahf#7*TL2HF7;*{7!)crG+Q5 z*BIy|{ROfZ#}z(WiDWLY*mWN!$HrV1p5&RSZ{`A_6?5F;+?)#G5&3;;-qIohnesFs zb1)M6HP*0Bo+6ND5Fzt%_pzZmCTwFEoMN}P!GOl7h>3*IV=dSH-Iac? zT5VDv=Py%8QNkLTd`1hzZ8AX^SnELBxf={w&m1p*Ki8sU&it_;HOuLttMrYyJ$6|n zJ|bi$)YxwkD7(xsK&jMxIlND99}`NqbiIisPBO^J99z71DJ?$&kvlLQxJrjkj2GEW z4i@WsE?vXh-hnL>P@Y{@S)aueSsz0#RFzn;J7%|;r;fm2YxdgGN>!c)JgFS`ev|@cld}XM;aFpF z=Cz;dl~F8v>$HczlK-?g?{h%PTf5RDoXmmX9s(lqwDn~`A$+5J4U7kh=ICOO!+n6) zJ2ysR$ROyL8lo*B6?hhEE7jgPSuC2F%>UrP`)p_GUR?AzlioLspvyc@IJM;uUKi}_ zZtbvR|1WT|OsOETlT>_6=H@?id$ez$=eobXH)oJnwK^zewb#~8Vr6E99JsuA@nWaa z%%5%R2T_-d8mJO!qJRH77=c0FqdTe1+Hj9eDPIOlQ zyP26w+6+`*t?4m?>%2p2w7APLiUfNyRsU})7CGN+697Hd{7!{0=<1sgNMO{ExkTq! zi{#Z+=)B)}g9$8i8d(YL^Mcng*X4prum`+V4pktB*ZukK-Mc;^z%YYTQ&W?qGDrGw zKU#z59yt>5B2wrbOv1JfbJfzm(3xMe9wo^=(K!U9SFg95%l~;I55Hnt9<%y?WNc~H zE74df%>0E3dY)BINnBeOdk<{cwfs&WI&zY(){NM%Y+`xnz`=dve3rqFH0$#N-y2*`t=RUatdCBYUKF&TO1} z2z2wQas;skI`qyNzp8~Kx3R=*M~p7g%ySs~2cW0(e|6W+DP&QK&xe6IsD{szvDDF> zF8)2w2(luoMDz??Q66mR43Nhu@JW;b8qUVFBW2ZVIDt?2&0dp8(vSwAFcmby$r|T;l}GS|FP8Qf$+tndtCjr zbua>v_3o$y68y>IXdzuw$3&XzOuW< zZ1`DbkL%)2uSl+AEkz6I4Su`KvQtSG;<}WcL#cLh270P z=7u7U9`qxn@ZvK+sK9Ka!aT5~ddsK|`jcGV=+_vx0b@3m%0staFF0-anGdLzyc6E@ zxmI%!q)t}EAK9kmgh+QIzO>_%3S=Kunl+I=?K2+y0#UsCe35!TT-ziRQAf||Y_JNU z+o6oo{98MMz(k!vSQzo@vO73~gM)Q*cDtn&rJ4fqP**<`E3)uV(~jP@>7@=k-^C`Di#dzug{6T5H2x3RW+7ikF3;0x)M7_o`spy zX;4MnG8oI^+>s%M5~2`N)329O7M4VjfQi<`Ha{kfpJSfz8D zGR^d7@~_4Qo;TNUf?Tb6KHT>3eop$nSR=LkJZk}6dy)$XL#uk$83JU6-CLc$R+$Uq zG{{}az+plMTGTwK5wxjKxCjt!NdgLA7={YH_`xHO?lB$r#TEIZZ^aP8J(7|z(l1Di zvLo>~lXMy?S9-ohHC|(78BeX-R%L`^T(K|S6Gk{+6fnXl)so0t zjp&55LojQ^m&7yHc$+$3kPXwl^!Mo`Mz|33E%Vs=Wf!bq$S@hd@(Tp|+~wiiDkQ+n-GvoIS$9CwPWSKTCAKH#_Vc z%WF!E)xAJvy&olc5Kb@Rj%HXy7DYd&+QWyggAtFjl!AlD(t{f=V$@H>&CPqdQB8)m zqHLc=28J<^3xZ7!wk$E0EFiUogS#R|sQ-5(JNK8yx&}gWn3lm^@X7;mB(Lw@(`7Wm zd;dD-UkAe||2b^c9GuBNkKb|=yOx)i%Ufi#B#|t$<_rp0Q}UR_h+!0p0T-f~nHiif zfVqdXHrUGv5^&N{S{v?(i^Ka(f_j@6L?nEiRmP^SqN1XyDU0lgL~ccYu1ErIxnEyj z-yg`l-ReBgr<-q)AtNu38Jm`tb|Acp1T`a9S(GKjP$xmheI=JnBuc(L^;#iH*<$?n zZ`ZYDkjB)^5&2kM4OWWsvN9Tw8Q*XRdC%XVMEp9}c_BFc95N`rhfEq#+urteO=?vY zkM5f{Z{iV5JGr^^%>`|3xe8;Apy;AiaQtmnf(a4jKbHuzW3pI%W$5tmFeJnrWW$P< zp9;Z%$g)`-O<5rJ`uf`J^yI|zJMiVoxLOh*lEw~bQS;yz+9q3xzen@4Y zaka7fU)O?!|AK&+9|APNjolW^gANOU7Egmks_YLPm322mp=TeKapJg63DglOK47A2Qx$!RP9#no(PBt z#ada5&1PA)iagG?>}o74Tl=%kO#?oPl4a!m6zA9xj$O=?m0IpTkHx8F;teS}n8!WM zsS=06!GAt=UoEitd)3$7TJGwHJ#KZIey{Jh|9=2y{~a9rzoKpb1-LCow;sK&FFacn zG4Kz1o}{hlpP_~Jp#brhJ}#8;ZWmD^v&w#}wA?GUze`LBOGWB>vND|M90lU-kCs?d zMt&y<2N?c-lzMcISOhe~AA5Vl=cA%tJ|v*22~q8hHDQiwL}G=14Htob#>sy@NEqxA z6Bl=pfB-ZsV_Y?qoO%i5?h&MNDAp%Rkw;o+{Mq#`<_^f$tD)ZGVNz0(n=%=2Tm$=Z zu=17}CKRcrObW#S1qqPG#Zf*G0~vJ+Eg;?=%G;eO&+zv{VQ*kpcpeaN1}v@23<2Vk z2UJ*cTOf7a0mF8A^0{R@jZyWD=y>@^i#jT zY9hXUa^MG85zt+E*}{O?MLCwNfRTVm1&vw047!)^?(73KI8tF$5g}g))LSM9fF;wy z2!$e45zXGawrVkv+LHj^0B-~U>mnkz#YQAIhi*{}DY*I*%eUDOl=icpmy{56?90=& z-d8WVRQczE&fYu0J=~a?d*Ubp08+37sK@|+;snhZ+=IjeLPZv^58bB5x9cXa>$=oB)w3nW*x;&N8F`rj5akQG+uz zVJ6%{4rmI`P@hc4@13j z#s0ad?m(wzKL)Z88Yi65>lp^6+F?-^MjzKw6CuS9#7p8@<+;~DM>45*>@gH{ngw8` z^a$=)o^+ms-y!Jd7Re}XD!>7Cp*zkJXWzN*dOIOt8G)O#oc)bqDFUT z;jQ=cKY~v0J_FDxu7P?M9~%Wgu{-SuPjs+1042)d`xn9BUqHc{COxP29{tK4fXIPV zVDXro<3TU}N?1aK8(iX114O(OBS3@vO}PvEafQ)@_a=yR-EF@nB7mxx@uz(zCDCsa zP*$%ATLA6Ya+r$x#1YN~SIcSIMeVnrZ~@61Q1g|Ue&*4%p`dl|h`BBZ1n?SZzv@!4MB-lNm*4601+UIboy<%`STrlB^*LVZ!?Ca<`)TWAmHDdHovMf zoycd%d1dg{i$YPK@(+LVz^}D?V5T_YCvjfumKrt(idec;=BX$u%ZVKA%c;Sz`tXTm zBB`@bd$pI84~(i4t^0l)iW(Gv0zUc&OM(Fmc;WW$@EVa}W@p)&YxDGjib!0!`v)4% z*BlRgsJpuH7HF4`ALEoD!Dvxr1x*{4hBRdxJpmJXqd+FxE#NVD4}i%Np4v@t{t~O> zBX^@Q4|Z|5R5y#jtaKk;14XJA;K#WZsIx}C|CT9tN%+8G=(UB`Crh%{W2 z?tQdxhOE_i2Gg18g*V5(SGP=}3{WEHdhou`o!&Z1++JXA08n{K=;G-m-*kfdHIu1{ zmzua=Htd*$7Wb~?g3bUSx;unhfy{}6+n#yW#%z!_CiNf!3d;HsGLa-WwfN1=u|kRH9FV>0OV#JHWnyDy^6{fo0o~HnOzw zTvSV%EyC1=3@N2m(M2#v?k>T1=Ol+aisO%U6jtl6kTTL}#+!ooq|Yj!wdXqhorw-- zq@g3oUHy6_lnGgD)YdvP6g7X>&t~GQ@65RJM2GrEBz8T9DfTT*{DTfh@n4aK2ow># z_|KjKjj5ZAn>)*=%#X@3R+SwVWjQn&3e&~N2(MR=wS-AIzUQ4q$cXSA_u!XQ%kQ?e za45omi9C8vVu#ks7GK5XZYFmoK!wA2q@2NR+-axVmE(kwdw(-gWk-U@tj$T9isI{n z%t?x<-+ZkNwIORrQ?OQN#tUXFs(ZWy{B_d5Jek8Dtki5Orqs#|0L+A2Z-$IqHZ;ki zRd~4K^JxKN3_Vyl#Is|EHJbzlH~xd7&XHq8+$i7f3L7cTM&FUb zWy@8hQN2@T@Dwd*qaVUI9Fh8XtKQ*GR=M#AI%V!zz3o_7uaK*n(6^dhjZ?~utFRCx zm90=kDIXJwefqWOh5D>PK5DsmOlZqLm$nn-HgfzkrvfbhTB2;+u5xe7WJ1H(!bfM^ z|2doJa7k*YN;ghEk~K!xbuu&L>W^}Z66Mey`_J{e)j>?14)k=j`Z(ohubGg=GHA)8?PT%;-~E5N~^)iVJ4q6xH3l)W{7UNWzPV4P%MuC*pLF3bLGP z0mD(+C;uqe!{h212CwSd*Yp~QS6b#5tvoEEy&ROHbA#ws!{tbt-XgDP+PuszkWmci zYY$?c>jU#G$=3~2Ic!@4S@+1W^%?U*ZZmN|(tj;>JC15F2B|%}GCmU{D?dzD{kng( zP}C7Rmi{Sj ztO_`mibw;d@~exBEb4&B11I==ZUhc}cVG6elix>aX%d4=aYEV8kvNzea|p@nAnoxMM~ zpWC0)A0Y{>?xa3!W}-HWG>h7-VGOIXt2>7#YU{EOgIZ|fYe;frtW*rVe*3X7HMTU~ z#6wRKbhIxOY7)pU;aw@VI39W`OSa!4rynT19d>c!exn(*pMo)qr-U%>8&}j&(mfJc zw_ugqnEg;zocck5p_ax9>!-Lq^Fg{4ITo;z&Ad|bhKes3r+HtsxOpx zv?r1^VQ*O)wlY+e_U+=H*=HUfgF2%q>#JD-M6?XfSXutTAihbY=b4`*rOzxa z^=vZPB-=rRuoL+c^jORN@p9xQ#xa#wSnuvk?xD=yC(z!XX5-2JMvcC3s0oX1{##cg zM&HpMbn#a1Vu6CqZeg@ICw(3+;YWr<Q>~}~S zO0vD3ap^_DJiRn|W?~6qjnFr8<|=hiH_AocW7PP+^^S1`lrNk*(&gyx?N7?9JuSUi zO@kLS?}&@!&Q>}HjCjLj_XBDzXZaT%tzEY?$0-+jpFH$kIcK2byGs&uT=NV=o$^y$ zShugXMJOwGFYYzjo~n?3#O6m8=3ZiR)Y?IK5pnD^tj;AsB&u9+t&h{EzcHGuuOe>j zv~a2Ye}*~#j(Prn0wK!4j$I7jdDi`T9q>i#)mj=!6wzaNJO zS(+^b?fsSd=(g<8kPwC%E(d<8WkG;b=3A|@zA{u$TiX@6`Rq9Bz-VfXka#aIM zU)sqqnTmVt*Wzy~)~(VGKp19hGVvZ*XZ-ZzF`(Yb30^DXk`4ijk7S&DE*DpLJ=VJu z@FM#O<^^|YsU7pz+~+0#^0xH7 zT>Lvci9>g(sdc(?3zK(AWq!tq@YtB$Z;!aE$6#NacF%a=`)Lz!zBdc2f1g-nQ&NAI@hUNm_hDX{^l+|Zwqpe{>c(cs zo{x|le@9R5z3~s>w82o}A{*C0t!$wO-%5&NG*)sX9z=SvFd((J)%m`F9eJutlqo#Kol0gvOK2H_`h zzXZc$t>x3^y_0GFlF4wDQr@B7F~F?zUj%F*gP8*$=P661_b@w2YN;xdKiI2IJW=v4K@c3avW{m^CwnJL8?Xw8PLgvcCx1iZ#;b}<>{tdURm5+MfuwX!N ztyR7T=7hS3bp7Th`#{T>(XM5fHtOfEecKpt%A*tX!*b^hUB!9{_6OMh_vZJ$04No# z|3%W_w(vNS>2mbbK$&u-5bkeFcE+Z$+%Nt4o#H&O*>U<*wR%7St&koQNcjznCOveA zphrY`q;jqWX{M#?RhJgjSg~MRxkF;V56o+3SeG?9&RKuPjs#C$sC*=uxO0vRki~Rp z_+@?luADGOy_^Rlxk#fCs>fIjBQGQ;_H#sl&ov2p5%02rfcWa0hJ;cPOY_Cnj@oRp zwdEo!RbN!m8A(_j$pd-`AJ_^F($w#H^-D zG)buizqT|3Y{QE;{TBjQVfTt;Y*T#Ow%q9JLDFYbjldiGCk5?HYPlCHJ*9m1<}gJ> zGK5wDuUK~&_a~RT?qnGSW@Qels%3Kl2SC~@?umuVtfHa>BB<#Tb^hZj(KBGFbeGF6 zkH@H{qv$@8>t*W7%8Dn~i-hQLA|eK<7B>O`1gHN3*cL4Dw)&uAOFTc@P>jE|u%6(a8Tyhgaso3C zKxeuV*wHg!u$iuydp%DO55Drf83ZKHd5pHk8&N8Sd{*H*>~&`kU@hV>N(Sqdky>Nv z1`6P}Z73Rewh}#qX`y8`Bf};v?-TTdQCCvm^cwU}9nsa!G6?Dm(#uIt^BnbtnjhzK z`~^vjINDl?hYeY##VpUB@3KT@7-f{621-BZ(MbCu+e8tESul(|#=r^(j?7c#cPzvM%&6p`|FOu~(8KoBY@D$@yA!c$f~Qrl4sJw^m@xu?_}1tV z?Y*);h@Oubu}78tNKQPBVf{Qh=P0CzT--+*dwPbZ)71*1egx%PSt8GGTl1gUC<&#cTAm^sPXUndsfkDV`N1_wMwtTf){c2}69N z=WMv&6viSMZSnG{*3q)1Fh_%&1!F2G<$xNUDL@cvH?YD!=LwQRPm5C?e%(xOSz?ij zZ0~m-&bKtHSf%;~Qe3W)2wps%q=L`KsK}gu_8s+`Zl!B4c)#qIEF?&n>AYfa{#d;x zBwaUvRAV!nm82DNKB#VNxOFm}Sr54lyVxnAe-`9jz?z|7B zJ#EoLnw#ZC9U$rt`X%Fcu#X=T|F)ENa4MRE?wOp9yZ9nnl1(JiEuHi}(vq7Nh!DS_ z<0fFfR^r0hKs8;S2J9pQf4aS+w7B@8Q@IvyKkZLKQd-i*#AO=lPxbT!y-gE5c4Hfo zYuEDnH-ejBXpd6%D_LOFMC5EEVXxSs_cFbVrufFRlr;ogoZ9L*<5{q#H=l^7P7>PJ z`w>O+Pi48*OiT?L!-muXcy;m#YXOXg0p7+p@-Gbzos-`T8FSluLGF_e445|I>&bi~^z}UE(%P zsHNs!PFaCJBi*7^>9Q!6wzSW(wAH&?QM|sp3?>Uaf)+K(8VJ(IWY}fu;%~rZV2wK+ z^GO=04&rkGi&ub_!y%nvWq`k9ml%WH4oJq9tA=8yHU$pbUpj2C&zV_>YneI~B%5wW zCzP6(8Wy^~4!NH|E`I8H{8N$enMVP*yt20%m<9F0R5&mg2p9ft&y^BRk0O7w?wdvT ztwU~jk()+8oA4wox91tL7JJe^6TZ3+<|f#4bTU}9(A>MudM*XMbuD-I7x17h%+G@T z=&Av^|)1G?!_ZB}d3LGpbR7_6nnRa7}VBM$gIWa7BV_Nx>88V`$ z<4>A>JQN>?DHHkV8nY9#nJf4{A|+=p#sjU5`5oDr+*I9ez({=d%--OixB16n1ndU? zu^15%`Nv`eYz9%@h2Q|90O^F3+Z-nCf2>GEL=NC9R1(d1=<;>`{Q%f8q7MCM1Bp5Y z3I#`@>`Umb_QT!3iSM__TYO9E#}bLuvmwj^xf?xY#OL^^zRhD9#Exn zO?a#Z?Pn&Tp~X8`)V~SeUFQf~#h)Xy_NVpfgGwfBIAXe7<66Bl*4|nmrsXABnn!LNLJ%jfMbq1CRc>M@e_D?I=OgZLlr8E1{(GDHz<$=S Uib6LPWnikRsHIRPXCD4P0II}yP5=M^ literal 0 HcmV?d00001 diff --git a/images/radar.png b/images/radar.png new file mode 100644 index 0000000000000000000000000000000000000000..421b62b623761ef00017bcf117259a40058ff74d GIT binary patch literal 17095 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

-JFR1U1(EbnxIFW9?6{>sY{ptHXH;XIxN(vF;X_ST$_o&-%g&%3^eYWNTqwKVen!Q)=1uP!ZK2tzb#HU zY|-F_<=$ai6JIp`osvoPqobt`?RC0rNVEu#W*}_t7g;?(uUM|_VAI$&mWC#-lSd*v z?)!pqZS@XN-!(y4w`Y-PKlYC5CycgRB0=Tl<+=dA)rr z*FX+K3E=(4(4wOkvl-d^_8^m7&0yIJ{$I{q}AHd(!1B)0CXnqcS$6{Ze^SK z%7|ZTbw{SvaNmW6EIoFTckT{+@VKoBm$t9>|EoHTw25W@)rra}Cm)bOaysRU()EDw@k`rYtSgOYJp zZd%$DIQ)arGrj1$zCM4aMAuHNW=W|9o1ETX*^L5%J_Su{6v^z& zj$sMceU<7=FYB|>j@=c&>%csYxvf0k$7Dn8jccv^-d0PmLS8*7fBk}+^Gszan^#%Y z)h=EvrsCc;3Yh z>KeUw_%4~n;xzq^{@2WMs}38I7E+rESU!(L@(!lneTgh>RD#hegZ*`|Ab3?>Yc~<2Z9(g?>I7PUf^pLBLRn{X>X}Amz&9_m>R-!jT=^V(yHET zwz^s^R&0uuWyrN-X_8IKaXa24fq~AXa*wu+Q6syu!!rHvWZ$_cXYT4xb+9u>OW??L zcVw{axlZ)JkFxpmxv%A+D)?@ZUO!(lQu+7WTF8)}s#8j;MH^)fzNV6Z{cT zJfUx!q={eE>c}5!^rxH$&7C;4w@w?}6USG{o@ILNzb03l=b>@X5qSK$Jht)?kYYr; zUCsT*1pG%!tO@=m+%<`TTrS(y;!LNsv#E6+YZkmMQI`#`3oDp$CRmSMy1yF^S_b-H zNo0%nQaQ|4O%pSS3;R5G(kEEhoK<|@v&{B&$@H8-zFv*t5IErGIUF#oQ2(f;c9d^6 zGufR>wXuzK<{Q!Ky;+EC>fF%Yu3=oC%;%y8Z#@-4aes$;h3M_je5+q`_OA9DgJ(6+ zhkN)y1H5B~!t+tiHOnH{Ykv8+Cp$tE#$8p~f5ZhT>-PdG-+N#7h=79}j4pI(;r5j~ zl@N;Y4G3@Dr%>@tO@A48m#vV|qu$mbebF=Sc)Y zfS5l5&`+O0r21fric?x_oJ^GqVU%mBoMal3punta!rlMN^G1O-e+uHH-N9b^#R^$5@Aw^ z=3iY;fR|WDK+~(&+c1VWJcu4F)TlxomIda_5$M6mH8K_~7y?rjv@g|*!?V1kFZ_?L z2t-86qM?*me9=<~_>>!^gb(QU;u8>1r~Q%%32gWB!G6~A{HtsTYB+ZBr=Iji_++MN z*xH)0G@%3jpZr(YVN7@RoT;RNCn~^u)Vo;2yvs{lWv#BRE~`)y=MgFvxj-z^2vY5< z_JucegBIfVb_~LIfhY8?Bg19Ff3FPUHMski{z2F7tgDy3rNI+9N>DP%f~X#p+}*G7 zdXxLx0b;TR?KxmzJA)2RPEPMHu5;S%*IR0|;Q!yV`zPfhaeKwE*Mt!NC_X_CGs4fa zwV~T>_xhIN2r2K6erY}Ycz=bjA=T;kQ|Ip`<^i=u`rq_8LnbV%GVPB0L$x|>AYc)N z2D}v$dp7>G`V1bFdW!#{!P}FQA%A4a|9y{8M+XOoyQ9h4>WQNz>`b9Bs=xjZQ>_|y zdr|wZk#9r~7*7Zn=e|9RisR@sCrQeg%D==(Kut_*&m=CfDz`Ol!)ZW7TW5N!0-dXAJ4>8_Zw>{05dw)3?=HzO+>DJe+sUF6Oa{fPKi8S#gjc~tN zN`N{|qU13~?{EGwZsqDHCh}hAKOH{Lzonlm2ITV$J|c59tzM+O)+)H?(DWT`!^zN4 z?IUGS8N1g}od!3hx?+b0QOVEcG{wRE1;^?YT$n9$lLd8x1!c#-Xd%R!|L%{<%y<4G z44~p1cZueoO^P#LjW*T#D=DdU>s;TmxIabP^cKtL{iVb+k&GZ-Kc~7{^5z@L2T?&F zPkS)S62@5IpS*~q%H)A>aQDK*UP2)_+c|8}SosdZn<%`(G+0Q;c) z(Uts_b#VX8WJXMmR?@*OIZGJiV1dt_77})H-3ZEX$6nj!pMB0lWdDVW+zV;JB$YSA zeo(RMmxIqbXOretn$brE!62`N?i5yZ9%bUVT3m=YWJX%GU^et{I-m*pEz20yH`T3p zV{1A@$}|P;l|v=eqnP9w)HG#12(i}EGZZO)8c6zI76Jd0fWn!qcu1aPh(^MUZqEt3 zh={Qck$g=DLtP6=y6`4@*xy%&J&G?hTE>fieT-{Htc=MD2_tNfY|1-1@a07Y&I9f` zY^fke|J>u~J&n*QLWSXk^Kzj0w=?*6%$ z-?-a2Wmua0he*_3!b`TJ0Em*Xf(C7fwu4D|u)d<>vy~cWfa!l29?%48;_dO_%FynT zEV#w#pSq&~#+lVbm(S>Sc6PHo7)RA@0OSgJD-QJsmsrxo(QIXjT8G2Lr7;lk}?ir{uLOYt-EDiE*x(Nc@)#N20)U&3W(x056BzSV^a> zjc1;sBrc5#nue|(RwB9CW4fbt3H2FV}89#{Fp=NoNBxf4_2rI)f9xD7$7-Sn3E1cARHghLg(78E)vX(im}O; zZq}8uP-!bW@T^YbC$(JhC*0VY@YGk*$raFcv~t&=HMMK>SSK7UUibLZ`4qnXb=FYN0 z)o`mI*A&JzSpwy}4!V<|C4_j4pqBWP7VkB7SBA6s{#CA_nh+&Y8?;E+P**@}Zy}u} zcoSy*#BMd$SBKi{riM86`Lb58Ex%e1SWKwhdL8p2DPbE{Cy)A}0%f^u6J&m+>fwyB zie^n^&EC0I56I+CdoS#kcWww|a4z)h`%~LLXDARNiTy?E_u*cy-JYX;<0J~+AibZq zHNprjvBOSoz1Lj)6jt0@1*og3W+PGh>!YAER>e_7oLQP_W|^hdkVQvLVqMQ9g^E#u z1-1SBVx}z+wxrd8DKl2Q`YRMS4Svn&th{F6xLO;T=ule>$Tj}c7k;F%wp|8>#GRB% zDN9O+q>A3uk8d^2{X`c{#xHQjU$8Md@y@Fx6P#CXP46tsv|qk7xe9N04ma)|#eA#d z2v`+kOPJL8Iy$i0;1yuO2EKk%X_rLVTRM^&wZ&f{xnk(X)B+)5nI~bCb2nsY)R}Uj zn4=;y#}s2pDSS40DTO<)86yWmfYj_3bUP;TuO`JEM{nPWj%r+koXn}g%^*0=28f~9 zSchM}&C@NKj9{YWcISq)3Sp#pF!Q~s9R=8~Y`VB7TFrsP)=J`YZzU4J&brb=CmY#K zG~6qY2~}b&-F1dG68eHc#fs8tI8IfvW<=5b%?S0lrW#<1rIt*Q$vA1w0BVZ*&o{f0 zI;(!trKiuCnoa6W(vcR{jLf1-;x= zqrrFE>OPrdn4MWl(DKHN^TwmO`wz;uwtC=2uJgVMvY5eR39-L>AX)Zgc=YDd+v0K* zLbUg)e`*++Vm#2ZBr1>nPp-x!bK=Yhgq$X&TS$9#p%t9AOr01zl_s{L%HC2%>s|K|> zxqS--4-}M*t)N972DIPKK^{zwsI@iBc*M_wH@n}%j5s9L9eP)Gjbyp?E`O-2#Z+-~Ucl6I+GZ>V>`)x3MM_bA9^l&8cB z^Vb~64FU7wReF13YWbEg2aV#|Dc?Xk{8zy?5*$XMw9|20t!pIXfs-VGCXXz_5v6mu zNdF-Aoj)qFCj5i-=Iz3M?d;~Z%V#jM8gz1cbW}-{Gp{C(545Wx+Dir)q;P^xSpSYD ztEy2+R}2E3%H8q9C|DXQGyrPpR0_FDW?62pk&!6y{(=R*zjGH4~i$0H*F}h zx?bbF(Q--?x=m(kl;Tk94}?~NcGnnW*X&m^Q!aM=c`@q+T=pTco-F4pPdDMCIcNL9 z?e(6=*WI^5Lvk;r=a-EfjMx7CpPjR8I=6jo0!Qn-l;5rb36&+3doP{415IkFBZd)3 zE>o968G#~w`fpqGpF8S%%|jcL{C;ha3uLI5E;%ahWvaaAQOhx%T5}3S%`_3Sw1CV0 z{U|>MqXPV-%SK2iTCzOj*6HU?@(4c0%x+y1qFMmIf)E5~xYpK!BhACt$883CK&h-K zs_VCRI*Y%W$q7_Q&ks|03F?s1;NTr2{4vZsNE-rCzHF@w*94@X_#?o}L~kxjjUS1V zF`}+)_13`-Y3(;rW8MD#$UPBHPu@A zHl6;kq*mg6ukVEnH z9A7|$6lh>mb(U68z!`r8>)(@bMIzb0pM7v?_nheR(FUtPO)o3o9w$!wW#i+T3o7vc znD?4lCA`1x@=g?=|7tiD5%Ul=`wUrSrbU-;k?sPR+ef;UEXwj5zHv>gvi)y@QCxRv zf9pkYeIUL*ABNx1iI(enXFGzIqR6=I*oEzOe|-JmtwVp^@HuOfAIbmt2e*c(&Lq{1 zQ$Q==pmk&Uqklh+S}KDcWgXc5wDQOt=W{_ID4_qZZ;d1v7o(}0uVlH)MOIr7Q?`aB zEzx!b47wAqJ;cM5rCs#lsMD|a>OsB#z5U%9>-VL=+q*NsV||#$@5yJF`1LCTbf=-z z4gM|wC*_}}#gw=jy?B%;P~-;+lyM67dYgU}?|qQMmKOmU>dfRf*@sg9(tcVj8{Z^8 z#nwQ@5L32+p!;WN5m4nHD3YU4id*JCC_l-D+C5$SS~$zp%;y)r80}{)7X0S(PnTMu z1!=)c5i7d5)OxCJnAdYwA|SejDanpFN70EzUci?=*Ogp%;nw1{#bt~8t~e)A_4Uq2 z5A^@PupC*4$v;wUh^xjr7FemT?_zG-YC?_G%T$NE%pnEPLgb`Tv`#bB@;l0?l@hO8 z&K-?)--iAvyH5>@i~f*HW{Wmio&x=}Dkp|@Hq9ct;(Pl7>uCt^r@~`J=cD@L7ePNz zc&uy7UnY?*uEr_~s_-vmRpTzTF<_ZpIwtJhS8ZB_lKdNo^`46b@Gc{VMKL{_KMQk3 zTfSF7|7tC`4%9rs5ws;|2N}#`&P5kQPEPXWck(1W$u0BS6UK4r3eb7Q6ApNS=rv8s z?i4%)$GleD#_Uukso5B+%D=0rDhABO{3D2}C z3xs^CnMGNBMaa4;-F@J53}<$2ZL4X!@Sv#=z7+S`%&@=E>$y}28G`^?2h8;2>Fk?F zHYp!eU=>$=t)2%z**ok*RP#O~@{bKI*ly$L+*;x;5f4dnwK_5P<2p|we$BIvTKw`; z<^cFW5s{dOZ;pmXxgMA$nZ7#26|Ad`RzDhLR(oUZ4x?ZQEn%@(aLSq6u$dx9=aTD7 zPL1~{!4sb0Ualf;ojrF)K{*-B<7;~hRUO%G+i=`(IT(d$z)AFUWc?MH|E5@o0}ot7 z<0)fUKP93>_kC9HVlKX{#7~HOx$ENy6>12HubzzKAgtoZM^ZX?)f5=@HFQ2f)G*o6~u;T{f83BR>{ zF65e43U9K+_1(d=Q!l?xCJ-U{;E5gP%hXD_h&r^MF{aqfiq&@_)vWQa_gBB-MW*pO zlv?iTivB;@t@6uYrDo_uFuBY9hIN{AR5-JcZp0o7Tupfvm+6^4C&&%J8pfq=P?G#Y zJ?e9Rs7sb~UX3-AmHO3YCPnaG9cZw*fyu6)Lf*K!d}yTH9L|Euz0K~7WEQC97Vl+` ziv~R{nk$Bna%@x()79{4)%PcO(AZpQ0yCH2vHf3V0|kVJq&I}m@p31ve6wQS1V z)ZnNg!qXEMA{_gf4qZapwB!yVCY9cf~E?%JQK+HFjZ>No%jc|ohgK=|8I+8Kb+2YGZkpoU=X zH?9D+&$5WthzySbd|@PN;Vw1n-BqA5=u#k>`Ec6r!T^>NpP$FTWCl?vLVpfi&+D(Zp;OO}T0%3~xe-8eJ8yIxvD(QxvuLWsdY!71y|* z6g4zPrz>Y8+k^SsZyB~M#>{UP5KU_i;f!`^REj8e(}pE;tboz62ea;`zbi*ZTUo>PXD2`k`$ zn*4cd>tn`=?)h+ zLB%r8!c~6ZSJF8=62!CB)0NXllcbI25`XB#wF9U-6|+1*W@FBb2M-7py_sR5G)cXC z7`;M+_zs)Oj=cZN4#!Hl7>Dv@ZsjVF;V@8 z^{tVdGtm?Cy>bO*pIJxbKXvZ#S4({I6xZle4+oXDL!LK&$Il+HkW`N?uUIOQCU%cK6ejhMwc}P?-Lzx})ZqQ`IRLzu&0s3m#4!0nRPy@USafY4x;DG0SL;oT zo^|W-{!TYaWX>=4hEz!(En@dlQru>p)XNuR9cDiG^4t^$U-=_(bt%e`5593eU$9Zl zPiB)$#`#G5hsKYW5@oM3RsGJn#6M#HTdXFo1tFqX{p6N1T8l}3MXJmFQTrk{`?l2- zCBuJKQmD&S_@#WE4<|ga`0(h6)$s1Q>-|brIY?-w`8*9ew7}2hn#s79ZSbqSWj~Qz zeHwJo{JJ|~V4Gm&=2vB9OoW%BJhLkA9+HLTii|z9dlb!mURGWt?pXCV%smNaOFFqH z2^!10T%HV#|AQl1Lr06XCN0^FF8^qO5vak_;@C7~WbA!4f*mVLaSwI~)&J^YwN!{>=Lrj)Zoo z=X5)5PMr~8in7z~?BGo82^7yztk{>)M)M=|hXcVC|MPWI7MP)a+&xXa&j@zYj_Y|V zoSClHx8sbI8V}_Je5ycl`~2%v+tI6gG9h&aF&}Bi_%_PxU-$`fM*CQcLRatC8K+SC z$ZC&Izpei|K#XwjI6$-^?+T*q?0f%R!tVA&_-KbDrf9Eyd5C{?i1>s7nLa3op6i-Y znbht(zK)PR(a!nKJN~ds?g3%aamoJhBdu_%9u=kRS=bpdZ8?Vp_&4XKs9_Y&U#+$y& zo~vSC(EkUGyt+ZO$!{hm`m_qK9bG@%@6ZD`Vdt8-qT8N#sEB>=gW}H?piR zN?pIx_rAxS0op#l4But*Vj1ZFh7?lQC;O8%6y4uRKtG`?{ttHtO3oJj{FtoR8 zY^!h9I7d8ieHi0h^{x1kjCV-3Kl&Pw!$G%xtkAD!_k-mfcPXa+qq=igZoh;=^6x+r z4U;?7+kG^K?8tZ_ELop7&Q`?VO75qH{})|*%eRA__$r;(&}l;g`9P`= zR^#OwUQOO5&#Fu1Hum>;o2KoW^}#odKZHG)$YHp`&V?ZEICvBOdbcc~hD3`(zhcdb`C~*b$8p0y@e}3~>I3Eh*t_L^sZ3(}y%2ig2PusT z%?7dd*G8H-?3vao*?t+d=rJLrKk0v@5&NZ?!jolTle<Vb?6TL_MLh+^ z5XL$EhVo)T8J1~QR*+F=kL%uSerA^m3y2;sYd8%&PB*gx%?2;Xgj$Dfrk-Bf#_S(~ z_l$ovoq$M-{C=-r38%IY{T!8mU#E3{5sp*_%lE%mt#S(VK>AMy7FhltlMzfFZy6+sC>IQ9dZ#8T>y8XWws$W7t6(3|smBkl#~Gwd>{mQAS3c zj9<3KSUSwh?uLBhINvEN&RGL^0mvnOw%L<>%58yByc!0}~$ISr#A6z0-I(UNclwjLYqRfopIwh`vr@R4RKK#m?`>~I4TvdOS=NhVxTZqB9r5QGCR~BZaJpoS{ z1`F#bMZK5nn13Y^!!qchutL$rQ8PeD=g01L0pjHz97FFGYM1pI^Llc6se|f$Q)8EPY zg;Uchu}AfDo^#$G%t`rT>Z7Gee+t85=UbZ~Nax=O;-qeUMPF_>(~Y7Ke&%4F_Jo-_ z`K1qh*g!I#(L*ayLuV~LMsq;DHHtv$%|kkEh?a+`MTUI1Q3^9G zd+E5M3UvE1JmV5B0ynwOReDa_XbhXp6Nf-TyRSPLmwJ%5Iae0?_Y1FXUv1y zjpEVLivsTwPjpId-oo6INA)yA-=OOi@Ndr-!NKP(Z!$H@K{fz^DV&w)DDO9?7jq$* zl}Dskx0&pMhNWBXYk!21BQ$6H>5CdVKX2V7C10gvvs0}{+dkyW%|^aR)&cE*B92C! zgq7N#nKeeJ9tbNl<6^E6FI{s5O8%2?lb*=>!o6L*4(aBY5%^?KKa2E=BN=*!THQ<} ztQ=+8Y&2EMfpK+lYR0?KkO}zs%7QnBy@^$jzLuNF{#QYO2RBs>2Dww$T9BR87>9&C zS5u3r0MkwTLJBTFmdA?rVUGn)7!2qR8t@p93;Fdh zztD!`4{R3QG#0oRkDgFc9ZCCLcly--brU>6NdeX{8lqL)Y}Z0@loC9YLcE}omQ8cU zl?)Y@p0x$4t{v}e72$cF7jjjN?;_LJ{imXWGwxBWp48rr5bf#u+b=|^-%lt*$$?+H zP;ur=Oe~H}PE%N?=XmQ_+UboJjUx3tlX*TlW2BFqnbR`t5+K8ed^b@Q#*9Yy+Ldj^ z-yH)D{<$ri_!3GPX%?+0)|k@hsIDvuc}Z#XXZ;K~+x_x(R``LRhU85xgOn0S!0(>0 z^K@A*V~7-xB#FhTE5?04LnWk09_c*`8q`sfp!suYi!efz`l~p?cpvt1unYBGWCh26 zXhf9bC7C@^<Q~MW;L&}rG2i0~L78{e~ z_tfL2`aCF5NtgRqAslJdv7kklOuGEw$kyBv^5a6FDs_@a?duuLEMx?s4K zTvb`n!>)@06(3wE=>IBV){9`Ryh*(zOrvo8@$t{#fm32OE)edkXmaX zQU;-~nx!bBHbi2>vW{2(ByA}~E{Sz{rx;nXV4^8QCjiHP?3BgD zf#+GuuF#IXRD0iv$OT2-DaakS{~9rSHuAG&zwxksU?yQdiA~*GG&k}>iJP*v3=X^p zNu2d!+9OVh=n^MsvbI5nFxVSVKNgJVrkM-?hAM0#B1gJ+X{k7a@`PGM5CNCQy+$>Oi9p&)n+p&rj#ZvSp;yn90GsIf%4pBeX4 zIXkP8!cL0Z>t~?A%Mel-FiOJDlsxjvOEQZ8!xVqTHeN#Ep z=*#&~!vAh+K5}gaPLh34eVQHRx?waudE8E2I98gj2I=|A%EhyN*`M5aX6_etUT+t$ zO8DVo>sl^%gJBaiR<$}{wy<>NGD8u_G-a7=FBJt`q84UbC?F=-_anUHqo2sF&fm?hx>OS*_q_4zJ!Pl z#f)ljiB@P)E;-xS_cTAbrMm_E1^i}{5;$Q*VWU`*D8Gd%jSdiH96L49lV`IxU2Tm< zfLP>%!y|4Y_9K%RvJ<5F*sTodxQ0?#oyf~^)+dCO&{v#t_V59zI4%70p_ z{Gw@sr}b$oSHB^wf@O=pjFaVNsjnZuqH#(*V(nHHBe)%|y;^cGftfp6{aV?nSglNZ zt?}d)?fsMNrC?2p;NZ~H(Zc0EG*5ue=Da~QSQqPY2rQwU#lE|JEOLYtvvU~z-)@-0 z@Z)Ch+FbE#pL=JBgvfv_?L-u5bTF09)ZRHXx6wsFI>Bw3m*5y2{a#?d0|R1z1<%=M*TIRIXE`B` z;QKQfEM|2CP7ycNM~_|cjOnGSRl7O^Us}k6_9q7oqOA|lMtk_c3l&qW1uDy8yBzNs${@S`3_TZ$)wY=G51EI~7-r%KkaPh<^rnnV@s% zRi#Kqly1Q3OmefbKpwr!KhEbl1V1*AA>%D&!*8*cuH9`@KgNU>DfmGV`JC1-nSg*wTStpq6vrzqPrhShU6`2KKP9LrMjh(mRqmrCe2U(6`N^Yh|>_ zOiDnh{-g=gbx91X^CeosYxykODa!a@0l0uWSfb{lX~n336c$%l)1j?p z;avHrEO!nPLlTJ=EcB?M7V;`f?IkwE}tUrTV`yOJ~311uO< z8tf46agklnIGpfT2Z~+#{ACXM$VqWY%Go|tqS=?oh2juTAot*D5`n;A0Rg-Y+l+(pb=};! z@Mq*UeGau)cKZCW4o~yWhuC=^+Lz<*-3uog2Wh+YS4z{f(5Ug}t#8vqgGT9!<8K%t zWN#S&jp0NEJ^sAeCbt5=H8*=M^H+oBidVp4iJRDpsL%x(=o7#S)^E9k`&X82sT1M{ zM_;6mar=Jkp&K4xLCCQU+wpVD*G6y+*N!kg1LaD+Nm zxvfbYMAW3kO_s_L58x}H?y+y54Lci%S6#f+zYUa)gRrzdMM#uw9`%ij<81Bogq$Ci zN|?`z$JPYnzaK|`g?QfO;}LQjI0Jku17<&us%%UcBQ-}o7kxXCLM!Wp9e4qIfcWK$r#a=$x=y(41H@VlAT*sZ&@#*DJF4)i)Ug$<8Je+%3G4 z0jekE>{*(nji#L(k{ZVg#`w)lOr!*Yb+gFID2DN10a6Q&+ByE@&`kP;N~nG5sTv%c zLCa43W2TQf{IEw;mRMRE8^o|;VuS4X#DvawUyzMYtv3PreiFGiLa82bcv`O&K}=zZ zjM>Bhk&@r!*JWEsRjM@-7sKBZ9g8^__Z`N>YTxDymvL?+kAF4xWjo%o+>rC6jm< z&Ro8`QY;J;B;RK!rTi_jqIVD?wc?-rrivyf!I(u9&M?xNqB8%i>v56bMSeBC7HECNe=)`j&#`$rH2m{QfMf=uuAtK0 zC2+%Q&e031bbv<)`KZ`N$-+Fj#ZDq9B14T~J%}_^aQoNLeAQ#Y&5wl}r(mAEJPPY{ zY-nt)U)f?l^p??8@QroC6eMX&UnDiHl&I?@z^j{|;0w>hKyuW~{IWy^7E#^?}tp&AnAN#P7F%Y(XbMhEw zt%M`EBC~xDa;9BDx}{%UC!2xN*|OPpP9$cApf~>1X&as+t|U-@IJrD^2+UcHqIg<4 z=j2p~T|Xd8QF=f;kahOqVlb_zity;Ir|@%+`7xV;JDvH*sWG_s7+9}1>?uyi&y&~I zo~R5isWX+{T;=U$Pm|4hU~GN&n8=DhgeCc7 zaFnmschqTV)0lD!*>O4oyl06qLpsj4jYl7kTz;ob04ofKX7ey6?}%<}DWY-)Tn81i zyjX{k0b}v$`O|u4g4p(ex|EgmQkfv1|80jY2Iv~4Umgtc7X`&p8^7KDiUp0 z@v<@P!+8#J?i%-R8b&mw?a9z&^;5m13sgXq1N+UIj(wCf6s0IG-aoHZ(q--EgxXgs zxub+fi-}@?;fXxBj!_=l0O=hv=11D z`R!Bjsd$N@5!&)*kq-bod*aw06VW02m*^JBhmB#qME=EBo_|inKoqtX0$G1reYAND z{r&VTjSMIZUHmSXRj`37joO+?|12Zz#*T-3+Ub1%hH7P+oOfM zki}BHmtmINMY7~wHCq+a7o*sv1XvW%s)YdieM@(LZ)l1b=%30X zLsCQ(pY}==_^_I_cGoBvQ`JfdU+u>kb`z*e=RcWoO||D~y7VH}4vuY5!?Rp(z}9hN z)#N(kzuxm0s_P2xFw^i!o)&Gj6^kV*t`sG!$YGrfL8w(-4iS|8CYqV&G;&IUW!)rR z&*y_>YI?JHGaN$sYNql!{O}FEf5o_a3b0Q@u+*n+_Dhgw962lW$(x$D=xiscf-kJ>3oV9kl{WN+1-TWZ0@nI635 zl&&t8&v;zQE-UQiUW{U^l4&iDJ~IO$RzTZ2n7*`I&tU@~PZVppfJgRN-Jzev>ewab z*i-yQ-*}A)B7W0w+x}!7?X+(!mZpc(TMBU0!ab%Ir{k*Fb0TkFCS_Ytmd`?x8>lQlE{2D!EJ6GP*d+vOlvbpv>K1knDJ`mneo>~lE^{lB> znCQiR38iw>p8Ryp+;fA53@$8SDab6C!c2{ODun1H9ut?7?+}xA8QqHS*;w=HtZoUl z|3*x4%zNcDZGJz{reCkoiRTYo6nN#kxJ+H(`8l1+>);Dhclpblx*Ki0Dkk1fS9{;} zu3-iGU-CWi4*uJAKkl2N=EYAP2`M9CCg#}Uyyy@X8EL#IaEW86-m?~tH{TA-gCz?n ziVggaebmQx0Uv~fXSbX*9Pjj%yLR{c6Ww>cO1oiy!(BStQ80NvGXP`gUnK~4z{iM} zTqb@WLOHJ5yuwFsP?*Fxtm4DJo1P{r6USQ1vr9WMBRi89*U4`Us1cM Ss{kBfTB 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 ol>Ytsz@PeG*ZHvNKXv^6KZQ~T$^ZZW literal 0 HcmV?d00001 diff --git a/images/rails_guides_kindle_cover.jpg b/images/rails_guides_kindle_cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f068bd9a040a294af09cc1a05fdda0bbc5de22e3 GIT binary patch literal 20955 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 literal 0 HcmV?d00001 diff --git a/images/session_fixation.png b/images/session_fixation.png new file mode 100644 index 0000000000000000000000000000000000000000..ac3ab01614354bebd481139fa84f0d71b7c9a264 GIT binary patch literal 38451 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 Xx#W5y{a*!y(g2s4k+oriJ}&V;exrV` literal 0 HcmV?d00001 diff --git a/images/tab_grey.gif b/images/tab_grey.gif new file mode 100644 index 0000000000000000000000000000000000000000..995adb76cfc2a4c900b01e29beeff301310a6fd2 GIT binary patch literal 4684 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 O!_K_U0nMsG00287a!r*0 literal 0 HcmV?d00001 diff --git a/images/tab_info.gif b/images/tab_info.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9dd164f182c9c74812e5178d467a3a23f8f11ce GIT binary patch literal 4522 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 I5ETRfJHFW)mH+?% literal 0 HcmV?d00001 diff --git a/images/tab_note.gif b/images/tab_note.gif new file mode 100644 index 0000000000000000000000000000000000000000..f9b546c6f84323c008d9d7930c2f0e4a88437a54 GIT binary patch literal 4566 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 literal 0 HcmV?d00001 diff --git a/images/tab_yellow.gif b/images/tab_yellow.gif new file mode 100644 index 0000000000000000000000000000000000000000..39a3c2dc6a5acc6915e535e3f92b0b1a68c8b07c GIT binary patch literal 4519 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 F06Y2}P>uiq literal 0 HcmV?d00001 diff --git a/images/tab_yellow.png b/images/tab_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab1c56c4d7b3465f5147eabd680c5d57b525821 GIT binary patch literal 1441 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 DpkoHo literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..9514145 --- /dev/null +++ b/index.html @@ -0,0 +1,383 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + + +

+ +
+ +
+
+

Ruby on Rails 指南 (v5.0.1)

+ +

+ 这是 Rails 5.0 的最新指南,基于 v5.0.1。 + 这份指南旨在使您立即获得 Rails 的生产力,并帮助您了解所有组件如何组合在一起。 +

+

+早前版本的指南: +Rails 4.2, +Rails 4.1, +Rails 4.0, +Rails 3.2,和 +Rails 2.3。 +

+ + + +
+
+
+
Rails 同时提供 Kindle 版。
+
标记了这个图标的指南还在编写中,不会出现在指南索引。这些指南可能包含不完整的信息甚至错误。您可以帮忙检查并且提交评论和修正。
+
+
+ +
+
+ +
+
+
+ + + +

入门

+
+
Rails 入门
+

从安装到建立第一个应用程序所需知道的一切。

+
+

模型

+
+
Active Record 基础
+

本篇介绍 Models、数据库持久性以及 Active Record 模式。

+
Active Record 数据库迁移
+

本篇介绍如何有条有理地使用 Active Record 来修改数据库。

+
Active Record 数据验证
+

本篇介绍如何使用 Active Record 验证功能。

+
Active Record 回调
+

本篇介绍如何使用 Active Record 回调功能。

+
Active Record 关联
+

本篇介绍如何使用 Active Record 的关联功能。

+
Active Record 查询
+

本篇介绍如何使用 Active Record 的数据库查询功能。

+
Active Model 基础
Work in progress
+

本篇介绍如何使用 Active Model。

+
+

视图

+
+
Action View 概述
Work in progress
+

本篇介绍 Action View 和常用辅助方法。

+
Rails 布局和视图渲染
+

本篇介绍 Action Controller 与 Action View 基本的版型功能,包含了渲染、重定向、使用 content_for 区块、以及局部模版。

+
Action View 表单辅助方法
+

本篇介绍 Action View 的表单帮助方法。

+
+

控制器

+
+
Action Controller 概览
+

本篇介绍 Controller 的工作原理,Controller 在请求周期所扮演的角色。内容包含 Session、滤动器、Cookies、资料串流以及如何处理由请求所发起的异常。

+
Rails 路由全解
+

本篇介绍与使用者息息相关的路由功能。想了解如何使用 Rails 的路由,从这里开始。

+
+

深入

+
+
Active Support 核心扩展
+

本篇介绍由 Active Support 定义的核心扩展功能。

+
Rails 国际化 API
+

本篇介绍如何国际化应用程序。将应用程序翻译成多种语言、更改单复数规则、对不同的国家使用正确的日期格式等。

+
Action Mailer 基础
+

本篇介绍如何使用 Action Mailer 来收发信件。

+
Active Job 基础
+

本篇提供创建背景任务、任务排程以及执行任务的所有知识。

+
测试 Rails 应用
+

这是 Rails 中测试设施的综合指南。它涵盖了从“什么是测试?”到集成测试的知识。

+
Rails 安全指南
+

本篇介绍网路应用程序常见的安全问题,如何在 Rails 里避免这些问题。

+
调试 Rails 应用
+

本篇介绍如何给 Rails 应用程式除错。包含了多种除错技巧、如何理解与了解代码背后究竟发生了什么事。

+
配置 Rails 应用
+

本篇介绍 Rails 应用程序的基本配置选项。

+
Rails 命令行
+

本篇介绍 Rails 提供的命令行工具。

+
Asset Pipeline
+

本篇介绍 Asset Pipeline.

+
在 Rails 中使用 JavaScript
+

本篇介绍 Rails 内置的 Ajax 与 JavaScript 功能。

+
Rails 初始化过程
Work in progress
+

本篇介绍 Rails 内部初始化过程。

+
自动加载和重新加载常量
+

本篇介绍自动加载和重新加载常量是如何工作的。

+
Rails 缓存概览
+

本篇介绍如何通过缓存给 Rails 应用提速。

+
Active Support 监测程序
Work in progress
+

本篇介绍如何通过 Active Support 监测 API 观察 Rails 和其他 Ruby 代码的事件。

+
Rails 应用分析指南
Work in progress
+

本篇介绍如何分析 Rails 应用并提高性能。

+
使用 Rails 开发只提供 API 的应用
+

本篇介绍如何将 Rails 用于只提供 API 的应用。

+
Action Cable 概览
+

本篇介绍 Action Cable 如何工作,以及如何使用 WebSockets 创建实时功能。

+
+

扩展 Rails

+
+
Rails 插件开发简介
Work in progress
+

本篇介绍如何开发插件扩展 Rails 的功能。

+
Rails on Rack
+

本篇介绍 Rails 和 Rack 的集成以及和其他 Rack 组件的交互。

+
创建及定制 Rails 生成器
+

本篇介绍如何添加新的生成器,或者为 Rails 内置生成器提供替代选项(例如替换 scaffold 生成器的测试组件)。

+
引擎
Work in progress
+

本篇介绍如何编写可挂载的引擎。

+
+

贡献 Ruby on Rails

+
+
贡献 Ruby on Rails
+

Rails 不是“别人的框架”。本篇提供几条贡献 Rails 开发的路线。

+
API 文档守则
+

本篇介绍 Ruby on Rails API 文档守则。

+
Ruby on Rails 指南守则
+

本篇介绍 Ruby on Rails 指南守则。

+
+

维护方针

+
+
维护方针
+

Ruby on Rails 当前支持版本,和什么时候发布新版本。

+
+

发布说明

+
+
升级 Ruby on Rails
+

本篇帮助升级到 Ruby on Rails 最新版。

+
Ruby on Rails 5.0 发布说明
+

Rails 5.0 的发布说明。

+
Ruby on Rails 4.2 发布说明
+

Rails 4.2 的发布说明。

+
Ruby on Rails 4.1 发布说明
+

Rails 4.1 的发布说明。

+
Ruby on Rails 4.0 发布说明
+

Rails 4.0 的发布说明

+
Ruby on Rails 3.2 发布说明
+

Rails 3.2 的发布说明

+
Ruby on Rails 3.1 发布说明
+

Rails 3.1 的发布说明

+
Ruby on Rails 3.0 发布说明
+

Rails 3.0 的发布说明

+
Ruby on Rails 2.3 发布说明
+

Rails 2.3 的发布说明

+
Ruby on Rails 2.2 发布说明
+

Rails 2.2 的发布说明

+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/initialization.html b/initialization.html new file mode 100644 index 0000000..c0cc0fa --- /dev/null +++ b/initialization.html @@ -0,0 +1,232 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+

Rails 初始化过程

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/javascripts/guides.js b/javascripts/guides.js new file mode 100644 index 0000000..e4d25df --- /dev/null +++ b/javascripts/guides.js @@ -0,0 +1,53 @@ +$.fn.selectGuide = function(guide) { + $("select", this).val(guide); +}; + +var guidesIndex = { + bind: function() { + var currentGuidePath = window.location.pathname; + var currentGuide = currentGuidePath.substring(currentGuidePath.lastIndexOf("/")+1); + $(".guides-index-small"). + on("change", "select", guidesIndex.navigate). + selectGuide(currentGuide); + $(document).on("click", ".more-info-button", function(e){ + e.stopPropagation(); + if ($(".more-info-links").is(":visible")) { + $(".more-info-links").addClass("s-hidden").unwrap(); + } else { + $(".more-info-links").wrap("
").removeClass("s-hidden"); + } + }); + $("#guidesMenu").on("click", function(e) { + $("#guides").toggle(); + return false; + }); + $(document).on("click", function(e){ + e.stopPropagation(); + var $button = $(".more-info-button"); + var element; + + // Cross browser find the element that had the event + if (e.target) element = e.target; + else if (e.srcElement) element = e.srcElement; + + // Defeat the older Safari bug: + // http://www.quirksmode.org/js/events_properties.html + if (element.nodeType === 3) element = element.parentNode; + + var $element = $(element); + + var $container = $element.parents(".more-info-container"); + + // We've captured a click outside the popup + if($container.length === 0){ + $container = $button.next(".more-info-container"); + $container.find(".more-info-links").addClass("s-hidden").unwrap(); + } + }); + }, + navigate: function(e){ + var $list = $(e.target); + var url = $list.val(); + window.location = url; + } +}; diff --git a/javascripts/jquery.min.js b/javascripts/jquery.min.js new file mode 100644 index 0000000..93adea1 --- /dev/null +++ b/javascripts/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.2 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="
"+""+"
",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
t
",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( +a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f +.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/javascripts/responsive-tables.js b/javascripts/responsive-tables.js new file mode 100644 index 0000000..8554a13 --- /dev/null +++ b/javascripts/responsive-tables.js @@ -0,0 +1,43 @@ +$(document).ready(function() { + var switched = false; + $("table").not(".syntaxhighlighter").addClass("responsive"); + var updateTables = function() { + if (($(window).width() < 767) && !switched ){ + switched = true; + $("table.responsive").each(function(i, element) { + splitTable($(element)); + }); + return true; + } + else if (switched && ($(window).width() > 767)) { + switched = false; + $("table.responsive").each(function(i, element) { + unsplitTable($(element)); + }); + } + }; + + $(window).load(updateTables); + $(window).bind("resize", updateTables); + + + function splitTable(original) + { + original.wrap("
"); + + var copy = original.clone(); + copy.find("td:not(:first-child), th:not(:first-child)").css("display", "none"); + copy.removeClass("responsive"); + + original.closest(".table-wrapper").append(copy); + copy.wrap("
"); + original.wrap("
"); + } + + function unsplitTable(original) { + original.closest(".table-wrapper").find(".pinned").remove(); + original.unwrap(); + original.unwrap(); + } + +}); diff --git a/javascripts/syntaxhighlighter.js b/javascripts/syntaxhighlighter.js new file mode 100644 index 0000000..584aaed --- /dev/null +++ b/javascripts/syntaxhighlighter.js @@ -0,0 +1,20 @@ +/*! + * SyntaxHighlighter + * https://github.com/syntaxhighlighter/syntaxhighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 4.0.1 (Sun, 03 Jul 2016 06:45:54 GMT) + * + * @copyright + * Copyright (C) 2004-2016 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ + + +!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function i(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var a=n(1);Object.keys(a).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}})});var s=n(28),o=i(s),l=i(a),u=n(29),c=r(u);n(30),(0,o["default"])(function(){return l["default"].highlight(c.object(window.syntaxhighlighterConfig||{}))})},function(e,t,n){"use strict";function r(e){window.alert("SyntaxHighlighter\n\n"+e)}function i(e,t){var n=h.vars.discoveredBrushes,i=null;if(null==n){n={};for(var a in h.brushes){var s=h.brushes[a],o=s.aliases;if(null!=o){s.className=s.className||s.aliases[0],s.brushName=s.className||a.toLowerCase();for(var l=0,u=o.length;u>l;l++)n[o[l]]=a}}h.vars.discoveredBrushes=n}return i=h.brushes[n[e]],null==i&&t&&r(h.config.strings.noBrush+e),i}function a(e){var t="",r=u.trim(e),i=!1,a=t.length,s=n.length;0==r.indexOf(t)&&(r=r.substring(a),i=!0);var o=r.length;return r.indexOf(n)==o-s&&(r=r.substring(0,o-s),i=!0),i?r:e}Object.defineProperty(t,"__esModule",{value:!0});var s=n(2),o=n(5),l=n(9)["default"],u=n(10),c=n(11),f=n(17),g=n(18),p=n(19),d=n(20),h={Match:o.Match,Highlighter:n(22),config:n(18),regexLib:n(3).commonRegExp,vars:{discoveredBrushes:null,highlighters:{}},brushes:{},findElements:function(e,t){var n=t?[t]:u.toArray(document.getElementsByTagName(h.config.tagName)),r=(h.config,[]);if(n=n.concat(f.getSyntaxHighlighterScriptTags()),0===n.length)return r;for(var i=0,a=n.length;a>i;i++){var o={target:n[i],params:s.defaults(s.parse(n[i].className),e)};null!=o.params.brush&&r.push(o)}return r},highlight:function(e,t){var n,r=h.findElements(e,t),u="innerHTML",m=null,x=h.config;if(0!==r.length)for(var v=0,y=r.length;y>v;v++){var m,w,b,t=r[v],E=t.target,S=t.params,C=S.brush;null!=C&&(m=i(C),m&&(S=s.defaults(S||{},p),S=s.defaults(S,g),1==S["html-script"]||1==p["html-script"]?(m=new d(i("xml"),m),C="htmlscript"):m=new m,b=E[u],x.useScriptTags&&(b=a(b)),""!=(E.title||"")&&(S.title=E.title),S.brush=C,b=c(b,S),w=o.applyRegexList(b,m.regexList,S),n=new l(b,w,S),t=f.create("div"),t.innerHTML=n.getHtml(),S.quickCode&&f.attachEvent(f.findElement(t,".code"),"dblclick",f.quickCodeHandler),""!=(E.id||"")&&(t.id=E.id),E.parentNode.replaceChild(t,E)))}}},m=0;t["default"]=h;var x=t.registerBrush=function(e){return h.brushes["brush"+m++]=e["default"]||e};t.clearRegisteredBrushes=function(){h.brushes={},m=0};x(n(23)),x(n(24)),x(n(25)),x(n(26)),x(n(27))},function(e,t,n){"use strict";function r(e){return e.replace(/-(\w+)/g,function(e,t){return t.charAt(0).toUpperCase()+t.substr(1)})}function i(e){var t=s[e];return null==t?e:t}var a=n(3).XRegExp,s={"true":!0,"false":!1};e.exports={defaults:function(e,t){for(var n in t||{})e.hasOwnProperty(n)||(e[n]=e[r(n)]=t[n]);return e},parse:function(e){for(var t,n={},s=a("^\\[(?(.*?))\\]$"),o=0,l=a("(?[\\w-]+)\\s*:\\s*(?[\\w%#-]+|\\[.*?\\]|\".*?\"|'.*?')\\s*;?","g");null!=(t=a.exec(e,l,o));){var u=t.value.replace(/^['"]|['"]$/g,"");if(null!=u&&s.test(u)){var c=a.exec(u,s);u=c.values.length>0?c.values.split(/\s*,\s*/):[]}u=i(u),n[t.name]=n[r(t.name)]=u,o=t.index+t[0].length}return n}}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0}),t.commonRegExp=t.XRegExp=void 0;var i=n(4),a=r(i);t.XRegExp=a["default"];t.commonRegExp={multiLineCComments:(0,a["default"])("/\\*.*?\\*/","gs"),singleLineCComments:/\/\/.*$/gm,singleLinePerlComments:/#.*$/gm,doubleQuotedString:/"([^\\"\n]|\\.)*"/g,singleQuotedString:/'([^\\'\n]|\\.)*'/g,multiLineDoubleQuotedString:(0,a["default"])('"([^\\\\"]|\\\\.)*"',"gs"),multiLineSingleQuotedString:(0,a["default"])("'([^\\\\']|\\\\.)*'","gs"),xmlComments:(0,a["default"])("(<|<)!--.*?--(>|>)","gs"),url:/\w+:\/\/[\w-.\/?%&=:@;#]*/g,phpScriptTags:{left:/(<|<)\?(?:=|php)?/g,right:/\?(>|>)/g,eof:!0},aspScriptTags:{left:/(<|<)%=?/g,right:/%(>|>)/g},scriptScriptTags:{left:/(<|<)\s*script.*?(>|>)/gi,right:/(<|<)\/\s*script\s*(>|>)/gi}}},function(e,t){"use strict";function n(e,t,n,r,i){var a;if(e[b]={captureNames:t},i)return e;if(e.__proto__)e.__proto__=w.prototype;else for(a in w.prototype)e[a]=w.prototype[a];return e[b].source=n,e[b].flags=r?r.split("").sort().join(""):r,e}function r(e){return S.replace.call(e,/([\s\S])(?=[\s\S]*\1)/g,"")}function i(e,t){if(!w.isRegExp(e))throw new TypeError("Type RegExp expected");var i=e[b]||{},a=s(e),l="",u="",c=null,f=null;return t=t||{},t.removeG&&(u+="g"),t.removeY&&(u+="y"),u&&(a=S.replace.call(a,new RegExp("["+u+"]+","g"),"")),t.addG&&(l+="g"),t.addY&&(l+="y"),l&&(a=r(a+l)),t.isInternalOnly||(void 0!==i.source&&(c=i.source),null!=i.flags&&(f=l?r(i.flags+l):i.flags)),e=n(new RegExp(e.source,a),o(e)?i.captureNames.slice(0):null,c,f,t.isInternalOnly)}function a(e){return parseInt(e,16)}function s(e){return M?e.flags:S.exec.call(/\/([a-z]*)$/i,RegExp.prototype.toString.call(e))[1]}function o(e){return!(!e[b]||!e[b].captureNames)}function l(e){return parseInt(e,10).toString(16)}function u(e,t){var n,r=e.length;for(n=0;r>n;++n)if(e[n]===t)return n;return-1}function c(e,t){return $.call(e)==="[object "+t+"]"}function f(e,t,n){return S.test.call(n.indexOf("x")>-1?/^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/:/^(?:\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/,e.slice(t))}function g(e){for(;e.length<4;)e="0"+e;return e}function p(e,t){var n;if(r(t)!==t)throw new SyntaxError("Invalid duplicate regex flag "+t);for(e=S.replace.call(e,/^\(\?([\w$]+)\)/,function(e,n){if(S.test.call(/[gy]/,n))throw new SyntaxError("Cannot use flag g or y in mode modifier "+e);return t=r(t+n),""}),n=0;n"}else if(i)return"\\"+(+i+n);return e};if(!c(e,"Array")||!e.length)throw new TypeError("Must provide a nonempty array of patterns to merge");for(a=0;a1&&u(s,"")>-1&&(n=i(this,{removeG:!0,isInternalOnly:!0}),S.replace.call(String(e).slice(s.index),n,function(){var e,t=arguments.length;for(e=1;t-2>e;++e)void 0===arguments[e]&&(s[e]=void 0)})),this[b]&&this[b].captureNames)for(r=1;rs.index&&(this.lastIndex=s.index)}return this.global||(this.lastIndex=a),s},C.test=function(e){return!!C.exec.call(this,e)},C.match=function(e){var t;if(w.isRegExp(e)){if(e.global)return t=S.match.apply(this,arguments),e.lastIndex=0,t}else e=new RegExp(e);return C.exec.call(e,y(this))},C.replace=function(e,t){var n,r,i,a=w.isRegExp(e);return a?(e[b]&&(r=e[b].captureNames),n=e.lastIndex):e+="",i=c(t,"Function")?S.replace.call(String(this),e,function(){var n,i=arguments;if(r)for(i[0]=new String(i[0]),n=0;na)throw new SyntaxError("Backreference to undefined group "+t);return e[a+1]||""}if("$"===i)return"$";if("&"===i||0===+i)return e[0];if("`"===i)return e[e.length-1].slice(0,e[e.length-2]);if("'"===i)return e[e.length-1].slice(e[e.length-2]+e[0].length);if(i=+i,!isNaN(i)){if(i>e.length-3)throw new SyntaxError("Backreference to undefined group "+t);return e[i]||""}throw new SyntaxError("Invalid token "+t)})}),a&&(e.global?e.lastIndex=0:e.lastIndex=n),i},C.split=function(e,t){if(!w.isRegExp(e))return S.split.apply(this,arguments);var n,r=String(this),i=[],a=e.lastIndex,s=0;return t=(void 0===t?-1:t)>>>0,w.forEach(r,e,function(e){e.index+e[0].length>s&&(i.push(r.slice(s,e.index)),e.length>1&&e.indext?i.slice(0,t):i},w.addToken(/\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\dA-Fa-f]{4}|{[\dA-Fa-f]+})|x(?![\dA-Fa-f]{2}))/,function(e,t){if("B"===e[1]&&t===R)return e[0];throw new SyntaxError("Invalid escape "+e[0])},{scope:"all",leadChar:"\\"}),w.addToken(/\\u{([\dA-Fa-f]+)}/,function(e,t,n){var r=a(e[1]);if(r>1114111)throw new SyntaxError("Invalid Unicode code point "+e[0]);if(65535>=r)return"\\u"+g(l(r));if(I&&n.indexOf("u")>-1)return e[0];throw new SyntaxError("Cannot use Unicode code point above \\u{FFFF} without flag u")},{scope:"all",leadChar:"\\"}),w.addToken(/\[(\^?)]/,function(e){return e[1]?"[\\s\\S]":"\\b\\B"},{leadChar:"["}),w.addToken(/\(\?#[^)]*\)/,function(e,t,n){return f(e.input,e.index+e[0].length,n)?"":"(?:)"},{leadChar:"("}),w.addToken(/\s+|#.*/,function(e,t,n){return f(e.input,e.index+e[0].length,n)?"":"(?:)"},{flag:"x"}),w.addToken(/\./,function(){return"[\\s\\S]"},{flag:"s",leadChar:"."}),w.addToken(/\\k<([\w$]+)>/,function(e){var t=isNaN(e[1])?u(this.captureNames,e[1])+1:+e[1],n=e.index+e[0].length;if(!t||t>this.captureNames.length)throw new SyntaxError("Backreference to undefined group "+e[0]);return"\\"+t+(n===e.input.length||isNaN(e.input.charAt(n))?"":"(?:)")},{leadChar:"\\"}),w.addToken(/\\(\d+)/,function(e,t){if(!(t===R&&/^[1-9]/.test(e[1])&&+e[1]<=this.captureNames.length)&&"0"!==e[1])throw new SyntaxError("Cannot use octal escape or backreference to undefined group "+e[0]);return e[0]},{scope:"all",leadChar:"\\"}),w.addToken(/\(\?P?<([\w$]+)>/,function(e){if(!isNaN(e[1]))throw new SyntaxError("Cannot use integer as capture name "+e[0]);if("length"===e[1]||"__proto__"===e[1])throw new SyntaxError("Cannot use reserved word as capture name "+e[0]);if(u(this.captureNames,e[1])>-1)throw new SyntaxError("Cannot use same name for multiple groups "+e[0]);return this.captureNames.push(e[1]),this.hasNamedCapture=!0,"("},{leadChar:"("}),w.addToken(/\((?!\?)/,function(e,t,n){return n.indexOf("n")>-1?"(?:":(this.captureNames.push(null),"(")},{optionalFlags:"n",leadChar:"("}),e.exports=w},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(6);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})});var i=n(7);Object.keys(i).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}})})},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;nr;r++)"object"===i(t[r])&&(n=n.concat((0,a.find)(e,t[r])));return n=(0,a.sort)(n),n=(0,a.removeNested)(n),n=(0,a.compact)(n)}Object.defineProperty(t,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};t.applyRegexList=r;var a=n(8)},function(e,t,n){"use strict";function r(e,t){function n(e,t){return e[0]}for(var r=null,i=[],a=t.func?t.func:n,s=0;r=l.XRegExp.exec(e,t.regex,s);){var u=a(r,t);"string"==typeof u&&(u=[new o.Match(u,r.index,t.css)]),i=i.concat(u),s=r.index+r[0].length}return i}function i(e){function t(e,t){return e.indext.index?1:e.lengtht.length?1:0}return e.sort(t)}function a(e){var t,n,r=[];for(t=0,n=e.length;n>t;t++)e[t]&&r.push(e[t]);return r}function s(e){for(var t=0,n=e.length;n>t;t++)if(null!==e[t])for(var r=e[t],i=r.index+r.length,a=t+1,n=e.length;n>a&&null!==e[t];a++){var s=e[a];if(null!==s){if(s.index>i)break;s.index==r.index&&s.length>r.length?e[t]=null:s.index>=r.index&&s.indexr;r++)i[t[r]]=!0;return i}function a(e,t,n){var a=this;a.opts=n,a.code=e,a.matches=t,a.lines=r(e),a.linesToHighlight=i(n)}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=a,a.prototype={wrapLinesWithCode:function(e,t){if(null==e||0==e.length||"\n"==e||null==t)return e;var n,i,a,s,o,l=this,u=[];for(e=e.replace(/s;s++)a+=l.opts.space;return a+" "}),n=r(e),s=0,o=n.length;o>s;s++)i=n[s],a="",i.length>0&&(i=i.replace(/^( | )+/,function(e){return a=e,""}),i=0===i.length?a:a+''+i+""),u.push(i);return u.join("\n")},processUrls:function(e){var t=/(.*)((>|<).*)/,n=/\w+:\/\/[\w-.\/?%&=:@;#]*/g;return e.replace(n,function(e){var n="",r=null;return(r=t.exec(e))&&(e=r[1],n=r[2]),''+e+""+n})},figureOutLineNumbers:function(e){var t,n,r=[],i=this.lines,a=parseInt(this.opts.firstLine||1);for(t=0,n=i.length;n>t;t++)r.push(t+a);return r},wrapLine:function(e,t,n){var r=["line","number"+t,"index"+e,"alt"+(t%2==0?1:2).toString()];return this.linesToHighlight[t]&&r.push("highlighted"),0==t&&r.push("break"),'
'+n+"
"},renderLineNumbers:function(e,t){var r,i,a=this,s=a.opts,o="",l=a.lines.length,u=parseInt(s.firstLine||1),c=s.padLineNumbers;for(1==c?c=(u+l-1).toString().length:1==isNaN(c)&&(c=0),i=0;l>i;i++)r=t?t[i]:u+i,e=0==r?s.space:n(r,c),o+=a.wrapLine(i,r,e);return o},getCodeLinesHtml:function(e,t){for(var n=this,i=n.opts,a=r(e),s=(i.padLineNumbers,parseInt(i.firstLine||1)),o=i.brush,e="",l=0,u=a.length;u>l;l++){var c=a[l],f=/^( |\s)+/.exec(c),g=null,p=t?t[l]:s+l;null!=f&&(g=f[0].toString(),c=c.substr(g.length),g=g.replace(" ",i.space)),0==c.length&&(c=i.space),e+=n.wrapLine(l,p,(null!=g?''+g+"":"")+c)}return e},getTitleHtml:function(e){return e?"
":""},getMatchesHtml:function(e,t){function n(e){var t=e?e.brushName||c:c;return t?t+" ":""}var r,i,a,s,o=this,l=0,u="",c=o.opts.brush||"";for(a=0,s=t.length;s>a;a++)r=t[a],null!==r&&0!==r.length&&(i=n(r),u+=o.wrapLinesWithCode(e.substr(l,r.index-l),i+"plain")+o.wrapLinesWithCode(r.value,i+r.css),l=r.index+r.length+(r.offset||0));return u+=o.wrapLinesWithCode(e.substr(l),n()+"plain")},getHtml:function(){var e,t,n,r=this,i=r.opts,a=r.code,s=r.matches,o=["syntaxhighlighter"];return i.collapse===!0&&o.push("collapsed"),t=i.gutter!==!1,t||o.push("nogutter"),o.push(i.className),o.push(i.brush),t&&(e=r.figureOutLineNumbers(a)),n=r.getMatchesHtml(a,s),n=r.getCodeLinesHtml(n,e),i.autoLinks&&(n=r.processUrls(n)),n='\n
\n
"+e+"
\n '+r.getTitleHtml(i.title)+"\n \n \n "+(t?'":"")+'\n \n \n \n
'+r.renderLineNumbers(a)+"\n
'+n+"
\n
\n \n "}}},function(e,t){"use strict";function n(e){return e.split(/\r?\n/)}function r(e,t){for(var r=n(e),i=0,a=r.length;a>i;i++)r[i]=t(r[i],i);return r.join("\n")}function i(e){return(e||"")+Math.round(1e6*Math.random()).toString()}function a(e,t){var n,r={};for(n in e)r[n]=e[n];for(n in t)r[n]=t[n];return r}function s(e){return e.replace(/^\s+|\s+$/g,"")}function o(e){return Array.prototype.slice.apply(e)}function l(e){var t={"true":!0,"false":!1}[e];return null==t?e:t}e.exports={splitLines:n,eachLine:r,guid:i,merge:a,trim:s,toArray:o,toBoolean:l}},function(e,t,n){"use strict";var r=n(12),i=n(13),a=n(14),s=n(15),o=n(16);e.exports=function(e,t){e=r(e,t),e=i(e,t),e=a(e,t),e=s.unindent(e,t);var n=t["tab-size"];return e=t["smart-tabs"]===!0?o.smart(e,n):o.regular(e,n)}},function(e,t){"use strict";e.exports=function(e,t){return e.replace(/^[ ]*[\n]+|[\n]*[ ]*$/g,"").replace(/\r/g," ")}},function(e,t){"use strict";e.exports=function(e,t){var n=/|<br\s*\/?>/gi;return t.bloggerMode===!0&&(e=e.replace(n,"\n")),e}},function(e,t){"use strict";e.exports=function(e,t){var n=/|<br\s*\/?>/gi;return t.stripBrs===!0&&(e=e.replace(n,"")),e}},function(e,t){"use strict";function n(e){return/^\s*$/.test(e)}e.exports={unindent:function(e){var t,r,i,a,s=e.split(/\r?\n/),o=/^\s*/,l=1e3;for(i=0,a=s.length;a>i&&l>0;i++)if(t=s[i],!n(t)){if(r=o.exec(t),null==r)return e;l=Math.min(r[0].length,l)}if(l>0)for(i=0,a=s.length;a>i;i++)n(s[i])||(s[i]=s[i].substr(l));return s.join("\n")}}},function(e,t){"use strict";function n(e,t,n){return e.substr(0,t)+r.substr(0,n)+e.substr(t+1,e.length)}for(var r="",i=0;50>i;i++)r+=" ";e.exports={smart:function(e,t){var r,i,a,s,o=e.split(/\r?\n/),l=" ";for(a=0,s=o.length;s>a;a++)if(r=o[a],-1!==r.indexOf(l)){for(i=0;-1!==(i=r.indexOf(l));)r=n(r,i,t-i%t);o[a]=r}return o.join("\n")},regular:function(e,t){return e.replace(/\t/g,r.substr(0,t))}}},function(e,t){"use strict";function n(){for(var e=document.getElementsByTagName("script"),t=[],n=0;nl&&null==i;l++)i=o(a[l],t,n);return i}function l(e,t){return o(e,t,!0)}function u(e,t,n,r,i){var a=(screen.width-n)/2,s=(screen.height-r)/2;i+=", left="+a+", top="+s+", width="+n+", height="+r,i=i.replace(/^,/,"");var o=window.open(e,t,i);return o.focus(),o}function c(e){return document.getElementsByTagName(e)}function f(e){var t,n,r=c(e.tagName);if(e.useScriptTags)for(t=c("script"),n=0;ng;g++)f.push(c[g].innerText||c[g].textContent);f=f.join("\r"),f=f.replace(/\u00a0/g," "),u.readOnly=!0,u.appendChild(document.createTextNode(f)),r.appendChild(u),u.focus(),u.select(),s(u,"blur",function(e){u.parentNode.removeChild(u),a(n,"source")})}}e.exports={quickCodeHandler:p,create:g,popup:u,hasClass:r,addClass:i,removeClass:a,attachEvent:s,findElement:o,findParentElement:l,getSyntaxHighlighterScriptTags:n,findElementsToHighlight:f}},function(e,t){"use strict";e.exports={space:" ",useScriptTags:!0,bloggerMode:!1,stripBrs:!1,tagName:"pre"}},function(e,t){"use strict";e.exports={"class-name":"","first-line":1,"pad-line-numbers":!1,highlight:null,title:null,"smart-tabs":!0,"tab-size":4,gutter:!0,"quick-code":!0,collapse:!1,"auto-links":!0,unindent:!0,"html-script":!1}},function(e,t,n){(function(t){"use strict";function r(e,t){function n(e,t){for(var n=0,r=e.length;r>n;n++)e[n].index+=t}function r(e,r){function s(e){u=u.concat(e)}var o,l=e.code,u=[],c=a.regexList,f=e.index+e.left.length,g=a.htmlScript;o=i(l,c),n(o,f),s(o),null!=g.left&&null!=e.left&&(o=i(e.left,[g.left]),n(o,e.index),s(o)),null!=g.right&&null!=e.right&&(o=i(e.right,[g.right]),n(o,e.index+e[0].lastIndexOf(e.right)),s(o));for(var p=0,d=u.length;d>p;p++)u[p].brushName=t.brushName;return u}var a,s=new e;if(null!=t){if(a=new t,null==a.htmlScript)throw new Error("Brush wasn't configured for html-script option: "+t.brushName);s.regexList.push({regex:a.htmlScript.code,func:r}),this.regexList=s.regexList}}var i=n(5).applyRegexList;e.exports=r}).call(t,n(21))},function(e,t){"use strict";function n(){f&&u&&(f=!1,u.length?c=u.concat(c):g=-1,c.length&&r())}function r(){if(!f){var e=s(n);f=!0;for(var t=c.length;t;){for(u=c,c=[];++g1)for(var n=1;n"+e.left.source+")(?.*?)(?"+t.end+")","sgi")}}},{key:"getHtml",value:function(e){var t=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],n=(0,u.applyRegexList)(e,this.regexList),r=new o["default"](e,n,t);return r.getHtml()}}]),e}()},function(e,t,n){"use strict";function r(){var e="break case catch class continue default delete do else enum export extends false for from as function if implements import in instanceof interface let new null package private protected static return super switch this throw true try typeof var while with yield";this.regexList=[{regex:a.multiLineDoubleQuotedString,css:"string"},{regex:a.multiLineSingleQuotedString,css:"string"},{regex:a.singleLineCComments,css:"comments"},{regex:a.multiLineCComments,css:"comments"},{regex:/\s*#.*/gm,css:"preprocessor"},{regex:new RegExp(this.getKeywords(e),"gm"),css:"keyword"}],this.forHtmlScript(a.scriptScriptTags)}var i=n(22),a=n(3).commonRegExp;r.prototype=new i,r.aliases=["js","jscript","javascript","json"],e.exports=r},function(e,t,n){"use strict";function r(){var e="alias and BEGIN begin break case class def define_method defined do each else elsif END end ensure false for if in module new next nil not or raise redo rescue retry return self super then throw true undef unless until when while yield",t="Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ThreadGroup Thread Time TrueClass";this.regexList=[{regex:a.singleLinePerlComments,css:"comments"},{regex:a.doubleQuotedString,css:"string"},{regex:a.singleQuotedString,css:"string"},{regex:/\b[A-Z0-9_]+\b/g,css:"constants"},{regex:/:[a-z][A-Za-z0-9_]*/g,css:"color2"},{regex:/(\$|@@|@)\w+/g,css:"variable bold"},{regex:new RegExp(this.getKeywords(e),"gm"),css:"keyword"},{regex:new RegExp(this.getKeywords(t),"gm"),css:"color1"}],this.forHtmlScript(a.aspScriptTags)}var i=n(22),a=n(3).commonRegExp;r.prototype=new i,r.aliases=["ruby","rails","ror","rb"],e.exports=r},function(e,t,n){"use strict";function r(){function e(e,t){var n=e[0],r=s.exec(n,s("(<|<)[\\s\\/\\?!]*(?[:\\w-\\.]+)","xg")),i=[];if(null!=e.attributes)for(var a,l=0,u=s("(? [\\w:.-]+)\\s*=\\s*(? \".*?\"|'.*?'|\\w+)","xg");null!=(a=s.exec(n,u,l));)i.push(new o(a.name,e.index+a.index,"color1")),i.push(new o(a.value,e.index+a.index+a[0].indexOf(a.value),"string")),l=a.index+a[0].length;return null!=r&&i.push(new o(r.name,e.index+r[0].indexOf(r.name),"keyword")),i}this.regexList=[{regex:s("(\\<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\>|>)","gm"),css:"color2"},{regex:a.xmlComments,css:"comments"},{regex:s("(<|<)[\\s\\/\\?!]*(\\w+)(?.*?)[\\s\\/\\?]*(>|>)","sg"),func:e}]}var i=n(22),a=n(3).commonRegExp,s=n(3).XRegExp,o=n(5).Match;r.prototype=new i,r.aliases=["xml","xhtml","xslt","html","plist"],e.exports=r},function(e,t,n){"use strict";function r(){var e="abs avg case cast coalesce convert count current_timestamp current_user day isnull left lower month nullif replace right session_user space substring sum system_user upper user year",t="absolute action add after alter as asc at authorization begin bigint binary bit by cascade char character check checkpoint close collate column commit committed connect connection constraint contains continue create cube current current_date current_time cursor database date deallocate dec decimal declare default delete desc distinct double drop dynamic else end end-exec escape except exec execute false fetch first float for force foreign forward free from full function global goto grant group grouping having hour ignore index inner insensitive insert instead int integer intersect into is isolation key last level load local max min minute modify move name national nchar next no numeric of off on only open option order out output partial password precision prepare primary prior privileges procedure public read real references relative repeatable restrict return returns revoke rollback rollup rows rule schema scroll second section select sequence serializable set size smallint static statistics table temp temporary then time timestamp to top transaction translation trigger true truncate uncommitted union unique update values varchar varying view when where with work",n="all and any between cross in join like not null or outer some"; + this.regexList=[{regex:/--(.*)$/gm,css:"comments"},{regex:/\/\*([^\*][\s\S]*?)?\*\//gm,css:"comments"},{regex:a.multiLineDoubleQuotedString,css:"string"},{regex:a.multiLineSingleQuotedString,css:"string"},{regex:new RegExp(this.getKeywords(e),"gmi"),css:"color2"},{regex:new RegExp(this.getKeywords(n),"gmi"),css:"color1"},{regex:new RegExp(this.getKeywords(t),"gmi"),css:"keyword"}]}var i=n(22),a=n(3).commonRegExp;r.prototype=new i,r.aliases=["sql"],e.exports=r},function(e,t,n){"use strict";function r(){this.regexList=[]}var i=n(22);n(3).commonRegExp;r.prototype=new i,r.aliases=["text","plain"],e.exports=r},function(e,t,n){"use strict";"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(t,n){e.exports=n()}("domready",function(){var e,t=[],n=document,r=n.documentElement.doScroll,i="DOMContentLoaded",a=(r?/^loaded|^c/:/^loaded|^i|^c/).test(n.readyState);return a||n.addEventListener(i,e=function(){for(n.removeEventListener(i,e),a=1;e=t.shift();)e()}),function(e){a?setTimeout(e,0):t.push(e)}})},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=t.string=function(e){return e.replace(/^([A-Z])/g,function(e,t){return t.toLowerCase()}).replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()})};t.object=function(e){var t={};return Object.keys(e).forEach(function(r){return t[n(r)]=e[r]}),t}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}var i=n(1),a=r(i);window.SyntaxHighlighter=a["default"],"undefined"==typeof window.XRegExp&&(window.XRegExp=n(3).XRegExp)}]); diff --git a/layout.html b/layout.html new file mode 100644 index 0000000..a0c25b9 --- /dev/null +++ b/layout.html @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + + + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/layouts_and_rendering.html b/layouts_and_rendering.html new file mode 100644 index 0000000..6841726 --- /dev/null +++ b/layouts_and_rendering.html @@ -0,0 +1,1590 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Rails 布局和视图渲染

本文介绍 Action Controller 和 Action View 的基本布局功能。

读完本文后,您将学到:

+
    +
  • 如何使用 Rails 内置的各种渲染方法;

  • +
  • 如果创建具有多个内容区域的布局;

  • +
  • 如何使用局部视图去除重复;

  • +
  • 如何使用嵌套布局(子模板)。

  • +
+

1 概览:各组件之间如何协作

本文关注 MVC 架构中控制器和视图之间的交互。你可能已经知道,控制器在 Rails 中负责协调处理请求的整个过程,它经常把繁重的操作交给模型去做。返回响应时,控制器把一些操作交给视图——这正是本文的话题。

总的来说,这个过程涉及到响应中要发送什么内容,以及调用哪个方法创建响应。如果响应是个完整的视图,Rails 还要做些额外工作,把视图套入布局,有时还要渲染局部视图。后文会详细讲解整个过程。

2 创建响应

从控制器的角度来看,创建 HTTP 响应有三种方法:

+
    +
  • 调用 render 方法,向浏览器发送一个完整的响应;

  • +
  • 调用 redirect_to 方法,向浏览器发送一个 HTTP 重定向状态码;

  • +
  • 调用 head 方法,向浏览器发送只含 HTTP 首部的响应;

  • +
+

2.1 默认的渲染行为

你可能已经听说过 Rails 的开发原则之一是“多约定,少配置”。默认的渲染行为就是这一原则的完美体现。默认情况下,Rails 中的控制器渲染路由名对应的视图。假如 BooksController 类中有下述代码:

+
+class BooksController < ApplicationController
+end
+
+
+
+

在路由文件中有如下代码:

+
+resources :books
+
+
+
+

而且有个名为 app/views/books/index.html.erb 的视图文件:

+
+<h1>Books are coming soon!</h1>
+
+
+
+

那么,访问 /books 时,Rails 会自动渲染视图 app/views/books/index.html.erb,网页中会看到显示有“Books are coming soon!”。

然而,网页中显示这些文字没什么用,所以后续你可能会创建一个 Book 模型,然后在 BooksController 中添加 index 动作:

+
+class BooksController < ApplicationController
+  def index
+    @books = Book.all
+  end
+end
+
+
+
+

注意,基于“多约定,少配置”原则,在 index 动作末尾并没有指定要渲染视图,Rails 会自动在控制器的视图文件夹中寻找 action_name.html.erb 模板,然后渲染。这里,Rails 渲染的是 app/views/books/index.html.erb 文件。

如果要在视图中显示书籍的属性,可以使用 ERB 模板,如下所示:

+
+<h1>Listing Books</h1>
+
+
+
+<br>
+
+<%= link_to "New book", new_book_path %>
+
+
+
+

真正处理渲染过程的是 ActionView::TemplateHandlers 的子类。本文不做深入说明,但要知道,文件的扩展名决定了要使用哪个模板处理程序。从 Rails 2 开始,ERB 模板(含有嵌入式 Ruby 代码的 HTML)的标准扩展名是 .erb,Builder 模板(XML 生成器)的标准扩展名是 .builder

2.2 使用 render 方法

多数情况下,ActionController::Base#render 方法都能担起重则,负责渲染应用的内容,供浏览器使用。render 方法的行为有多种定制方式,可以渲染 Rails 模板的默认视图、指定的模板、文件、行间代码或者什么也不渲染。渲染的内容可以是文本、JSON 或 XML。而且还可以设置响应的内容类型和 HTTP 状态码。

如果不想使用浏览器而直接查看调用 render 方法得到的结果,可以调用 render_to_string 方法。它与 render 的用法完全一样,但是不会把响应发给浏览器,而是直接返回一个字符串。

2.2.1 渲染动作的视图

如果想渲染同个控制器中的其他模板,可以把视图的名字传给 render 方法:

+
+def update
+  @book = Book.find(params[:id])
+  if @book.update(book_params)
+    redirect_to(@book)
+  else
+    render "edit"
+  end
+end
+
+
+
+

如果调用 update 失败,update 动作会渲染同个控制器中的 edit.html.erb 模板。

如果不想用字符串,还可使用符号指定要渲染的动作:

+
+def update
+  @book = Book.find(params[:id])
+  if @book.update(book_params)
+    redirect_to(@book)
+  else
+    render :edit
+  end
+end
+
+
+
+
2.2.2 渲染其他控制器中某个动作的模板

如果想渲染其他控制器中的模板该怎么做呢?还是使用 render 方法,指定模板的完整路径(相对于 app/views)即可。例如,如果控制器 AdminProductsControllerapp/controllers/admin 文件夹中,可使用下面的方式渲染 app/views/products 文件夹中的模板:

+
+render "products/show"
+
+
+
+

因为参数中有条斜线,所以 Rails 知道这个视图属于另一个控制器。如果想让代码的意图更明显,可以使用 :template 选项(Rails 2.2 及之前的版本必须这么做):

+
+render template: "products/show"
+
+
+
+
2.2.3 渲染任意文件

render 方法还可渲染应用之外的视图:

+
+render file: "/u/apps/warehouse_app/current/app/views/products/show"
+
+
+
+

:file 选项的值是绝对文件系统路径。当然,你要对使用的文件拥有相应权限。

如果 :file 选项的值来自用户输入,可能导致安全问题,因为攻击者可以利用这一点访问文件系统中的机密文件。

+
+

默认情况下,使用当前布局渲染文件。

+
+

如果在 Microsoft Windows 中运行 Rails,必须使用 :file 选项指定文件的路径,因为 Windows 中的文件名和 Unix 格式不一样。

2.2.4 小结

上述三种渲染方式(渲染同一个控制器中的另一个模板,选择另一个控制器中的模板,以及渲染文件系统中的任意文件)的作用其实是一样的。

BooksController 控制器的 update 动作中,如果更新失败后想渲染 views/books 文件夹中的 edit.html.erb 模板,下面这些做法都能达到这个目的:

+
+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"
+
+
+
+

你可以根据自己的喜好决定使用哪种方式,总的原则是,使用符合代码意图的最简单方式。

2.2.5 使用 render 方法的 :inline 选项

如果通过 :inline 选项提供 ERB 代码,render 方法就不会渲染视图。下述写法完全有效:

+
+render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>"
+
+
+
+

但是很少使用这个选项。在控制器中混用 ERB 代码违反了 MVC 架构原则,也让应用的其他开发者难以理解应用的逻辑思路。请使用单独的 ERB 视图。

默认情况下,行间渲染使用 ERB。你可以使用 :type 选项指定使用 Builder:

+
+render inline: "xml.p {'Horrid coding practice!'}", type: :builder
+
+
+
+
2.2.6 渲染文本

调用 render 方法时指定 :plain 选项,可以把没有标记语言的纯文本发给浏览器:

+
+render plain: "OK"
+
+
+
+

渲染纯文本主要用于响应 Ajax 或无需使用 HTML 的网络服务。

默认情况下,使用 :plain 选项渲染纯文本时不会套用应用的布局。如果想使用布局,要指定 layout: true 选项。此时,使用扩展名为 .txt.erb 的布局文件。

2.2.7 渲染 HTML

调用 render 方法时指定 :html 选项,可以把 HTML 字符串发给浏览器:

+
+render html: "<strong>Not Found</strong>".html_safe
+
+
+
+

这种方式可用于渲染 HTML 片段。如果标记很复杂,就要考虑使用模板文件了。

使用 html: 选项时,如果没调用 html_safe 方法把 HTML 字符串标记为安全的,HTML 实体会转义。

2.2.8 渲染 JSON

JSON 是一种 JavaScript 数据格式,很多 Ajax 库都用这种格式。Rails 内建支持把对象转换成 JSON,经渲染后再发送给浏览器。

+
+render json: @product
+
+
+
+

在需要渲染的对象上无需调用 to_json 方法。如果有 :json 选项,render 方法会自动调用 to_json

2.2.9 渲染 XML

Rails 也内建支持把对象转换成 XML,经渲染后再发给调用方:

+
+render xml: @product
+
+
+
+

在需要渲染的对象上无需调用 to_xml 方法。如果有 :xml 选项,render 方法会自动调用 to_xml

2.2.10 渲染普通的 JavaScript

Rails 能渲染普通的 JavaScript:

+
+render js: "alert('Hello Rails');"
+
+
+
+

此时,发给浏览器的字符串,其 MIME 类型为 text/javascript

2.2.11 渲染原始的主体

调用 render 方法时使用 :body 选项,可以不设置内容类型,把原始的内容发送给浏览器:

+
+render body: "raw"
+
+
+
+

只有不在意内容类型时才应该使用这个选项。多数时候,使用 :plain:html 选项更合适。

如果没有修改,这种方式返回的内容类型是 text/html,因为这是 Action Dispatch 响应默认使用的内容类型。

2.2.12 render 方法的选项

render 方法一般可接受五个选项:

+
    +
  • :content_type

  • +
  • :layout

  • +
  • :location

  • +
  • :status

  • +
  • :formats

  • +
+
2.2.12.1 :content_type 选项

默认情况下,Rails 渲染得到的结果内容类型为 text/html(如果使用 :json 选项,内容类型为 application/json;如果使用 :xml 选项,内容类型为 application/xml)。如果需要修改内容类型,可使用 :content_type 选项:

+
+render file: filename, content_type: "application/rss"
+
+
+
+
2.2.12.2 :layout 选项

render 方法的大多数选项渲染得到的结果都会作为当前布局的一部分显示。后文会详细介绍布局。

:layout 选项告诉 Rails,在当前动作中使用指定的文件作为布局:

+
+render layout: "special_layout"
+
+
+
+

也可以告诉 Rails 根本不使用布局:

+
+render layout: false
+
+
+
+
2.2.12.3 :location 选项

:location 选项用于设置 HTTP Location 首部:

+
+render xml: photo, location: photo_url(http://github.com/photo)
+
+
+
+
2.2.12.4 :status 选项

Rails 会自动为生成的响应附加正确的 HTTP 状态码(大多数情况下是 200 OK)。使用 :status 选项可以修改状态码:

+
+render status: 500
+render status: :forbidden
+
+
+
+

Rails 能理解数字状态码和对应的符号,如下所示:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
响应类别HTTP 状态码符号
信息100:continue
101:switching_protocols
102:processing
成功200:ok
201:created
202:accepted
203:non_authoritative_information
204:no_content
205:reset_content
206:partial_content
207:multi_status
208:already_reported
226:im_used
重定向300:multiple_choices
301:moved_permanently
302:found
303:see_other
304:not_modified
305:use_proxy
307:temporary_redirect
308:permanent_redirect
客户端错误400:bad_request
401:unauthorized
402:payment_required
403:forbidden
404:not_found
405:method_not_allowed
406:not_acceptable
407:proxy_authentication_required
408:request_timeout
409:conflict
410:gone
411:length_required
412:precondition_failed
413:payload_too_large
414:uri_too_long
415:unsupported_media_type
416:range_not_satisfiable
417:expectation_failed
422:unprocessable_entity
423:locked
424:failed_dependency
426:upgrade_required
428:precondition_required
429:too_many_requests
431:request_header_fields_too_large
服务器错误500:internal_server_error
501:not_implemented
502:bad_gateway
503:service_unavailable
504:gateway_timeout
505:http_version_not_supported
506:variant_also_negotiates
507:insufficient_storage
508:loop_detected
510:not_extended
511:network_authentication_required
+

如果渲染内容时指定了与内容无关的状态码(100-199、204、205 或 304),响应会弃之不用。

2.2.12.5 :formats 选项

Rails 使用请求中指定的格式(或者使用默认的 :html)。如果想改变格式,可以指定 :formats 选项。它的值是一个符号或一个数组。

+
+render formats: :xml
+render formats: [:json, :xml]
+
+
+
+
2.2.13 查找布局

查找布局时,Rails 首先查看 app/views/layouts 文件夹中是否有和控制器同名的文件。例如,渲染 PhotosController 中的动作会使用 app/views/layouts/photos.html.erb(或 app/views/layouts/photos.builder)。如果没找到针对控制器的布局,Rails 会使用 app/views/layouts/application.html.erbapp/views/layouts/application.builder。如果没有 .erb 布局,Rails 会使用 .builder 布局(如果文件存在)。Rails 还提供了多种方法用来指定单个控制器和动作使用的布局。

2.2.13.1 指定控制器所用的布局

在控制器中使用 layout 声明,可以覆盖默认使用的布局约定。例如:

+
+class ProductsController < ApplicationController
+  layout "inventory"
+  #...
+end
+
+
+
+

这么声明之后,ProductsController 渲染的所有视图都将使用 app/views/layouts/inventory.html.erb 文件作为布局。

要想指定整个应用使用的布局,可以在 ApplicationController 类中使用 layout 声明:

+
+class ApplicationController < ActionController::Base
+  layout "main"
+  #...
+end
+
+
+
+

这么声明之后,整个应用的视图都会使用 app/views/layouts/main.html.erb 文件作为布局。

2.2.13.2 在运行时选择布局

可以使用一个符号把布局延后到处理请求时再选择:

+
+class ProductsController < ApplicationController
+  layout :products_layout
+
+  def show
+    @product = Product.find(params[:id])
+  end
+
+  private
+    def products_layout
+      @current_user.special? ? "special" : "products"
+    end
+
+end
+
+
+
+

现在,如果当前用户是特殊用户,会使用一个特殊布局渲染产品视图。

还可使用行间方法,例如 Proc,决定使用哪个布局。如果使用 Proc,其代码块可以访问 controller 实例,这样就能根据当前请求决定使用哪个布局:

+
+class ProductsController < ApplicationController
+  layout Proc.new { |controller| controller.request.xhr? ? "popup" : "application" }
+end
+
+
+
+
2.2.13.3 根据条件设定布局

在控制器中指定布局时可以使用 :only:except 选项。这两个选项的值可以是一个方法名或者一个方法名数组,对应于控制器中的动作:

+
+class ProductsController < ApplicationController
+  layout "product", except: [:index, :rss]
+end
+
+
+
+

这么声明后,除了 rssindex 动作之外,其他动作都使用 product 布局渲染视图。

2.2.13.4 布局继承

布局声明按层级顺序向下顺延,专用布局比通用布局优先级高。例如:

+
    +
  • +

    application_controller.rb

    +
    +
    +class ApplicationController < ActionController::Base
    +  layout "main"
    +end
    +
    +
    +
    +
  • +
  • +

    articles_controller.rb

    +
    +
    +class ArticlesController < ApplicationController
    +end
    +
    +
    +
    +
  • +
  • +

    special_articles_controller.rb

    +
    +
    +class SpecialArticlesController < ArticlesController
    +  layout "special"
    +end
    +
    +
    +
    +
  • +
  • +

    old_articles_controller.rb

    +
    +
    +class OldArticlesController < SpecialArticlesController
    +  layout false
    +
    +  def show
    +    @article = Article.find(params[:id])
    +  end
    +
    +  def index
    +    @old_articles = Article.older
    +    render layout: "old"
    +  end
    +  # ...
    +end
    +
    +
    +
    +
  • +
+

在这个应用中:

+
    +
  • 一般情况下,视图使用 main 布局渲染;

  • +
  • ArticlesController#index 使用 main 布局;

  • +
  • SpecialArticlesController#index 使用 special 布局;

  • +
  • OldArticlesController#show 不用布局;

  • +
  • OldArticlesController#index 使用 old 布局;

  • +
+
2.2.13.5 模板继承

与布局的继承逻辑一样,如果在约定的路径上找不到模板或局部视图,控制器会在继承链中查找模板或局部视图。例如:

+
+# in app/controllers/application_controller
+class ApplicationController < ActionController::Base
+end
+
+# in app/controllers/admin_controller
+class AdminController < ApplicationController
+end
+
+# in app/controllers/admin/products_controller
+class Admin::ProductsController < AdminController
+  def index
+  end
+end
+
+
+
+

admin/products#index 动作的查找顺序为:

+
    +
  • app/views/admin/products/

  • +
  • app/views/admin/

  • +
  • app/views/application/

  • +
+

因此,app/views/application/ 最适合放置共用的局部视图,在 ERB 中可以像下面这样渲染:

+
+<%# app/views/admin/products/index.html.erb %>
+<%= render @products || "empty_list" %>
+
+<%# app/views/application/_empty_list.html.erb %>
+There are no items in this list <em>yet</em>.
+
+
+
+
2.2.14 避免双重渲染错误

多数 Rails 开发者迟早都会看到这个错误消息:Can only render or redirect once per action(一个动作只能渲染或重定向一次)。这个提示很烦人,也很容易修正。出现这个错误的原因是,没有理解 render 的工作原理。

例如,下面的代码会导致这个错误:

+
+def show
+  @book = Book.find(params[:id])
+  if @book.special?
+    render action: "special_show"
+  end
+  render action: "regular_show"
+end
+
+
+
+

如果 @book.special? 的求值结果是 true,Rails 开始渲染,把 @book 变量导入 special_show 视图中。但是,show 动作并不会就此停止运行,当 Rails 运行到动作的末尾时,会渲染 regular_show 视图,从而导致这个错误。解决的办法很简单,确保在一次代码运行路径中只调用一次 renderredirect_to 方法。有一个语句可以帮助解决这个问题,那就是 and return。下面的代码对上述代码做了修改:

+
+def show
+  @book = Book.find(params[:id])
+  if @book.special?
+    render action: "special_show" and return
+  end
+  render action: "regular_show"
+end
+
+
+
+

千万别用 && return 代替 and return,因为 Ruby 语言运算符优先级的关系,&& return 根本不起作用。

注意,ActionController 能检测到是否显式调用了 render 方法,所以下面这段代码不会出错:

+
+def show
+  @book = Book.find(params[:id])
+  if @book.special?
+    render action: "special_show"
+  end
+end
+
+
+
+

如果 @book.special? 的结果是 true,会渲染 special_show 视图,否则就渲染默认的 show 模板。

2.3 使用 redirect_to 方法

响应 HTTP 请求的另一种方法是使用 redirect_to。如前所述,render 告诉 Rails 构建响应时使用哪个视图(或其他静态资源)。redirect_to 做的事情则完全不同,它告诉浏览器向另一个 URL 发起新请求。例如,在应用中的任何地方使用下面的代码都可以重定向到 photos 控制器的 index 动作:

+
+redirect_to photos_url
+
+
+
+

你可以使用 redirect_back 把用户带回他们之前所在的页面。前一个页面的地址从 HTTP_REFERER 首部中获取,浏览器不一定会设定,因此必须提供 fallback_location

+
+redirect_back(fallback_location: root_path)
+
+
+
+
2.3.1 设置不同的重定向状态码

调用 redirect_to 方法时,Rails 把 HTTP 状态码设为 302,即临时重定向。如果想使用其他状态码,例如 301(永久重定向),可以设置 :status 选项:

+
+redirect_to photos_path, status: 301
+
+
+
+

render 方法的 :status 选项一样,redirect_to 方法的 :status 选项同样可使用数字状态码或符号。

2.3.2 renderredirect_to 的区别

有些经验不足的开发者会认为 redirect_to 方法是一种 goto 命令,把代码从一处转到别处。这么理解是不对的。执行到 redirect_to 方法时,代码会停止运行,等待浏览器发起新请求。你需要告诉浏览器下一个请求是什么,并返回 302 状态码。

下面通过实例说明。

+
+def index
+  @books = Book.all
+end
+
+def show
+  @book = Book.find_by(id: params[:id])
+  if @book.nil?
+    render action: "index"
+  end
+end
+
+
+
+

在这段代码中,如果 @book 变量的值为 nil,很可能会出问题。记住,render :action 不会执行目标动作中的任何代码,因此不会创建 index 视图所需的 @books 变量。修正方法之一是不渲染,而是重定向:

+
+def index
+  @books = Book.all
+end
+
+def show
+  @book = Book.find_by(id: params[:id])
+  if @book.nil?
+    redirect_to action: :index
+  end
+end
+
+
+
+

这样修改之后,浏览器会向 index 页面发起新请求,执行 index 方法中的代码,因此一切都能正常运行。

这种方法唯有一个缺点:增加了浏览器的工作量。浏览器通过 /books/1show 动作发起请求,控制器做了查询,但没有找到对应的图书,所以返回 302 重定向响应,告诉浏览器访问 /books/。浏览器收到指令后,向控制器的 index 动作发起新请求,控制器从数据库中取出所有图书,渲染 index 模板,将其返回给浏览器,在屏幕上显示所有图书。

在小型应用中,额外增加的时间不是个问题。如果响应时间很重要,这个问题就值得关注了。下面举个虚拟的例子演示如何解决这个问题:

+
+def index
+  @books = Book.all
+end
+
+def show
+  @book = Book.find_by(id: params[:id])
+  if @book.nil?
+    @books = Book.all
+    flash.now[:alert] = "Your book was not found"
+    render "index"
+  end
+end
+
+
+
+

在这段代码中,如果指定 ID 的图书不存在,会从模型中取出所有图书,赋值给 @books 实例变量,然后直接渲染 index.html.erb 模板,并显示一个闪现消息,告知用户出了什么问题。

2.4 使用 head 构建只有首部的响应

head 方法只把首部发送给浏览器,它的参数是 HTTP 状态码数字或符号形式(参见前面的表格),选项是一个散列,指定首部的名称和对应的值。例如,可以只返回一个错误首部:

+
+head :bad_request
+
+
+
+

生成的首部如下:

+
+HTTP/1.1 400 Bad Request
+Connection: close
+Date: Sun, 24 Jan 2010 12:15:53 GMT
+Transfer-Encoding: chunked
+Content-Type: text/html; charset=utf-8
+X-Runtime: 0.013483
+Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
+Cache-Control: no-cache
+
+
+
+

也可以使用其他 HTTP 首部提供额外信息:

+
+head :created, location: photo_path(@photo)
+
+
+
+

生成的首部如下:

+
+HTTP/1.1 201 Created
+Connection: close
+Date: Sun, 24 Jan 2010 12:16:44 GMT
+Transfer-Encoding: chunked
+Location: /photos/1
+Content-Type: text/html; charset=utf-8
+X-Runtime: 0.083496
+Set-Cookie: _blog_session=...snip...; path=/; HttpOnly
+Cache-Control: no-cache
+
+
+
+

3 布局的结构

Rails 渲染响应的视图时,会把视图和当前模板结合起来。查找当前模板的方法前文已经介绍过。在布局中可以使用三种工具把各部分合在一起组成完整的响应:

+
    +
  • 静态资源标签

  • +
  • yieldcontent_for

  • +
  • 局部视图

  • +
+

3.1 静态资源标签辅助方法

静态资源辅助方法用于生成链接到订阅源、JavaScript、样式表、图像、视频和音频的 HTML 代码。Rails 提供了六个静态资源标签辅助方法:

+
    +
  • auto_discovery_link_tag

  • +
  • javascript_include_tag

  • +
  • stylesheet_link_tag

  • +
  • image_tag

  • +
  • video_tag

  • +
  • audio_tag

  • +
+

这六个辅助方法可以在布局或视图中使用,不过 auto_discovery_link_tagjavascript_include_tagstylesheet_link_tag 最常出现在布局的 <head> 元素中。

静态资源标签辅助方法不会检查指定位置是否存在静态资源,而是假定你知道自己在做什么,它只负责生成对相应的链接。

auto_discovery_link_tag 辅助方法生成的 HTML,多数浏览器和订阅源阅读器都能从中自动识别 RSS 或 Atom 订阅源。这个方法的参数包括链接的类型(:rss:atom)、传递给 url_for 的散列选项,以及该标签使用的散列选项:

+
+<%= auto_discovery_link_tag(:rss, {action: "feed"},
+  {title: "RSS Feed"}) %>
+
+
+
+

auto_discovery_link_tag 的标签选项有三个:

+
    +
  • :rel:指定链接中 rel 属性的值,默认值为 "alternate"

  • +
  • :type:指定 MIME 类型,不过 Rails 会自动生成正确的 MIME 类型;

  • +
  • :title:指定链接的标题,默认值是 :type 参数值的全大写形式,例如 "ATOM""RSS"

  • +
+
3.1.2 使用 javascript_include_tag 链接 JavaScript 文件

javascript_include_tag 辅助方法为指定的各个资源生成 HTML script 标签。

如果启用了 Asset Pipeline,这个辅助方法生成的链接指向 /assets/javascripts/ 而不是 Rails 旧版中使用的 public/javascripts。链接的地址由 Asset Pipeline 伺服。

Rails 应用或 Rails 引擎中的 JavaScript 文件可存放在三个位置:app/assetslib/assetsvendor/assets。详细说明参见 Asset Organization section in the Asset Pipeline Guide

文件的地址可使用相对文档根目录的完整路径或 URL。例如,如果想链接到 app/assetslib/assetsvendor/assets 文件夹中名为 javascripts 的子文件夹中的文件,可以这么做:

+
+<%= javascript_include_tag "main" %>
+
+
+
+

Rails 生成的 script 标签如下:

+
+<script src='http://github.com/assets/main.js'></script>
+
+
+
+

对这个静态资源的请求由 Sprockets gem 伺服。

若想同时引入多个文件,例如 app/assets/javascripts/main.jsapp/assets/javascripts/columns.js,可以这么做:

+
+<%= javascript_include_tag "main", "columns" %>
+
+
+
+

引入 app/assets/javascripts/main.jsapp/assets/javascripts/photos/columns.js 的方式如下:

+
+<%= javascript_include_tag "main", "/photos/columns" %>
+
+
+
+

引入 http://example.com/main.js 的方式如下:

+
+<%= javascript_include_tag "http://example.com/main.js" %>
+
+
+
+

stylesheet_link_tag 辅助方法为指定的各个资源生成 HTML <link> 标签。

如果启用了 Asset Pipeline,这个辅助方法生成的链接指向 /assets/stylesheets/,由 Sprockets gem 伺服。样式表文件可以存放在三个位置:app/assetslib/assetsvendor/assets

文件的地址可使用相对文档根目录的完整路径或 URL。例如,如果想链接到 app/assetslib/assetsvendor/assets 文件夹中名为 stylesheets 的子文件夹中的文件,可以这么做:

+
+<%= stylesheet_link_tag "main" %>
+
+
+
+

引入 app/assets/stylesheets/main.cssapp/assets/stylesheets/columns.css 的方式如下:

+
+<%= stylesheet_link_tag "main", "columns" %>
+
+
+
+

引入 app/assets/stylesheets/main.cssapp/assets/stylesheets/photos/columns.css 的方式如下:

+
+<%= stylesheet_link_tag "main", "photos/columns" %>
+
+
+
+

引入 http://example.com/main.css 的方式如下:

+
+<%= stylesheet_link_tag "http://example.com/main.css" %>
+
+
+
+

默认情况下,stylesheet_link_tag 创建的链接属性为 media="screen" rel="stylesheet"。指定相应的选项(:media:rel)可以覆盖默认值:

+
+<%= stylesheet_link_tag "main_print", media: "print" %>
+
+
+
+
3.1.4 使用 image_tag 链接图像

image_tag 辅助方法为指定的文件生成 HTML <img /> 标签。默认情况下,从 public/images 文件夹中加载文件。

注意,必须指定图像的扩展名。

+
+<%= image_tag "header.png" %>
+
+
+
+

还可以指定图像的路径:

+
+<%= image_tag "icons/delete.gif" %>
+
+
+
+

可以使用散列指定额外的 HTML 属性:

+
+<%= image_tag "icons/delete.gif", {height: 45} %>
+
+
+
+

可以指定一个替代文本,在关闭图像的浏览器中显示。如果没指定替代文本,Rails 会使用图像的文件名,去掉扩展名,并把首字母变成大写。例如,下面两个标签会生成相同的代码:

+
+<%= image_tag "home.gif" %>
+<%= image_tag "home.gif", alt: "Home" %>
+
+
+
+

还可指定图像的尺寸,格式为“{width}x{height}”:

+
+<%= image_tag "home.gif", size: "50x20" %>
+
+
+
+

除了上述特殊的选项外,还可在最后一个参数中指定标准的 HTML 属性,例如 :class:id:name

+
+<%= image_tag "home.gif", alt: "Go Home",
+                          id: "HomeImage",
+                          class: "nav_bar" %>
+
+
+
+
3.1.5 使用 video_tag 链接视频

video_tag 辅助方法为指定的文件生成 HTML5 <video> 标签。默认情况下,从 public/videos 文件夹中加载视频文件。

+
+<%= video_tag "movie.ogg" %>
+
+
+
+

生成的 HTML 如下:

+
+<video src="http://github.com/videos/movie.ogg" />
+
+
+
+

image_tag 类似,视频的地址可以使用绝对路径,或者相对 public/videos 文件夹的路径。而且也可以指定 size: "{width}x{height}" 选项。在 video_tag 的末尾还可指定其他 HTML 属性,例如 idclass 等。

video_tag 方法还可使用散列指定 <video> 标签的所有属性,包括:

+
    +
  • poster: "image_name.png":指定视频播放前在视频的位置显示的图片;

  • +
  • autoplay: true:页面加载后开始播放视频;

  • +
  • loop: true:视频播完后再次播放;

  • +
  • controls: true:为用户显示浏览器提供的控件,用于和视频交互;

  • +
  • autobuffer: true:页面加载时预先加载视频文件;

  • +
+

把数组传递给 video_tag 方法可以指定多个视频:

+
+<%= video_tag ["trailer.ogg", "movie.ogg"] %>
+
+
+
+

生成的 HTML 如下:

+
+<video>
+  <source src="http://github.com/trailer.ogg" />
+  <source src="http://github.com/movie.ogg" />
+</video>
+
+
+
+
3.1.6 使用 audio_tag 链接音频

audio_tag 辅助方法为指定的文件生成 HTML5 <audio> 标签。默认情况下,从 public/audio 文件夹中加载音频文件。

+
+<%= audio_tag "music.mp3" %>
+
+
+
+

还可指定音频文件的路径:

+
+<%= audio_tag "music/first_song.mp3" %>
+
+
+
+

还可使用散列指定其他属性,例如 :id:class 等。

video_tag 类似,audio_tag 也有特殊的选项:

+
    +
  • autoplay: true:页面加载后开始播放音频;

  • +
  • controls: true:为用户显示浏览器提供的控件,用于和音频交互;

  • +
  • autobuffer: true:页面加载时预先加载音频文件;

  • +
+

3.2 理解 yield +

在布局中,yield 标明一个区域,渲染的视图会插入这里。最简单的情况是只有一个 yield,此时渲染的整个视图都会插入这个区域:

+
+<html>
+  <head>
+  </head>
+  <body>
+  <%= yield %>
+  </body>
+</html>
+
+
+
+

布局中可以标明多个区域:

+
+<html>
+  <head>
+  <%= yield :head %>
+  </head>
+  <body>
+  <%= yield %>
+  </body>
+</html>
+
+
+
+

视图的主体会插入未命名的 yield 区域。若想在具名 yield 区域插入内容,要使用 content_for 方法。

3.3 使用 content_for 方法

content_for 方法在布局的具名 yield 区域插入内容。例如,下面的视图会在前一节的布局中插入内容:

+
+<% content_for :head do %>
+  <title>A simple page</title>
+<% end %>
+
+<p>Hello, Rails!</p>
+
+
+
+

套入布局后生成的 HTML 如下:

+
+<html>
+  <head>
+  <title>A simple page</title>
+  </head>
+  <body>
+  <p>Hello, Rails!</p>
+  </body>
+</html>
+
+
+
+

如果布局中不同的区域需要不同的内容,例如侧边栏和页脚,就可以使用 content_for 方法。content_for 方法还可以在通用布局中引入特定页面使用的 JavaScript 或 CSS 文件。

3.4 使用局部视图

局部视图把渲染过程分为多个管理方便的片段,把响应的某个特殊部分移入单独的文件。

3.4.1 具名局部视图

在视图中渲染局部视图可以使用 render 方法:

+
+<%= render "menu" %>
+
+
+
+

渲染这个视图时,会渲染名为 _menu.html.erb 的文件。注意文件名开头有个下划线。局部视图的文件名以下划线开头,以便和普通视图区分开,不过引用时无需加入下划线。即便从其他文件夹中引入局部视图,规则也是一样:

+
+<%= render "shared/menu" %>
+
+
+
+

这行代码会引入 app/views/shared/_menu.html.erb 这个局部视图。

3.4.2 使用局部视图简化视图

局部视图的一种用法是作为子程序(subroutine),把细节提取出来,以便更好地理解整个视图的作用。例如,有如下的视图:

+
+<%= render "shared/ad_banner" %>
+
+<h1>Products</h1>
+
+<p>Here are a few of our fine products:</p>
+...
+
+<%= render "shared/footer" %>
+
+
+
+

这里,局部视图 _ad_banner.html.erb_footer.html.erb 可以包含应用多个页面共用的内容。在编写某个页面的视图时,无需关心这些局部视图中的详细内容。

如前几节所述,yield 是保持布局简洁的利器。要知道,那是纯 Ruby,几乎可以在任何地方使用。例如,可以使用它去除相似资源的表单布局定义:

+
    +
  • +

    users/index.html.erb

    +
    +
    +<%= render "shared/search_filters", search: @q do |f| %>
    +  <p>
    +    Name contains: <%= f.text_field :name_contains %>
    +  </p>
    +<% end %>
    +
    +
    +
    +
  • +
  • +

    roles/index.html.erb

    +
    +
    +<%= render "shared/search_filters", search: @q do |f| %>
    +  <p>
    +    Title contains: <%= f.text_field :title_contains %>
    +  </p>
    +<% end %>
    +
    +
    +
    +
  • +
  • +

    shared/_search_filters.html.erb

    +
    +
    +<%= form_for(@q) do |f| %>
    +  <h1>Search form:</h1>
    +  <fieldset>
    +    <%= yield f %>
    +  </fieldset>
    +  <p>
    +    <%= f.submit "Search" %>
    +  </p>
    +<% end %>
    +
    +
    +
    +
  • +
+

应用所有页面共用的内容,可以直接在布局中使用局部视图渲染。

3.4.3 局部布局

与视图可以使用布局一样,局部视图也可使用自己的布局文件。例如,可以这样调用局部视图:

+
+<%= render partial: "link_area", layout: "graybar" %>
+
+
+
+

这行代码会使用 _graybar.html.erb 布局渲染局部视图 _link_area.html.erb。注意,局部布局的名称也以下划线开头,而且与局部视图保存在同一个文件夹中(不在 layouts 文件夹中)。

还要注意,指定其他选项时,例如 :layout,必须明确地使用 :partial 选项。

3.4.4 传递局部变量

局部变量可以传入局部视图,这么做可以把局部视图变得更强大、更灵活。例如,可以使用这种方法去除新建和编辑页面的重复代码,但仍然保有不同的内容:

+
    +
  • +

    new.html.erb

    +
    +
    +<h1>New zone</h1>
    +<%= render partial: "form", locals: {zone: @zone} %>
    +
    +
    +
    +
  • +
  • +

    edit.html.erb

    +
    +
    +<h1>Editing zone</h1>
    +<%= render partial: "form", locals: {zone: @zone} %>
    +
    +
    +
    +
  • +
  • +

    _form.html.erb

    +
    +
    +<%= form_for(zone) do |f| %>
    +  <p>
    +    <b>Zone name</b><br>
    +    <%= f.text_field :name %>
    +  </p>
    +  <p>
    +    <%= f.submit %>
    +  </p>
    +<% end %>
    +
    +
    +
    +
  • +
+

虽然两个视图使用同一个局部视图,但 Action View 的 submit 辅助方法为 new 动作生成的提交按钮名为“Create Zone”,而为 edit 动作生成的提交按钮名为“Update Zone”。

把局部变量传入局部视图的方式是使用 local_assigns

+
    +
  • +

    index.html.erb

    +
    +
    +<%= render user.articles %>
    +
    +
    +
    +
  • +
  • +

    show.html.erb

    +
    +
    +<%= render article, full: true %>
    +
    +
    +
    +
  • +
  • +

    _articles.html.erb

    +
    +
    +<h2><%= article.title %></h2>
    +
    +<% if local_assigns[:full] %>
    +  <%= simple_format article.body %>
    +<% else %>
    +  <%= truncate article.body %>
    +<% end %>
    +
    +
    +
    +
  • +
+

这样无需声明全部局部变量。

每个局部视图中都有个和局部视图同名的局部变量(去掉前面的下划线)。通过 object 选项可以把对象传给这个变量:

+
+<%= render partial: "customer", object: @new_customer %>
+
+
+
+

customer 局部视图中,变量 customer 的值为父级视图中的 @new_customer

如果要在局部视图中渲染模型实例,可以使用简写句法:

+
+<%= render @customer %>
+
+
+
+

假设实例变量 @customer 的值为 Customer 模型的实例,上述代码会渲染 _customer.html.erb,其中局部变量 customer 的值为父级视图中 @customer 实例变量的值。

3.4.5 渲染集合

渲染集合时使用局部视图特别方便。通过 :collection 选项把集合传给局部视图时,会把集合中每个元素套入局部视图渲染:

+
    +
  • +

    index.html.erb

    +
    +
    +<h1>Products</h1>
    +<%= render partial: "product", collection: @products %>
    +
    +
    +
    +
  • +
  • +

    _product.html.erb

    +
    +
    +<p>Product Name: <%= product.name %></p>
    +
    +
    +
    +
  • +
+

传入复数形式的集合时,在局部视图中可以使用和局部视图同名的变量引用集合中的成员。在上面的代码中,局部视图是 _product,在其中可以使用 product 引用渲染的实例。

渲染集合还有个简写形式。假设 @productsproduct 实例集合,在 index.html.erb 中可以直接写成下面的形式,得到的结果是一样的:

+
+<h1>Products</h1>
+<%= render @products %>
+
+
+
+

Rails 根据集合中各元素的模型名决定使用哪个局部视图。其实,集合中的元素可以来自不同的模型,Rails 会选择正确的局部视图进行渲染。

+
    +
  • +

    index.html.erb

    +
    +
    +<h1>Contacts</h1>
    +<%= render [customer1, employee1, customer2, employee2] %>
    +
    +
    +
    +
  • +
  • +

    customers/_customer.html.erb

    +
    +
    +<p>Customer: <%= customer.name %></p>
    +
    +
    +
    +
  • +
  • +

    employees/_employee.html.erb

    +
    +
    +<p>Employee: <%= employee.name %></p>
    +
    +
    +
    +
  • +
+

在上面几段代码中,Rails 会根据集合中各成员所属的模型选择正确的局部视图。

如果集合为空,render 方法返回 nil,所以最好提供替代内容。

+
+<h1>Products</h1>
+<%= render(@products) || "There are no products available." %>
+
+
+
+
3.4.6 局部变量

要在局部视图中自定义局部变量的名字,调用局部视图时通过 :as 选项指定:

+
+<%= render partial: "product", collection: @products, as: :item %>
+
+
+
+

这样修改之后,在局部视图中可以使用局部变量 item 访问 @products 集合中的实例。

使用 locals: {} 选项可以把任意局部变量传入局部视图:

+
+<%= render partial: "product", collection: @products,
+           as: :item, locals: {title: "Products Page"} %>
+
+
+
+

在局部视图中可以使用局部变量 title,其值为 "Products Page"

在局部视图中还可使用计数器变量,变量名是在集合成员名后加上 _counter。例如,渲染 @products 时,在局部视图中可以使用 product_counter 表示局部视图渲染了多少次。但是不能和 as: :value 选项一起使用。

在使用主局部视图渲染两个实例中间还可使用 :spacer_template 选项指定第二个局部视图。

3.4.7 间隔模板
+
+<%= render partial: @products, spacer_template: "product_ruler" %>
+
+
+
+

Rails 会在两次渲染 _product 局部视图之间渲染 _product_ruler 局部视图(不传入任何数据)。

3.4.8 集合局部布局

渲染集合时也可使用 :layout 选项:

+
+<%= render partial: "product", collection: @products, layout: "special_layout" %>
+
+
+
+

使用局部视图渲染集合中的各个元素时会套用指定的模板。与局部视图一样,当前渲染的对象以及 object_counter 变量也可在布局中使用。

3.5 使用嵌套布局

在应用中有时需要使用不同于常规布局的布局渲染特定的控制器。此时无需复制主视图进行编辑,可以使用嵌套布局(有时也叫子模板)。下面举个例子。

假设 ApplicationController 布局如下:

+
    +
  • +

    app/views/layouts/application.html.erb

    +
    +
    +<html>
    +<head>
    +  <title><%= @page_title or "Page Title" %></title>
    +  <%= stylesheet_link_tag "layout" %>
    +  <style><%= yield :stylesheets %></style>
    +</head>
    +<body>
    +  <div id="top_menu">Top menu items here</div>
    +  <div id="menu">Menu items here</div>
    +  <div id="content"><%= content_for?(:content) ? yield(:content) : yield %></div>
    +</body>
    +</html>
    +
    +
    +
    +
  • +
+

NewsController 生成的页面中,我们想隐藏顶部目录,在右侧添加一个目录:

+
    +
  • +

    app/views/layouts/news.html.erb

    +
    +
    +<% content_for :stylesheets do %>
    +  #top_menu {display: none}
    +  #right_menu {float: right; background-color: yellow; color: black}
    +<% end %>
    +<% content_for :content do %>
    +  <div id="right_menu">Right menu items here</div>
    +  <%= content_for?(:news_content) ? yield(:news_content) : yield %>
    +<% end %>
    +<%= render template: "layouts/application" %>
    +
    +
    +
    +
  • +
+

就这么简单。News 视图会使用 news.html.erb 布局,隐藏顶部目录,在 <div id="content"> 中添加一个右侧目录。

使用子模板方式实现这种效果有很多方法。注意,布局的嵌套层级没有限制。使用 render template: 'layouts/news' 可以指定使用一个新布局。如果确定,可以不为 News 控制器创建子模板,直接把 content_for?(:news_content) ? yield(:news_content) : yield 替换成 yield 即可。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/maintenance_policy.html b/maintenance_policy.html new file mode 100644 index 0000000..774c928 --- /dev/null +++ b/maintenance_policy.html @@ -0,0 +1,246 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Ruby on Rails 的维护方针

对 Rails 框架的支持分为四种:新功能、缺陷修正、安全问题和严重安全问题。各自的处理方式如下,所有版本号都使用 X.Y.Z 格式。

Rails 遵照语义版本更替版本号:

补丁版 Z
+只修正缺陷,不改变 API,也不新增功能。安全修正可能例外。

小版本 Y
+新增功能,可能改变 API(相当于语义版本中的大版本)。重大改变在之前的小版本或大版本中带有弃用提示。

大版本 X
+新增功能,可能改变 API。Rails 的大版本和小版本之间的区别是对重大改变的处理方式不同,有时也有例外。

1 新功能

新功能只添加到 master 分支,不会包含在补丁版中。

2 缺陷修正

只有最新的发布系列接收缺陷修正。如果修正的缺陷足够多,值得发布新的 gem,从这个分支中获取代码。

如果核心团队中有人同意支持更多的发布系列,也会包含在支持的系列中——这是特殊情况。

目前支持的系列:5.0.Z4.2.Z

3 安全问题

发现安全问题时,当前发布系列和下一个最新版接收补丁和新版本。

新版代码从最近的发布版中获取,应用安全补丁之后发布。然后把安全补丁应用到 x-y-stable 分支。例如,1.2.3 安全发布在 1.2.2 版的基础上得来,然后再把安全补丁应用到 1-2-stable 分支。因此,如果你使用 Rails 的最新版,很容易升级安全修正版。

目前支持的系列:5.0.Z4.2.Z

4 严重安全问题

发现严重安全问题时,会发布新版,最近的主发布系列也会接收补丁和新版。安全问题由核心团队甄别分类。

目前支持的系列:5.0.Z4.2.Z

5 不支持的发布系列

如果一个发布系列不再得到支持,你要自己负责处理缺陷和安全问题。我们可能会逆向移植,把修正代码发布到 Git 仓库中,但是不会发布新版本。如果你不想自己维护,应该升级到我们支持的版本。

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/nested_model_forms.html b/nested_model_forms.html new file mode 100644 index 0000000..23accb7 --- /dev/null +++ b/nested_model_forms.html @@ -0,0 +1,421 @@ + + + + + + + +Rails Nested Model Forms — Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+

Rails Nested Model Forms

Creating a form for a model and its associations can become quite tedious. Therefore Rails provides helpers to assist in dealing with the complexities of generating these forms and the required CRUD operations to create, update, and destroy associations.

After reading this guide, you will know:

+
    +
  • do stuff.
  • +
+ + +
+

Chapters

+
    +
  1. +Model setup + + +
  2. +
  3. +Views + + +
  4. +
+ +
+ +
+
+ +
+
+
+

This guide assumes the user knows how to use the Rails form helpers in general. Also, it's not an API reference. For a complete reference please visit the Rails API documentation.

1 Model setup

To be able to use the nested model functionality in your forms, the model will need to support some basic operations.

First of all, it needs to define a writer method for the attribute that corresponds to the association you are building a nested model form for. The fields_for form helper will look for this method to decide whether or not a nested model form should be built.

If the associated object is an array, a form builder will be yielded for each object, else only a single form builder will be yielded.

Consider a Person model with an associated Address. When asked to yield a nested FormBuilder for the :address attribute, the fields_for form helper will look for a method on the Person instance named address_attributes=.

1.1 ActiveRecord::Base model

For an ActiveRecord::Base model and association this writer method is commonly defined with the accepts_nested_attributes_for class method:

1.1.1 has_one
+
+class Person < ApplicationRecord
+  has_one :address
+  accepts_nested_attributes_for :address
+end
+
+
+
+
1.1.2 belongs_to
+
+class Person < ApplicationRecord
+  belongs_to :firm
+  accepts_nested_attributes_for :firm
+end
+
+
+
+
1.1.3 has_many / has_and_belongs_to_many
+
+class Person < ApplicationRecord
+  has_many :projects
+  accepts_nested_attributes_for :projects
+end
+
+
+
+

For greater detail on associations see Active Record Associations. +For a complete reference on associations please visit the API documentation for ActiveRecord::Associations::ClassMethods.

1.2 Custom model

As you might have inflected from this explanation, you don't necessarily need an ActiveRecord::Base model to use this functionality. The following examples are sufficient to enable the nested model form behavior:

1.2.1 Single associated object
+
+class Person
+  def address
+    Address.new
+  end
+
+  def address_attributes=(attributes)
+    # ...
+  end
+end
+
+
+
+
1.2.2 Association collection
+
+class Person
+  def projects
+    [Project.new, Project.new]
+  end
+
+  def projects_attributes=(attributes)
+    # ...
+  end
+end
+
+
+
+

See (TODO) in the advanced section for more information on how to deal with the CRUD operations in your custom model.

2 Views

2.1 Controller code

A nested model form will only be built if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first.

Consider the following typical RESTful controller which will prepare a new Person instance and its address and projects associations before rendering the new template:

+
+class PeopleController < ApplicationController
+  def new
+    @person = Person.new
+    @person.build_address
+    2.times { @person.projects.build }
+  end
+
+  def create
+    @person = Person.new(params[:person])
+    if @person.save
+      # ...
+    end
+  end
+end
+
+
+
+

Obviously the instantiation of the associated object(s) can become tedious and not DRY, so you might want to move that into the model itself. ActiveRecord::Base provides an after_initialize callback which is a good way to refactor this.

2.2 Form code

Now that you have a model instance, with the appropriate methods and associated object(s), you can start building the nested model form.

2.2.1 Standard form

Start out with a regular RESTful form:

+
+<%= form_for @person do |f| %>
+  <%= f.text_field :name %>
+<% end %>
+
+
+
+

This will generate the following html:

+
+<form action="http://github.com/people" class="new_person" id="new_person" method="post">
+  <input id="person_name" name="person[name]" type="text" />
+</form>
+
+
+
+
2.2.2 Nested form for a single associated object

Now add a nested form for the address association:

+
+<%= form_for @person do |f| %>
+  <%= f.text_field :name %>
+
+  <%= f.fields_for :address do |af| %>
+    <%= af.text_field :street %>
+  <% end %>
+<% end %>
+
+
+
+

This generates:

+
+<form action="http://github.com/people" class="new_person" id="new_person" method="post">
+  <input id="person_name" name="person[name]" type="text" />
+
+  <input id="person_address_attributes_street" name="person[address_attributes][street]" type="text" />
+</form>
+
+
+
+

Notice that fields_for recognized the address as an association for which a nested model form should be built by the way it has namespaced the name attribute.

When this form is posted the Rails parameter parser will construct a hash like the following:

+
+{
+  "person" => {
+    "name" => "Eloy Duran",
+    "address_attributes" => {
+      "street" => "Nieuwe Prinsengracht"
+    }
+  }
+}
+
+
+
+

That's it. The controller will simply pass this hash on to the model from the create action. The model will then handle building the address association for you and automatically save it when the parent (person) is saved.

2.2.3 Nested form for a collection of associated objects

The form code for an association collection is pretty similar to that of a single associated object:

+
+<%= form_for @person do |f| %>
+  <%= f.text_field :name %>
+
+  <%= f.fields_for :projects do |pf| %>
+    <%= pf.text_field :name %>
+  <% end %>
+<% end %>
+
+
+
+

Which generates:

+
+<form action="http://github.com/people" class="new_person" id="new_person" method="post">
+  <input id="person_name" name="person[name]" type="text" />
+
+  <input id="person_projects_attributes_0_name" name="person[projects_attributes][0][name]" type="text" />
+  <input id="person_projects_attributes_1_name" name="person[projects_attributes][1][name]" type="text" />
+</form>
+
+
+
+

As you can see it has generated 2 project name inputs, one for each new project that was built in the controller's new action. Only this time the name attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as:

+
+{
+  "person" => {
+    "name" => "Eloy Duran",
+    "projects_attributes" => {
+      "0" => { "name" => "Project 1" },
+      "1" => { "name" => "Project 2" }
+    }
+  }
+}
+
+
+
+

You can basically see the projects_attributes hash as an array of attribute hashes, one for each model instance.

The reason that fields_for constructed a hash instead of an array is that it won't work for any form nested deeper than one level deep.

You can however pass an array to the writer method generated by accepts_nested_attributes_for if you're using plain Ruby or some other API access. See (TODO) for more info and example.

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/plugins.html b/plugins.html new file mode 100644 index 0000000..561e1b9 --- /dev/null +++ b/plugins.html @@ -0,0 +1,680 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Rails 插件开发简介

Rails 插件是对核心框架的扩展或修改。插件有下述作用:

+
    +
  • 供开发者分享突发奇想,但不破坏稳定的代码基

  • +
  • 碎片式架构,代码自成一体,能按照自己的日程表修正或更新

  • +
  • 核心开发者使用的外延工具,不必把每个新特性都集成到核心框架中

  • +
+

读完本文后,您将学到:

+
    +
  • 如何从零开始创建一个插件

  • +
  • 如何编写插件的代码和测试

  • +
+

本文使用测试驱动开发方式编写一个插件,它具有下述功能:

+
    +
  • 扩展 Ruby 核心类,如 Hash 和 String

  • +
  • 通过传统的 acts_as 插件形式为 ApplicationRecord 添加方法

  • +
  • 说明生成器放在插件的什么位置

  • +
+

本文暂且假设你是热衷观察鸟类的人。你钟爱的鸟是绿啄木鸟(Yaffle),因此你想创建一个插件,供其他开发者分享心得。

本文原文尚未完工!

1 准备

目前,Rails 插件构建成 gem 的形式,叫做 gem 式插件(gemified plugin)。如果愿意,可以通过 RubyGems 和 Bundler 在多个 Rails 应用中共享。

1.1 生成 gem 式插件

Rails 自带一个 rails plugin new 命令,用于创建任何 Rails 扩展的骨架。这个命令还会生成一个虚设的 Rails 应用,用于运行集成测试。请使用下述命令创建这个插件:

+
+$ rails plugin new yaffle
+
+
+
+

如果想查看用法和选项,执行下述命令:

+
+$ rails plugin new --help
+
+
+
+

2 测试新生成的插件

进入插件所在的目录,运行 bundle install 命令,然后使用 bin/test 命令运行生成的一个测试。

你会看到下述输出:

+
+1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

这表明一切都正确生成了,接下来可以添加功能了。

3 扩展核心类

本节说明如何为 String 类添加一个方法,让它在整个 Rails 应用中都可以使用。

这里,我们为 String 添加的方法名为 to_squawk。首先,创建一个测试文件,写入几个断言:

+
+# yaffle/test/core_ext_test.rb
+
+require 'test_helper'
+
+class CoreExtTest < ActiveSupport::TestCase
+  def test_to_squawk_prepends_the_word_squawk
+    assert_equal "squawk! Hello World", "Hello World".to_squawk
+  end
+end
+
+
+
+

然后使用 bin/test 运行测试。这个测试应该失败,因为我们还没实现 to_squawk 方法。

+
+E
+
+Error:
+CoreExtTest#test_to_squawk_prepends_the_word_squawk:
+NoMethodError: undefined method `to_squawk' for "Hello World":String
+
+
+bin/test /path/to/yaffle/test/core_ext_test.rb:4
+
+.
+
+Finished in 0.003358s, 595.6483 runs/s, 297.8242 assertions/s.
+
+2 runs, 1 assertions, 0 failures, 1 errors, 0 skips
+
+
+
+

很好,下面可以开始开发了。

lib/yaffle.rb 文件中添加 require 'yaffle/core_ext'

+
+# yaffle/lib/yaffle.rb
+
+require 'yaffle/core_ext'
+
+module Yaffle
+end
+
+
+
+

最后,创建 core_ext.rb 文件,添加 to_squawk 方法:

+
+# yaffle/lib/yaffle/core_ext.rb
+
+String.class_eval do
+  def to_squawk
+    "squawk! #{self}".strip
+  end
+end
+
+
+
+

为了测试方法的行为是否得当,在插件目录中使用 bin/test 运行单元测试:

+
+2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

为了实测一下,进入 test/dummy 目录,打开控制台:

+
+$ bin/rails console
+>> "Hello World".to_squawk
+=> "squawk! Hello World"
+
+
+
+

4 为 Active Record 添加“acts_as”方法

插件经常为模型添加名为 acts_as_something 的方法。这里,我们要编写一个名为 acts_as_yaffle 的方法,为 Active Record 添加 squawk 方法。

首先,创建几个文件:

+
+# yaffle/test/acts_as_yaffle_test.rb
+
+require 'test_helper'
+
+class ActsAsYaffleTest < ActiveSupport::TestCase
+end
+
+
+
+
+
+# yaffle/lib/yaffle.rb
+
+require 'yaffle/core_ext'
+require 'yaffle/acts_as_yaffle'
+
+module Yaffle
+end
+
+
+
+
+
+# yaffle/lib/yaffle/acts_as_yaffle.rb
+
+module Yaffle
+  module ActsAsYaffle
+    # 在这里编写你的代码
+  end
+end
+
+
+
+

4.1 添加一个类方法

这个插件将为模型添加一个名为 last_squawk 的方法。然而,插件的用户可能已经在模型中定义了同名方法,做其他用途使用。这个插件将允许修改插件的名称,为此我们要添加一个名为 yaffle_text_field 的类方法。

首先,为预期行为编写一个失败测试:

+
+# yaffle/test/acts_as_yaffle_test.rb
+
+require 'test_helper'
+
+class ActsAsYaffleTest < ActiveSupport::TestCase
+  def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
+    assert_equal "last_squawk", Hickwall.yaffle_text_field
+  end
+
+  def test_a_wickwalls_yaffle_text_field_should_be_last_tweet
+    assert_equal "last_tweet", Wickwall.yaffle_text_field
+  end
+end
+
+
+
+

执行 bin/test 命令,应该看到下述输出:

+
+# Running:
+
+..E
+
+Error:
+ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
+NameError: uninitialized constant ActsAsYaffleTest::Wickwall
+
+
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:8
+
+E
+
+Error:
+ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
+NameError: uninitialized constant ActsAsYaffleTest::Hickwall
+
+
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:4
+
+
+
+Finished in 0.004812s, 831.2949 runs/s, 415.6475 assertions/s.
+
+4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
+
+
+
+

输出表明,我们想测试的模型(Hickwall 和 Wickwall)不存在。为此,可以在 test/dummy 目录中运行下述命令生成:

+
+$ cd test/dummy
+$ bin/rails generate model Hickwall last_squawk:string
+$ bin/rails generate model Wickwall last_squawk:string last_tweet:string
+
+
+
+

然后,进入虚设的应用,迁移数据库,创建所需的数据库表。首先,执行:

+
+$ cd test/dummy
+$ bin/rails db:migrate
+
+
+
+

同时,修改 Hickwall 和 Wickwall 模型,让它们知道自己的行为像绿啄木鸟。

+
+# test/dummy/app/models/hickwall.rb
+
+class Hickwall < ApplicationRecord
+  acts_as_yaffle
+end
+
+# test/dummy/app/models/wickwall.rb
+
+class Wickwall < ApplicationRecord
+  acts_as_yaffle yaffle_text_field: :last_tweet
+end
+
+
+
+

再添加定义 acts_as_yaffle 方法的代码:

+
+# yaffle/lib/yaffle/acts_as_yaffle.rb
+
+module Yaffle
+  module ActsAsYaffle
+    extend ActiveSupport::Concern
+
+    included do
+    end
+
+    module ClassMethods
+      def acts_as_yaffle(options = {})
+        # your code will go here
+      end
+    end
+  end
+end
+
+# test/dummy/app/models/application_record.rb
+
+class ApplicationRecord < ActiveRecord::Base
+  include Yaffle::ActsAsYaffle
+
+  self.abstract_class = true
+end
+
+
+
+

然后,回到插件的根目录(cd ../..),使用 bin/test 再次运行测试:

+
+# Running:
+
+.E
+
+Error:
+ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
+NoMethodError: undefined method `yaffle_text_field' for #<Class:0x0055974ebbe9d8>
+
+
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:4
+
+E
+
+Error:
+ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
+NoMethodError: undefined method `yaffle_text_field' for #<Class:0x0055974eb8cfc8>
+
+
+bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:8
+
+.
+
+Finished in 0.008263s, 484.0999 runs/s, 242.0500 assertions/s.
+
+4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
+
+
+
+

快完工了……接下来实现 acts_as_yaffle 方法,让测试通过:

+
+# yaffle/lib/yaffle/acts_as_yaffle.rb
+
+module Yaffle
+  module ActsAsYaffle
+    extend ActiveSupport::Concern
+
+    included do
+    end
+
+    module ClassMethods
+      def acts_as_yaffle(options = {})
+        cattr_accessor :yaffle_text_field
+        self.yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s
+      end
+    end
+  end
+end
+
+# test/dummy/app/models/application_record.rb
+
+class ApplicationRecord < ActiveRecord::Base
+  include Yaffle::ActsAsYaffle
+
+  self.abstract_class = true
+end
+
+
+
+

再次运行 bin/test,测试应该都能通过:

+
+4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

4.2 添加一个实例方法

这个插件能为任何模型添加调用 acts_as_yaffle 方法的 squawk 方法。squawk 方法的作用很简单,设定数据库中某个字段的值。

首先,为预期行为编写一个失败测试:

+
+# yaffle/test/acts_as_yaffle_test.rb
+require 'test_helper'
+
+class ActsAsYaffleTest < ActiveSupport::TestCase
+  def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
+    assert_equal "last_squawk", Hickwall.yaffle_text_field
+  end
+
+  def test_a_wickwalls_yaffle_text_field_should_be_last_tweet
+    assert_equal "last_tweet", Wickwall.yaffle_text_field
+  end
+
+  def test_hickwalls_squawk_should_populate_last_squawk
+    hickwall = Hickwall.new
+    hickwall.squawk("Hello World")
+    assert_equal "squawk! Hello World", hickwall.last_squawk
+  end
+
+  def test_wickwalls_squawk_should_populate_last_tweet
+    wickwall = Wickwall.new
+    wickwall.squawk("Hello World")
+    assert_equal "squawk! Hello World", wickwall.last_tweet
+  end
+end
+
+
+
+

运行测试,确保最后两个测试的失败消息中有“NoMethodError: undefined method `squawk'”。然后,按照下述方式修改 acts_as_yaffle.rb 文件:

+
+# yaffle/lib/yaffle/acts_as_yaffle.rb
+
+module Yaffle
+  module ActsAsYaffle
+    extend ActiveSupport::Concern
+
+    included do
+    end
+
+    module ClassMethods
+      def acts_as_yaffle(options = {})
+        cattr_accessor :yaffle_text_field
+        self.yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s
+
+        include Yaffle::ActsAsYaffle::LocalInstanceMethods
+      end
+    end
+
+    module LocalInstanceMethods
+      def squawk(string)
+        write_attribute(self.class.yaffle_text_field, string.to_squawk)
+      end
+    end
+  end
+end
+
+# test/dummy/app/models/application_record.rb
+
+class ApplicationRecord < ActiveRecord::Base
+  include Yaffle::ActsAsYaffle
+
+  self.abstract_class = true
+end
+
+
+
+

最后再运行一次 bin/test,应该看到:

+
+6 runs, 6 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

这里使用 write_attribute 写入模型中的字段,这只是插件与模型交互的方式之一,并不总是应该使用它。例如,也可以使用:

+
+
+
+send("#{self.class.yaffle_text_field}=", string.to_squawk)
+
+
+
+
+

5 生成器

gem 中可以包含生成器,只需将其放在插件的 lib/generators 目录中。创建生成器的更多信息参见创建及定制 Rails 生成器和模板

6 发布 gem

正在开发的 gem 式插件可以通过 Git 仓库轻易分享。如果想与他人分享这个 Yaffle gem,只需把代码纳入一个 Git 仓库(如 GitHub),然后在想使用它的应用中,在 Gemfile 中添加一行代码:

+
+gem 'yaffle', git: 'git://github.com/yaffle_watcher/yaffle.git'
+
+
+
+

运行 bundle install 之后,应用就可以使用插件提供的功能了。

gem 式插件准备好正式发布之后,可以发布到 RubyGems 网站中。关于这个话题的详细信息,参阅“Creating and Publishing Your First Ruby Gem”一文。

7 RDoc 文档

插件稳定后可以部署了,为了他人使用方便,一定要编写文档!幸好,为插件编写文档并不难。

首先,更新 README 文件,说明插件的用法。要包含以下几个要点:

+
    +
  • 你的名字

  • +
  • 插件用法

  • +
  • 如何把插件的功能添加到应用中(举几个示例,说明常见用例)

  • +
  • 提醒、缺陷或小贴士,这样能节省用户的时间

  • +
+

README 文件写好之后,为开发者将使用的方法添加 rdoc 注释。通常,还要为不在公开 API 中的代码添加 #:nodoc: 注释。

添加好注释之后,进入插件所在的目录,执行:

+
+$ bundle exec rake rdoc
+
+
+
+

8 参考资料

+ + + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/profiling.html b/profiling.html new file mode 100644 index 0000000..070eb6f --- /dev/null +++ b/profiling.html @@ -0,0 +1,238 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + +
+
+ +
+
+
+

Rails 应用分析指南

本文介绍 Rails 内置的应用分析(profile)机制。

读完本文后,您将学到:

+
    +
  • Rails 分析术语;

  • +
  • 如何为应用编写基准测试;

  • +
  • 其他基准测试方案和插件。

  • +
+

本文原文尚未完工!

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/rails_application_templates.html b/rails_application_templates.html new file mode 100644 index 0000000..ebdef65 --- /dev/null +++ b/rails_application_templates.html @@ -0,0 +1,479 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Rails 应用模板

应用模板是包含 DSL 的 Ruby 文件,作用是为新建的或现有的 Rails 项目添加 gem 和初始化脚本等。

读完本文后,您将学到:

+
    +
  • 如何使用模板生成和定制 Rails 应用;

  • +
  • 如何使用 Rails Templates API 编写可复用的应用模板。

  • +
+

1 用法

若想使用模板,调用 Rails 生成器时把模板的位置传给 -m 选项。模板的位置可以是文件路径,也可以是 URL。

+
+$ rails new blog -m ~/template.rb
+$ rails new blog -m http://example.com/template.rb
+
+
+
+

可以使用 app:template 任务在现有的 Rails 应用中使用模板。模板的位置要通过 LOCATION 环境变量指定。同样,模板的位置可以是文件路径,也可以是 URL。

+
+$ bin/rails app:template LOCATION=~/template.rb
+$ bin/rails app:template LOCATION=http://example.com/template.rb
+
+
+
+

2 Templates API

Rails Templates API 易于理解。下面是一个典型的 Rails 模板:

+
+# template.rb
+generate(:scaffold, "person name:string")
+route "root to: 'people#index'"
+rails_command("db:migrate")
+
+after_bundle do
+  git :init
+  git add: "."
+  git commit: %Q{ -m 'Initial commit' }
+end
+
+
+
+

下面各小节简介这个 API 提供的主要方法。

2.1 gem(*args) +

在生成的应用的 Gemfile 中添加指定的 gem 条目。

例如,如果应用依赖 bjnokogiri

+
+gem "bj"
+gem "nokogiri"
+
+
+
+

请注意,这么做不会为你安装 gem,你要执行 bundle install 命令安装。

+
+$ bundle install
+
+
+
+

2.2 gem_group(*names, &block) +

把指定的 gem 条目放在一个分组中。

例如,如果只想在 developmenttest 组中加载 rspec-rails

+
+gem_group :development, :test do
+  gem "rspec-rails"
+end
+
+
+
+

2.3 add_source(source, options={}, &block) +

在生成的应用的 Gemfile 中添加指定的源。

例如,如果想安装 "http://code.whytheluckystiff.net/" 源中的 gem:

+
+add_source "http://code.whytheluckystiff.net/"
+
+
+
+

如果提供块,块中的 gem 条目放在指定的源分组里:

+
+add_source "http://gems.github.com/" do
+  gem "rspec-rails"
+end
+
+
+
+

2.4 environment/application(data=nil, options={}, &block) +

config/application.rb 文件中的 Application 类里添加一行代码。

如果指定了 options[:env],代码添加到 config/environments 目录中对应的文件中。

+
+environment 'config.action_mailer.default_url_options = {host: "http://yourwebsite.example.com/"}', env: 'production'
+
+
+
+

data 参数的位置可以使用块。

2.5 vendor/lib/file/initializer(filename, data = nil, &block) +

在生成的应用的 config/initializers 目录中添加一个初始化脚本。

假设你想使用 Object#not_nil?Object#not_blank? 方法:

+
+initializer 'bloatlol.rb', <<-CODE
+  class Object
+    def not_nil?
+      !nil?
+    end
+
+    def not_blank?
+      !blank?
+    end
+  end
+CODE
+
+
+
+

类似地,lib() 方法在 lib/ directory 目录中创建一个文件,vendor() 方法在 vendor/ 目录中创建一个文件。

此外还有个 file() 方法,它的参数是一个相对于 Rails.root 的路径,用于创建所需的目录和文件:

+
+file 'app/components/foo.rb', <<-CODE
+  class Foo
+  end
+CODE
+
+
+
+

上述代码会创建 app/components 目录,然后在里面创建 foo.rb 文件。

2.6 rakefile(filename, data = nil, &block) +

lib/tasks 目录中创建一个 Rake 文件,写入指定的任务:

+
+rakefile("bootstrap.rake") do
+  <<-TASK
+    namespace :boot do
+      task :strap do
+        puts "i like boots!"
+      end
+    end
+  TASK
+end
+
+
+
+

上述代码会创建 lib/tasks/bootstrap.rake 文件,写入 boot:strap rake 任务。

2.7 generate(what, *args) +

运行指定的 Rails 生成器,并传入指定的参数。

+
+generate(:scaffold, "person", "name:string", "address:text", "age:number")
+
+
+
+

2.8 run(command) +

运行任意命令。作用类似于反引号。假如你想删除 README.rdoc 文件:

+
+run "rm README.rdoc"
+
+
+
+

2.9 rails_command(command, options = {}) +

在 Rails 应用中运行指定的任务。假如你想迁移数据库:

+
+rails_command "db:migrate"
+
+
+
+

还可以在不同的 Rails 环境中运行任务:

+
+rails_command "db:migrate", env: 'production'
+
+
+
+

还能以超级用户的身份运行任务:

+
+rails_command "log:clear", sudo: true
+
+
+
+

2.10 route(routing_code) +

config/routes.rb 文件中添加一条路由规则。在前面几节中,我们使用脚手架生成了 Person 资源,还删除了 README.rdoc 文件。现在,把 PeopleController#index 设为应用的首页:

+
+route "root to: 'person#index'"
+
+
+
+

2.11 inside(dir) +

在指定的目录中执行命令。假如你有一份最新版 Rails,想通过符号链接指向 rails 命令,可以这么做:

+
+inside('vendor') do
+  run "ln -s ~/commit-rails/rails rails"
+end
+
+
+
+

2.12 ask(question) +

ask() 方法获取用户的反馈,供模板使用。假如你想让用户为新添加的库起个响亮的名称:

+
+lib_name = ask("What do you want to call the shiny library ?")
+lib_name << ".rb" unless lib_name.index(".rb")
+
+lib lib_name, <<-CODE
+  class Shiny
+  end
+CODE
+
+
+
+

2.13 yes?(question)no?(question) +

这两个方法用于询问用户问题,然后根据用户的回答决定流程。假如你想在用户同意时才冰封 Rails:

+
+rails_command("rails:freeze:gems") if yes?("Freeze rails gems?")
+# no?(question) 的作用正好相反
+
+
+
+

2.14 git(:command) +

在 Rails 模板中可以运行任意 Git 命令:

+
+git :init
+git add: "."
+git commit: "-a -m 'Initial commit'"
+
+
+
+

2.15 after_bundle(&block) +

注册一个回调,在安装好 gem 并生成 binstubs 之后执行。可以用来把生成的文件纳入版本控制:

+
+after_bundle do
+  git :init
+  git add: '.'
+  git commit: "-a -m 'Initial commit'"
+end
+
+
+
+

即便传入 --skip-bundle 和(或) --skip-spring 选项,也会执行这个回调。

3 高级用法

应用模板在 Rails::Generators::AppGenerator 实例的上下文中运行,用到了 Thor 提供的 apply 方法。因此,你可以扩展或修改这个实例,满足自己的需求。

例如,覆盖指定模板位置的 source_paths 方法。现在,copy_file 等方法能接受相对于模板位置的相对路径。

+
+def source_paths
+  [File.expand_path(File.dirname(__FILE__))]
+end
+
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/rails_on_rack.html b/rails_on_rack.html new file mode 100644 index 0000000..6099123 --- /dev/null +++ b/rails_on_rack.html @@ -0,0 +1,448 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Rails on Rack

本文简介 Rails 与 Rack 的集成,以及与其他 Rack 组件的配合。

读完本文后,您将学到:

+
    +
  • 如何在 Rails 应用中使用 Rack 中间件;

  • +
  • Action Pack 内部的中间件栈;

  • +
  • 如何自定义中间件栈。

  • +
+

本文假定你对 Rack 协议和相关概念有一定了解,例如中间件、URL 映射和 Rack::Builder

1 Rack 简介

Rack 为使用 Ruby 开发的 Web 应用提供最简单的模块化接口,而且适应性强。Rack 使用最简单的方式包装 HTTP 请求和响应,从而抽象了 Web 服务器、Web 框架,以及二者之间的软件(称为中间件)的 API,统一成一个方法调用。

+ +

本文不详尽说明 Rack。如果你不了解 Rack 的基本概念,请参阅 资源

2 Rails on Rack

2.1 Rails 应用的 Rack 对象

Rails.application 是 Rails 应用的主 Rack 应用对象。任何兼容 Rack 的 Web 服务器都应该使用 Rails.application 对象伺服 Rails 应用。

2.2 rails server +

rails server 负责创建 Rack::Server 对象和启动 Web 服务器。

rails server 创建 Rack::Server 实例的方式如下:

+
+Rails::Server.new.tap do |server|
+  require APP_PATH
+  Dir.chdir(Rails.application.root)
+  server.start
+end
+
+
+
+

Rails::Server 继承自 Rack::Server,像下面这样调用 Rack::Server#start 方法:

+
+class Server < ::Rack::Server
+  def start
+    ...
+    super
+  end
+end
+
+
+
+

2.3 rackup +

如果不想使用 Rails 提供的 rails server 命令,而是使用 rackup,可以把下述代码写入 Rails 应用根目录中的 config.ru 文件里:

+
+# Rails.root/config.ru
+require ::File.expand_path('../config/environment', __FILE__)
+run Rails.application
+
+
+
+

然后使用下述命令启动服务器:

+
+$ rackup config.ru
+
+
+
+

rackup 命令的各个选项可以通过下述命令查看:

+
+$ rackup --help
+
+
+
+

2.4 开发和自动重新加载

中间件只加载一次,不会监视变化。若想让改动生效,必须重启服务器。

3 Action Dispatcher 中间件栈

Action Dispatcher 的内部组件很多都实现为 Rack 中间件。Rails::Application 使用 ActionDispatch::MiddlewareStack 把不同的内部和外部中间件组合在一起,构成完整的 Rails Rack 中间件。

Rails 中的 ActionDispatch::MiddlewareStack 相当于 Rack::Builder,但是为了满足 Rails 的需求,前者更灵活,而且功能更多。

3.1 审查中间件栈

Rails 提供了一个方便的任务,用于查看在用的中间件栈:

+
+$ bin/rails middleware
+
+
+
+

在新生成的 Rails 应用中,上述命令可能会输出下述内容:

+
+use Rack::Sendfile
+use ActionDispatch::Static
+use ActionDispatch::Executor
+use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000000029a0838>
+use Rack::Runtime
+use Rack::MethodOverride
+use ActionDispatch::RequestId
+use Rails::Rack::Logger
+use ActionDispatch::ShowExceptions
+use ActionDispatch::DebugExceptions
+use ActionDispatch::RemoteIp
+use ActionDispatch::Reloader
+use ActionDispatch::Callbacks
+use ActiveRecord::Migration::CheckPending
+use ActiveRecord::ConnectionAdapters::ConnectionManagement
+use ActiveRecord::QueryCache
+use ActionDispatch::Cookies
+use ActionDispatch::Session::CookieStore
+use ActionDispatch::Flash
+use Rack::Head
+use Rack::ConditionalGet
+use Rack::ETag
+run Rails.application.routes
+
+
+
+

这里列出的默认中间件(以及其他一些)在 内部中间件栈概述。

3.2 配置中间件栈

Rails 提供了一个简单的配置接口,config.middleware,用于在 application.rb 或针对环境的配置文件 environments/<environment>.rb 中添加、删除和修改中间件栈。

3.2.1 添加中间件

可以通过下述任意一种方法向中间件栈里添加中间件:

+
    +
  • config.middleware.use(new_middleware, args):在中间件栈的末尾添加一个中间件。

  • +
  • config.middleware.insert_before(existing_middleware, new_middleware, args):在中间件栈里指定现有中间件的前面添加一个中间件。

  • +
  • config.middleware.insert_after(existing_middleware, new_middleware, args):在中间件栈里指定现有中间件的后面添加一个中间件。

  • +
+
+
+# config/application.rb
+
+# 把 Rack::BounceFavicon 放在默认
+config.middleware.use Rack::BounceFavicon
+
+# 在 ActiveRecord::QueryCache 后面添加 Lifo::Cache
+# 把 { page_cache: false } 参数传给 Lifo::Cache.
+config.middleware.insert_after ActiveRecord::QueryCache, Lifo::Cache, page_cache: false
+
+
+
+
3.2.2 替换中间件

可以使用 config.middleware.swap 替换中间件栈里的现有中间件:

+
+# config/application.rb
+
+# 把 ActionDispatch::ShowExceptions 换成 Lifo::ShowExceptions
+config.middleware.swap ActionDispatch::ShowExceptions, Lifo::ShowExceptions
+
+
+
+
3.2.3 删除中间件

在应用的配置文件中添加下面这行代码:

+
+# config/application.rb
+config.middleware.delete Rack::Runtime
+
+
+
+

然后审查中间件栈,你会发现没有 Rack::Runtime 了:

+
+$ bin/rails middleware
+(in /Users/lifo/Rails/blog)
+use ActionDispatch::Static
+use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000001c304c8>
+use Rack::Runtime
+...
+run Rails.application.routes
+
+
+
+

若想删除会话相关的中间件,这么做:

+
+# config/application.rb
+config.middleware.delete ActionDispatch::Cookies
+config.middleware.delete ActionDispatch::Session::CookieStore
+config.middleware.delete ActionDispatch::Flash
+
+
+
+

若想删除浏览器相关的中间件,这么做:

+
+# config/application.rb
+config.middleware.delete Rack::MethodOverride
+
+
+
+

3.3 内部中间件栈

Action Controller 的大部分功能都实现成中间件。下面概述它们的作用。

Rack::Sendfile
+在服务器端设定 X-Sendfile 首部。通过 config.action_dispatch.x_sendfile_header 选项配置。

ActionDispatch::Static
+用于伺服 public 目录中的静态文件。如果把 config.public_file_server.enabled 设为 false,禁用这个中间件。

Rack::Lock
+把 env["rack.multithread"] 设为 false,把应用包装到 Mutex 中。

ActionDispatch::Executor
+用于在开发环境中以线程安全方式重新加载代码。

ActiveSupport::Cache::Strategy::LocalCache::Middleware
+用于缓存内存。这个缓存对线程不安全。

Rack::Runtime
+设定 X-Runtime 首部,包含执行请求的用时(单位为秒)。

Rack::MethodOverride
+如果设定了 params[:_method],允许覆盖请求方法。PUTDELETE 两个 HTTP 方法就是通过这个中间件提供支持的。

ActionDispatch::RequestId
+在响应中设定唯一的 X-Request-Id 首部,并启用 ActionDispatch::Request#request_id 方法。

Rails::Rack::Logger
+通知日志,请求开始了。请求完毕后,清空所有相关日志。

ActionDispatch::ShowExceptions
+拯救应用返回的所有异常,调用处理异常的应用,把异常包装成对终端用户友好的格式。

ActionDispatch::DebugExceptions
+如果是本地请求,负责在日志中记录异常,并显示调试页面。

ActionDispatch::RemoteIp
+检查 IP 欺骗攻击。

ActionDispatch::Reloader
+提供准备和清理回调,目的是在开发环境中协助重新加载代码。

ActionDispatch::Callbacks
+提供回调,在分派请求前后执行。

ActiveRecord::Migration::CheckPending
+检查有没有待运行的迁移,如果有,抛出 ActiveRecord::PendingMigrationError

ActiveRecord::ConnectionAdapters::ConnectionManagement
+如果没在请求环境中把 rack.test 键设为 true,每次请求后清理活跃连接。

ActiveRecord::QueryCache
+启用 Active Record 查询缓存。

ActionDispatch::Cookies
+为请求设定 cookie。

ActionDispatch::Session::CookieStore
+负责把会话存储在 cookie 中。

ActionDispatch::Flash
+设置闪现消息的键。仅当为 config.action_controller.session_store 设定值时才启用。

Rack::Head
+把 HEAD 请求转换成 GET 请求,然后伺服 GET 请求。

Rack::ConditionalGet
+支持“条件 GET 请求”,如果页面没变,服务器不做响应。

Rack::ETag
+为所有字符串主体添加 ETag 首部。ETag 用于验证缓存。

在自定义的 Rack 栈中可以使用上述任何一个中间件。

4 资源

4.1 学习 Rack

+ +

4.2 理解中间件

+ + + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/routing.html b/routing.html new file mode 100644 index 0000000..19c5276 --- /dev/null +++ b/routing.html @@ -0,0 +1,1671 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Rails 路由全解

本文介绍 Rails 路由面向用户的特性。

读完本文后,您将学到:

+
    +
  • 如何理解 config/routes.rb 文件中的代码;

  • +
  • 如何使用推荐的资源式风格或 match 方法构建路由;

  • +
  • 控制器动作预期收到什么参数;

  • +
  • 如何使用路由辅助方法自动创建路径和 URL 地址;

  • +
  • 约束和 Rack 端点等高级技术。

  • +
+

1 Rails 路由的用途

Rails 路由能够识别 URL 地址,并把它们分派给控制器动作进行处理。它还能生成路径和 URL 地址,从而避免在视图中硬编码字符串。

1.1 把 URL 地址连接到代码

当 Rails 应用收到下面的请求时:

+
+GET /patients/17
+
+
+
+

会查询路由,找到匹配的控制器动作。如果第一个匹配的路由是:

+
+get '/patients/:id', to: 'patients#show'
+
+
+
+

该请求会被分派给 patients 控制器的 show 动作,同时把 { id: '17' } 传入 params

1.2 从代码生成路径和 URL 地址

Rails 路由还可以生成路径和 URL 地址。如果把上面的路由修改为:

+
+get '/patients/:id', to: 'patients#show', as: 'patient'
+
+
+
+

并且在控制器中包含下面的代码:

+
+@patient = Patient.find(17)
+
+
+
+

同时在对应的视图中包含下面的代码:

+
+<%= link_to 'Patient Record', patient_path(@patient) %>
+
+
+
+

那么路由会生成路径 /patients/17。这种方式使视图代码更容易维护和理解。注意,在路由辅助方法中不需要指定 ID。

2 资源路由:Rails 的默认风格

资源路由(resource routing)允许我们为资源式控制器快速声明所有常见路由。只需一行代码即可完成资源路由的声明,无需为 indexshowneweditcreateupdatedestroy 动作分别声明路由。

2.1 网络资源

浏览器使用特定的 HTTP 方法向 Rails 应用请求页面,例如 GETPOSTPATCHPUTDELETE。每个 HTTP 方法对应对资源的一种操作。资源路由会把多个相关请求映射到单个控制器的不同动作上。

当 Rails 应用收到下面的请求:

+
+DELETE /photos/17
+
+
+
+

会查询路由,并把请求映射到控制器动作上。如果第一个匹配的路由是:

+
+resources :photos
+
+
+
+

Rails 会把请求分派给 photos 控制器的 destroy 动作,并把 { id: '17' } 传入 params

2.2 CRUD、HTTP 方法和控制器动作

在 Rails 中,资源路由把 HTTP 方法和 URL 地址映射到控制器动作上。按照约定,每个控制器动作也会映射到对应的数据库 CRUD 操作上。路由文件中的单行声明,例如:

+
+resources :photos
+
+
+
+

会在应用中创建 7 个不同的路由,这些路由都会映射到 Photos 控制器上。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作用途
GET/photosphotos#index显示所有照片的列表
GET/photos/newphotos#new返回用于新建照片的 HTML 表单
POST/photosphotos#create新建照片
GET/photos/:idphotos#show显示指定照片
GET/photos/:id/editphotos#edit返回用于修改照片的 HTML 表单
PATCH/PUT/photos/:idphotos#update更新指定照片
DELETE/photos/:idphotos#destroy删除指定照片
+

因为路由使用 HTTP 方法和 URL 地址来匹配请求,所以 4 个 URL 地址会映射到 7 个不同的控制器动作上。

Rails 路由按照声明顺序进行匹配。如果 resources :photos 声明在先,get 'photos/poll' 声明在后,那么由前者声明的 show 动作的路由会先于后者匹配。要想匹配 get 'photos/poll',就必须将其移到 resources :photos 之前。

2.3 用于生成路径和 URL 地址的辅助方法

在创建资源路由时,会同时创建多个可以在控制器中使用的辅助方法。例如,在创建 resources :photos 路由时,会同时创建下面的辅助方法:

+
    +
  • photos_path 辅助方法,返回值为 /photos

  • +
  • new_photo_path 辅助方法,返回值为 /photos/new

  • +
  • edit_photo_path(:id) 辅助方法,返回值为 /photos/:id/edit(例如,edit_photo_path(10) 的返回值为 /photos/10/edit

  • +
  • photo_path(:id) 辅助方法,返回值为 /photos/:id(例如,photo_path(10) 的返回值为 /photos/10

  • +
+

这些辅助方法都有对应的 _url 形式(例如 photos_url)。前者的返回值是路径,后者的返回值是路径加上由当前的主机名、端口和路径前缀组成的前缀。

2.4 同时定义多个资源

如果需要为多个资源创建路由,可以只调用一次 resources 方法,节约一点敲键盘的时间。

+
+resources :photos, :books, :videos
+
+
+
+

上面的代码等价于:

+
+resources :photos
+resources :books
+resources :videos
+
+
+
+

2.5 单数资源

有时我们希望不使用 ID 就能查找资源。例如,让 /profile 总是显示当前登录用户的个人信息。这种情况下,我们可以使用单数资源来把 /profile 而不是 /profile/:id 映射到 show 动作:

+
+get 'profile', to: 'users#show'
+
+
+
+

如果 get 方法的 to 选项的值是字符串,那么这个字符串应该使用 controller#action 格式。如果 to 选项的值是表示动作的符号,那么还需要使用 controller 选项指定控制器:

+
+get 'profile', to: :show, controller: 'users'
+
+
+
+

下面的资源路由:

+
+resource :geocoder
+
+
+
+

会在应用中创建 6 个不同的路由,这些路由会映射到 Geocoders 控制器的动作上:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作用途
GET/geocoder/newgeocoders#new返回用于创建 geocoder 的 HTML 表单
POST/geocodergeocoders#create新建 geocoder
GET/geocodergeocoders#show显示唯一的 geocoder 资源
GET/geocoder/editgeocoders#edit返回用于修改 geocoder 的 HTML 表单
PATCH/PUT/geocodergeocoders#update更新唯一的 geocoder 资源
DELETE/geocodergeocoders#destroy删除 geocoder 资源
+

有时我们想要用同一个控制器处理单数路由(如 /account)和复数路由(如 /accounts/45),也就是把单数资源映射到复数资源对应的控制器上。例如,resource :photo 创建的单数路由和 resources :photos 创建的复数路由都会映射到相同的 Photos 控制器上。

在创建单数资源路由时,会同时创建下面的辅助方法:

+
    +
  • new_geocoder_path 辅助方法,返回值是 /geocoder/new

  • +
  • edit_geocoder_path 辅助方法,返回值是 /geocoder/edit

  • +
  • geocoder_path 辅助方法,返回值是 /geocoder

  • +
+

和创建复数资源路由时一样,上面这些辅助方法都有对应的 _url 形式,其返回值也包含了主机名、端口和路径前缀。

有一个长期存在的缺陷使 form_for 辅助方法无法自动处理单数资源。有一个解决方案是直接指定表单 URL,例如:

+
+
+
+form_for @geocoder, url: geocoder_path do |f|
+
+# 为了行文简洁,省略以下内容
+
+
+
+
+

2.6 控制器命名空间和路由

有时我们会把一组控制器放入同一个命名空间中。最常见的例子,是把和管理相关的控制器放入 Admin:: 命名空间中。为此,我们可以把控制器文件放在 app/controllers/admin 文件夹中,然后在路由文件中作如下声明:

+
+namespace :admin do
+  resources :articles, :comments
+end
+
+
+
+

上面的代码会为 articlescomments 控制器分别创建多个路由。对于 Admin::Articles 控制器,Rails 会创建下列路由:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作具名辅助方法
GET/admin/articlesadmin/articles#indexadmin_articles_path
GET/admin/articles/newadmin/articles#newnew_admin_article_path
POST/admin/articlesadmin/articles#createadmin_articles_path
GET/admin/articles/:idadmin/articles#showadmin_article_path(:id)
GET/admin/articles/:id/editadmin/articles#editedit_admin_article_path(:id)
PATCH/PUT/admin/articles/:idadmin/articles#updateadmin_article_path(:id)
DELETE/admin/articles/:idadmin/articles#destroyadmin_article_path(:id)
+

如果想把 /articles 路径(不带 /admin 前缀) 映射到 Admin::Articles 控制器上,可以这样声明:

+
+scope module: 'admin' do
+  resources :articles, :comments
+end
+
+
+
+

对于单个资源的情况,还可以这样声明:

+
+resources :articles, module: 'admin'
+
+
+
+

如果想把 /admin/articles 路径映射到 Articles 控制器上(不带 Admin:: 前缀),可以这样声明:

+
+scope '/admin' do
+  resources :articles, :comments
+end
+
+
+
+

对于单个资源的情况,还可以这样声明:

+
+resources :articles, path: '/admin/articles'
+
+
+
+

在上述各个例子中,不管是否使用了 scope 方法,具名路由都保持不变。在最后一个例子中,下列路径都会映射到 Articles 控制器上:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作具名辅助方法
GET/admin/articlesarticles#indexarticles_path
GET/admin/articles/newarticles#newnew_article_path
POST/admin/articlesarticles#createarticles_path
GET/admin/articles/:idarticles#showarticle_path(:id)
GET/admin/articles/:id/editarticles#editedit_article_path(:id)
PATCH/PUT/admin/articles/:idarticles#updatearticle_path(:id)
DELETE/admin/articles/:idarticles#destroyarticle_path(:id)
+

如果想在命名空间代码块中使用另一个控制器命名空间,可以指定控制器的绝对路径,例如 get '/foo' => '/foo#index'

2.7 嵌套资源

有的资源是其他资源的子资源,这种情况很常见。例如,假设我们的应用中包含下列模型:

+
+class Magazine < ApplicationRecord
+  has_many :ads
+end
+
+class Ad < ApplicationRecord
+  belongs_to :magazine
+end
+
+
+
+

通过嵌套路由,我们可以在路由中反映模型关联。在本例中,我们可以这样声明路由:

+
+resources :magazines do
+  resources :ads
+end
+
+
+
+

上面的代码不仅为 magazines 创建了路由,还创建了映射到 Ads 控制器的路由。在 ad 的 URL 地址中,需要指定对应的 magazine 的 ID:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作用途
GET/magazines/:magazine_id/adsads#index显示指定杂志的所有广告的列表
GET/magazines/:magazine_id/ads/newads#new返回为指定杂志新建广告的 HTML 表单
POST/magazines/:magazine_id/adsads#create为指定杂志新建广告
GET/magazines/:magazine_id/ads/:idads#show显示指定杂志的指定广告
GET/magazines/:magazine_id/ads/:id/editads#edit返回用于修改指定杂志的广告的 HTML 表单
PATCH/PUT/magazines/:magazine_id/ads/:idads#update更新指定杂志的指定广告
DELETE/magazines/:magazine_id/ads/:idads#destroy删除指定杂志的指定广告
+

在创建路由的同时,还会创建 magazine_ads_urledit_magazine_ad_path 等路由辅助方法。这些辅助方法以 Magazine 类的实例作为第一个参数,例如 magazine_ads_url(http://github.com/@magazine)

2.7.1 嵌套限制

我们可以在嵌套资源中继续嵌套资源。例如:

+
+resources :publishers do
+  resources :magazines do
+    resources :photos
+  end
+end
+
+
+
+

随着嵌套层级的增加,嵌套资源的处理会变得很困难。例如,下面这个路径:

+
+/publishers/1/magazines/2/photos/3
+
+
+
+

对应的路由辅助方法是 publisher_magazine_photo_url,需要指定三层对象。这种用法很容易就把人搞糊涂了,为此,Jamis Buck 在一篇广为流传的文章中提出了使用嵌套路由的经验法则:

嵌套资源的层级不应超过 1 层。

2.7.2 浅层嵌套

如前文所述,避免深层嵌套(deep nesting)的方法之一,是把动作集合放在在父资源中,这样既可以表明层级关系,又不必嵌套成员动作。换句话说,只用最少的信息创建路由,同样可以唯一地标识资源,例如:

+
+resources :articles do
+  resources :comments, only: [:index, :new, :create]
+end
+resources :comments, only: [:show, :edit, :update, :destroy]
+
+
+
+

这种方式在描述性路由(descriptive route)和深层嵌套之间取得了平衡。上面的代码还有简易写法,即使用 :shallow 选项:

+
+resources :articles do
+  resources :comments, shallow: true
+end
+
+
+
+

这两种写法创建的路由完全相同。我们还可以在父资源中使用 :shallow 选项,这样会在所有嵌套的子资源中应用 :shallow 选项:

+
+resources :articles, shallow: true do
+  resources :comments
+  resources :quotes
+  resources :drafts
+end
+
+
+
+

可以用 shallow 方法创建作用域,使其中的所有嵌套都成为浅层嵌套。通过这种方式创建的路由,仍然和上面的例子相同:

+
+shallow do
+  resources :articles do
+    resources :comments
+    resources :quotes
+    resources :drafts
+  end
+end
+
+
+
+

scope 方法有两个选项用于自定义浅层路由。:shallow_path 选项会为成员路径添加指定前缀:

+
+scope shallow_path: "sekret" do
+  resources :articles do
+    resources :comments, shallow: true
+  end
+end
+
+
+
+

上面的代码会为 comments 资源生成下列路由:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作具名辅助方法
GET/articles/:article_id/comments(.:format)comments#indexarticle_comments_path
POST/articles/:article_id/comments(.:format)comments#createarticle_comments_path
GET/articles/:article_id/comments/new(.:format)comments#newnew_article_comment_path
GET/sekret/comments/:id/edit(.:format)comments#editedit_comment_path
GET/sekret/comments/:id(.:format)comments#showcomment_path
PATCH/PUT/sekret/comments/:id(.:format)comments#updatecomment_path
DELETE/sekret/comments/:id(.:format)comments#destroycomment_path
+

:shallow_prefix 选项会为具名辅助方法添加指定前缀:

+
+scope shallow_prefix: "sekret" do
+  resources :articles do
+    resources :comments, shallow: true
+  end
+end
+
+
+
+

上面的代码会为 comments 资源生成下列路由:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作具名辅助方法
GET/articles/:article_id/comments(.:format)comments#indexarticle_comments_path
POST/articles/:article_id/comments(.:format)comments#createarticle_comments_path
GET/articles/:article_id/comments/new(.:format)comments#newnew_article_comment_path
GET/comments/:id/edit(.:format)comments#editedit_sekret_comment_path
GET/comments/:id(.:format)comments#showsekret_comment_path
PATCH/PUT/comments/:id(.:format)comments#updatesekret_comment_path
DELETE/comments/:id(.:format)comments#destroysekret_comment_path
+

2.8 路由 concern

路由 concern 用于声明公共路由,公共路由可以在其他资源和路由中重复使用。定义路由 concern 的方式如下:

+
+concern :commentable do
+  resources :comments
+end
+
+concern :image_attachable do
+  resources :images, only: :index
+end
+
+
+
+

我们可以在资源中使用已定义的路由 concern,以避免代码重复,并在路由间共享行为:

+
+resources :messages, concerns: :commentable
+
+resources :articles, concerns: [:commentable, :image_attachable]
+
+
+
+

上面的代码等价于:

+
+resources :messages do
+  resources :comments
+end
+
+resources :articles do
+  resources :comments
+  resources :images, only: :index
+end
+
+
+
+

我们还可以在各种路由声明中使用已定义的路由 concern,例如在作用域或命名空间中:

+
+namespace :articles do
+  concerns :commentable
+end
+
+
+
+

2.9 从对象创建路径和 URL 地址

除了使用路由辅助方法,Rails 还可以从参数数组创建路径和 URL 地址。例如,假设有下面的路由:

+
+resources :magazines do
+  resources :ads
+end
+
+
+
+

在使用 magazine_ad_path 方法时,我们可以传入 MagazineAd 的实例,而不是数字 ID:

+
+<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
+
+
+
+

我们还可以在使用 url_for 方法时传入一组对象,Rails 会自动确定对应的路由:

+
+<%= link_to 'Ad details', url_for([@magazine, @ad]) %>
+
+
+
+

在这种情况下,Rails 知道 @magazineMagazine 的实例,而 @adAd 的实例,因此会使用 magazine_ad_path 辅助方法。在使用 link_to 等辅助方法时,我们可以只指定对象,而不必完整调用 url_for 方法:

+
+<%= link_to 'Ad details', [@magazine, @ad] %>
+
+
+
+

如果想链接到一本杂志,可以直接指定 Magazine 的实例:

+
+<%= link_to 'Magazine details', @magazine %>
+
+
+
+

如果想链接到其他控制器动作,只需把动作名称作为第一个元素插入对象数组即可:

+
+<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>
+
+
+
+

这样,我们就可以把模型实例看作 URL 地址,这是使用资源式风格最关键的优势之一。

2.10 添加更多 REST 式动作

我们可以使用的路由,并不仅限于 REST 式路由默认创建的那 7 个。我们可以根据需要添加其他路由,包括集合路由(collection route)和成员路由(member route)。

2.10.1 添加成员路由

要添加成员路由,只需在 resource 块中添加 member 块:

+
+resources :photos do
+  member do
+    get 'preview'
+  end
+end
+
+
+
+

通过上述声明,Rails 路由能够识别 /photos/1/preview 路径上的 GET 请求,并把请求映射到 Photos 控制器的 preview 动作上,同时把资源 ID 传入 params[:id],并创建 preview_photo_urlpreview_photo_path 辅助方法。

member 块中,每个成员路由都要指定对应的 HTTP 方法,即 getpatchputpostdelete。如果只有一个成员路由,我们就可以忽略 member 块,直接使用成员路由的 :on 选项。

+
+resources :photos do
+  get 'preview', on: :member
+end
+
+
+
+

如果不使用 :on 选项,创建的成员路由也是相同的,但资源 ID 就必须通过 params[:photo_id] 而不是 params[:id] 来获取了。

2.10.2 添加集合路由

添加集合路由的方式如下:

+
+resources :photos do
+  collection do
+    get 'search'
+  end
+end
+
+
+
+

通过上述声明,Rails 路由能够识别 /photos/search 路径上的 GET 请求,并把请求映射到 Photos 控制器的 search 动作上,同时创建 search_photos_urlsearch_photos_path 辅助方法。

和成员路由一样,我们可以使用集合路由的 :on 选项:

+
+resources :photos do
+  get 'search', on: :collection
+end
+
+
+
+
2.10.3 为附加的 new 动作添加路由

我们可以通过 :on 选项,为附加的 new 动作添加路由:

+
+resources :comments do
+  get 'preview', on: :new
+end
+
+
+
+

通过上述声明,Rails 路由能够识别 /comments/new/preview 路径上的 GET 请求,并把请求映射到 Comments 控制器的 preview 动作上,同时创建 preview_new_comment_urlpreview_new_comment_path 辅助方法。

如果我们为资源路由添加了过多动作,就需要考虑一下,是不是应该声明新资源了。

3 非资源式路由

除了资源路由之外,对于把任意 URL 地址映射到控制器动作的路由,Rails 也提供了强大的支持。和资源路由自动生成一系列路由不同,这时我们需要分别声明各个路由。

尽管我们通常会使用资源路由,但在一些情况下,使用简单路由更为合适。对于不适合使用资源路由的情况,我们也不必强迫自己使用资源路由。

对于把旧系统的 URL 地址映射到新 Rails 应用上的情况,简单路由特别适用。

3.1 绑定参数

在声明普通路由时,我们可以使用符号,将其作为 HTTP 请求的一部分。其中有两个特殊符号::controller 会被映射到控制器的名称上,:action 会被映射到控制器动作的名称上。例如,下面的路由:

+
+get ':controller(/:action(/:id))'
+
+
+
+

在处理 /photos/show/1 请求时(假设这个路由是第一个匹配的路由),会把请求映射到 Photos 控制器的 show 动作上,并把参数 1 传入 params[:id]。而 /photos 请求,也会被这个路由映射到 PhotosController#index 上,因为 :action:id 都在括号中,是可选参数。

3.2 动态片段

在声明普通路由时,我们可以根据需要使用多个动态片段(dynamic segment)。除了 :controller:action,其他动态片段都会传入 params,以便在控制器动作中使用。例如,对于下面的路由:

+
+get ':controller/:action/:id/:user_id'
+
+
+
+

/photos/show/1/2 路径会被映射到 Photos 控制器的 show 动作上。此时,params[:id] 的值是 "1"params[:user_id] 的值是 "2"

:namespace:module 不能用作动态片段。如果需要这一功能,可以通过为控制器添加约束,来匹配所需的命名空间。例如:

+
+
+
+get ':controller(/:action(/:id))', controller: /admin\/[^\/]+/
+
+
+
+
+

默认情况下,在动态片段中不能使用小圆点(.),因为小圆点是格式化路由(formatted route)的分隔符。如果想在动态片段中使用小圆点,可以通过添加约束来实现相同效果,例如,id: /[^\/]+/ 可以匹配除斜线外的一个或多个字符。

3.3 静态片段

在创建路由时,我们可以用不带冒号的片段来指定静态片段(static segment):

+
+get ':controller/:action/:id/with_user/:user_id'
+
+
+
+

这个路由可以响应像 /photos/show/1/with_user/2 这样的路径,此时,params 的值为 { controller: 'photos', action: 'show', id: '1', user_id: '2' }

3.4 查询字符串

params 也包含了查询字符串中的所有参数。例如,对于下面的路由:

+
+get ':controller/:action/:id'
+
+
+
+

/photos/show/1?user_id=2 路径会被映射到 Photos 控制器的 show 动作上,此时,params 的值是 { controller: 'photos', action: 'show', id: '1', user_id: '2' }

3.5 定义默认值

通过定义默认值,我们可以避免在路由声明中显式使用 :controller:action 符号:

+
+get 'photos/:id', to: 'photos#show'
+
+
+
+

这个路由会把 /photos/12 路径映射到 Photos 控制器的 show 动作上。

在路由声明中,我们还可以使用 :defaults 选项(其值为散列)定义更多默认值。对于未声明为动态片段的参数,也可以使用 :defaults 选项。例如:

+
+get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg' }
+
+
+
+

这个路由会把 photos/12 路径映射到 Photos 控制器的 show 动作上,并把 params[:format] 的值设置为 "jpg"

出于安全考虑,Rails 不允许用查询参数来覆盖默认值。只有一种情况下可以覆盖默认值,即通过 URL 路径替换来覆盖动态片段。

3.6 为路由命名

通过 :as 选项,我们可以为路由命名:

+
+get 'exit', to: 'sessions#destroy', as: :logout
+
+
+
+

这个路由声明会创建 logout_pathlogout_url 具名辅助方法。其中,logout_path 辅助方法的返回值是 /exit

通过为路由命名,我们还可以覆盖由资源路由定义的路由辅助方法,例如:

+
+get ':username', to: 'users#show', as: :user
+
+
+
+

这个路由声明会定义 user_path 辅助方法,此方法可以在控制器、辅助方法和视图中使用,其返回值类似 /bob。在 Users 控制器的 show 动作中,params[:username] 的值是用户名。如果不想使用 :username 作为参数名,可以在路由声明中把 :username 改为其他名字。

3.7 HTTP 方法约束

通常,我们应该使用 getpostputpatchdelete 方法来约束路由可以匹配的 HTTP 方法。通过使用 match 方法和 :via 选项,我们可以一次匹配多个 HTTP 方法:

+
+match 'photos', to: 'photos#show', via: [:get, :post]
+
+
+
+

通过 via: :all 选项,路由可以匹配所有 HTTP 方法:

+
+match 'photos', to: 'photos#show', via: :all
+
+
+
+

GETPOST 请求映射到同一个控制器动作上会带来安全隐患。通常,除非有足够的理由,我们应该避免把使用不同 HTTP 方法的所有请求映射到同一个控制器动作上。

Rails 在处理 GET 请求时不会检查 CSRF 令牌。在处理 GET 请求时绝对不可以对数据库进行写操作,更多介绍请参阅 安全指南

3.8 片段约束

我们可以使用 :constraints 选项来约束动态片段的格式:

+
+get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }
+
+
+
+

这个路由会匹配 /photos/A12345 路径,但不会匹配 /photos/893 路径。此路由还可以简写为:

+
+get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
+
+
+
+

:constraints 选项的值可以是正则表达式,但不能使用 ^ 符号。例如,下面的路由写法是错误的:

+
+get '/:id', to: 'articles#show', constraints: { id: /^\d/ }
+
+
+
+

其实,使用 ^ 符号也完全没有必要,因为路由总是从头开始匹配。

例如,对于下面的路由,/1-hello-world 路径会被映射到 articles#show 上,而 /david 路径会被映射到 users#show 上:

+
+get '/:id', to: 'articles#show', constraints: { id: /\d.+/ }
+get '/:username', to: 'users#show'
+
+
+
+

3.9 请求约束

如果在请求对象上调用某个方法的返回值是字符串,我们就可以用这个方法来约束路由。

请求约束和片段约束的用法相同:

+
+get 'photos', to: 'photos#index', constraints: { subdomain: 'admin' }
+
+
+
+

我们还可以用块来指定约束:

+
+namespace :admin do
+  constraints subdomain: 'admin' do
+    resources :photos
+  end
+end
+
+
+
+

请求约束(request constraint)的工作原理,是在请求对象上调用和约束条件中散列的键同名的方法,然后比较返回值和散列的值。因此,约束中散列的值和调用方法返回的值的类型应当相同。例如,constraints: { subdomain: 'api' } 会匹配 api 子域名,但是 constraints: { subdomain: :api } 不会匹配 api 子域名,因为后者散列的值是符号,而 request.subdomain 方法的返回值 'api' 是字符串。

格式约束(format constraint)是一个例外:尽管格式约束是在请求对象上调用的方法,但同时也是路径的隐式可选参数(implicit optional parameter)。片段约束的优先级高于格式约束,而格式约束在通过散列指定时仅作为隐式可选参数。例如,get 'foo', constraints: { format: 'json' } 路由会匹配 GET /foo 请求,因为默认情况下格式约束是可选的。尽管如此,我们可以使用 lambda,例如,get 'foo', constraints: lambda { |req| req.format == :json } 路由只匹配显式 JSON 请求。

3.10 高级约束

如果需要更复杂的约束,我们可以使用能够响应 matches? 方法的对象作为约束。假设我们想把所有黑名单用户映射到 Blacklist 控制器,可以这么做:

+
+class BlacklistConstraint
+  def initialize
+    @ips = Blacklist.retrieve_ips
+  end
+
+  def matches?(request)
+    @ips.include?(request.remote_ip)
+  end
+end
+
+Rails.application.routes.draw do
+  get '*path', to: 'blacklist#index',
+    constraints: BlacklistConstraint.new
+end
+
+
+
+

我们还可以用 lambda 来指定约束:

+
+Rails.application.routes.draw do
+  get '*path', to: 'blacklist#index',
+    constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
+end
+
+
+
+

在上面两段代码中,matches? 方法和 lambda 都是把请求对象作为参数。

3.11 路由通配符和通配符片段

路由通配符用于指定特殊参数,这一参数会匹配路由的所有剩余部分。例如:

+
+get 'photos/*other', to: 'photos#unknown'
+
+
+
+

这个路由会匹配 photos/12/photos/long/path/to/12 路径,并把 params[:other] 分别设置为 "12""long/path/to/12"。像 *other 这样以星号开头的片段,称作“通配符片段”。

通配符片段可以出现在路由中的任何位置。例如:

+
+get 'books/*section/:title', to: 'books#show'
+
+
+
+

这个路由会匹配 books/some/section/last-words-a-memoir 路径,此时,params[:section] 的值是 'some/section'params[:title] 的值是 'last-words-a-memoir'

严格来说,路由中甚至可以有多个通配符片段,其匹配方式也非常直观。例如:

+
+get '*a/foo/*b', to: 'test#index'
+
+
+
+

会匹配 zoo/woo/foo/bar/baz 路径,此时,params[:a] 的值是 'zoo/woo'params[:b] 的值是 'bar/baz'

get '*pages', to: 'pages#show' 路由在处理 '/foo/bar.json' 请求时,params[:pages] 的值是 'foo/bar',请求格式(request format)是 JSON。如果想让 Rails 按 3.0.x 版本的方式进行匹配,可以使用 format: false 选项,例如:

+
+
+
+get '*pages', to: 'pages#show', format: false
+
+
+
+

如果想强制使用格式约束,或者说让格式约束不再是可选的,我们可以使用 format: true 选项,例如:

+
+
+get '*pages', to: 'pages#show', format: true
+
+
+
+
+

3.12 重定向

在路由中,通过 redirect 辅助方法可以把一个路径重定向到另一个路径:

+
+get '/stories', to: redirect('/articles')
+
+
+
+

在重定向的目标路径中,可以使用源路径中的动态片段:

+
+get '/stories/:name', to: redirect('/articles/%{name}')
+
+
+
+

我们还可以重定向到块,这个块可以接受符号化的路径参数和请求对象:

+
+get '/stories/:name', to: redirect { |path_params, req| "/articles/#{path_params[:name].pluralize}" }
+get '/stories', to: redirect { |path_params, req| "/articles/#{req.subdomain}" }
+
+
+
+

请注意,redirect 重定向默认是 301 永久重定向,有些浏览器或代理服务器会缓存这种类型的重定向,从而导致无法访问重定向前的网页。为了避免这种情况,我们可以使用 :status 选项修改响应状态:

+
+get '/stories/:name', to: redirect('/articles/%{name}', status: 302)
+
+
+
+

在重定向时,如果不指定主机(例如 http://www.example.com),Rails 会使用当前请求的主机。

3.13 映射到 Rack 应用的路由

在声明路由时,我们不仅可以使用字符串,例如映射到 Articles 控制器的 index 动作的 'articles#index',还可以指定 Rack 应用为端点:

+
+match '/application.js', to: MyRackApp, via: :all
+
+
+
+

只要 MyRackApp 应用能够响应 call 方法并返回 [status, headers, body] 数组,对于路由来说,Rack 应用和控制器动作就没有区别。via: :all 选项使 Rack 应用可以处理所有 HTTP 方法。

实际上,'articles#index' 会被展开为 ArticlesController.action(:index),其返回值正是一个 Rack 应用。

记住,路由所匹配的路径,就是 Rack 应用接收的路径。例如,对于下面的路由,Rack 应用接收的路径是 /admin

+
+match '/admin', to: AdminApp, via: :all
+
+
+
+

如果想让 Rack 应用接收根路径上的请求,可以使用 mount 方法:

+
+mount AdminApp, at: '/admin'
+
+
+
+

3.14 使用 root 方法

root 方法指明如何处理根路径(/)上的请求:

+
+root to: 'pages#main'
+root 'pages#main' # 上一行代码的简易写法
+
+
+
+

root 路由应该放在路由文件的顶部,因为最常用的路由应该首先匹配。

root 路由只处理 GET 请求。

我们还可以在命名空间和作用域中使用 root 方法,例如:

+
+namespace :admin do
+  root to: "admin#index"
+end
+
+root to: "home#index"
+
+
+
+

3.15 Unicode 字符路由

在声明路由时,可以直接使用 Unicode 字符,例如:

+
+get 'こんにちは', to: 'welcome#index'
+
+
+
+

4 自定义资源路由

尽管 resources :articles 默认生成的路由和辅助方法通常都能很好地满足需求,但是也有一些情况下我们需要自定义资源路由。Rails 允许我们通过各种方式自定义资源式辅助方法(resourceful helper)。

4.1 指定控制器

:controller 选项用于显式指定资源使用的控制器,例如:

+
+resources :photos, controller: 'images'
+
+
+
+

这个路由会把 /photos 路径映射到 Images 控制器上:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作具名辅助方法
GET/photosimages#indexphotos_path
GET/photos/newimages#newnew_photo_path
POST/photosimages#createphotos_path
GET/photos/:idimages#showphoto_path(:id)
GET/photos/:id/editimages#editedit_photo_path(:id)
PATCH/PUT/photos/:idimages#updatephoto_path(:id)
DELETE/photos/:idimages#destroyphoto_path(:id)
+

请使用 photos_pathnew_photo_path 等辅助方法为资源生成路径。

对于命名空间中的控制器,我们可以使用目录表示法(directory notation)。例如:

+
+resources :user_permissions, controller: 'admin/user_permissions'
+
+
+
+

这个路由会映射到 Admin::UserPermissions 控制器。

在这种情况下,我们只能使用目录表示法。如果我们使用 Ruby 的常量表示法(constant notation),例如 controller: 'Admin::UserPermissions',有可能导致路由错误,而使 Rails 显示警告信息。

4.2 指定约束

:constraints 选项用于指定隐式 ID 必须满足的格式要求。例如:

+
+resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }
+
+
+
+

这个路由声明使用正则表达式来约束 :id 参数。此时,路由将不会匹配 /photos/1 路径,但会匹配 /photos/RR27 路径。

我们可以通过块把一个约束应用于多个路由:

+
+constraints(id: /[A-Z][A-Z][0-9]+/) do
+  resources :photos
+  resources :accounts
+end
+
+
+
+

当然,在这种情况下,我们也可以使用非资源路由的高级约束。

默认情况下,在 :id 参数中不能使用小圆点,因为小圆点是格式化路由的分隔符。如果想在 :id 参数中使用小圆点,可以通过添加约束来实现相同效果,例如,id: /[^\/]+/ 可以匹配除斜线外的一个或多个字符。

4.3 覆盖具名路由辅助方法

通过 :as 选项,我们可以覆盖具名路由辅助方法的默认名称。例如:

+
+resources :photos, as: 'images'
+
+
+
+

这个路由会把以 /photos 开头的路径映射到 Photos 控制器上,同时通过 :as 选项设置具名辅助方法的名称。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作具名辅助方法
GET/photosphotos#indeximages_path
GET/photos/newphotos#newnew_image_path
POST/photosphotos#createimages_path
GET/photos/:idphotos#showimage_path(:id)
GET/photos/:id/editphotos#editedit_image_path(:id)
PATCH/PUT/photos/:idphotos#updateimage_path(:id)
DELETE/photos/:idphotos#destroyimage_path(:id)
+

4.4 覆盖 newedit 片段

:path_names 选项用于覆盖路径中自动生成的 newedit 片段,例如:

+
+resources :photos, path_names: { new: 'make', edit: 'change' }
+
+
+
+

这个路由能够识别下面的路径:

+
+/photos/make
+/photos/1/change
+
+
+
+

:path_names 选项不会改变控制器动作的名称,上面这两个路径仍然被分别映射到 newedit 动作上。

通过作用域,我们可以对所有路由应用 :path_names 选项。

+
+scope path_names: { new: 'make' } do
+  # 其余路由
+end
+
+
+
+

4.5 为具名路由辅助方法添加前缀

通过 :as 选项,我们可以为具名路由辅助方法添加前缀。通过在作用域中使用 :as 选项,我们可以解决路由名称冲突的问题。例如:

+
+scope 'admin' do
+  resources :photos, as: 'admin_photos'
+end
+
+resources :photos
+
+
+
+

上述路由声明会生成 admin_photos_pathnew_admin_photo_path 等辅助方法。

通过在作用域中使用 :as 选项,我们可以为一组路由辅助方法添加前缀:

+
+scope 'admin', as: 'admin' do
+  resources :photos, :accounts
+end
+
+resources :photos, :accounts
+
+
+
+

上述路由会生成 admin_photos_pathadmin_accounts_path 等辅助方法,其返回值分别为 /admin/photos/admin/accounts 等。

namespace 作用域除了添加 :as 选项指定的前缀,还会添加 :module:path 前缀。

我们还可以使用具名参数指定路由前缀,例如:

+
+scope ':username' do
+  resources :articles
+end
+
+
+
+

这个路由能够识别 /bob/articles/1 路径,此时,在控制器、辅助方法和视图中,我们可以使用 params[:username] 获取路径中的 username 部分,即 bob

4.6 限制所创建的路由

默认情况下,Rails 会为每个 REST 式路由创建 7 个默认动作(indexshownewcreateeditupdatedestroy)。我们可以使用 :only:except 选项来微调此行为。:only 选项用于指定想要生成的路由:

+
+resources :photos, only: [:index, :show]
+
+
+
+

此时,/photos 路径上的 GET 请求会成功,而 POST 请求会失败,因为后者会被映射到 create 动作上。

:except 选项用于指定不想生成的路由:

+
+resources :photos, except: :destroy
+
+
+
+

此时,Rails 会创建除 destroy 之外的所有路由,因此 /photos/:id 路径上的 DELETE 请求会失败。

如果应用中有很多资源式路由,通过 :only:except 选项,我们可以只生成实际需要的路由,这样可以减少内存使用、加速路由处理过程。

4.7 本地化路径

在使用 scope 方法时,我们可以修改 resources 方法生成的路径名称。例如:

+
+scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
+  resources :categories, path: 'kategorien'
+end
+
+
+
+

Rails 会生成下列映射到 Categories 控制器的路由:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP 方法路径控制器#动作具名辅助方法
GET/kategoriencategories#indexcategories_path
GET/kategorien/neucategories#newnew_category_path
POST/kategoriencategories#createcategories_path
GET/kategorien/:idcategories#showcategory_path(:id)
GET/kategorien/:id/bearbeitencategories#editedit_category_path(:id)
PATCH/PUT/kategorien/:idcategories#updatecategory_path(:id)
DELETE/kategorien/:idcategories#destroycategory_path(:id)
+

4.8 覆盖资源的单数形式

通过为 Inflector 添加附加的规则,我们可以定义资源的单数形式。例如:

+
+ActiveSupport::Inflector.inflections do |inflect|
+  inflect.irregular 'tooth', 'teeth'
+end
+
+
+
+

4.9 在嵌套资源中使用 :as 选项

在嵌套资源中,我们可以使用 :as 选项覆盖自动生成的辅助方法名称。例如:

+
+resources :magazines do
+  resources :ads, as: 'periodical_ads'
+end
+
+
+
+

会生成 magazine_periodical_ads_urledit_magazine_periodical_ad_path 等辅助方法。

4.10 覆盖具名路由的参数

:param 选项用于覆盖默认的资源标识符 :id(用于生成路由的动态片段的名称)。在控制器中,我们可以通过 params[<:param>] 访问资源标识符。

+
+resources :videos, param: :identifier
+
+
+
+
+
+videos GET  /videos(.:format)                  videos#index
+       POST /videos(.:format)                  videos#create
+new_videos GET  /videos/new(.:format)              videos#new
+edit_videos GET  /videos/:identifier/edit(.:format) videos#edit
+
+
+
+
+
+Video.find_by(identifier: params[:identifier])
+
+
+
+

通过覆盖相关模型的 ActiveRecord::Base#to_param 方法,我们可以构造 URL 地址:

+
+class Video < ApplicationRecord
+  def to_param
+    identifier
+  end
+end
+
+video = Video.find_by(identifier: "Roman-Holiday")
+edit_videos_path(video) # => "/videos/Roman-Holiday"
+
+
+
+

5 审查和测试路由

Rails 提供了路由检查和测试的相关功能。

5.1 列出现有路由

要想得到应用中现有路由的完整列表,可以在开发环境中运行服务器,然后在浏览器中访问 http://localhost:3000/rails/info/routes。在终端中执行 rails routes 命令,也会得到相同的输出结果。

这两种方式都会按照路由在 config/routes.rb 文件中的声明顺序,列出所有路由。每个路由都包含以下信息:

+
    +
  • 路由名称(如果有的话)

  • +
  • 所使用的 HTTP 方法(如果路由不响应所有的 HTTP 方法)

  • +
  • 所匹配的 URL 模式

  • +
  • 路由参数

  • +
+

例如,下面是执行 rails routes 命令后,REST 式路由的一部分输出结果:

+
+    users GET    /users(.:format)          users#index
+          POST   /users(.:format)          users#create
+ new_user GET    /users/new(.:format)      users#new
+edit_user GET    /users/:id/edit(.:format) users#edit
+
+
+
+

可以使用 grep 选项(即 -g)搜索路由。只要路由的 URL 辅助方法的名称、HTTP 方法或 URL 路径中有部分匹配,该路由就会显示在搜索结果中。

+
+$ bin/rails routes -g new_comment
+$ bin/rails routes -g POST
+$ bin/rails routes -g admin
+
+
+
+

要想查看映射到指定控制器的路由,可以使用 -c 选项。

+
+$ bin/rails routes -c users
+$ bin/rails routes -c admin/users
+$ bin/rails routes -c Comments
+$ bin/rails routes -c Articles::CommentsController
+
+
+
+

为了增加 rails routes 命令输出结果的可读性,可以增加终端窗口的宽度,避免输出结果折行。

5.2 测试路由

路由和应用的其他部分一样,也应该包含在测试策略中。为了简化路由测试,Rails 提供了三个内置断言

+
    +
  • assert_generates 断言

  • +
  • assert_recognizes 断言

  • +
  • assert_routing 断言

  • +
+
5.2.1 assert_generates 断言

assert_generates 断言的功能是断定所指定的一组选项会生成指定路径,它可以用于默认路由或自定义路由。例如:

+
+assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
+assert_generates '/about', controller: 'pages', action: 'about'
+
+
+
+
5.2.2 assert_recognizes 断言

assert_recognizes 断言和 assert_generates 断言的功能相反,它断定所提供的路径能够被路由识别并映射到指定控制器动作。例如:

+
+assert_recognizes({ controller: 'photos', action: 'show', id: '1' }, '/photos/1')
+
+
+
+

我们可以通过 :method 参数指定 HTTP 方法:

+
+assert_recognizes({controller:'photos',action:'create'},{path:'photos',method::post})
+
+
+
+
5.2.3 assert_routing 断言

assert_routing 断言会对路由进行双向测试:既测试路径能否生成选项,也测试选项能否生成路径。也就是集 assert_generatesassert_recognizes 这两种断言的功能于一身。

+
+assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
+
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/ruby_on_rails_guides_guidelines.html b/ruby_on_rails_guides_guidelines.html new file mode 100644 index 0000000..1f37f12 --- /dev/null +++ b/ruby_on_rails_guides_guidelines.html @@ -0,0 +1,338 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + + + +
+
+ +
+
+
+

Ruby on Rails 指南指导方针

本文说明编写 Ruby on Rails 指南的指导方针。本文也遵守这一方针,本身就是个示例。

读完本文后,您将学到:

+
    +
  • Rails 文档使用的约定;

  • +
  • 如何在本地生成指南。

  • +
+

1 Markdown

指南使用 GitHub Flavored Markdown 编写。Markdown 有完整的文档,还有速查表

2 序言

每篇文章的开头要有介绍性文字(蓝色区域中的简短介绍)。序言应该告诉读者文章的主旨,以及能让读者学到什么。可以以Rails 路由全解为例。

3 标题

每篇文章的标题使用 h1 标签,文章中的小节使用 h2 标签,子节使用 h3 标签,以此类推。注意,生成的 HTML 从 <h2> 标签开始。

+
+Guide Title
+===========
+
+Section
+-------
+
+### Sub Section
+
+
+
+

标题中除了介词、连词、冠词和“to be”这种形式的动词之外,每个词的首字母大写:

+
+#### Middleware Stack is an Array
+#### When are Objects Saved?
+
+
+
+

行内格式与正文一样:

+
+##### The `:content_type` Option
+
+
+
+

4 API 文档指导方针

指南和 API 应该连贯一致。尤其是API 文档指导方针中的下述几节,同样适用于指南:

+ +

5 HTML 版指南

在生成指南之前,先确保你的系统中安装了 Bundler 的最新版。写作本文时,要在你的设备中安装 Bundler 1.3.5 或以上版本。

安装最新版 Bundler 的方法是,执行 gem install bundler 命令。

5.1 生成

若想生成全部指南,进入 guides 目录,执行 bundle install 命令之后再执行:

+
+$ bundle exec rake guides:generate
+
+
+
+

或者

+
+$ bundle exec rake guides:generate:html
+
+
+
+

得到的 HTML 文件在 ./output 目录中。

如果只想处理 my_guide.md,使用 ONLY 环境变量:

+
+$ touch my_guide.md
+$ bundle exec rake guides:generate ONLY=my_guide
+
+
+
+

默认情况下,没有改动的文章不会处理,因此实际使用中很少用到 ONLY

如果想强制处理所有文章,传入 ALL=1

此外,建议你加上 WARNINGS=1。这样能检测到重复的 ID,遇到死链还会提醒。

如果想生成英语之外的指南,可以把译文放在 source 中的子目录里(如 source/es),然后使用 GUIDES_LANGUAGE 环境变量:

+
+$ bundle exec rake guides:generate GUIDES_LANGUAGE=es
+
+
+
+

如果想查看可用于配置生成脚本的全部环境变量,只需执行:

+
+$ rake
+
+
+
+

5.2 验证

请使用下述命令验证生成的 HTML:

+
+$ bundle exec rake guides:validate
+
+
+
+

尤其要注意,ID 是从标题的内容中生成的,往往会重复。生成指南时请设定 WARNINGS=1,监测重复的 ID。提醒消息中有建议的解决方案。

6 Kindle 版指南

6.1 生成

如果想生成 Kindle 版指南,使用下述 Rake 任务:

+
+$ bundle exec rake guides:generate:kindle
+
+
+
+ + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/security.html b/security.html new file mode 100644 index 0000000..c91d44c --- /dev/null +++ b/security.html @@ -0,0 +1,587 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Ruby on Rails 安全指南

本文介绍 Web 应用中常见的安全问题,以及如何在 Rails 中避免这些问题。

读完本文后,您将学到:

+
    +
  • 所有需要强调的安全对策;

  • +
  • Rails 中会话的概念,应该在会话中保存什么内容,以及常见的攻击方式;

  • +
  • 为什么访问网站也可能带来安全问题(跨站请求伪造);

  • +
  • 处理文件或提供管理界面时需要注意的问题;

  • +
  • 如何管理用户:登录、退出,以及不同层次上的攻击方式;

  • +
  • 最常见的注入攻击方式。

  • +
+

1 简介

Web 应用框架的作用是帮助开发者创建 Web 应用。其中一些框架还能帮助我们提高 Web 应用的安全性。事实上,框架之间无所谓谁更安全,对于许多框架来说,只要使用正确,我们都能开发出安全的应用。Ruby on Rails 提供了一些十分智能的辅助方法,例如,用于防止 SQL 注入的辅助方法,极大减少了这一安全风险。

一般来说,并不存在什么即插即用的安全机制。安全性取决于开发者如何使用框架,有时也取决于开发方式。安全性还取决于 Web 应用环境的各个层面,包括后端存储、Web 服务器和 Web 应用自身等(甚至包括其他 Web应用)。

不过,据高德纳咨询公司(Gartner Group)估计,75% 的攻击发生在 Web 应用层面,报告称“在进行了安全审计的 300 个网站中,97% 存在被攻击的风险”。这是因为针对 Web 应用的攻击相对来说更容易实施,其工作原理和具体操作都比较简单,即使是非专业人士也能发起攻击。

针对 Web 应用的安全威胁包括账户劫持、绕过访问控制、读取或修改敏感数据,以及显示欺诈信息等。有时,攻击者还会安装木马程序或使用垃圾邮件群发软件,以便获取经济利益,或者通过篡改公司资源来损害品牌形象。为了防止这些攻击,最大限度降低或消除攻击造成的影响,首先我们必须全面了解各种攻击方式,只有这样才能找出正确对策——这正是本文的主要目的。

为了开发安全的 Web 应用,我们必须从各个层面紧跟安全形势,做到知己知彼。为此,我们可以订阅安全相关的邮件列表,阅读相关博客,同时养成及时更新并定期进行安全检查的习惯(请参阅其他资源一节)。这些工作都是手动完成的,只有这样我们才能发现潜在安全隐患。

2 会话

从会话入手来了解安全问题是一个很好的切入点,因为会话对于特定攻击十分脆弱。

2.1 会话是什么

HTTP 是无状态协议,会话使其有状态。

大多数应用需要跟踪特定用户的某些状态,例如购物车里的商品、当前登录用户的 ID 等。如果没有会话,就需要为每一次请求标识用户甚至进行身份验证。当新用户访问应用时,Rails 会自动新建会话,如果用户曾经访问过应用,就会加载已有会话。

会话通常由值的散列和会话 ID(通常为 32 个字符的字符串)组成,其中会话 ID 用于标识散列。发送到客户端浏览器的每个 Cookie 都包含会话 ID,另一方面,客户端浏览器发送到服务器的每个请求也包含会话 ID。在 Rails 中,我们可以使用 session 方法保存和取回值:

+
+session[:user_id] = @current_user.id
+User.find(session[:user_id])
+
+
+
+

2.2 会话 ID

会话 ID 是长度为 32 字节的 MD5 散列值。

会话 ID 由随机字符串的散列值组成。这个随机字符串包含当前时间,一个 0 到 1 之间的随机数,Ruby 解析器的进程 ID(基本上也是一个随机数),以及一个常量字符串。目前 Rails 会话 ID 还无法暴力破解。尽管直接破解 MD5 很难,但存在 MD5 碰撞的可能性,理论上可以创建具有相同散列值的另一个输入文本。不过到目前为止,这个问题还未产生安全影响。

2.3 会话劫持

通过窃取用户的会话 ID,攻击者能够以受害者的身份使用 Web 应用。

很多 Web 应用都有身份验证系统:用户提供用户名和密码,Web 应用在验证后把对应的用户 ID 储存到会话散列中。之后,会话就可以合法使用了。对于每个请求,应用都会通过识别会话中储存的用户 ID 来加载用户,从而避免了重新进行身份验证。Cookie 中的会话 ID 用于标识会话。

因此,Cookie 提供了 Web 应用的临时身份验证。只要得到了他人的 Cookie,任何人都能以该用户的身份使用 Web 应用,这可能导致严重的后果。下面介绍几种劫持会话的方式及其对策:

+
    +
  • 在不安全的网络中嗅探 Cookie。无线局域网就是一个例子。在未加密的无线局域网中,监听所有已连接客户端的流量极其容易。因此,Web 应用开发者应该通过 SSL 提供安全连接。在 Rails 3.1 和更高版本中,可以在应用配置文件中设置强制使用 SSL 连接:
  • +
+
+
+config.force_ssl = true
+
+
+
+ +
    +
  • 大多数人在使用公共终端后不会清除 Cookie。因此,如果最后一个用户没有退出 Web 应用,后续用户就能以该用户的身份继续使用。因此,Web 应用一定要提供“退出”按钮,并且要尽可能显眼。

  • +
  • 很多跨站脚本(XSS)攻击的目标是获取用户 Cookie。更多介绍请参阅跨站脚本攻击一节。

  • +
  • 有的攻击者不窃取 Cookie,而是篡改用户 Cookie 中的会话 ID。这种攻击方式被称为固定会话攻击,后文会详细介绍。

  • +
+

大多数攻击者的主要目标是赚钱。根据赛门铁克《互联网安全威胁报告》,被窃取的银行登录账户的黑市价格从 10 到 1000 美元不等(取决于账户余额),信用卡卡号为 0.40 到 20 美元,在线拍卖网站的账户为 1 到 8 美元,电子邮件账户密码为 4 到 30 美元。

2.4 会话安全指南

下面是一些关于会话安全的一般性指南。

+
    +
  • 不要在会话中储存大型对象,而应该把它们储存在数据库中,并将其 ID 保存在会话中。这么做可以避免同步问题,并且不会导致会话存储空间耗尽(会话存储空间的大小取决于其类型,详见后文)。如果不这么做,当修改了对象结构时,用户 Cookie 中保存的仍然是对象的旧版本。通过在服务器端储存会话,我们可以轻而易举地清除会话,而在客户端储存会话,要想清除会话就很麻烦了。

  • +
  • 关键数据不应该储存在会话中。如果用户清除了 Cookie 或关闭了浏览器,这些关键数据就会丢失。并且在客户端储存会话,还会导致用户能够读取关键数据。

  • +
+

2.5 会话存储

Rails 提供了几种会话散列的存储机制。其中最重要的是 ActionDispatch::Session::CookieStore

Rails 2 引入了一种新的默认会话存储机制——CookieStore。CookieStore 把会话散列直接储存在客户端的 Cookie 中。无需会话 ID,服务器就可以从 Cookie 中取回会话散列。这么做可以显著提高程序的运行速度,但也存在争议,因为这种存储机制具有下列安全隐患:

+
    +
  • Cookie 的大小被严格限制为 4 KB。这个限制本身没问题,因为如前文所述,本来就不应该在会话中储存大量数据。在会话中储存当前用户的数据库 ID 一般没问题。

  • +
  • 客户端可以看到储存在会话中的所有内容,因为数据是以明文形式储存的(实际上是 Base64 编码,因此没有加密)。因此,我们不应该在会话中储存隐私数据。为了防止会话散列被篡改,应该根据服务器端密令(secrets.secret_token)计算会话的摘要(digest),然后把这个摘要添加到 Cookie 的末尾。

  • +
+

不过,从 Rails 4 开始,默认存储机制是 EncryptedCookieStore。EncryptedCookieStore 会先对会话进行加密,再储存到 Cookie 中。这么做可以防止用户访问和篡改 Cookie 的内容。因此,会话也成为储存数据的更安全的地方。加密时需要使用 config/secrets.yml 文件中储存的服务器端密钥 secrets.secret_key_base

这意味着 EncryptedCookieStore 存储机制的安全性由密钥(以及摘要算法,出于兼容性考虑默认为 SHA1 算法)决定。因此,密钥不能随意取值,例如从字典中找一个单词,或少于 30 个字符,应该使用 rails secret 生成密钥。

secrets.secret_key_base 用于指定密钥,在应用中会话使用这个密钥来验证已知密钥,以防止篡改。在创建应用时,config/secrets.yml 文件中储存的 secrets.secret_key_base 是一个随机密钥,例如:

+
+development:
+  secret_key_base: a75d...
+
+test:
+  secret_key_base: 492f...
+
+production:
+  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
+
+
+
+

Rails 老版本中的 CookieStore 使用的是 secret_token,而不是 EncryptedCookieStore 所使用的 secret_key_base。更多介绍请参阅升级文档。

如果应用的密钥泄露了(例如应用开放了源代码),强烈建议更换密钥。

2.6 对 CookieStore 会话的重放攻击(replay attack)

重放攻击是使用 CookieStore 时必须注意的另一种攻击方式。

重放攻击的工作原理如下:

+
    +
  • 用户获得的信用额度保存在会话中(信用额度实际上不应该保存在会话中,这里只是出于演示目的才这样做);

  • +
  • 用户使用部分信用额度购买商品;

  • +
  • 减少后的信用额度仍然保存在会话中;

  • +
  • 用户先前复制了第一步中的 Cookie,并用这个 Cookie 替换浏览器中的当前 Cookie;

  • +
  • 用户重新获得了消费前的信用额度。

  • +
+

在会话中包含随机数可以防止重放攻击。每个随机数验证一次后就会失效,服务器必须跟踪所有有效的随机数。当有多个应用服务器时,情况会变得更复杂,因为我们不能把随机数储存在数据库中,否则就违背了使用 CookieStore 的初衷(避免访问数据库)。

因此,防止重放攻击的最佳方案,不是把这类敏感数据储存在会话中,而是把它们储存在数据库中。回到上面的例子,我们可以把信用额度储存在数据库中,而把当前用户的 ID 储存在会话中。

2.7 会话固定攻击(session fixation)

除了窃取用户的会话 ID 之外,攻击者还可以直接使用已知的会话 ID。这种攻击方式被称为会话固定攻击。

session fixation

会话固定攻击的关键是强制用户的浏览器使用攻击者已知的会话 ID,这样攻击者就无需窃取会话 ID。会话固定攻击的工作原理如下:

+
    +
  • 攻击者创建一个有效的会话 ID:打开 Web 应用的登录页面,从响应中获取 Cookie 中的会话 ID(参见上图中的第 1 和第 2 步)。

  • +
  • 攻击者定期访问 Web 应用,以避免会话过期。

  • +
  • 攻击者强制用户的浏览器使用这个会话 ID(参见上图中的第 3 步)。由于无法修改另一个域名的 Cookie(基于同源原则的限制),攻击者必须在目标 Web 应用的域名上运行 JavaScript,也就是通过 XSS 把 JavaScript 注入目标 Web 应用来完成攻击。例如:<script>document.cookie="_session_id=16d5b78abb28e3d6206b60f22a03c8d9";</script>。关于 XSS 和注入的更多介绍见后文。

  • +
  • 攻击者诱使用户访问包含恶意 JavaScript 代码的页面,这样用户的浏览器中的会话 ID 就会被篡改为攻击者已知的会话 ID。

  • +
  • 由于这个被篡改的会话还未使用过,Web 应用会进行身份验证。

  • +
  • 此后,用户和攻击者将共用同一个会话来访问 Web 应用。攻击者篡改后的会话成为了有效会话,用户面对攻击却浑然不知。

  • +
+

2.8 会话固定攻击的对策

一行代码就能保护我们免受会话固定攻击。

面对会话固定攻击,最有效的对策是在登录成功后重新设置会话 ID,并使原有会话 ID 失效,这样攻击者持有的会话 ID 也就失效了。这也是防止会话劫持的有效对策。在 Rails 中重新设置会话 ID 的方式如下:

+
+reset_session
+
+
+
+

如果我们使用流行的 Devise gem 完成用户管理,Devise 会在用户登录和退出时自动使原有会话过期。如果打算手动完成用户管理,请记住在登录操作后(新会话创建后)使原有会话过期。会话过期后其中的值都会被删除,因此我们需要把有用的值转移到新会话中。

另一个对策是在会话中保存用户相关的属性,对于每次请求都验证这些属性,如果信息不匹配就拒绝访问。这些属性包括 IP 地址、用户代理(Web 浏览器名称),其中用户代理的用户相关性要弱一些。在保存 IP 地址时,必须注意,有些网络服务提供商(ISP)或大型组织,会把用户置于代理服务器之后。在会话的生命周期中,这些代理服务器有可能发生变化,从而导致用户无法正常使用应用,或出现权限问题。

2.9 会话过期

永不过期的会话增加了跨站请求伪造(CSRF)、会话劫持和会话固定攻击的风险。

Cookie 的过期时间可以通过会话 ID 设置。然而,客户端能够修改储存在 Web 浏览器中的 Cookie,因此在服务器上使会话过期更安全。下面的例子演示了如何使储存在数据库中的会话过期。通过调用 Session.sweep("20 minutes"),可以使闲置超过 20 分钟的会话过期。

+
+class Session < ApplicationRecord
+  def self.sweep(time = 1.hour)
+    if time.is_a?(String)
+      time = time.split.inject { |count, unit| count.to_i.send(unit) }
+    end
+
+    delete_all "updated_at < '#{time.ago.to_s(:db)}'"
+  end
+end
+
+
+
+

“会话固定攻击”一节介绍了维护会话的问题。攻击者每五分钟维护一次会话,就可以使会话永远保持活动,不会过期。针对这个问题的一个简单解决方案是在会话数据表中添加 created_at 字段,这样就可以找出创建了很长时间的会话并删除它们。可以用下面这行代码代替上面例子中的对应代码:

+
+delete_all "updated_at < '#{time.ago.to_s(:db)}' OR
+  created_at < '#{2.days.ago.to_s(:db)}'"
+
+
+
+

3 跨站请求伪造(CSRF)

跨站请求伪造的工作原理是,通过在页面中包含恶意代码或链接,访问已验证用户才能访问的 Web 应用。如果该 Web 应用的会话未超时,攻击者就能执行未经授权的操作。

csrf

会话一节中,我们了解到大多数 Rails 应用都使用基于 Cookie 的会话。它们或者把会话 ID 储存在 Cookie 中并在服务器端储存会话散列,或者把整个会话散列储存在客户端。不管是哪种情况,只要浏览器能够找到某个域名对应的 Cookie,就会自动在发送请求时包含该 Cookie。有争议的是,即便请求来源于另一个域名上的网站,浏览器在发送请求时也会包含客户端的 Cookie。让我们来看个例子:

+
    +
  • 鲍勃在访问留言板时浏览了一篇黑客发布的帖子,其中有一个精心设计的 HTML 图片元素。这个元素实际指向的是鲍勃的项目管理应用中的某个操作,而不是真正的图片文件:<img src="http://www.webapp.com/project/1/destroy">

  • +
  • 鲍勃在 www.webapp.com 上的会话仍然是活动的,因为几分钟前他访问这个应用后没有退出。

  • +
  • 当鲍勃浏览这篇帖子时,浏览器发现了这个图片标签,于是尝试从 www.webapp.com 上加载图片。如前文所述,浏览器在发送请求时包含了 Cookie,其中包含了有效的会话 ID。

  • +
  • www.webapp.com 上的 Web 应用会验证对应会话散列中的用户信息,并删除 ID 为 1 的项目,然后返回结果页面。由于返回的并非浏览器所期待的结果,图片无法显示。

  • +
  • 鲍勃当时并未发觉受到了攻击,但几天后,他发现 ID 为 1 的项目不见了。

  • +
+

有一点需要特别注意,像上面这样精心设计的图片或链接,并不一定要出现在 Web 应用所在的域名上,而是可以出现在任何地方,例如论坛、博客帖子,甚至电子邮件中。

CSRF 在 CVE(Common Vulnerabilities and Exposures,公共漏洞披露)中很少出现,在 2006 年不到 0.1%,但却是个可怕的隐形杀手。对于很多安全保障工作来说,CSRF 是一个严重的安全问题。

3.1 CSRF 对策

首先,根据 W3C 的要求,应该适当地使用 GETPOST HTTP 方法。其次,在非 GET 请求中使用安全令牌(security token),可以防止应用受到 CSRF 攻击。

HTTP 协议提供了两种主要的基本请求类型,GETPOST(还有其他请求类型,但大多数浏览器不支持)。万维网联盟(W3C)提供了检查表,以帮助开发者在 GETPOST 这两个 HTTP 方法之间做出正确选择:

使用 GET HTTP 方法的情形:

+
    +
  • 当交互更像是在询问时,例如查询、读取、查找等安全操作。
  • +
+

使用 POST HTTP 方法的情形:

+
    +
  • 当交互更像是在执行命令时;

  • +
  • 当交互改变了资源的状态并且这种变化能够被用户察觉时,例如订阅某项服务;

  • +
  • 当用户需要对交互结果负责时。

  • +
+

如果应用是 REST 式的,我们还可以使用附加的 HTTP 方法,例如 PATCHPUTDELETE。然而现今的大多数浏览器都不支持这些 HTTP 方法,只有 GETPOST 得到了普遍支持。Rails 通过隐藏的 _method 字段来解决这个问题。

POST 请求也可以自动发送。在下面的例子中,链接 www.harmless.com 在浏览器状态栏中显示为目标地址,实际上却动态新建了一个发送 POST 请求的表单:

+
+<a href="http://www.harmless.com/" onclick="
+  var f = document.createElement('form');
+  f.style.display = 'none';
+  this.parentNode.appendChild(f);
+  f.method = 'POST';
+  f.action = 'http://www.example.com/account/destroy';
+  f.submit();
+  return false;">To the harmless survey</a>
+
+
+
+

攻击者还可以把代码放在图片的 onmouseover 事件句柄中:

+
+<img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." />
+
+
+
+

CSRF 还有很多可能的攻击方式,例如使用 <script> 标签向返回 JSONP 或 JavaScript 的 URL 地址发起跨站请求。对跨站请求的响应,返回的如果是攻击者可以设法运行的可执行代码,就有可能导致敏感数据泄露。为了避免发生这种情况,我们必须禁用跨站 <script> 标签。不过 Ajax 请求是遵循同源原则的(只有在同一个网站中才能初始化 XmlHttpRequest),因此在响应 Ajax 请求时返回 JavaScript 是安全的,不必担心跨站请求问题。

注意:我们无法区分 <script> 标签的来源,无法知道这个标签是自己网站上的,还是其他恶意网站上的,因此我们必须全面禁止 <script> 标签,哪怕这个标签实际上来源于自己网站上的安全的同源脚本。在这种情况下,对于返回 JavaScript 的控制器动作,显式跳过 CSRF 保护,就意味着允许使用 <scipt> 标签。

为了防止其他各种伪造请求,我们引入了安全令牌,这个安全令牌只有我们自己的网站知道,其他网站不知道。我们把安全令牌包含在请求中,并在服务器上进行验证。这是应用的控制器中的一个线程,也是新建 Rails 应用的默认值:

+
+protect_from_forgery with: :exception
+
+
+
+

这行代码会在 Rails 生成的所有表单和 Ajax 请求中包含安全令牌。如果安全令牌验证失败,就会抛出异常。

默认情况下,Rails 会包含 jQuery 和 jQuery 非侵入式适配器,后者会在 jQuery 的每个非 GET Ajax 调用中添加名为 X-CSRF-Token 的头信息,其中包含安全令牌。如果没有这个头信息,Rails 不会接受非 GET Ajax 请求。当使用其他库进行 Ajax 调用时,同样需要把安全令牌作为 Ajax 调用的默认头信息添加到库中。要想获取令牌,请查看应用视图中由 <%= csrf_meta_tags %> 这行代码生成的 <meta name='csrf-token' content='THE-TOKEN'> 标签。

通常我们会使用持久化 Cookie 来储存用户信息,例如使用 cookies.permanent。在这种情况下,Cookie 不会被清除,CSRF 保护也无法自动生效。如果使用了其他 Cookie 存储而不是会话来保存用户信息,我们就必须手动解决这个问题:

+
+rescue_from ActionController::InvalidAuthenticityToken do |exception|
+  sign_out_user # 删除用户 Cookie 的示例方法
+end
+
+
+
+

这段代码可以放在 ApplicationController 中。对于非 GET 请求,如果 CSRF 令牌不存在或不正确,就会执行这段代码。

注意,跨站脚本(XSS)漏洞能够绕过所有 CSRF 保护。攻击者通过 XSS 可以访问页面中的所有元素,也就是说攻击者可以读取表单中的 CSRF 安全令牌,也可以直接提交表单。更多介绍请参阅跨站脚本一节。

4 重定向和文件

另一类安全漏洞由 Web 应用中的重定向和文件引起。

4.1 重定向

Web 应用中的重定向是一个被低估的黑客工具:攻击者不仅能够把用户的访问跳转到恶意网站,还能够发起独立攻击。

只要允许用户指定 URL 重定向地址(或其中的一部分),就有可能造成风险。最常见的攻击方式是,把用户重定向到假冒的 Web 应用,这个假冒的 Web 应用看起来感觉和真的一模一样。这就是所谓的钓鱼攻击。攻击者发动钓鱼攻击时,或者给用户发送包含恶意链接的邮件,或者通过 XSS 在 Web 应用中注入恶意链接,或者把恶意链接放入其他网站。这些恶意链接一般不会引起用户的怀疑,因为它们以正常的网站 URL 开头,而把恶意网站的 URL 隐藏在重定向参数中,例如http://www.example.com/site/redirect?to= www.attacker.com。让我们来看一个例子:

+
+def legacy
+  redirect_to(params.update(action:'main'))
+end
+
+
+
+

如果用户访问 legacy 动作,就会被重定向到 main 动作,同时传递给 legacy 动作的 URL 参数会被保留并传递给 main 动作。然而,攻击者通过在 URL 地址中包含 host 参数就可以发动攻击:

+
+http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com
+
+
+
+

如果 host 参数出现在 URL 地址末尾,将很难被注意到,从而会把用户重定向到 www.attacker.com 这个恶意网站。一个简单的对策是,在 legacy 动作中只保留所期望的参数(使用白名单,而不是去删除不想要的参数)。对于用户指定的重定向 URL 地址,应该通过白名单或正则表达式进行检查。

4.1.1 独立的 XSS

在 Firefox 和 Opera 浏览器中,通过使用 data 协议,还能发起另一种重定向和独立 XSS 攻击。data 协议允许把内容直接显示在浏览器中,支持的类型包括 HTML、JavaScript 和图片,例如:

+
+data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K
+
+
+
+

这是一段使用 Base64 编码的 JavaScript 代码,运行后会显示一个消息框。通过这种方式,攻击者可以使用恶意代码把用户重定向到恶意网站。为了防止这种攻击,我们的对策是禁止用户指定 URL 重定向地址。

4.2 文件上传

请确保文件上传时不会覆盖重要文件,同时对于媒体文件应该采用异步上传方式。

很多 Web 应用都允许用户上传文件。由于文件名通常由用户指定(或部分指定),必须对文件名进行过滤,以防止攻击者通过指定恶意文件名覆盖服务器上的文件。如果我们把上传的文件储存在 /var/www/uploads 文件夹中,而用户输入了类似 "../../../etc/passwd" 的文件名,在没有对文件名进行过滤的情况下,passwd 这个重要文件就有可能被覆盖。当然,只有在 Ruby 解析器具有足够权限时文件才会被覆盖,这也是不应该使用 Unix 特权用户运行 Web 服务器、数据库服务器和其他应用的原因之一。

在过滤用户输入的文件名时,不要去尝试删除文件名的恶意部分。我们可以设想这样一种情况,Web 应用把文件名中所有的 "../" 都删除了,但攻击者使用的是 "…​.//" 这样的字符串,于是过滤后的文件名中仍然包含 "../"。最佳策略是使用白名单,只允许在文件名中使用白名单中的字符。黑名单的做法是尝试删除禁止使用的字符,白名单的做法恰恰相反。对于无效的文件名,可以直接拒绝(或者把禁止使用的字符都替换掉),但不要尝试删除禁止使用的字符。下面这个文件名净化程序来自 attachment_fu 插件:

+
+def sanitize_filename(filename)
+  filename.strip.tap do |name|
+    # NOTE: File.basename doesn't work right with Windows paths on Unix
+    # get only the filename, not the whole path
+    name.sub! /\A.*(\\|\/)/, ''
+    # Finally, replace all non alphanumeric, underscore
+    # or periods with underscore
+    name.gsub! /[^\w\.\-]/, '_'
+  end
+end
+
+
+
+

通过同步方式上传文件(attachment_fu 插件也可能被用于上传图片)的一个明显缺点是,存在受到拒绝服务攻击(denial-of-service,简称 DoS)的风险。攻击者可以通过很多计算机同时上传图片,这将导致服务器负载增加,并最终导致应用崩溃或服务器宕机。

最佳解决方案是,对于媒体文件采用异步上传方式:保存媒体文件,并通过数据库调度程序处理请求。由另一个进程在后台完成文件上传。

4.3 文件上传中的可执行代码

如果把上传的文件储存在某些特定的文件夹中,文件中的源代码就有可能被执行。因此,如果 Rails 应用的 /public 文件夹被设置为 Apache 的主目录,请不要在这个文件夹中储存上传的文件。

流行的 Apache Web 服务器的配置文件中有一个名为 DocumentRoot 的选项,用于指定网站的主目录。主目录及其子文件夹中的所有内容都由 Web 服务器直接处理。如果其中包含了一些具有特定扩展名的文件,就能够通过 HTTP 请求执行这些文件中的代码(可能还需要设置一些选项),例如 PHP 和 CGI 文件。假设攻击者上传了 "file.cgi" 文件,其中包含了可执行代码,那么之后有人下载这个文件时,这些代码就会在服务器上执行。

如果 Apache 的 DocumentRoot 选项指向 Rails 的 /public 文件夹,请不要在其中储存上传的文件,至少也应该储存在子文件夹中。

4.4 文件下载

请确保用户不能随意下载文件。

正如在上传文件时必须过滤文件名,在下载文件时也必须进行过滤。send_file() 方法用于把服务器上的文件发送到客户端。如果传递给 send_file() 方法的文件名参数是由用户输入的,却没有进行过滤,用户就能够下载服务器上的任何文件:

+
+send_file('/var/www/uploads/' + params[:filename])
+
+
+
+

可以看到,只要指定 "../../../etc/passwd" 这样的文件名,用户就可以下载服务器登录信息。对此,一个简单的解决方案是,检查所请求的文件是否在规定的文件夹中:

+
+basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files'))
+filename = File.expand_path(File.join(basename, @file.public_filename))
+raise if basename !=
+     File.expand_path(File.join(File.dirname(filename), '../../../'))
+send_file filename, disposition: 'inline'
+
+
+
+

另一个(附加的)解决方案是在数据库中储存文件名,并以数据库中的记录 ID 作为文件名,把文件保存到磁盘。这样做还能有效防止上传的文件中的代码被执行。attachment_fu 插件具有类似的工作原理。

5 局域网和管理界面的安全

由于具有访问特权,局域网和管理界面成为了常见的攻击目标。因此理应为它们采取多种安全防护措施,然而实际情况却不理想。

2007年,第一个在局域网中窃取信息的专用木马出现了,它的名字叫“员工怪兽”(Monster for employers),用于攻击在线招聘网站 Monster.com。专用木马非常少见,迄今为止造成的安全风险也相当低,但这种攻击方式毕竟是存在的,说明客户端的安全问题不容忽视。然而,对局域网和管理界面而言,最大的安全威胁来自 XSS 和 CSRF。

XSS 如果在应用中显示了来自外网的恶意内容,应用就有可能受到 XSS 攻击。例如用户名、用户评论、垃圾信息报告、订单地址等等,都有可能受到 XSS攻击。

在局域网和管理界面中,只要有一个地方没有对输入进行过滤,整个应用就有可能受到 XSS 攻击。可能发生的攻击包括:窃取具有特权的管理员的 Cookie,注入 iframe 以窃取管理员密码,以及通过浏览器漏洞安装恶意软件以控制管理员的计算机。

关于 XSS 攻击的对策,请参阅注入一节。在局域网和管理界面中同样推荐使用 SafeErb 插件。

CSRF 跨站请求伪造(CSRF),也称为跨站引用伪造(XSRF),是一种破坏性很强的攻击方法,它允许攻击者完成管理员或局域网用户可以完成的一切操作。前文我们已经介绍过 CSRF 的工作原理,下面是攻击者针对局域网和管理界面发动 CSRF 攻击的几个例子。

一个真实案例是通过 CSRF 攻击重新设置路由器。攻击者向墨西哥用户发送包含 CSRF 代码的恶意电子邮件。邮件声称用户收到了一张电子贺卡,并且包含了一个能够发起 HTTP GET 请求的图片标签,以便重新设置用户的路由器(针对一款在墨西哥很常见的路由器)。攻击改变了路由器的 DNS 设置,当用户访问墨西哥境内银行的网站时,就会被带到攻击者的网站。通过受攻击的路由器访问银行网站的所有用户,都会被带到攻击者的假冒网站,最终导致用户的网银账号失窍。

另一个例子是修改 Google Adsense 账户的电子邮件和密码。一旦受害者登录 Google Adsense,打算对自己投放的 Google 广告进行管理,攻击者就能够趁机修改受害者的登录信息。

还有一种常见的攻击方式是在 Web 应用中大量发布垃圾信息,通过博客、论坛来传播 XSS 恶意脚本。当然,攻击者还得知道 URL 地址的结构才能发动攻击,但是大多数 Rails 应用的 URL 地址结构都很简单,很容易就能搞清楚,对于开源应用的管理界面更是如此。通过包含恶意图片标签,攻击者甚至可以进行上千次猜测,把 URL 地址结构所有可能的组合都尝试一遍。

关于针对局域网和管理界面发动的 CSRF 攻击的对策,请参阅CSRF 对策一节。

5.1 其他预防措施

通用管理界面的一般工作原理如下:通过 www.example.com/admin 访问,访问仅限于 User 模型的 admin 字段设置为 true 的用户。管理界面中会列出用户输入的数据,管理员可以根据需要对数据进行删除、添加或修改。下面是关于管理界面的一些参考意见:

+
    +
  • 考虑最坏的情况非常重要:如果有人真的得到了用户的 Cookie 或账号密码怎么办?可以为管理界面引入用户角色权限设计,以限制攻击者的权限。或者为管理界面启用特殊的登录账号密码,而不采用应用的其他部分所使用的账号密码。对于特别重要的操作,还可以要求用户输入专用密码。

  • +
  • 管理员真的有可能从世界各地访问管理界面吗?可以考虑对登录管理界面的 IP 段进行限制。用户的 IP 地址可以通过 request.remote_ip 获取。这个解决方案虽然不能说万无一失,但确实为管理界面筑起了一道坚实的防线。不过在实际操作中,还要注意用户是否使用了代理服务器。

  • +
  • 通过专用子域名访问管理界面,如 admin.application.com,并为管理界面建立独立的应用和账户系统。这样,攻击者就无法从日常使用的域名(如 www.application.com)中窃取管理员的 Cookie。其原理是:基于浏览器的同源原则,在 www.application.com 中注入的 XSS 脚本,无法读取 admin.application.com 的 Cookie,反之亦然。

  • +
+

6 用户管理

几乎每个 Web 应用都必须处理授权和身份验证。自己实现这些功能并非首选,推荐的做法是使用插件。但在使用插件时,一定要记得及时更新。此外,还有一些预防措施可以使我们的应用更安全。

Rails 有很多可用的身份验证插件,其中有不少佳作,例如 deviseauthlogic。这些插件只储存加密后的密码,而不储存明文密码。从 Rails 3.1 起,我们可以使用实现了类似功能的 has_secure_password 内置方法。

每位新注册用户都会收到一封包含激活码和激活链接的电子邮件,以便激活账户。账户激活后,该用户的数据库记录的 activation_code 字段会被设置为 NULL。如果有人访问了下列 URL 地址,就有可能以数据库中找到的第一个已激活用户的身份登录(有可能是管理员):

+
+http://localhost:3006/user/activate
+http://localhost:3006/user/activate?id=
+
+
+
+

之所以出现这种可能性,是因为对于某些服务器,ID 参数 params[:id] 的值是 nil,而查找激活码的代码如下:

+
+User.find_by_activation_code(params[:id])
+
+
+
+

当 ID 参数为 nil 时,生成的 SQL 查询如下:

+
+SELECT * FROM users WHERE (users.activation_code IS NULL) LIMIT 1
+
+
+
+

因此,查询结果是数据库中的第一个已激活用户,随后将以这个用户的身份登录。关于这个问题的更多介绍,请参阅这篇博客。在使用插件时,建议及时更新。此外,通过代码审查可以找出应用的更多类似缺陷。

6.1 暴力破解账户

对账户的暴力攻击是指对登录的账号密码进行试错攻击。通过显示较为模糊的错误信息、要求输入验证码等方式,可以增加暴力破解的难度。

Web 应用的用户名列表有可能被滥用于暴力破解密码,因为大多数用户并没有使用复杂密码。大多数密码是字典中的单词的组合,或单词和数字的组合。有了用户名列表和字典,自动化程序在几分钟内就可能找到正确密码。

因此,如果登录时用户名或密码不正确,大多数 Web 应用都会显示较为模糊的错误信息,如“用户名或密码不正确”。如果提示“未找到您输入的用户名”,攻击者就可以根据错误信息,自动生成精简后的有效用户名列表,从而提高攻击效率。

不过,容易被大多数 Web 应用设计者忽略的,是忘记密码页面。通过这个页面,通常能够确认用户名或电子邮件地址是否有效,攻击者可以据此生成用于暴力破解的用户名列表。

为了规避这种攻击,忘记密码页面也应该显示较为模糊的错误信息。此外,当某个 IP 地址多次登录失败时,可以要求输入验证码。但是要注意,这并非防范自动化程序的万无一失的解决方案,因为这些程序可能会频繁更换 IP 地址,不过毕竟还是筑起了一道防线。

6.2 账户劫持

对于很多 Web 应用来说,实施账户劫持是一件很容易的事情。既然这样,为什么不尝试改变,想办法增加账户劫持的难度呢?

6.2.1 密码

假设攻击者窃取了用户会话的 Cookie,因而能够像用户一样使用应用。此时,如果修改密码很容易,攻击者只需点击几次鼠标就能劫持该账户。另一种可能性是,修改密码的表单容易受到 CSRF 攻击,攻击者可以诱使受害者访问包含精心设计的图片标签的网页,通过 CSRF 窃取密码。针对这种攻击的对策是,在修改密码的表单中加入 CSRF 防护,同时要求用户在修改密码时先输入旧密码。

6.2.2 电子邮件

然而,攻击者还能通过修改电子邮件地址来劫持账户。一旦攻击者修改了账户的电子邮件地址,他们就会进入忘记密码页面,通过新邮件地址接收找回密码邮件。针对这种攻击的对策是,要求用户在修改电子邮件地址时同样先输入旧密码。

6.2.3 其他

针对不同的 Web 应用,还可能存在更多的劫持用户账户的攻击方式。这些攻击方式大都借助于 CSRF 和 XSS,例如 Gmail 的 CSRF 漏洞。在这种概念验证攻击中,攻击者诱使受害者访问自己控制的网站,其中包含了精心设计的图片标签,然后通过 HTTP GET 请求修改 Gmail 的过滤器设置。如果受害者已经登录了 Gmail,攻击者就能通过修改后的过滤器把受害者的所有电子邮件转发到自己的电子邮件地址。这种攻击的危害性几乎和劫持账户一样大。针对这种攻击的对策是,通过代码审查封堵所有 XSS 和 CSRF 漏洞。

6.3 验证码

验证码是一种质询-响应测试,用于判断响应是否由计算机生成。验证码要求用户输入变形图片中的字符,以防止恶意注册和发布垃圾评论。验证码又分为积极验证码和消极验证码。消极验证码的思路不是证明用户是人类,而是证明机器人是机器人。

reCAPTCHA(注:链接已失效)是一种流行的积极验证码 API,它会显示两张来自古籍的单词的变形图片,同时还添加了弯曲的中划线。相比之下,早期的验证码仅使用了扭曲的背景和高度变形的文本,所以后来被破解了。此外,使用 reCAPTCHA 同时是在为古籍数字化作贡献。和 reCAPTCHA API 同名的 reCAPTCHA 是一个 Rails 插件。

reCAPTCHA API 提供了公钥、私钥两个密钥,它们应该在 Rails 环境中设置。设置完成后,我们就可以在视图中使用 recaptcha_tags 方法,在控制器中使用 verify_recaptcha 方法。如果验证码验证失败,verify_recaptcha 方法会返回 false。验证码的缺点是影响用户体验。并且对于视障用户,有些变形的验证码难以看清。尽管如此,积极验证码仍然是防止各种机器人提交表单的最有效的方法之一。

大多数机器人都很笨拙,它们在网上爬行,并在找到的每一个表单字段中填入垃圾信息。消极验证码正是利用了这一点,只要通过 JavaScript 或 CSS 在表单中添加隐藏的“蜜罐”字段,就能发现那些机器人。

注意,消极验证码只能有效防范笨拙的机器人,对于那些针对关键应用的专用机器人就力不从心了。不过,通过组合使用消极验证码和积极验证码,可以获得更好的性能表现。例如,如果“蜜罐”字段不为空(发现了机器人),再验证积极验码就没有必要了,从而避免了向 Google ReCaptcha 发起 HTTPS 请求。

通过 JavaScript 或 CSS 隐藏“蜜罐”字段有下面几种思路:

+
    +
  • 把字段置于页面的可见区域之外;

  • +
  • 使元素非常小或使它们的颜色与页面背景相同;

  • +
  • 仍然显示字段,但告诉用户不要填写。

  • +
+

最简单的消极验证码是一个隐藏的“蜜罐”字段。在服务器端,我们需要检查这个字段的值:如果包含任何文本,就说明请求来自机器人。然后,我们可以直接忽略机器人提交的表单数据。也可以提示保存成功但实际上并不写入数据库,这样被愚弄的机器人就会自动离开了。对于不受欢迎的用户,也可以采取类似措施。

Ned Batchelder 在博客文章中介绍了更复杂的消极验证码:

+
    +
  • 在表单中包含带有当前 UTC 时间戳的字段,并在服务器端检查这个字段。无论字段中的时间过早还是过晚,都说该明表单不合法;

  • +
  • 随机生成字段名;

  • +
  • 包含各种类型的多个“蜜罐”字段,包括提交按钮。

  • +
+

注意,消极验证码只能防范自动机器人,而不能防范专用机器人。因此,消极验证码并非保护登录表单的最佳方案。

6.4 日志

告诉 Rails 不要把密码写入日志。

默认情况下,Rails 会记录 Web 应用收到的所有请求。但是日志文件也可能成为巨大的安全问题,因为其中可能包含登录的账号密码、信用卡号码等。当我们考虑 Web 应用的安全性时,我们应该设想攻击者完全获得 Web 服务器访问权限的情况。如果在日志文件中可以找到密钥和密码的明文,在数据库中对这些信息进行加密就变得毫无意义。在应用配置文件中,我们可以通过设置 config.filter_parameters 选项,指定写入日志时需要过滤的请求参数。在日志中,这些被过滤的参数会显示为 [FILTERED]

+
+config.filter_parameters << :password
+
+
+
+

通过正则表达式,与配置中指定的参数部分匹配的所有参数都会被过滤掉。默认情况下,Rails 已经在初始化程序(initializers/filter_parameter_logging.rb)中指定了 :password 参数,因此应用中常见的 passwordpassword_confirmation 参数都会被过滤。

6.5 好的密码

你是否发现,要想记住所有密码太难了?请不要因此把所有密码都完整地记下来,我们可以使用容易记住的句子中单词的首字母作为密码。

安全技术专家 Bruce Schneier 通过分析下面提到的 MySpace 钓鱼攻击中 34,000 个真实的用户名和密码,发现绝大多数密码非常容易破解。其中最常见的 20 个密码是:

+
+password1, abc123, myspace1, password, blink182, qwerty1, ****you, 123abc, baseball1, football1, 123456, soccer, monkey1, liverpool1, princess1, jordan23, slipknot1, superman1, iloveyou1, monkey
+
+
+
+

有趣的是,这些密码中只有 4% 是字典单词,绝大多数密码实际是由字母和数字组成的。不过,用于破解密码的字典中包含了大量目前常用的密码,而且攻击者还会尝试各种字母数字的组合。如果我们使用了弱密码,一旦攻击者知道了我们的用户名,就能轻易破解我们的账户。

好的密码是混合使用大小写字母和数字的长密码。但这样的密码很难记住,因此我们可以使用容易记住的句子中单词的首字母作为密码。例如,“The quick brown fox jumps over the lazy dog”对应的密码是“Tqbfjotld”。当然,这里只是举一个例子,实际在选择密码时不应该使用这样的名句,因为用于破解密码的字典中很可能包含了这些名句对应的密码。

6.6 正则表达式

在使用 Ruby 的正则表达式时,一个常见错误是使用 ^$ 分别匹配字符串的开头和结尾,实际上正确的做法是使用 \A\z

Ruby 的正则表达式匹配字符串开头和结尾的方式与很多其他语言略有不同。甚至很多 Ruby 和 Rails 的书籍都把这个问题搞错了。那么,为什么这个问题会造成安全威胁呢?让我们看一个例子。如果想要不太严谨地验证 URL 地址,我们可以使用下面这个简单的正则表达式:

+
+/^https?:\/\/[^\n]+$/i
+
+
+
+

这个正则表达式在某些语言中可以正常工作,但在 Ruby 中,^$ 分别匹配行首和行尾,因此下面这个 URL 能够顺利通过验证:

+
+javascript:exploit_code();/*
+http://hi.com
+*/
+
+
+
+

之所以能通过验证,是因为用于验证的正则表达式匹配了这个 URL 的第二行,因而不会再验证其他两行。假设我们在视图中像下面这样显示 URL:

+
+link_to "Homepage", @user.homepage
+
+
+
+

这个链接看起来对访问者无害,但只要一点击,就会执行 exploit_code 这个 JavaScript 函数或攻击者提供的其他 JavaScript 代码。

要想修正这个正则表达式,我们可以用 \A\z 分别代替 ^$,即:

+
+/\Ahttps?:\/\/[^\n]+\z/i
+
+
+
+

由于这是一个常见错误,Rails 已经采取了预防措施,如果提供的正则表达式以 ^ 开头或以 $ 结尾,格式验证器(validates_format_of)就会抛出异常。如果确实需要用 ^$ 代替 \A\z(这种情况很少见),我们可以把 :multiline 选项设置为 true,例如:

+
+# content 字符串应包含 “Meanwhile” 这样一行
+validates :content, format: { with: /^Meanwhile$/, multiline: true }
+
+
+
+

注意,这种方式只能防止格式验证中的常见错误,在 Ruby 中,我们需要时刻记住,^$ 分别匹配行首和行尾,而不是整个字符串的开头和结尾。

6.7 提升权限

只需纂改一个参数,就有可能使用户获得未经授权的权限。记住,不管我们如何隐藏或混淆,每一个参数都有可能被纂改。

用户最常篡改的参数是 ID,例如在 http://www.domain.com/project/1 这个 URL 地址中,ID 是 1。在控制器中可以通过 params 得到这个 ID,通常的操作如下:

+
+@project = Project.find(params[:id])
+
+
+
+

对于某些 Web 应用,这样做没问题。但如果用户不具有查看所有项目的权限,就不能这样做。否则,如果某个用户把 URL 地址中的 ID 改为 42,并且该用户没有查看这个项目的权限,结果却仍然能够查看项目。为此,我们需要同时查询用户的访问权限:

+
+@project = @current_user.projects.find(params[:id])
+
+
+
+

对于不同的 Web 应用,用户能够纂改的参数也不同。根据经验,未经验证的用户输入都是不安全的,来自用户的参数都有被纂改的潜在风险。

通过混淆参数或 JavaScript 来实现安全性一点儿也不可靠。通过 Mozilla Firefox 的 Web 开发者工具栏,我们可以查看和修改表单的隐藏字段。JavaScript 常用于验证用户输入数据,但无法防止攻击者发送带有不合法数据的恶意请求。Mozilla Firefox 的 Live Http Headers 插件,可以记录每次请求,而且可以重复发起并修改这些请求,这样就能轻易绕过 JavaScript 验证。还有一些客户端代理,允许拦截进出的任何网络请求和响应。

7 注入

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/stylesheets/fixes.css b/stylesheets/fixes.css new file mode 100644 index 0000000..bf86b29 --- /dev/null +++ b/stylesheets/fixes.css @@ -0,0 +1,16 @@ +/* + Fix a rendering issue affecting WebKits on Mac. + See https://github.com/lifo/docrails/issues#issue/16 for more information. +*/ +.syntaxhighlighter a, +.syntaxhighlighter div, +.syntaxhighlighter code, +.syntaxhighlighter table, +.syntaxhighlighter table td, +.syntaxhighlighter table tr, +.syntaxhighlighter table tbody, +.syntaxhighlighter table thead, +.syntaxhighlighter table caption, +.syntaxhighlighter textarea { + line-height: 1.25em !important; +} diff --git a/stylesheets/kindle.css b/stylesheets/kindle.css new file mode 100644 index 0000000..b26cd17 --- /dev/null +++ b/stylesheets/kindle.css @@ -0,0 +1,11 @@ +p { text-indent: 0; } + +p, H1, H2, H3, H4, H5, H6, H7, H8, table { margin-top: 1em;} + +.pagebreak { page-break-before: always; } +#toc H3 { + text-indent: 1em; +} +#toc .document { + text-indent: 2em; +} \ No newline at end of file diff --git a/stylesheets/main.css b/stylesheets/main.css new file mode 100644 index 0000000..ed558e4 --- /dev/null +++ b/stylesheets/main.css @@ -0,0 +1,713 @@ +/* Guides.rubyonrails.org */ +/* Main.css */ +/* Created January 30, 2009 */ +/* Modified February 8, 2009 +--------------------------------------- */ + +/* General +--------------------------------------- */ + +.left {float: left; margin-right: 1em;} +.right {float: right; margin-left: 1em;} +@media screen and (max-width: 480px) { + .left, .right { float: none; } +} +.small {font-size: smaller;} +.large {font-size: larger;} +.hide {display: none;} + +li ul, li ol { margin:0 1.5em; } +ul, ol { margin: 0 1.5em 1.5em 1.5em; } + +ul { list-style-type: disc; } +ol { list-style-type: decimal; } + +dl { margin: 0 0 1.5em 0; } +dl dt { font-weight: bold; } +dd { margin-left: 1.5em;} + +pre, code { + font-size: 1em; + font-family: "Anonymous Pro", "Inconsolata", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + line-height: 1.5; + margin: 1.5em 0; + overflow: auto; + color: #222; +} +pre, tt, code { + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ +} + +abbr, acronym { border-bottom: 1px dotted #666; } +address { margin: 0 0 1.5em; font-style: italic; } +del { color:#666; } + +blockquote { margin: 1.5em; color: #666; font-style: italic; } +strong { font-weight: bold; } +em, dfn { font-style: italic; } +dfn { font-weight: bold; } +sup, sub { line-height: 0; } +p {margin: 0 0 1.5em;} + +label { font-weight: bold; } +fieldset { padding:1.4em; margin: 0 0 1.5em 0; border: 1px solid #ccc; } +legend { font-weight: bold; font-size:1.2em; } + +input.text, input.title, +textarea, select { + margin:0.5em 0; + border:1px solid #bbb; +} + +table { + margin: 0 0 1.5em; + border: 2px solid #CCC; + background: #FFF; + border-collapse: collapse; +} + +table th, table td { + padding: 0.25em 1em; + border: 1px solid #CCC; + border-collapse: collapse; +} + +table th { + border-bottom: 2px solid #CCC; + background: #EEE; + font-weight: bold; + padding: 0.5em 1em; +} + +img { + max-width: 100%; +} + + +/* Structure and Layout +--------------------------------------- */ + +body { + text-align: center; + font-family: Helvetica, Arial, sans-serif; + font-size: 87.5%; + line-height: 1.5em; + background: #fff; + color: #999; +} + +.wrapper { + text-align: left; + margin: 0 auto; + max-width: 960px; + padding: 0 1em; +} + +.red-button { + display: inline-block; + border-top: 1px solid rgba(255,255,255,.5); + background: #751913; + background: -webkit-gradient(linear, left top, left bottom, from(#c52f24), to(#751913)); + background: -webkit-linear-gradient(top, #c52f24, #751913); + background: -moz-linear-gradient(top, #c52f24, #751913); + background: -ms-linear-gradient(top, #c52f24, #751913); + background: -o-linear-gradient(top, #c52f24, #751913); + padding: 9px 18px; + -webkit-border-radius: 11px; + -moz-border-radius: 11px; + border-radius: 11px; + -webkit-box-shadow: rgba(0,0,0,1) 0 1px 0; + -moz-box-shadow: rgba(0,0,0,1) 0 1px 0; + box-shadow: rgba(0,0,0,1) 0 1px 0; + text-shadow: rgba(0,0,0,.4) 0 1px 0; + color: white; + font-size: 15px; + font-family: Helvetica, Arial, Sans-Serif; + text-decoration: none; + vertical-align: middle; + cursor: pointer; +} +.red-button:active { + border-top: none; + padding-top: 10px; + background: -webkit-gradient(linear, left top, left bottom, from(#751913), to(#c52f24)); + background: -webkit-linear-gradient(top, #751913, #c52f24); + background: -moz-linear-gradient(top, #751913, #c52f24); + background: -ms-linear-gradient(top, #751913, #c52f24); + background: -o-linear-gradient(top, #751913, #c52f24); +} + +#topNav { + padding: 1em 0; + color: #565656; + background: #222; +} + +.s-hidden { + display: none; +} + +@media screen and (min-width: 1025px) { + .more-info-button { + display: none; + } + .more-info-links { + list-style: none; + display: inline; + margin: 0; + } + + .more-info { + display: inline-block; + } + .more-info:after { + content: " |"; + } + + .more-info:last-child:after { + content: ""; + } +} + +@media screen and (max-width: 1024px) { + #topNav .wrapper { text-align: center; } + .more-info-button { + position: relative; + z-index: 25; + } + + .more-info-label { + display: none; + } + + .more-info-container { + position: absolute; + top: .5em; + z-index: 20; + margin: 0 auto; + left: 0; + right: 0; + width: 20em; + } + + .more-info-links { + display: block; + list-style: none; + background-color: #c52f24; + border-radius: 5px; + padding-top: 5.25em; + border: 1px #980905 solid; + } + .more-info-links.s-hidden { + display: none; + } + .more-info { + padding: .75em; + border-top: 1px #980905 solid; + } + .more-info a, .more-info a:link, .more-info a:visited { + display: block; + color: white; + width: 100%; + height: 100%; + text-decoration: none; + text-transform: uppercase; + } +} + +#header { + background: #c52f24 url(http://github.com/images/header_tile.gif) repeat-x; + color: #FFF; + padding: 1.5em 0; + z-index: 99; +} + +#feature { + background: #d5e9f6 url(http://github.com/images/feature_tile.gif) repeat-x; + color: #333; + padding: 0.5em 0 1.5em; +} + +#container { + color: #333; + padding: 0.5em 0 1.5em 0; +} + +#mainCol { + max-width: 630px; + margin-left: 2em; +} + +#subCol { + position: absolute; + z-index: 0; + top: 21px; + right: 0; + background: #FFF; + padding: 1em 1.5em 1em 1.25em; + width: 17em; + font-size: 0.9285em; + line-height: 1.3846em; + margin-right: 1em; +} + + +@media screen and (max-width: 800px) { + #subCol { + position: static; + width: inherit; + margin-left: -1em; + margin-right: 0; + padding-right: 1.25em; + } +} + +#extraCol {display: none;} + +#footer { + padding: 2em 0; + background: #222 url(http://github.com/images/footer_tile.gif) repeat-x; +} +#footer .wrapper { + padding-left: 1em; + max-width: 960px; +} + +#header .wrapper, #topNav .wrapper, #feature .wrapper {padding-left: 1em; max-width: 960px;} +#feature .wrapper {max-width: 640px; padding-right: 23em; position: relative; z-index: 0;} + +@media screen and (max-width: 800px) { + #feature .wrapper { padding-right: 0; } +} + +/* Links +--------------------------------------- */ + +a, a:link, a:visited { + color: #ee3f3f; + text-decoration: underline; +} + +#mainCol a, #subCol a, #feature a {color: #980905;} +#mainCol a code, #subCol a code, #feature a code {color: #980905;} + +/* Navigation +--------------------------------------- */ + +.nav { + margin: 0; + padding: 0; + list-style: none; + float: right; + margin-top: 1.5em; + font-size: 1.2857em; +} + +.nav .nav-item {color: #FFF; text-decoration: none;} +.nav .nav-item:hover {text-decoration: underline;} + +.guides-index-large, .guides-index-small .guides-index-item { + padding: 0.5em 1.5em; + border-radius: 1em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + background: #980905; + position: relative; + color: white; +} + +.guides-index .guides-index-item { + background: #980905 url(http://github.com/images/nav_arrow.gif) no-repeat right top; + padding-right: 1em; + position: relative; + z-index: 15; + padding-bottom: 0.125em; +} + +.guides-index:hover .guides-index-item, .guides-index .guides-index-item:hover { + background-position: right -81px; + text-decoration: underline !important; +} + +@media screen and (min-width: 481px) { + .nav { + float: right; + margin-top: 1.5em; + font-size: 1.2857em; + } + .nav>li { + display: inline; + margin-left: 0.5em; + } + .guides-index.guides-index-small { + display: none; + } +} + +@media screen and (max-width: 480px) { + .nav { + float: none; + width: 100%; + text-align: center; + } + .nav .nav-item { + display: block; + margin: 0; + width: 100%; + background-color: #980905; + border: solid 1px #620c04; + border-top: 0; + padding: 15px 0; + text-align: center; + } + .nav .nav-item, .nav-item.guides-index-item { + text-transform: uppercase; + } + .nav .nav-item:first-child, .nav-item.guides-index-small { + border-top: solid 1px #620c04; + } + .guides-index.guides-index-small { + display: block; + margin-top: 1.5em; + } + .guides-index.guides-index-large { + display: none; + } + .guides-index-small .guides-index-item { + font: inherit; + padding-left: .75em; + font-size: .95em; + background-position: 96% 16px; + -webkit-appearance: none; + } + .guides-index-small .guides-index-item:hover{ + background-position: 96% -65px; + } +} + +#guides { + width: 27em; + display: block; + background: #980905; + border-radius: 1em; + -webkit-border-radius: 1em; + -moz-border-radius: 1em; + -webkit-box-shadow: 0.25em 0.25em 1em rgba(0,0,0,0.25); + -moz-box-shadow: rgba(0,0,0,0.25) 0.25em 0.25em 1em; + color: #f1938c; + padding: 1.5em 2em; + position: absolute; + z-index: 10; + top: -0.25em; + right: 0; + padding-top: 2em; +} + +#guides dt, #guides dd { + font-weight: normal; + font-size: 0.722em; + margin: 0; + padding: 0; +} +#guides dt {padding:0; margin: 0.5em 0 0;} +#guides a {color: #FFF; background: none !important; text-decoration: none;} +#guides a:hover {text-decoration: underline;} +#guides .L, #guides .R {float: left; width: 50%; margin: 0; padding: 0;} +#guides .R {float: right;} +#guides hr { + display: block; + border: none; + height: 1px; + color: #f1938c; + background: #f1938c; +} + +/* Headings +--------------------------------------- */ + +h1 { + font-size: 2.5em; + line-height: 1em; + margin: 0.6em 0 .2em; + font-weight: bold; +} + +h2 { + font-size: 2.1428em; + line-height: 1em; + margin: 0.7em 0 .2333em; + font-weight: bold; +} + +@media screen and (max-width: 480px) { + h2 { + font-size: 1.45em; + } +} + +h3 { + font-size: 1.7142em; + line-height: 1.286em; + margin: 0.875em 0 0.2916em; + font-weight: bold; +} + +@media screen and (max-width: 480px) { + h3 { + font-size: 1.45em; + } +} + +h4 { + font-size: 1.2857em; + line-height: 1.2em; + margin: 1.6667em 0 .3887em; + font-weight: bold; +} + +h5 { + font-size: 1em; + line-height: 1.5em; + margin: 1em 0 .5em; + font-weight: bold; +} + +h6 { + font-size: 1em; + line-height: 1.5em; + margin: 1em 0 .5em; + font-weight: normal; +} + +.section { + padding-bottom: 0.25em; + border-bottom: 1px solid #999; +} + +/* Content +--------------------------------------- */ + +.pic { + margin: 0 2em 2em 0; +} + +#topNav strong {color: #999; margin-right: 0.5em;} +#topNav strong a {color: #FFF;} + +#header h1 { + float: left; + background: url(http://github.com/images/rails_guides_logo.gif) no-repeat; + width: 297px; + text-indent: -9999em; + margin: 0; + padding: 0; +} + +@media screen and (max-width: 480px) { + #header h1 { + float: none; + } +} + +#header h1 a { + text-decoration: none; + display: block; + height: 77px; +} + +#feature p { + font-size: 1.2857em; + margin-bottom: 0.75em; +} + +@media screen and (max-width: 480px) { + #feature p { + font-size: 1em; + } +} + +#feature ul {margin-left: 0;} +#feature ul li { + list-style: none; + background: url(http://github.com/images/check_bullet.gif) no-repeat left 0.5em; + padding: 0.5em 1.75em 0.5em 1.75em; + font-size: 1.1428em; + font-weight: bold; +} + +#mainCol dd, #subCol dd { + padding: 0.25em 0 1em; + border-bottom: 1px solid #CCC; + margin-bottom: 1em; + margin-left: 0; + /*padding-left: 28px;*/ + padding-left: 0; +} + +#mainCol dt, #subCol dt { + font-size: 1.2857em; + padding: 0.125em 0 0.25em 0; + margin-bottom: 0; + /*background: url(http://github.com/images/book_icon.gif) no-repeat left top; + padding: 0.125em 0 0.25em 28px;*/ +} + +@media screen and (max-width: 480px) { + #mainCol dt, #subCol dt { + font-size: 1em; + } +} + +#mainCol dd.work-in-progress, #subCol dd.work-in-progress { + background: #fff9d8 url(http://github.com/images/tab_yellow.gif) no-repeat left top; + border: none; + padding: 1.25em 1em 1.25em 48px; + margin-left: 0; + margin-top: 0.25em; +} + +#mainCol dd.kindle, #subCol dd.kindle { + background: #d5e9f6 url(http://github.com/images/tab_info.gif) no-repeat left top; + border: none; + padding: 1.25em 1em 1.25em 48px; + margin-left: 0; + margin-top: 0.25em; +} + +#mainCol div.warning, #subCol dd.warning { + background: #f9d9d8 url(http://github.com/images/tab_red.gif) no-repeat left top; + border: none; + padding: 1.25em 1.25em 0.25em 48px; + margin-left: 0; + margin-top: 0.25em; +} + +#subCol .chapters {color: #980905;} +#subCol .chapters a {font-weight: bold;} +#subCol .chapters ul a {font-weight: normal;} +#subCol .chapters li {margin-bottom: 0.75em;} +#subCol h3.chapter {margin-top: 0.25em;} +#subCol h3.chapter img {vertical-align: text-bottom;} +#subCol .chapters ul {margin-left: 0; margin-top: 0.5em;} +#subCol .chapters ul li { + list-style: none; + padding: 0 0 0 1em; + background: url(http://github.com/images/bullet.gif) no-repeat left 0.45em; + margin-left: 0; + font-size: 1em; + font-weight: normal; +} + +div.code_container { + background: #EEE url(http://github.com/images/tab_grey.gif) no-repeat left top; + padding: 0.25em 1em 0.5em 48px; +} + +.note { + background: #fff9d8 url(http://github.com/images/tab_note.gif) no-repeat left top; + border: none; + padding: 1em 1em 0.25em 48px; + margin: 0.25em 0 1.5em 0; +} + +.info { + background: #d5e9f6 url(http://github.com/images/tab_info.gif) no-repeat left top; + border: none; + padding: 1em 1em 0.25em 48px; + margin: 0.25em 0 1.5em 0; +} + +#mainCol div.todo { + background: #fff9d8 url(http://github.com/images/tab_yellow.gif) no-repeat left top; + border: none; + padding: 1em 1em 0.25em 48px; + margin: 0.25em 0 1.5em 0; +} + +.note code, .info code, .todo code {border:none; background: none; padding: 0;} + +#mainCol ul li { + list-style:none; + background: url(http://github.com/images/grey_bullet.gif) no-repeat left 0.5em; + padding-left: 1em; + margin-left: 0; +} + +#subCol .content { + font-size: 0.7857em; + line-height: 1.5em; +} + +#subCol .content li { + font-weight: normal; + background: none; + padding: 0 0 1em; + font-size: 1.1667em; +} + +/* Clearing +--------------------------------------- */ + +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +.clearfix {display: inline-block;} +* html .clearfix {height: 1%;} +.clearfix {display: block;} +.clear { clear:both; } + +/* Same bottom margin for special boxes than for regular paragraphs, this way +intermediate whitespace looks uniform. */ +div.code_container, div.important, div.caution, div.warning, div.note, div.info { + margin-bottom: 1.5em; +} + +/* Remove bottom margin of paragraphs in special boxes, otherwise they get a +spurious blank area below with the box background. */ +div.important p, div.caution p, div.warning p, div.note p, div.info p { + margin-bottom: 1em; +} + +/* Edge Badge +--------------------------------------- */ + +#edge-badge { + position: fixed; + right: 0px; + top: 0px; + z-index: 100; + border: none; +} + +/* Foundation v2.1.4 http://foundation.zurb.com */ +/* Artfully masterminded by ZURB */ + +table th { font-weight: bold; } +table td, table th { padding: 9px 10px; text-align: left; } + +/* Mobile */ +@media only screen and (max-width: 767px) { + table.responsive { margin-bottom: 0; } + + .pinned { position: absolute; left: 0; top: 0; background: #fff; width: 35%; overflow: hidden; overflow-x: scroll; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } + .pinned table { border-right: none; border-left: none; width: 100%; } + .pinned table th, .pinned table td { white-space: nowrap; } + .pinned td:last-child { border-bottom: 0; } + + div.table-wrapper { position: relative; margin-bottom: 20px; overflow: hidden; border-right: 1px solid #ccc; } + div.table-wrapper div.scrollable table { margin-left: 35%; } + div.table-wrapper div.scrollable { overflow: scroll; overflow-y: hidden; } + + table.responsive td, table.responsive th { position: relative; white-space: nowrap; overflow: hidden; } + table.responsive th:first-child, table.responsive td:first-child, table.responsive td:first-child, table.responsive.pinned td { display: none; } + +} diff --git a/stylesheets/print.css b/stylesheets/print.css new file mode 100644 index 0000000..bdc8ec9 --- /dev/null +++ b/stylesheets/print.css @@ -0,0 +1,52 @@ +/* Guides.rubyonrails.org */ +/* Print.css */ +/* Created January 30, 2009 */ +/* Modified January 31, 2009 +--------------------------------------- */ + +body, .wrapper, .note, .info, code, #topNav, .L, .R, #frame, #container, #header, #navigation, #footer, #feature, #mainCol, #subCol, #extraCol, .content {position: static; text-align: left; text-indent: 0; background: White; color: Black; border-color: Black; width: auto; height: auto; display: block; float: none; min-height: 0; margin: 0; padding: 0;} + +body { + background: #FFF; + font-size: 10pt !important; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + line-height: 1.5; + color: #000; + padding: 0 3%; + } + +.hide, .nav { + display: none !important; + } + +a:link, a:visited { + background: transparent; + font-weight: bold; + text-decoration: underline; + } + +hr { + background:#ccc; + color:#ccc; + width:100%; + height:2px; + margin:2em 0; + padding:0; + border:none; +} + +h1,h2,h3,h4,h5,h6 { font-family: "Helvetica Neue", Arial, "Lucida Grande", sans-serif; } +code { font:.9em "Courier New", Monaco, Courier, monospace; display:inline} + +img { float:left; margin:1.5em 1.5em 1.5em 0; } +a img { border:none; } + +blockquote { + margin:1.5em; + padding:1em; + font-style:italic; + font-size:.9em; +} + +.small { font-size: .9em; } +.large { font-size: 1.1em; } diff --git a/stylesheets/reset.css b/stylesheets/reset.css new file mode 100644 index 0000000..cb14fbc --- /dev/null +++ b/stylesheets/reset.css @@ -0,0 +1,43 @@ +/* Guides.rubyonrails.org */ +/* Reset.css */ +/* Created January 30, 2009 +--------------------------------------- */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + background: transparent; +} + +body {line-height: 1; color: black; background: white;} +a img {border:none;} +ins {text-decoration: none;} +del {text-decoration: line-through;} + +:focus { + -moz-outline:0; + outline:0; + outline-offset:0; +} + +/* tables still need 'cellspacing="0"' in the markup */ +table {border-collapse: collapse; border-spacing: 0;} +caption, th, td {text-align: left; font-weight: normal;} + +blockquote, q {quotes: none;} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} diff --git a/stylesheets/responsive-tables.css b/stylesheets/responsive-tables.css new file mode 100755 index 0000000..f5fbcbf --- /dev/null +++ b/stylesheets/responsive-tables.css @@ -0,0 +1,50 @@ +/* Foundation v2.1.4 http://foundation.zurb.com */ +/* Artfully masterminded by ZURB */ + +/* -------------------------------------------------- + Table of Contents +----------------------------------------------------- +:: Shared Styles +:: Page Name 1 +:: Page Name 2 +*/ + + +/* ----------------------------------------- + Shared Styles +----------------------------------------- */ + +table th { font-weight: bold; } +table td, table th { padding: 9px 10px; text-align: left; } + +/* Mobile */ +@media only screen and (max-width: 767px) { + + table { margin-bottom: 0; } + + .pinned { position: absolute; left: 0; top: 0; background: #fff; width: 35%; overflow: hidden; overflow-x: scroll; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } + .pinned table { border-right: none; border-left: none; width: 100%; } + .pinned table th, .pinned table td { white-space: nowrap; } + .pinned td:last-child { border-bottom: 0; } + + div.table-wrapper { position: relative; margin-bottom: 20px; overflow: hidden; border-right: 1px solid #ccc; } + div.table-wrapper div.scrollable table { margin-left: 35%; } + div.table-wrapper div.scrollable { overflow: scroll; overflow-y: hidden; } + + table td, table th { position: relative; white-space: nowrap; overflow: hidden; } + table th:first-child, table td:first-child, table td:first-child, table.pinned td { display: none; } + +} + +/* ----------------------------------------- + Page Name 1 +----------------------------------------- */ + + + + +/* ----------------------------------------- + Page Name 2 +----------------------------------------- */ + + diff --git a/stylesheets/style.css b/stylesheets/style.css new file mode 100644 index 0000000..89b2ab8 --- /dev/null +++ b/stylesheets/style.css @@ -0,0 +1,13 @@ +/* Guides.rubyonrails.org */ +/* Style.css */ +/* Created January 30, 2009 +--------------------------------------- */ + +/* +--------------------------------------- +Import advanced style sheet +--------------------------------------- +*/ + +@import url("http://github.com/reset.css"); +@import url("http://github.com/main.css"); diff --git a/stylesheets/syntaxhighlighter/shCore.css b/stylesheets/syntaxhighlighter/shCore.css new file mode 100644 index 0000000..34f6864 --- /dev/null +++ b/stylesheets/syntaxhighlighter/shCore.css @@ -0,0 +1,226 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +.syntaxhighlighter a, +.syntaxhighlighter div, +.syntaxhighlighter code, +.syntaxhighlighter table, +.syntaxhighlighter table td, +.syntaxhighlighter table tr, +.syntaxhighlighter table tbody, +.syntaxhighlighter table thead, +.syntaxhighlighter table caption, +.syntaxhighlighter textarea { + -moz-border-radius: 0 0 0 0 !important; + -webkit-border-radius: 0 0 0 0 !important; + background: none !important; + border: 0 !important; + bottom: auto !important; + float: none !important; + height: auto !important; + left: auto !important; + line-height: 1.1em !important; + margin: 0 !important; + outline: 0 !important; + overflow: visible !important; + padding: 0 !important; + position: static !important; + right: auto !important; + text-align: left !important; + top: auto !important; + vertical-align: baseline !important; + width: auto !important; + box-sizing: content-box !important; + font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; + font-weight: normal !important; + font-style: normal !important; + font-size: 1em !important; + min-height: inherit !important; + min-height: auto !important; +} + +.syntaxhighlighter { + width: 100% !important; + margin: 1em 0 1em 0 !important; + position: relative !important; + overflow: auto !important; + font-size: 1em !important; +} +.syntaxhighlighter.source { + overflow: hidden !important; +} +.syntaxhighlighter .bold { + font-weight: bold !important; +} +.syntaxhighlighter .italic { + font-style: italic !important; +} +.syntaxhighlighter .line { + white-space: pre !important; +} +.syntaxhighlighter table { + width: 100% !important; +} +.syntaxhighlighter table caption { + text-align: left !important; + padding: .5em 0 0.5em 1em !important; +} +.syntaxhighlighter table td.code { + width: 100% !important; +} +.syntaxhighlighter table td.code .container { + position: relative !important; +} +.syntaxhighlighter table td.code .container textarea { + box-sizing: border-box !important; + position: absolute !important; + left: 0 !important; + top: 0 !important; + width: 100% !important; + height: 100% !important; + border: none !important; + background: white !important; + padding-left: 1em !important; + overflow: hidden !important; + white-space: pre !important; +} +.syntaxhighlighter table td.gutter .line { + text-align: right !important; + padding: 0 0.5em 0 1em !important; +} +.syntaxhighlighter table td.code .line { + padding: 0 1em !important; +} +.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line { + padding-left: 0em !important; +} +.syntaxhighlighter.show { + display: block !important; +} +.syntaxhighlighter.collapsed table { + display: none !important; +} +.syntaxhighlighter.collapsed .toolbar { + padding: 0.1em 0.8em 0em 0.8em !important; + font-size: 1em !important; + position: static !important; + width: auto !important; + height: auto !important; +} +.syntaxhighlighter.collapsed .toolbar span { + display: inline !important; + margin-right: 1em !important; +} +.syntaxhighlighter.collapsed .toolbar span a { + padding: 0 !important; + display: none !important; +} +.syntaxhighlighter.collapsed .toolbar span a.expandSource { + display: inline !important; +} +.syntaxhighlighter .toolbar { + position: absolute !important; + right: 1px !important; + top: 1px !important; + width: 11px !important; + height: 11px !important; + font-size: 10px !important; + z-index: 10 !important; +} +.syntaxhighlighter .toolbar span.title { + display: inline !important; +} +.syntaxhighlighter .toolbar a { + display: block !important; + text-align: center !important; + text-decoration: none !important; + padding-top: 1px !important; +} +.syntaxhighlighter .toolbar a.expandSource { + display: none !important; +} +.syntaxhighlighter.ie { + font-size: .9em !important; + padding: 1px 0 1px 0 !important; +} +.syntaxhighlighter.ie .toolbar { + line-height: 8px !important; +} +.syntaxhighlighter.ie .toolbar a { + padding-top: 0px !important; +} +.syntaxhighlighter.printing .line.alt1 .content, +.syntaxhighlighter.printing .line.alt2 .content, +.syntaxhighlighter.printing .line.highlighted .number, +.syntaxhighlighter.printing .line.highlighted.alt1 .content, +.syntaxhighlighter.printing .line.highlighted.alt2 .content { + background: none !important; +} +.syntaxhighlighter.printing .line .number { + color: #bbbbbb !important; +} +.syntaxhighlighter.printing .line .content { + color: black !important; +} +.syntaxhighlighter.printing .toolbar { + display: none !important; +} +.syntaxhighlighter.printing a { + text-decoration: none !important; +} +.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a { + color: black !important; +} +.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a { + color: #008200 !important; +} +.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a { + color: blue !important; +} +.syntaxhighlighter.printing .keyword { + color: #006699 !important; + font-weight: bold !important; +} +.syntaxhighlighter.printing .preprocessor { + color: gray !important; +} +.syntaxhighlighter.printing .variable { + color: #aa7700 !important; +} +.syntaxhighlighter.printing .value { + color: #009900 !important; +} +.syntaxhighlighter.printing .functions { + color: #ff1493 !important; +} +.syntaxhighlighter.printing .constants { + color: #0066cc !important; +} +.syntaxhighlighter.printing .script { + font-weight: bold !important; +} +.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a { + color: gray !important; +} +.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a { + color: #ff1493 !important; +} +.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a { + color: red !important; +} +.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a { + color: black !important; +} diff --git a/stylesheets/syntaxhighlighter/shThemeRailsGuides.css b/stylesheets/syntaxhighlighter/shThemeRailsGuides.css new file mode 100644 index 0000000..bc7afd3 --- /dev/null +++ b/stylesheets/syntaxhighlighter/shThemeRailsGuides.css @@ -0,0 +1,116 @@ +/** + * Theme by fxn, took shThemeEclipse.css as starting point. + */ +.syntaxhighlighter { + background-color: #eee !important; + font-family: "Anonymous Pro", "Inconsolata", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace !important; + overflow-y: hidden !important; + overflow-x: auto !important; +} +.syntaxhighlighter .line.alt1 { + background-color: #eee !important; +} +.syntaxhighlighter .line.alt2 { + background-color: #eee !important; +} +.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 { + background-color: #c3defe !important; +} +.syntaxhighlighter .line.highlighted.number { + color: #eee !important; +} +.syntaxhighlighter table caption { + color: #222 !important; +} +.syntaxhighlighter .gutter { + color: #787878 !important; +} +.syntaxhighlighter .gutter .line { + border-right: 3px solid #d4d0c8 !important; +} +.syntaxhighlighter .gutter .line.highlighted { + background-color: #d4d0c8 !important; + color: #eee !important; +} +.syntaxhighlighter.printing .line .content { + border: none !important; +} +.syntaxhighlighter.collapsed { + overflow: visible !important; +} +.syntaxhighlighter.collapsed .toolbar { + color: #3f5fbf !important; + background: #eee !important; + border: 1px solid #d4d0c8 !important; +} +.syntaxhighlighter.collapsed .toolbar a { + color: #3f5fbf !important; +} +.syntaxhighlighter.collapsed .toolbar a:hover { + color: #aa7700 !important; +} +.syntaxhighlighter .toolbar { + color: #a0a0a0 !important; + background: #d4d0c8 !important; + border: none !important; +} +.syntaxhighlighter .toolbar a { + color: #a0a0a0 !important; +} +.syntaxhighlighter .toolbar a:hover { + color: red !important; +} +.syntaxhighlighter .plain, .syntaxhighlighter .plain a { + color: #222 !important; +} +.syntaxhighlighter .comments, .syntaxhighlighter .comments a { + color: #708090 !important; +} +.syntaxhighlighter .string, .syntaxhighlighter .string a { + font-style: italic !important; + color: #6588A8 !important; +} +.syntaxhighlighter .keyword { + color: #64434d !important; +} +.syntaxhighlighter .preprocessor { + color: #646464 !important; +} +.syntaxhighlighter .variable { + color: #222 !important; +} +.syntaxhighlighter .value { + color: #009900 !important; +} +.syntaxhighlighter .functions { + color: #ff1493 !important; +} +.syntaxhighlighter .constants { + color: #0066cc !important; +} +.syntaxhighlighter .script { + color: #222 !important; + background-color: transparent !important; +} +.syntaxhighlighter .color1, .syntaxhighlighter .color1 a { + color: gray !important; +} +.syntaxhighlighter .color2, .syntaxhighlighter .color2 a { + color: #222 !important; + font-weight: bold !important; +} +.syntaxhighlighter .color3, .syntaxhighlighter .color3 a { + color: red !important; +} + +.syntaxhighlighter .xml .keyword { + color: #64434d !important; + font-weight: normal !important; +} +.syntaxhighlighter .xml .color1, .syntaxhighlighter .xml .color1 a { + color: #7f007f !important; +} +.syntaxhighlighter .xml .string { + font-style: italic !important; + color: #6588A8 !important; +} diff --git a/testing.html b/testing.html new file mode 100644 index 0000000..ee65dfd --- /dev/null +++ b/testing.html @@ -0,0 +1,1403 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

Rails 应用测试指南

本文介绍 Rails 内建对测试的支持。

读完本文后,您将学到:

+
    +
  • Rails 测试术语;

  • +
  • 如何为应用编写单元测试、功能测试和集成测试;

  • +
  • 其他常用的测试方法和插件。

  • +
+

1 为什么要为 Rails 应用编写测试?

在 Rails 中编写测试非常简单,生成模型和控制器时,已经生成了测试代码骨架。

即便是大范围重构后,只需运行测试就能确保实现了所需的功能。

Rails 测试还可以模拟浏览器请求,无需打开浏览器就能测试应用的响应。

2 测试简介

测试是 Rails 应用的重要组成部分,不是为了尝鲜和好奇而编写的。

2.1 Rails 内建对测试的支持

使用 rails new application_name 命令创建一个 Rails 项目时,Rails 会生成 test 目录。如果列出这个目录里的内容,你会看到下述目录和文件:

+
+$ ls -F test
+controllers/    helpers/        mailers/        test_helper.rb
+fixtures/       integration/    models/
+
+
+
+

models 目录存放模型的测试,controllers 目录存放控制器的测试,integration 目录存放涉及多个控制器交互的测试。此外,还有一个目录用于存放邮件程序的测试,以及一个目录用于存放辅助方法的测试。

测试数据使用固件(fixture)组织,存放在 fixtures 目录中。

test_helper.rb 文件存储测试的默认配置。

2.2 测试环境

默认情况下,Rails 应用有三个环境:开发环境、测试环境和生产环境。

各个环境的配置通过类似的方式修改。这里,如果想配置测试环境,可以修改 config/environments/test.rb 文件中的选项。

运行测试时,RAILS_ENV 环境变量的值是 test

2.3 使用 Minitest 测试 Rails 应用

还记得我们在Rails 入门用过的 rails generate model 命令吗?我们使用这个命令生成了第一个模型,这个命令会生成很多内容,其中就包括在 test 目录中创建的测试:

+
+$ bin/rails generate model article title:string body:text
+...
+create  app/models/article.rb
+create  test/models/article_test.rb
+create  test/fixtures/articles.yml
+...
+
+
+
+

默认在 test/models/article_test.rb 文件中生成的测试如下:

+
+require 'test_helper'
+
+class ArticleTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end
+
+
+
+

下面逐行说明这段代码,让你初步了解 Rails 测试代码和相关的术语。

+
+require 'test_helper'
+
+
+
+

这行代码引入 test_helper.rb 文件,即加载默认的测试配置。我们编写的所有测试都会引入这个文件,因此这个文件中定义的代码在所有测试中都可用。

+
+class ArticleTest < ActiveSupport::TestCase
+
+
+
+

ArticleTest 类定义一个测试用例(test case),它继承自 ActiveSupport::TestCase,因此继承了后者的全部方法。本文后面会介绍其中几个。

在继承自 Minitest::TestActiveSupport::TestCase 的超类)的类中定义的方法,只要名称以 test_ 开头(区分大小写),就是一个“测试”。因此,名为 test_passwordtest_valid_password 的方法是有效的测试,运行测试用例时会自动运行。

此外,Rails 定义了 test 方法,它接受一个测试名称和一个块。test 方法在测试名称前面加上 test_,生成常规的 Minitest::Unit 测试。因此,我们无需费心为方法命名,可以像下面这样写:

+
+test "the truth" do
+  assert true
+end
+
+
+
+

这段代码几乎与下述代码一样:

+
+def test_the_truth
+  assert true
+end
+
+
+
+

不过,使用 test 能让测试具有更易读的名称。如果愿意,依然可以使用常规的方式定义方法。

生成方法名时,空格会替换成下划线。不过,结果无需是有效的 Ruby 标识符,名称中可以包含标点符号等。这是因为,严格来说,在 Ruby 中任何字符串都可以作为方法的名称。这样,可能需要使用 define_methodsend 才能让方法其作用,不过在名称形式上的限制较少。

接下来是我们遇到的第一个断言(assertion):

+
+assert true
+
+
+
+

断言求值对象(或表达式),然后与预期结果比较。例如,断言可以检查:

+
    +
  • 两个值是否相等

  • +
  • 对象是否为 nil

  • +
  • 一行代码是否抛出异常

  • +
  • 用户的密码长度是否超过 5 个字符

  • +
+

一个测试中可以有一个或多个断言,对断言的数量没有限制。只有全部断言都成功,测试才能通过。

2.3.1 第一个失败测试

为了了解失败测试是如何报告的,下面在 article_test.rb 测试用例中添加一个失败测试:

+
+test "should not save article without title" do
+  article = Article.new
+  assert_not article.save
+end
+
+
+
+

然后运行这个新增的测试(其中,6 是测试定义所在的行号):

+
+$ bin/rails test test/models/article_test.rb:6
+Run options: --seed 44656
+
+# Running:
+
+F
+
+Failure:
+ArticleTest#test_should_not_save_article_without_title [/path/to/blog/test/models/article_test.rb:6]:
+Expected true to be nil or false
+
+
+bin/rails test test/models/article_test.rb:6
+
+
+
+Finished in 0.023918s, 41.8090 runs/s, 41.8090 assertions/s.
+
+1 runs, 1 assertions, 1 failures, 0 errors, 0 skips
+
+
+
+

输出中的 F 表示失败(failure)。可以看到,Failure 下面显示了相应的路径和失败测试的名称。下面几行是堆栈跟踪,以及传入断言的具体值和预期值。默认的断言消息足够用于定位错误了。如果想让断言失败消息提供更多的信息,可以使用每个断言都有的可选参数定制消息,如下所示:

+
+test "should not save article without title" do
+  article = Article.new
+  assert_not article.save, "Saved the article without a title"
+end
+
+
+
+

现在运行测试会看到更加友好的断言消息:

+
+Failure:
+ArticleTest#test_should_not_save_article_without_title [/path/to/blog/test/models/article_test.rb:6]:
+Saved the article without a title
+
+
+
+

为了让测试通过,我们可以为 title 字段添加一个模型层验证:

+
+class Article < ApplicationRecord
+  validates :title, presence: true
+end
+
+
+
+

现在测试应该能通过了。再次运行测试,确认一下:

+
+$ bin/rails test test/models/article_test.rb:6
+Run options: --seed 31252
+
+# Running:
+
+.
+
+Finished in 0.027476s, 36.3952 runs/s, 36.3952 assertions/s.
+
+1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

你可能注意到了,我们先编写一个测试检查所需的功能,它失败了,然后我们编写代码,添加功能,最后确认测试能通过。这种开发软件的方式叫做测试驱动开发(Test-Driven Development,TDD)。

2.3.2 失败的样子

为了查看错误是如何报告的,下面编写一个包含错误的测试:

+
+test "should report error" do
+  # 测试用例中没有定义 some_undefined_variable
+  some_undefined_variable
+  assert true
+end
+
+
+
+

然后运行测试,你会看到更多输出:

+
+$ bin/rails test test/models/article_test.rb
+Run options: --seed 1808
+
+# Running:
+
+.E
+
+Error:
+ArticleTest#test_should_report_error:
+NameError: undefined local variable or method `some_undefined_variable' for #<ArticleTest:0x007fee3aa71798>
+    test/models/article_test.rb:11:in `block in <class:ArticleTest>'
+
+
+bin/rails test test/models/article_test.rb:9
+
+
+
+Finished in 0.040609s, 49.2500 runs/s, 24.6250 assertions/s.
+
+2 runs, 1 assertions, 0 failures, 1 errors, 0 skips
+
+
+
+

注意输出中的“E”,它表示测试有错误(error)。

执行各个测试方法时,只要遇到错误或断言失败,就立即停止,然后接着运行测试组件中的下一个测试方法。测试方法以随机顺序执行。测试顺序可以使用 config.active_support.test_order 选项配置。

测试失败时会显示相应的回溯信息。默认情况下,Rails 会过滤回溯信息,只打印与应用有关的内容。这样不会被框架相关的内容搅乱,有助于集中精力排查代码中的错误。不过,有时需要查看完整的回溯信息。此时,只需设定 -b(或 --backtrace)参数就能启用这一行为:

+
+$ bin/rails test -b test/models/article_test.rb
+
+
+
+

若想让这个测试通过,可以使用 assert_raises 修改,如下:

+
+test "should report error" do
+  # 测试用例中没有定义 some_undefined_variable
+  assert_raises(NameError) do
+    some_undefined_variable
+  end
+end
+
+
+
+

现在这个测试应该能通过了。

2.4 可用的断言

我们大致了解了几个可用的断言。断言是测试的核心所在,是真正执行检查、确保功能符合预期的执行者。

下面摘录部分可以在 Minitest(Rails 默认使用的测试库)中使用的断言。[msg] 参数是可选的消息字符串,能让测试失败消息更明确。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
断言作用
assert( test, [msg] )确保 test 是真值。
assert_not( test, [msg] )确保 test 是假值。
assert_equal( expected, actual, [msg] )确保 expected == actual 成立。
assert_not_equal( expected, actual, [msg] )确保 expected != actual 成立。
assert_same( expected, actual, [msg] )确保 expected.equal?(actual) 成立。
assert_not_same( expected, actual, [msg] )确保 expected.equal?(actual) 不成立。
assert_nil( obj, [msg] )确保 obj.nil? 成立。
assert_not_nil( obj, [msg] )确保 obj.nil? 不成立。
assert_empty( obj, [msg] )确保 obj 是空的。
assert_not_empty( obj, [msg] )确保 obj 不是空的。
assert_match( regexp, string, [msg] )确保字符串匹配正则表达式。
assert_no_match( regexp, string, [msg] )确保字符串不匹配正则表达式。
assert_includes( collection, obj, [msg] )确保 obj 在 collection 中。
assert_not_includes( collection, obj, [msg] )确保 obj 不在 collection 中。
assert_in_delta( expected, actual, [delta], [msg] )确保 expected 和 actual 的差值在 delta 的范围内。
assert_not_in_delta( expected, actual, [delta], [msg] )确保 expected 和 actual 的差值不在 delta 的范围内。
assert_throws( symbol, [msg] ) { block }确保指定的块会抛出指定符号表示的异常。
assert_raises( exception1, exception2, …​ ) { block }确保指定块会抛出指定异常中的一个。
assert_nothing_raised { block }确保指定的块不会抛出任何异常。
assert_instance_of( class, obj, [msg] )确保 obj 是 class 的实例。
assert_not_instance_of( class, obj, [msg] )确保 obj 不是 class 的实例。
assert_kind_of( class, obj, [msg] )确保 obj 是 class 或其后代的实例。
assert_not_kind_of( class, obj, [msg] )确保 obj 不是 class 或其后代的实例。
assert_respond_to( obj, symbol, [msg] )确保 obj 能响应 symbol 对应的方法。
assert_not_respond_to( obj, symbol, [msg] )确保 obj 不能响应 symbol 对应的方法。
assert_operator( obj1, operator, [obj2], [msg] )确保 obj1.operator(obj2) 成立。
assert_not_operator( obj1, operator, [obj2], [msg] )确保 obj1.operator(obj2) 不成立。
assert_predicate( obj, predicate, [msg] )确保 obj.predicate 为真,例如 assert_predicate str, :empty?。
assert_not_predicate( obj, predicate, [msg] )确保 obj.predicate 为假,例如 assert_not_predicate str, :empty?。
assert_send( array, [msg] )确保能在 array[0] 对应的对象上调用 array[1] 对应的方法,并且传入 array[2] 之后的值作为参数,例如 assert_send [@user, :full_name, 'Sam Smith']。很独特吧?
flunk( [msg] )确保失败。可以用这个断言明确标记未完成的测试。
+

以上是 Minitest 支持的部分断言,完整且最新的列表参见 Minitest API 文档,尤其是 Minitest::Assertions 模块的文档

Minitest 这个测试框架是模块化的,因此还可以自己创建断言。事实上,Rails 就这么做了。Rails 提供了一些专门的断言,能简化测试。

自己创建断言是高级话题,本文不涉及。

2.5 Rails 专有的断言

在 Minitest 框架的基础上,Rails 添加了一些自定义的断言。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
断言作用
assert_difference(expressions, difference = 1, message = nil) {…​}运行代码块前后数量变化了多少(通过 expression 表示)。
assert_no_difference(expressions, message = nil, &block)运行代码块前后数量没变多少(通过 expression 表示)。
assert_recognizes(expected_options, path, extras={}, message=nil)断言正确处理了指定路径,而且解析的参数(通过 expected_options 散列指定)与路径匹配。基本上,它断言 Rails 能识别 expected_options 指定的路由。
assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)断言指定的选项能生成指定的路径。作用与 assert_recognizes 相反。extras 参数用于构建查询字符串。message 参数用于为断言失败定制错误消息。
assert_response(type, message = nil)断言响应的状态码。可以指定表示 200-299 的 :success,表示 300-399 的 :redirect,表示 404 的 :missing,或者表示 500-599 的 :error。此外,还可以明确指定数字状态码或对应的符号。详情参见完整的状态码列表及其与符号的对应关系。
assert_redirected_to(options = {}, message=nil)断言传入的重定向选项匹配最近一个动作中的重定向。重定向参数可以只指定部分,例如 assert_redirected_to(controller: "weblog"),也可以完整指定,例如 redirect_to(controller: "weblog", action: "show")。此外,还可以传入具名路由,例如 assert_redirected_to root_path,以及 Active Record 对象,例如 assert_redirected_to @article。
+

在接下来的内容中会用到其中一些断言。

2.6 关于测试用例的简要说明

Minitest::Assertions 模块定义的所有基本断言,例如 assert_equal,都可以在我们编写的测试用例中使用。Rails 提供了下述几个类供你继承:

+ +

这些类都引入了 Minitest::Assertions,因此可以在测试中使用所有基本断言。

Minitest 的详情参见文档

2.7 Rails 测试运行程序

全部测试可以使用 bin/rails test 命令统一运行。

也可以单独运行一个测试,方法是把测试用例所在的文件名传给 bin/rails test 命令。

+
+$ bin/rails test test/models/article_test.rb
+Run options: --seed 1559
+
+# Running:
+
+..
+
+Finished in 0.027034s, 73.9810 runs/s, 110.9715 assertions/s.
+
+2 runs, 3 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

上述命令运行测试用例中的所有测试方法。

也可以运行测试用例中特定的测试方法:指定 -n--name 旗标和测试方法的名称。

+
+$ bin/rails test test/models/article_test.rb -n test_the_truth
+Run options: -n test_the_truth --seed 43583
+
+# Running:
+
+.
+
+Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
+
+1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

也可以运行某一行中的测试,方法是指定行号。

+
+$ bin/rails test test/models/article_test.rb:6 # 运行某一行中的测试
+
+
+
+

也可以运行整个目录中的测试,方法是指定目录的路径。

+
+$ bin/rails test test/controllers # 运行指定目录中的所有测试
+
+
+
+

此外,测试运行程序还有很多功能,例如快速失败、测试运行结束后统一输出,等等。详情参见测试运行程序的文档,如下:

+
+$ bin/rails test -h
+minitest options:
+    -h, --help                       Display this help.
+    -s, --seed SEED                  Sets random seed. Also via env. Eg: SEED=n rake
+    -v, --verbose                    Verbose. Show progress processing files.
+    -n, --name PATTERN               Filter run on /regexp/ or string.
+        --exclude PATTERN            Exclude /regexp/ or string from run.
+
+Known extensions: rails, pride
+
+Usage: bin/rails test [options] [files or directories]
+You can run a single test by appending a line number to a filename:
+
+    bin/rails test test/models/user_test.rb:27
+
+You can run multiple files and directories at the same time:
+
+    bin/rails test test/controllers test/integration/login_test.rb
+
+By default test failures and errors are reported inline during a run.
+
+Rails options:
+    -e, --environment ENV            Run tests in the ENV environment
+    -b, --backtrace                  Show the complete backtrace
+    -d, --defer-output               Output test failures and errors after the test run
+    -f, --fail-fast                  Abort test run on first failure or error
+    -c, --[no-]color                 Enable color in the output
+
+
+
+

3 测试数据库

几乎每个 Rails 应用都经常与数据库交互,因此测试也需要这么做。为了有效编写测试,你要知道如何搭建测试数据库,以及如何使用示例数据填充。

默认情况下,每个 Rails 应用都有三个环境:开发环境、测试环境和生产环境。各个环境中的数据库在 config/database.yml 文件中配置。

为测试专门提供一个数据库方便我们单独设置和与测试数据交互。这样,我们可以放心地处理测试数据,不必担心会破坏开发数据库或生产数据库中的数据。

3.1 维护测试数据库的模式

为了能运行测试,测试数据库要有应用当前的数据库结构。测试辅助方法会检查测试数据库中是否有尚未运行的迁移。如果有,会尝试把 db/schema.rbdb/structure.sql 载入数据库。之后,如果迁移仍处于待运行状态,会抛出异常。通常,这表明数据库模式没有完全迁移。在开发数据库中运行迁移(bin/rails db:migrate)能更新模式。

如果修改了现有的迁移,要重建测试数据库。方法是执行 bin/rails db:test:prepare 命令。

3.2 固件详解

好的测试应该具有提供测试数据的方式。在 Rails 中,测试数据由固件(fixture)提供。关于固件的全面说明,参见 API 文档

3.2.1 固件是什么?

固件代指示例数据,在运行测试之前,使用预先定义好的数据填充测试数据库。固件与所用的数据库没有关系,使用 YAML 格式编写。一个模型有一个固件文件。

固件不是为了创建测试中用到的每一个对象,需要公用的默认数据时才应该使用。

固件保存在 test/fixtures 目录中。执行 rails generate model 命令生成新模型时,Rails 会在这个目录中自动创建固件文件。

3.2.2 YAML

使用 YAML 格式编写的固件可读性高,能更好地表述示例数据。这种固件文件的扩展名是 .yml(如 users.yml)。

下面举个例子:

+
+# lo & behold! I am a YAML comment!
+david:
+  name: David Heinemeier Hansson
+  birthday: 1979-10-15
+  profession: Systems development
+
+steve:
+  name: Steve Ross Kellock
+  birthday: 1974-09-27
+  profession: guy with keyboard
+
+
+
+

每个固件都有名称,后面跟着一个缩进的键值对(以冒号分隔)列表。记录之间往往使用空行分开。在固件中可以使用注释,在行首加上 # 符号即可。

如果涉及到关联,定义一个指向其他固件的引用即可。例如,下面的固件针对 belongs_to/has_many 关联:

+
+# In fixtures/categories.yml
+about:
+  name: About
+
+# In fixtures/articles.yml
+first:
+  title: Welcome to Rails!
+  body: Hello world!
+  category: about
+
+
+
+

注意,在 fixtures/articles.yml 文件中,first 文章的 categoryabout,这告诉 Rails,要加载 fixtures/categories.yml 文件中的 about 分类。

在固件中创建关联时,引用的是另一个固件的名称,而不是 id 属性。Rails 会自动分配主键。关于这种关联行为的详情,参阅固件的 API 文档

3.2.3 使用 ERB 增强固件

ERB 用于在模板中嵌入 Ruby 代码。Rails 加载 YAML 格式的固件时,会先使用 ERB 进行预处理,因此可使用 Ruby 代码协助生成示例数据。例如,下面的代码会生成一千个用户:

+
+<% 1000.times do |n| %>
+user_<%= n %>:
+  username: <%= "user#{n}" %>
+  email: <%= "user#{n}@example.com" %>
+<% end %>
+
+
+
+
3.2.4 固件实战

默认情况下,Rails 会自动加载 test/fixtures 目录中的所有固件。加载的过程分为三步:

+
    +
  1. 从数据表中删除所有和固件对应的数据;

  2. +
  3. 把固件载入数据表;

  4. +
  5. 把固件中的数据转储成方法,以便直接访问。

  6. +
+

为了从数据库中删除现有数据,Rails 会尝试禁用引用完整性触发器(如外键和约束检查)。运行测试时,如果见到烦人的权限错误,确保数据库用户有权在测试环境中禁用这些触发器。(对 PostgreSQL 来说,只有超级用户能禁用全部触发器。关于 PostgreSQL 权限的详细说明参阅这篇文章。)

3.2.5 固件是 Active Record 对象

固件是 Active Record 实例。如前一节的第 3 点所述,在测试用例中可以直接访问这个对象,因为固件中的数据会转储成测试用例作用域中的方法。例如:

+
+# 返回 david 固件对应的 User 对象
+users(:david)
+
+# 返回 david 的 id 属性
+users(:david).id
+
+# 还可以调用 User 类的方法
+david = users(:david)
+david.call(david.partner)
+
+
+
+

如果想一次获取多个固件,可以传入一个固件名称列表。例如:

+
+# 返回一个数组,包含 david 和 steve 两个固件
+users(:david, :steve)
+
+
+
+

4 模型测试

模型测试用于测试应用中的各个模型。

Rails 模型测试存储在 test/models 目录中。Rails 提供了一个生成器,可用它生成模型测试骨架。

+
+$ bin/rails generate test_unit:model article title:string body:text
+create  test/models/article_test.rb
+create  test/fixtures/articles.yml
+
+
+
+

模型测试没有专门的超类(如 ActionMailer::TestCase),而是继承自 ActiveSupport::TestCase

5 集成测试

集成测试用于测试应用中不同部分之间的交互,一般用于测试应用中重要的工作流程。

集成测试存储在 test/integration 目录中。Rails 提供了一个生成器,使用它可以生成集成测试骨架。

+
+$ bin/rails generate integration_test user_flows
+      exists  test/integration/
+      create  test/integration/user_flows_test.rb
+
+
+
+

上述命令生成的集成测试如下:

+
+require 'test_helper'
+
+class UserFlowsTest < ActionDispatch::IntegrationTest
+  # test "the truth" do
+  #   assert true
+  # end
+end
+
+
+
+

这个测试继承自 ActionDispatch::IntegrationTest 类,因此可以在集成测试中使用一些额外的辅助方法。

5.1 集成测试可用的辅助方法

除了标准的测试辅助方法之外,由于集成测试继承自 ActionDispatch::IntegrationTest,因此在集成测试中还可使用一些额外的辅助方法。下面简要介绍三类辅助方法。

集成测试运行程序的说明参阅 ActionDispatch::Integration::Runner 模块的文档

执行请求的方法参见 ActionDispatch::Integration::RequestHelpers 模块的文档

如果需要修改会话或集成测试的状态,参阅 ActionDispatch::Integration::Session 类的文档

5.2 编写一个集成测试

下面为博客应用添加一个集成测试。我们将执行基本的工作流程,新建一篇博客文章,确认一切都能正常运作。

首先,生成集成测试骨架:

+
+$ bin/rails generate integration_test blog_flow
+
+
+
+

这个命令会创建一个测试文件。在上述命令的输出中应该看到:

+
+invoke  test_unit
+create    test/integration/blog_flow_test.rb
+
+
+
+

打开那个文件,编写第一个断言:

+
+require 'test_helper'
+
+class BlogFlowTest < ActionDispatch::IntegrationTest
+  test "can see the welcome page" do
+    get "/"
+    assert_select "h1", "Welcome#index"
+  end
+end
+
+
+
+

assert_select 用于查询请求得到的 HTML,测试视图说明。我们使用它测试请求的响应:断言响应的内容中有关键的 HTML 元素。

访问根路径时,应该使用 welcome/index.html.erb 渲染视图。因此,这个断言应该通过。

5.2.1 测试发布文章的流程

下面测试在博客中新建文章以及查看结果的功能。

+
+test "can create an article" do
+  get "/articles/new"
+  assert_response :success
+
+  post "/articles",
+    params: { article: { title: "can create", body: "article successfully." } }
+  assert_response :redirect
+  follow_redirect!
+  assert_response :success
+  assert_select "p", "Title:\n  can create"
+end
+
+
+
+

我们来分析一下这段测试。

首先,我们调用 Articles 控制器的 new 动作。应该得到成功的响应。

然后,我们向 Articles 控制器的 create 动作发送 POST 请求:

+
+post "/articles",
+  params: { article: { title: "can create", body: "article successfully." } }
+assert_response :redirect
+follow_redirect!
+
+
+
+

请求后面两行的作用是处理创建文章后的重定向。

重定向后如果还想发送请求,别忘了调用 follow_redirect!

最后,我们断言得到的是成功的响应,而且页面中显示了新建的文章。

5.2.2 更进一步

我们刚刚测试了访问博客和新建文章功能,这只是工作流程的一小部分。如果想更进一步,还可以测试评论、删除文章或编辑评论。集成测试就是用来检查应用的各种使用场景的。

6 为控制器编写功能测试

在 Rails 中,测试控制器各动作需要编写功能测试(functional test)。控制器负责处理应用收到的请求,然后使用视图渲染响应。功能测试用于检查动作对请求的处理,以及得到的结果或响应(某些情况下是 HTML 视图)。

6.1 功能测试要测试什么

应该测试以下内容:

+
    +
  • 请求是否成功;

  • +
  • 是否重定向到正确的页面;

  • +
  • 用户是否通过身份验证;

  • +
  • 是否把正确的对象传给渲染响应的模板;

  • +
  • 是否在视图中显示相应的消息;

  • +
+

如果想看一下真实的功能测试,最简单的方法是使用脚手架生成器生成一个控制器:

+
+$ bin/rails generate scaffold_controller article title:string body:text
+...
+create  app/controllers/articles_controller.rb
+...
+invoke  test_unit
+create    test/controllers/articles_controller_test.rb
+...
+
+
+
+

上述命令会为 Articles 资源生成控制器和测试。你可以看一下 test/controllers 目录中的 articles_controller_test.rb 文件。

如果已经有了控制器,只想为默认的七个动作生成测试代码的话,可以使用下述命令:

+
+$ bin/rails generate test_unit:scaffold article
+...
+invoke  test_unit
+create test/controllers/articles_controller_test.rb
+...
+
+
+
+

下面分析一个功能测试:articles_controller_test.rb 文件中的 test_should_get_index

+
+# articles_controller_test.rb
+class ArticlesControllerTest < ActionDispatch::IntegrationTest
+  test "should get index" do
+    get articles_url
+    assert_response :success
+  end
+end
+
+
+
+

test_should_get_index 测试中,Rails 模拟了一个发给 index 动作的请求,确保请求成功,而且生成了正确的响应主体。

get 方法发起请求,并把结果传入响应中。这个方法可接受 6 个参数:

+
    +
  • 所请求控制器的动作,可使用字符串或符号。

  • +
  • params:一个选项散列,指定传入动作的请求参数(例如,查询字符串参数或文章变量)。

  • +
  • headers:设定随请求发送的首部。

  • +
  • env:按需定制请求环境。

  • +
  • xhr:指明是不是 Ajax 请求;设为 true 表示是 Ajax 请求。

  • +
  • as:使用其他内容类型编码请求;默认支持 :json

  • +
+

所有关键字参数都是可选的。

举个例子。调用 :show 动作,把 params 中的 id 设为 12,并且设定 HTTP_REFERER 首部:

+
+get :show, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://example.com/home" }
+
+
+
+

再举个例子。调用 :update 动作,把 params 中的 id 设为 12,并且指明是 Ajax 请求:

+
+patch update_url, params: { id: 12 }, xhr: true
+
+
+
+

如果现在运行 articles_controller_test.rb 文件中的 test_should_create_article 测试,它会失败,因为前文添加了模型层验证。

我们来修改 articles_controller_test.rb 文件中的 test_should_create_article 测试,让所有测试都通过:

+
+test "should create article" do
+  assert_difference('Article.count') do
+    post articles_url, params: { article: { body: 'Rails is awesome!', title: 'Hello Rails' } }
+  end
+
+  assert_redirected_to article_path(Article.last)
+end
+
+
+
+

现在你可以运行所有测试,应该都能通过。

6.2 功能测试中可用的请求类型

如果熟悉 HTTP 协议就会知道,get 是请求的一种类型。在 Rails 功能测试中可以使用 6 种请求:

+
    +
  • get

  • +
  • post

  • +
  • patch

  • +
  • put

  • +
  • head

  • +
  • delete

  • +
+

这几种请求都有相应的方法可用。在常规的 CRUD 应用中,最常使用 getpostputdelete

功能测试不检测动作是否能接受指定类型的请求,而是关注请求的结果。如果想做这样的测试,应该使用请求测试(request test)。

6.3 测试 XHR(Ajax)请求

如果想测试 Ajax 请求,要在 getpostpatchputdelete 方法中设定 xhr: true 选项。例如:

+
+test "ajax request" do
+  article = articles(:one)
+  get article_url(http://github.com/article), xhr: true
+
+  assert_equal 'hello world', @response.body
+  assert_equal "text/javascript", @response.content_type
+end
+
+
+
+

6.4 可用的三个散列

请求发送并处理之后,有三个散列对象可供我们使用:

+
    +
  • cookies:设定的 cookie

  • +
  • flash:闪现消息中的对象

  • +
  • session:会话中的对象

  • +
+

和普通的散列对象一样,可以使用字符串形式的键获取相应的值。此外,也可以使用符号形式的键。例如:

+
+flash["gordon"]               flash[:gordon]
+session["shmession"]          session[:shmession]
+cookies["are_good_for_u"]     cookies[:are_good_for_u]
+
+
+
+

6.5 可用的实例变量

在功能测试中还可以使用下面三个实例变量:

+
    +
  • @controller:处理请求的控制器

  • +
  • @request:请求对象

  • +
  • @response:响应对象

  • +
+

6.6 设定首部和 CGI 变量

HTTP 首部CGI 变量可以通过 headers 参数传入:

+
+# 设定一个 HTTP 首部
+get articles_url, headers: "Content-Type" => "text/plain" # 模拟有自定义首部的请求
+
+# 设定一个 CGI 变量
+get articles_url, headers: "HTTP_REFERER" => "http://example.com/home" # 模拟有自定义环境变量的请求
+
+
+
+

6.7 测试闪现消息

你可能还记得,在功能测试中可用的三个散列中有一个是 flash

我们想在这个博客应用中添加一个闪现消息,在成功发布新文章之后显示。

首先,在 test_should_create_article 测试中添加一个断言:

+
+test "should create article" do
+  assert_difference('Article.count') do
+    post article_url, params: { article: { title: 'Some title' } }
+  end
+
+  assert_redirected_to article_path(Article.last)
+  assert_equal 'Article was successfully created.', flash[:notice]
+end
+
+
+
+

现在运行测试,应该会看到有一个测试失败:

+
+$ bin/rails test test/controllers/articles_controller_test.rb -n test_should_create_article
+Run options: -n test_should_create_article --seed 32266
+
+# Running:
+
+F
+
+Finished in 0.114870s, 8.7055 runs/s, 34.8220 assertions/s.
+
+  1) Failure:
+ArticlesControllerTest#test_should_create_article [/test/controllers/articles_controller_test.rb:16]:
+--- expected
++++ actual
+@@ -1 +1 @@
+-"Article was successfully created."
++nil
+
+1 runs, 4 assertions, 1 failures, 0 errors, 0 skips
+
+
+
+

接下来,在控制器中添加闪现消息。现在,create 控制器应该是下面这样:

+
+def create
+  @article = Article.new(article_params)
+
+  if @article.save
+    flash[:notice] = 'Article was successfully created.'
+    redirect_to @article
+  else
+    render 'new'
+  end
+end
+
+
+
+

再运行测试,应该能通过:

+
+$ bin/rails test test/controllers/articles_controller_test.rb -n test_should_create_article
+Run options: -n test_should_create_article --seed 18981
+
+# Running:
+
+.
+
+Finished in 0.081972s, 12.1993 runs/s, 48.7972 assertions/s.
+
+1 runs, 4 assertions, 0 failures, 0 errors, 0 skips
+
+
+
+

6.8 测试其他动作

至此,我们测试了 Articles 控制器的 indexnewcreate 三个动作。那么,怎么处理现有数据呢?

下面为 show 动作编写一个测试:

+
+test "should show article" do
+  article = articles(:one)
+  get article_url(http://github.com/article)
+  assert_response :success
+end
+
+
+
+

还记得前文对固件的讨论吗?我们可以使用 articles() 方法访问 Articles 固件。

怎么删除现有的文章呢?

+
+test "should destroy article" do
+  article = articles(:one)
+  assert_difference('Article.count', -1) do
+    delete article_url(http://github.com/article)
+  end
+
+  assert_redirected_to articles_path
+end
+
+
+
+

我们还可以为更新现有文章这一操作编写一个测试。

+
+test "should update article" do
+  article = articles(:one)
+
+  patch article_url(http://github.com/article), params: { article: { title: "updated" } }
+
+  assert_redirected_to article_path(article)
+  # 重新加载关联,获取最新的数据,然后断定标题更新了
+  article.reload
+  assert_equal "updated", article.title
+end
+
+
+
+

可以看到,这三个测试中开始有重复了:都访问了同一个文章固件数据。为了避免自我重复,我们可以使用 ActiveSupport::Callbacks 提供的 setupteardown 方法清理。

清理后的测试如下。为了行为简洁,我们暂且不管其他测试。

+
+require 'test_helper'
+
+class ArticlesControllerTest < ActionDispatch::IntegrationTest
+  # 在各个测试之前调用
+  setup do
+    @article = articles(:one)
+  end
+
+  # 在各个测试之后调用
+  teardown do
+    # 如果控制器使用缓存,最好在后面重设
+    Rails.cache.clear
+  end
+
+  test "should show article" do
+    # 复用 setup 中定义的 @article 实例变量
+    get article_url(http://github.com/@article)
+    assert_response :success
+  end
+
+  test "should destroy article" do
+    assert_difference('Article.count', -1) do
+      delete article_url(http://github.com/@article)
+    end
+
+    assert_redirected_to articles_path
+  end
+
+  test "should update article" do
+    patch article_url(http://github.com/@article), params: { article: { title: "updated" } }
+
+    assert_redirected_to article_path(@article)
+    # 重新加载关联,获取最新的数据,然后断定标题更新了
+    @article.reload
+    assert_equal "updated", @article.title
+  end
+end
+
+
+
+

与 Rails 中的其他回调一样,setupteardown 也接受块、lambda 或符号形式的方法名。

6.9 测试辅助方法

为了避免代码重复,可以自定义测试辅助方法。下面实现用于登录的辅助方法:

+
+#test/test_helper.rb
+
+module SignInHelper
+  def sign_in_as(user)
+    post sign_in_url(/service/email: user.email, password: user.password)
+  end
+end
+
+class ActionDispatch::IntegrationTest
+  include SignInHelper
+end
+
+
+
+
+
+require 'test_helper'
+
+class ProfileControllerTest < ActionDispatch::IntegrationTest
+
+  test "should show profile" do
+    # 辅助方法在任何控制器测试用例中都可用
+    sign_in_as users(:david)
+
+    get profile_url
+    assert_response :success
+  end
+end
+
+
+
+

7 测试路由

与 Rails 应用中其他各方面内容一样,路由也可以测试。

应用的路由复杂也不怕,Rails 提供了很多有用的测试辅助方法。

关于 Rails 中可用的路由断言,参见 ActionDispatch::Assertions::RoutingAssertions 模块的 API 文档

8 测试视图

测试请求的响应中是否出现关键的 HTML 元素和相应的内容是测试应用视图的一种常见方式。与路由测试一样,视图测试放在 test/controllers/ 目录中,或者直接写在控制器测试中。assert_select 方法用于查询响应中的 HTML 元素,其句法简单而强大。

assert_select 有两种形式。

assert_select(selector, [equality], [message]) 测试 selector 选中的元素是否符合 equality 指定的条件。selector 可以是 CSS 选择符表达式(字符串),或者是有代入值的表达式。

assert_select(element, selector, [equality], [message]) 测试 selector 选中的元素和 elementNokogiri::XML::NodeNokogiri::XML::NodeSet 实例)及其子代是否符合 equality 指定的条件。

例如,可以使用下面的断言检测 title 元素的内容:

+
+assert_select 'title', "Welcome to Rails Testing Guide"
+
+
+
+

assert_select 的代码块还可嵌套使用。

在下述示例中,内层的 assert_select 会在外层块选中的元素集合中查询 li.menu_item

+
+assert_select 'ul.navigation' do
+  assert_select 'li.menu_item'
+end
+
+
+
+

除此之外,还可以遍历外层 assert_select 选中的元素集合,这样就可以在集合的每个元素上运行内层 assert_select 了。

假如响应中有两个有序列表,每个列表中都有 4 个列表项,那么下面这两个测试都会通过:

+
+assert_select "ol" do |elements|
+  elements.each do |element|
+    assert_select element, "li", 4
+  end
+end
+
+assert_select "ol" do
+  assert_select "li", 8
+end
+
+
+
+

assert_select 断言很强大,高级用法请参阅文档

8.1 其他视图相关的断言

还有一些断言经常在视图测试中使用:

+ + + + + + + + + + + + + + + + + + + + + +
断言作用
assert_select_email检查电子邮件的正文。
assert_select_encoded检查编码后的 HTML。先解码各元素的内容,然后在代码块中处理解码后的各个元素。
css_select(selector) 或 css_select(element, selector)返回由 selector 选中的所有元素组成的数组。在后一种用法中,首先会找到 element,然后在其中执行 selector 表达式查找元素,如果没有匹配的元素,两种用法都返回空数组。
+

下面是 assert_select_email 断言的用法举例:

+
+assert_select_email do
+  assert_select 'small', 'Please click the "Unsubscribe" link if you want to opt-out.'
+end
+
+
+
+

9 测试辅助方法

辅助方法是简单的模块,其中定义的方法可在视图中使用。

针对辅助方法的测试,只需检测辅助方法的输出和预期值是否一致。相应的测试文件保存在 test/helpers 目录中。

假设我们定义了下述辅助方法:

+
+module UserHelper
+  def link_to_user(user)
+    link_to "#{user.first_name} #{user.last_name}", user
+  end
+end
+
+
+
+

我们可以像下面这样测试它的输出:

+
+class UserHelperTest < ActionView::TestCase
+  test "should return the user's full name" do
+    user = users(:david)
+
+    assert_dom_equal %{<a href="http://github.com/user/#{user.id}">David Heinemeier Hansson</a>}, link_to_user(user)
+  end
+end
+
+
+
+

而且,因为测试类继承自 ActionView::TestCase,所以在测试中可以使用 Rails 内置的辅助方法,例如 link_topluralize

10 测试邮件程序

测试邮件程序需要一些特殊的工具才能完成。

10.1 确保邮件程序在管控内

和 Rails 应用的其他组件一样,邮件程序也应该测试,确保能正常工作。

测试邮件程序的目的是:

+
    +
  • 确保处理了电子邮件(创建及发送)

  • +
  • 确保邮件内容正确(主题、发件人、正文等)

  • +
  • 确保在正确的时间发送正确的邮件

  • +
+
10.1.1 要全面测试

针对邮件程序的测试分为两部分:单元测试和功能测试。在单元测试中,单独运行邮件程序,严格控制输入,然后和已知值(固件)对比。在功能测试中,不用这么细致的测试,只要确保控制器和模型正确地使用邮件程序,在正确的时间发送正确的邮件。

10.2 单元测试

为了测试邮件程序是否能正常使用,可以把邮件程序真正得到的结果和预先写好的值进行比较。

10.2.1 固件的另一个用途

在单元测试中,固件用于设定期望得到的值。因为这些固件是示例邮件,不是 Active Record 数据,所以要和其他固件分开,放在单独的子目录中。这个子目录位于 test/fixtures 目录中,其名称与邮件程序对应。例如,邮件程序 UserMailer 使用的固件保存在 test/fixtures/user_mailer 目录中。

生成邮件程序时,生成器会为其中每个动作生成相应的固件。如果没使用生成器,要手动创建这些文件。

10.2.2 基本的测试用例

下面的单元测试针对 UserMailerinvite 动作,这个动作的作用是向朋友发送邀请。这段代码改进了生成器为 invite 动作生成的测试。

+
+require 'test_helper'
+
+class UserMailerTest < ActionMailer::TestCase
+  test "invite" do
+    # 创建邮件,将其存储起来,供后面的断言使用
+    email = UserMailer.create_invite('me@example.com',
+                                     'friend@example.com', Time.now)
+
+    # 发送邮件,测试有没有入队
+    assert_emails 1 do
+      email.deliver_now
+    end
+
+    # 测试发送的邮件中有没有预期的内容
+    assert_equal ['me@example.com'], email.from
+    assert_equal ['friend@example.com'], email.to
+    assert_equal 'You have been invited by me@example.com', email.subject
+    assert_equal read_fixture('invite').join, email.body.to_s
+  end
+end
+
+
+
+

在这个测试中,我们发送了一封邮件,并把返回对象赋值给 email 变量。首先,我们确保邮件已经发送了;随后,确保邮件中包含预期的内容。read_fixture 这个辅助方法的作用是从指定的文件中读取内容。

invite 固件的内容如下:

+
+Hi friend@example.com,
+
+You have been invited.
+
+Cheers!
+
+
+
+

现在我们稍微深入一点地介绍针对邮件程序的测试。在 config/environments/test.rb 文件中,有这么一行设置:ActionMailer::Base.delivery_method = :test。这行设置把发送邮件的方法设为 :test,所以邮件并不会真的发送出去(避免测试时骚扰用户),而是添加到一个数组中(ActionMailer::Base.deliveries)。

ActionMailer::Base.deliveries 数组只会在 ActionMailer::TestCaseActionDispatch::IntegrationTest 测试中自动重设,如果想在这些测试之外使用空数组,可以手动重设:ActionMailer::Base.deliveries.clear

10.3 功能测试

邮件程序的功能测试不只是测试邮件正文和收件人等是否正确这么简单。在针对邮件程序的功能测试中,要调用发送邮件的方法,检查相应的邮件是否出现在发送列表中。你可以尽情放心地假定发送邮件的方法本身能顺利完成工作。你需要重点关注的是应用自身的业务逻辑,确保能在预期的时间发出邮件。例如,可以使用下面的代码测试邀请朋友的操作是否发出了正确的邮件:

+
+require 'test_helper'
+
+class UserControllerTest < ActionDispatch::IntegrationTest
+  test "invite friend" do
+    assert_difference 'ActionMailer::Base.deliveries.size', +1 do
+      post invite_friend_url, params: { email: 'friend@example.com' }
+    end
+    invite_email = ActionMailer::Base.deliveries.last
+
+    assert_equal "You have been invited by me@example.com", invite_email.subject
+    assert_equal 'friend@example.com', invite_email.to[0]
+    assert_match(/Hi friend@example.com/, invite_email.body.to_s)
+  end
+end
+
+
+
+

11 测试作业

因为自定义的作业在应用的不同层排队,所以我们既要测试作业本身(入队后的行为),也要测试是否正确入队了。

11.1 一个基本的测试用例

默认情况下,生成作业时也会生成相应的测试,存储在 test/jobs 目录中。下面是付款作业的测试示例:

+
+require 'test_helper'
+
+class BillingJobTest < ActiveJob::TestCase
+  test 'that account is charged' do
+    BillingJob.perform_now(account, product)
+    assert account.reload.charged_for?(product)
+  end
+end
+
+
+
+

这个测试相当简单,只是断言作业能做预期的事情。

默认情况下,ActiveJob::TestCase 把队列适配器设为 :async,因此作业是异步执行的。此外,在运行任何测试之前,它会清理之前执行的和入队的作业,因此我们可以放心假定在当前测试的作用域中没有已经执行的作业。

11.2 自定义断言和测试其他组件中的作业

Active Job 自带了很多自定义的断言,可以简化测试。可用的断言列表参见 ActiveJob::TestHelper 模块的 API 文档

不管作业是在哪里调用的(例如在控制器中),最好都要测试作业能正确入队或执行。这时就体现了 Active Job 提供的自定义断言的用处。例如,在模型中:

+
+require 'test_helper'
+
+class ProductTest < ActiveJob::TestCase
+  test 'billing job scheduling' do
+    assert_enqueued_with(job: BillingJob) do
+      product.charge(account)
+    end
+  end
+end
+
+
+
+

12 其他测试资源

12.1 测试与时间有关的代码

Rails 提供了一些内置的辅助方法,便于我们测试与时间有关的代码。

下述示例用到了 travel_to 辅助方法:

+
+# 假设用户在注册一个月内可以获取礼品
+user = User.create(name: 'Gaurish', activation_date: Date.new(2004, 10, 24))
+assert_not user.applicable_for_gifting?
+travel_to Date.new(2004, 11, 24) do
+  assert_equal Date.new(2004, 10, 24), user.activation_date # 在 travel_to 块中, `Date.current` 是拟件
+  assert user.applicable_for_gifting?
+end
+assert_equal Date.new(2004, 10, 24), user.activation_date # 改动只在 travel_to 块中可见
+
+
+
+

可用的时间辅助方法详情参见 ActiveSupport::Testing::TimeHelpers 模块的 API 文档

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/upgrading_ruby_on_rails.html b/upgrading_ruby_on_rails.html new file mode 100644 index 0000000..06ce8b0 --- /dev/null +++ b/upgrading_ruby_on_rails.html @@ -0,0 +1,1120 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ +
+
+ + +
+

Chapters

+
    +
  1. +一般建议 + + +
  2. +
  3. +从 Rails 4.2 升级到 5.0 + + +
  4. +
  5. +从 Rails 4.1 升级到 4.2 + + +
  6. +
  7. +从 Rails 4.0 升级到 4.1 + + +
  8. +
  9. +从 Rails 3.2 升级到 4.0 + + +
  10. +
+ +
+ +
+
+ +
+
+
+

Ruby on Rails 升级指南

本文说明把 Ruby on Rails 升级到新版本的步骤。各个版本的发布记中也有升级步骤。

1 一般建议

计划升级现有项目之前,应该确定有升级的必要。你要考虑几个因素:对新功能的需求,难于支持旧代码,以及你的时间和技能,等等。

1.1 测试覆盖度

为了确保升级后应用依然能正常运行,最好的方式是具有足够的测试覆盖度。如果没有自动化测试保障应用,你就要自己花时间检查有变化的部分。对升级 Rails 来说,你要检查应用的每个功能。不要给自己找麻烦,在升级之前一定要保障有足够的测试覆盖度。

1.2 升级过程

升级 Rails 版本时,最好放慢脚步,一次升级一个小版本,充分利用弃用提醒。Rails 版本号的格式是“大版本.小版本.补丁版本”。大版本和小版本允许修改公开 API,因此可能导致你的应用出错。补丁版本只修正缺陷,不改变公开 API。

升级过程如下:

+
    +
  1. 编写测试,确保能通过。

  2. +
  3. 升级到当前版本的最新补丁版本。

  4. +
  5. 修正测试和弃用的功能。

  6. +
  7. 升级到下一个小版本的补丁版本。

  8. +
+

重复上述过程,直到你所选的版本为止。每次升级版本都要修改 Gemfile 中的 Rails 版本号(以及其他需要升级的 gem),再运行 bundle update。然后,运行下文所述的 update 任务,更新配置文件。最后运行测试。

Rails 的所有版本在这个页面中列出。

1.3 Ruby 版本

发布新版 Rails 时,一般会紧跟最新的 Ruby 版本:

+
    +
  • Rails 5 要求 Ruby 2.2.2 或以上版本

  • +
  • Rails 4 建议使用 Ruby 2.0,要求 1.9.3 或以上版本

  • +
  • Rails 3.2.x 是支持 Ruby 1.8.7 的最后一个版本

  • +
  • Rails 3 及以上版本要求 Ruby 1.8.7 或以上版本。官方不再支持之前的 Ruby 版本,应该尽早升级。

  • +
+

Ruby 1.8.7 p248 和 p249 有一些缺陷,会导致 Rails 崩溃。 Ruby Enterprise Edition 1.8.7-2010.02 修正了这些缺陷。对 1.9 系列来说,1.9.1 完全不能用,因此如果你使用 1.9.x 的话,应该直接跳到 1.9.3。

1.4 update 任务

Rails 提供了 app:update 任务(4.2 及之前的版本是 rails:update)。更新 Gemfile 中的 Rails 版本号之后,运行这个任务。这个任务在交互式会话中协助你创建新文件和修改旧文件。

+
+$ rails app:update
+   identical  config/boot.rb
+       exist  config
+    conflict  config/routes.rb
+Overwrite /myapp/config/routes.rb? (enter "h" for help) [Ynaqdh]
+       force  config/routes.rb
+    conflict  config/application.rb
+Overwrite /myapp/config/application.rb? (enter "h" for help) [Ynaqdh]
+       force  config/application.rb
+    conflict  config/environment.rb
+...
+
+
+
+

别忘了检查差异,以防有意料之外的改动。

2 从 Rails 4.2 升级到 5.0

Rails 5.0 的变动参见发布记

2.1 要求 Ruby 2.2.2+

从 Ruby on Rails 5.0 开始,只支持 Ruby 2.2.2+。升级之前,确保你使用的是 Ruby 2.2.2 或以上版本。

2.2 现在 Active Record 模型默认继承自 ApplicationRecord

在 Rails 4.2 中,Active Record 模型继承自 ActiveRecord::Base。在 Rails 5.0 中,所有模型继承自 ApplicationRecord

现在,ApplicationRecord 是应用中所有模型的超类,而不是 ActionController::Base,这样结构就与 ApplicationController 一样了,因此可以在一个地方为应用中的所有模型配置行为。

从 Rails 4.2 升级到 5.0 时,要在 app/models/ 目录中创建 application_record.rb 文件,写入下述内容:

+
+class ApplicationRecord < ActiveRecord::Base
+  self.abstract_class = true
+end
+
+
+
+

然后让所有模型继承它。

2.3 通过 throw(:abort) 停止回调链

在 Rails 4.2 中,如果 Active Record 和 Active Model 中的一个前置回调返回 false,整个回调链停止。也就是说,后续前置回调不会执行,回调中的操作也不执行。

在 Rails 5.0 中,Active Record 和 Active Model 中的前置回调返回 false 时不再停止回调链。如果想停止,要调用 throw(:abort)

从 Rails 4.2 升级到 5.0 时,返回 false 的前置回调依然会停止回调链,但是你会收到一个弃用提醒,告诉你未来会像前文所述那样变化。

准备妥当之后,可以在 config/application.rb 文件中添加下述配置,启用新的行为(弃用消息不再显示):

+
+ActiveSupport.halt_callback_chains_on_return_false = false
+
+
+
+

注意,这个选项不影响 Active Support 回调,因为不管返回什么值,这种回调链都不停止。

详情参见 #17227 工单

2.4 现在 ActiveJob 默认继承自 ApplicationJob

在 Rails 4.2 中,Active Job 类继承自 ActiveJob::Base。在 Rails 5.0 中,这一行为变了,现在继承自 ApplicationJob

从 Rails 4.2 升级到 5.0 时,要在 app/jobs/ 目录中创建 application_job.rb 文件,写入下述内容:

+
+class ApplicationJob < ActiveJob::Base
+end
+
+
+
+

然后让所有作业类继承它。

详情参见 #19034 工单

2.5 Rails 控制器测试

assignsassert_template 提取到 rails-controller-testing gem 中了。如果想继续在控制器测试中使用这两个方法,把 gem 'rails-controller-testing' 添加到 Gemfile 中。

如果使用 RSpec 做测试,还要做些配置,详情参见这个 gem 的文档。

2.6 在生产环境启动后不再自动加载

现在,在生产环境启动后默认不再自动加载。

及早加载发生在应用的启动过程中,因此顶层常量不受影响,依然能自动加载,无需引入相应的文件。

层级较深的常量与常规的代码定义体一样,只在运行时执行,因此也不受影响,因为定义它们的文件在启动过程中及早加载了。

针对这一变化,大多数应用都无需改动。在少有的情况下,如果生产环境需要自动加载,把 Rails.application.config.enable_dependency_loading 设为 true

2.7 XML 序列化

ActiveModel::Serializers::Xml 从 Rails 中提取出来,变成 activemodel-serializers-xml gem 了。如果想继续在应用中使用 XML 序列化,把 gem 'activemodel-serializers-xml' 添加到 Gemfile 中。

2.8 不再支持旧的 mysql 数据库适配器

Rails 5 不再支持旧的 mysql 数据库适配器。多数用户应该换用 mysql2。找到维护人员之后,会作为一个单独的 gem 发布。

2.9 不再支持 debugger

Rails 5 要求的 Ruby 2.2 不支持 debugger。换用 byebug

2.10 使用 bin/rails 运行任务和测试

Rails 5 支持使用 bin/rails 运行任务和测试。一般来说,还有相应的 rake 任务,但有些完全移过来了。

新的测试运行程序使用 bin/rails test 运行。

rake dev:cache 现在变成了 rails dev:cache

执行 bin/rails 命令查看所有可用的命令。

2.11 ActionController::Parameters 不再继承自 HashWithIndifferentAccess +

现在,应用中的 params 不再返回散列。如果已经在参数上调用了 permit,无需做任何修改。如果使用 slice 及其他需要读取散列的方法,而不管是否调用了 permitted?,需要更新应用,首先调用 permit,然后转换成散列。

+
+params.permit([:proceed_to, :return_to]).to_h
+
+
+
+

2.12 protect_from_forgery 的选项现在默认为 prepend: false +

protect_from_forgery 的选项现在默认为 prepend: false,这意味着,在应用中调用 protect_from_forgery 时,会插入回调链。如果始终想让 protect_from_forgery 先运行,应该修改应用,使用 protect_from_forgery prepend: true

2.13 默认的模板处理程序现在是 raw

文件扩展名中没有模板处理程序的,现在使用 raw 处理程序。以前,Rails 使用 ERB 模板处理程序渲染这种文件。

如果不想让 raw 处理程序处理文件,应该添加文件扩展名,让相应的模板处理程序解析。

2.14 为模板依赖添加通配符匹配

现在可以使用通配符匹配模板依赖。例如,如果像下面这样定义模板:

+
+<% # Template Dependency: recordings/threads/events/subscribers_changed %>
+<% # Template Dependency: recordings/threads/events/completed %>
+<% # Template Dependency: recordings/threads/events/uncompleted %>
+
+
+
+

现在可以使用通配符一次调用所有依赖:

+
+<% # Template Dependency: recordings/threads/events/* %>
+
+
+
+

2.15 不再支持 protected_attributes gem

Rails 5 不再支持 protected_attributes gem。

2.16 不再支持 activerecord-deprecated_finders gem

Rails 5 不再支持 activerecord-deprecated_finders gem。

2.17 ActiveSupport::TestCase 现在默认随机运行测试

应用中的测试现在默认的运行顺序是 :random,不再是 :sorted。如果想改回 :sorted,使用下述配置选项:

+
+# config/environments/test.rb
+Rails.application.configure do
+  config.active_support.test_order = :sorted
+end
+
+
+
+

2.18 ActionController::Live 变为一个 Concern +

如果在引入控制器的模块中引入了 ActionController::Live,还应该使用 ActiveSupport::Concern 扩展模块。或者,也可以使用 self.included 钩子在引入 StreamingSupport 之后直接把 ActionController::Live 引入控制器。

这意味着,如果应用有自己的流模块,下述代码在生产环境不可用:

+
+# This is a work-around for streamed controllers performing authentication with Warden/Devise.
+# See https://github.com/plataformatec/devise/issues/2332
+# Authenticating in the router is another solution as suggested in that issue
+class StreamingSupport
+  include ActionController::Live # this won't work in production for Rails 5
+  # extend ActiveSupport::Concern # unless you uncomment this line.
+
+  def process(name)
+    super(name)
+  rescue ArgumentError => e
+    if e.message == 'uncaught throw :warden'
+      throw :warden
+    else
+      raise e
+    end
+  end
+end
+
+
+
+

2.19 框架的新默认值

2.19.1 Active Record belongs_to_required_by_default 选项

如果关联不存在,belongs_to 现在默认触发验证错误。

这一行为可在具体的关联中使用 optional: true 选项禁用。

新应用默认自动配置这一行为。如果现有项目想使用这一特性,可以在初始化脚本中启用:

+
+config.active_record.belongs_to_required_by_default = true
+
+
+
+
2.19.2 每个表单都有自己的 CSRF 令牌

现在,Rails 5 支持每个表单有自己的 CSRF 令牌,从而降低 JavaScript 创建的表单遭受代码注入攻击的风险。启用这个选项后,应用中的表单都有自己的 CSRF 令牌,专门针对那个表单的动作和方法。

+
+config.action_controller.per_form_csrf_tokens = true
+
+
+
+
2.19.3 伪造保护检查源

现在,可以配置应用检查 HTTP Origin 首部和网站的源,增加一道 CSRF 防线。把下述配置选项设为 true

+
+config.action_controller.forgery_protection_origin_check = true
+
+
+
+
2.19.4 允许配置 Action Mailer 队列的名称

默认的邮件程序队列名为 mailers。这个配置选项允许你全局修改队列名称。在配置文件中添加下述内容:

+
+config.action_mailer.deliver_later_queue_name = :new_queue_name
+
+
+
+
2.19.5 Action Mailer 视图支持片段缓存

在配置文件中设定 config.action_mailer.perform_caching 选项,决定是否让 Action Mailer 视图支持缓存。

+
+config.action_mailer.perform_caching = true
+
+
+
+
2.19.6 配置 db:structure:dump 的输出

如果使用 schema_search_path 或者其他 PostgreSQL 扩展,可以控制如何转储数据库模式。设为 :all 生成全部转储,设为 :schema_search_path 从模式搜索路径中生成转储。

+
+config.active_record.dump_schemas = :all
+
+
+
+
2.19.7 配置 SSL 选项为子域名启用 HSTS

在配置文件中设定下述选项,为子域名启用 HSTS:

+
+config.ssl_options = { hsts: { subdomains: true } }
+
+
+
+
2.19.8 保留接收者的时区

使用 Ruby 2.4 时,调用 to_time 时可以保留接收者的时区:

+
+ActiveSupport.to_time_preserves_timezone = false
+
+
+
+

3 从 Rails 4.1 升级到 4.2

3.1 Web Console

首先,把 gem 'web-console', '~> 2.0' 添加到 Gemfile:development 组里(升级时不含这个 gem),然后执行 bundle install 命令。安装好之后,可以在任何想使用 Web Console 的视图里调用辅助方法 <%= console %>。开发环境的错误页面中也有 Web Console。

3.2 responders gem

respond_with 实例方法和 respond_to 类方法已经提取到 responders gem 中。如果想使用这两个方法,只需把 gem 'responders', '~> 2.0' 添加到 Gemfile 中。如果依赖中没有 responders gem,无法调用二者。

+
+# app/controllers/users_controller.rb
+
+class UsersController < ApplicationController
+  respond_to :html, :json
+
+  def show
+    @user = User.find(params[:id])
+    respond_with @user
+  end
+end
+
+
+
+

respond_to 实例方法不受影响,无需添加额外的 gem:

+
+# app/controllers/users_controller.rb
+
+class UsersController < ApplicationController
+  def show
+    @user = User.find(params[:id])
+    respond_to do |format|
+      format.html
+      format.json { render json: @user }
+    end
+  end
+end
+
+
+
+

详情参见 #16526 工单

3.3 事务回调中的错误处理

目前,Active Record 压制 after_rollbackafter_commit 回调抛出的错误,只将其输出到日志里。在下一版中,这些错误不再得到压制,而像其他 Active Record 回调一样正常冒泡。

你定义的 after_rollbackafter_commit 回调会收到一个弃用提醒,说明这一变化。如果你做好了迎接新行为的准备,可以在 config/application.rb 文件中添加下述配置,不再发出弃用提醒:

+
+config.active_record.raise_in_transactional_callbacks = true
+
+
+
+

详情参见 #14488#16537 工单

3.4 测试用例的运行顺序

在 Rails 5.0 中,测试用例将默认以随机顺序运行。为了抢先使用这一个改变,Rails 4.2 引入了一个新配置选项,即 active_support.test_order,用于指定测试的运行顺序。你可以将其设为 :sorted,继续使用目前的行为,或者设为 :random,使用未来的行为。

如果不为这个选项设定一个值,Rails 会发出弃用提醒。如果不想看到弃用提醒,在测试环境的配置文件中添加下面这行:

+
+# config/environments/test.rb
+Rails.application.configure do
+  config.active_support.test_order = :sorted # 如果愿意,也可以设为 `:random`
+end
+
+
+
+

3.5 序列化的属性

使用定制的编码器时(如 serialize :metadata, JSON),如果把 nil 赋值给序列化的属性,存入数据库中的值是 NULL,而不是通过编码器传递的 nil 值(例如,使用 JSON 编码器时的 "null")。

3.6 生产环境的日志等级

Rails 5 将把生产环境的默认日志等级改为 :debug(以前是 :info)。若想继续使用目前的默认值,在 production.rb 文件中添加下面这行:

+
+# Set to `:info` to match the current default, or set to `:debug` to opt-into
+# the future default.
+config.log_level = :info
+
+
+
+

3.7 在 Rails 模板中使用 after_bundle +

如果你的 Rails 模板把所有文件纳入版本控制,无法添加生成的 binstubs,因为模板在 Bundler 之前执行:

+
+# template.rb
+generate(:scaffold, "person name:string")
+route "root to: 'people#index'"
+rake("db:migrate")
+
+git :init
+git add: "."
+git commit: %Q{ -m 'Initial commit' }
+
+
+
+

现在,你可以把 git 调用放在 after_bundle 块中,在生成 binstubs 之后执行:

+
+# template.rb
+generate(:scaffold, "person name:string")
+route "root to: 'people#index'"
+rake("db:migrate")
+
+after_bundle do
+  git :init
+  git add: "."
+  git commit: %Q{ -m 'Initial commit' }
+end
+
+
+
+

3.8 rails-html-sanitizer

现在,净化应用中的 HTML 片段有了新的选择。古老的 html-scanner 方式正式弃用,换成了 rails-html-sanitizer

因此,sanitizesanitize_cssstrip_tagsstrip_links 等方法现在有了新的实现方式。

新的净化程序内部使用 Loofah,而它使用 Nokogiri。Nokogiri 包装了使用 C 和 Java 编写的 XML 解析器,因此不管使用哪个 Ruby 版本,净化的过程应该都很快。

新版本更新了 sanitize,它接受一个 Loofah::Scrubber 对象,提供强有力的清洗功能。清洗程序的示例参见这里

此外,还添加了两个新清洗程序:PermitScrubberTargetScrubber。详情参阅 rails-html-sanitizer gem 的自述文件

PermitScrubberTargetScrubber 的文档说明了如何完全控制何时以及如何剔除元素。

如果应用想使用旧的净化程序,把 rails-deprecated_sanitizer 添加到 Gemfile 中:

+
+gem 'rails-deprecated_sanitizer'
+
+
+
+

3.9 Rails DOM 测试

TagAssertions 模块(包含 assert_tag 等方法)已经弃用,换成了 SelectorAssertions 模块的 assert_select 方法。新的方法提取到 rails-dom-testing gem 中了。

3.10 遮蔽真伪令牌

为了防范 SSL 攻击,form_authenticity_token 现在做了遮蔽,每次请求都不同。因此,验证令牌时先解除遮蔽,然后再解密。所以,验证非 Rails 表单发送的,而且依赖静态会话 CSRF 令牌的请求时,要考虑这一点。

3.11 Action Mailer

以前,在邮件程序类上调用邮件程序方法会直接执行相应的实例方法。引入 Active Job 和 #deliver_later 之后,情况变了。在 Rails 4.2 中,实例方法延后到调用 deliver_nowdeliver_later 时才执行。例如:

+
+class Notifier < ActionMailer::Base
+  def notify(user, ...)
+    puts "Called"
+    mail(to: user.email, ...)
+  end
+end
+
+mail = Notifier.notify(user, ...) # 此时 Notifier#notify 还未执行
+mail = mail.deliver_now           # 打印“Called”
+
+
+
+

对大多数应用来说,这不会导致明显的差别。然而,如果非邮件程序方法要同步执行,而以前依靠同步代理行为的话,应该将其定义为邮件程序类的类方法:

+
+class Notifier < ActionMailer::Base
+  def self.broadcast_notifications(users, ...)
+    users.each { |user| Notifier.notify(user, ...) }
+  end
+end
+
+
+
+

3.12 支持外键

迁移 DSL 做了扩充,支持定义外键。如果你以前使用 foreigner gem,可以考虑把它删掉了。注意,Rails 对外键的支持没有 foreigner 全面。这意味着,不是每一个 foreigner 定义都可以完全替换成 Rails 中相应的迁移 DSL。

替换的过程如下:

+
    +
  1. Gemfile 中删除 gem "foreigner"

  2. +
  3. 执行 bundle install 命令。

  4. +
  5. 执行 bin/rake db:schema:dump 命令。

  6. +
  7. 确保 db/schema.rb 文件中包含每一个外键定义,而且有所需的选项。

  8. +
+

4 从 Rails 4.0 升级到 4.1

4.1 保护远程 <script> 标签免受 CSRF 攻击

或者“我的测试为什么失败了!?”“我的 <script> 小部件不能用了!!!”

现在,跨站请求伪造(Cross-site request forgery,CSRF)涵盖获取 JavaScript 响应的 GET 请求。这样能防止第三方网站通过 <script> 标签引用你的 JavaScript,获取敏感数据。

因此,使用下述代码的功能测试和集成测试现在会触发 CSRF 保护:

+
+get :index, format: :js
+
+
+
+

换成下述代码,明确测试 XmlHttpRequest

+
+xhr :get, :index, format: :js
+
+
+
+

注意,站内的 <script> 标签也认为是跨源的,因此默认被阻拦。如果确实想使用 <script> 加载 JavaScript,必须在动作中明确指明跳过 CSRF 保护。

4.2 Spring

如果想使用 Spring 预加载应用,要这么做:

+
    +
  1. gem 'spring', group: :development 添加到 Gemfile 中。

  2. +
  3. 执行 bundle install 命令,安装 Spring。

  4. +
  5. 执行 bundle exec spring binstub --all,用 Spring 运行 binstub。

  6. +
+

用户定义的 Rake 任务默认在开发环境中运行。如果想在其他环境中运行,查阅 Spring 的自述文件

4.3 config/secrets.yml +

若想使用新增的 secrets.yml 文件存储应用的机密信息,要这么做:

+
    +
  1. +

    config 文件夹中创建 secrets.yml 文件,写入下述内容:

    +
    +
    +development:
    +  secret_key_base:
    +
    +test:
    +  secret_key_base:
    +
    +production:
    +  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
    +
    +
    +
    +
  2. +
  3. 使用 secret_token.rb 初始化脚本中的 secret_key_base 设定 SECRET_KEY_BASE 环境变量,供生产环境中的用户使用。此外,还可以直接复制 secret_key_base 的值,把 <%= ENV["SECRET_KEY_BASE"] %> 替换掉。

  4. +
  5. 删除 secret_token.rb 初始化脚本。

  6. +
  7. 运行 rake secret 任务,为开发环境和测试环境生成密钥。

  8. +
  9. 重启服务器。

  10. +
+

4.4 测试辅助方法的变化

如果测试辅助方法中有调用 ActiveRecord::Migration.check_pending!,可以将其删除了。现在,引入 rails/test_help 文件时会自动做此项检查,不过留着那一行代码也没什么危害。

4.5 cookies 序列化程序

使用 Rails 4.1 之前的版本创建的应用使用 Marshal 序列化签名和加密的 cookie 值。若想使用新的基于 JSON 的格式,创建一个初始化脚本,写入下述内容:

+
+Rails.application.config.action_dispatch.cookies_serializer = :hybrid
+
+
+
+

这样便能平顺地从现在的 Marshal 序列化形式改成基于 JSON 的格式。

使用 :json:hybrid 序列化程序时要注意,不是所有 Ruby 对象都能序列化成 JSON。例如,DateTime 对象序列化成字符串,散列的键序列化成字符串。

+
+class CookiesController < ApplicationController
+  def set_cookie
+    cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014
+    redirect_to action: 'read_cookie'
+  end
+
+  def read_cookie
+    cookies.encrypted[:expiration_date] # => "2014-03-20"
+  end
+end
+
+
+
+

建议只在 cookie 中存储简单的数据(字符串和数字)。如果存储复杂的对象,在后续请求中读取 cookie 时要自己动手转换。

如果使用 cookie 会话存储器,sessionflash 散列也是如此。

4.6 闪现消息结构的变化

闪现消息的键会整形成字符串,不过依然可以使用符号或字符串访问。迭代闪现消息时始终使用字符串键:

+
+flash["string"] = "a string"
+flash[:symbol] = "a symbol"
+
+# Rails < 4.1
+flash.keys # => ["string", :symbol]
+
+# Rails >= 4.1
+flash.keys # => ["string", "symbol"]
+
+
+
+

一定要使用字符串比较闪现消息的键。

4.7 JSON 处理方式的变化

Rails 4.1 对 JSON 的处理方式做了几项修改。

4.7.1 删除 MultiJSON

MultiJSON 结束历史使命,Rails 把它删除了。

如果你的应用现在直接依赖 MultiJSON,有几种解决方法:

+
    +
  1. multi_json gem 添加到 Gemfile 中。注意,未来这种方法可能失效。

  2. +
  3. 摒除 MultiJSON,换用 obj.to_jsonJSON.parse(str)

  4. +
+

不要直接把 MultiJson.dumpMultiJson.load 换成 JSON.dumpJSON.load。这两个 JSON gem API 的作用是序列化和反序列化任意的 Ruby 对象,一般不安全

4.7.2 JSON gem 的兼容性

由于历史原因,Rails 有些 JSON gem 的兼容性问题。在 Rails 应用中使用 JSON.generateJSON.dump 可能导致意料之外的错误。

Rails 4.1 修正了这些问题:在 JSON gem 之外提供了单独的编码器。JSON gem 的 API 现在能正常使用了,但是不能访问任何 Rails 专用的功能。例如:

+
+class FooBar
+  def as_json(options = nil)
+    { foo: 'bar' }
+  end
+end
+
+>> FooBar.new.to_json # => "{\"foo\":\"bar\"}"
+>> JSON.generate(FooBar.new, quirks_mode: true) # => "\"#<FooBar:0x007fa80a481610>\""
+
+
+
+
4.7.3 新的 JSON 编码器

Rails 4.1 重写了 JSON 编码器,充分利用了 JSON gem。对多数应用来说,这一变化没有显著影响。然而,在重写的过程中从编码器中移除了下述功能:

+
    +
  1. 环形数据结构检测

  2. +
  3. encode_json 钩子的支持

  4. +
  5. BigDecimal 对象编码成数字而不是字符串的选项

  6. +
+

如果你的应用依赖这些功能,可以把 activesupport-json_encoder gem 添加到 Gemfile 中。

4.7.4 时间对象的 JSON 表述

在包含时间组件的对象(TimeDateTimeActiveSupport::TimeWithZone)上调用 #as_json,现在返回值的默认精度是毫秒。如果想继续使用旧的行为,不含毫秒,在一个初始化脚本中设定下述选项:

+
+ActiveSupport::JSON::Encoding.time_precision = 0
+
+
+
+

4.8 行内回调块中 return 的用法

以前,Rails 允许在行内回调块中像下面这样使用 return

+
+class ReadOnlyModel < ActiveRecord::Base
+  before_save { return false } # BAD
+end
+
+
+
+

这种行为一直没得到广泛支持。由于 ActiveSupport::Callbacks 内部的变化,Rails 4.1 不再允许这么做。如果在行内回调块中使用 return,执行回调时会抛出 LocalJumpError 异常。

使用 return 的行内回调块可以重构成求取返回值:

+
+class ReadOnlyModel < ActiveRecord::Base
+  before_save { false } # GOOD
+end
+
+
+
+

如果想使用 return,建议定义为方法:

+
+class ReadOnlyModel < ActiveRecord::Base
+  before_save :before_save_callback # GOOD
+
+  private
+    def before_save_callback
+      return false
+    end
+end
+
+
+
+

这一变化影响使用回调的多数地方,包括 Active Record 和 Active Model 回调,以及 Action Controller 的过滤器(如 before_action)。

详情参见这个拉取请求

4.9 Active Record 固件中定义的方法

Rails 4.1 在各自的上下文中处理各个固件中的 ERB,因此一个附件中定义的辅助方法,无法在另一个固件中使用。

在多个固件中使用的辅助方法应该在 test_helper.rb 文件的一个模块中定义,然后使用新的 ActiveRecord::FixtureSet.context_class 引入。

+
+module FixtureFileHelpers
+  def file_sha(path)
+    Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
+  end
+end
+ActiveRecord::FixtureSet.context_class.include FixtureFileHelpers
+
+
+
+

4.10 i18n 强制检查可用的本地化

现在,Rails 4.1 默认把 i18n 的 enforce_available_locales 选项设为 true。这意味着,传给它的所有本地化都必须在 available_locales 列表中声明。

如果想禁用这一行为(让 i18n 接受任何本地化选项),在应用的配置文件中添加下述选项:

+
+config.i18n.enforce_available_locales = false
+
+
+
+

注意,这个选项是一项安全措施,为的是确保不把用户的输入作为本地化信息,除非这个信息之前是已知的。因此,除非有十足的原因,否则不建议禁用这个选项。

4.11 在 Relation 上调用的可变方法

Relation 不再提供可变方法,如 #map!#delete_if。如果想使用这些方法,调用 #to_a 把它转换成数组。

这样改的目的是避免奇怪的缺陷,以及防止代码意图不明。

+
+# 现在不能这么写
+Author.where(name: 'Hank Moody').compact!
+
+# 要这么写
+authors = Author.where(name: 'Hank Moody').to_a
+authors.compact!
+
+
+
+

4.12 默认作用域的变化

默认作用域不再能够使用链式条件覆盖。

在之前的版本中,模型中的 default_scope 会被同一字段的链式条件覆盖。现在,与其他作用域一样,变成了合并。

以前:

+
+class User < ActiveRecord::Base
+  default_scope { where state: 'pending' }
+  scope :active, -> { where state: 'active' }
+  scope :inactive, -> { where state: 'inactive' }
+end
+
+User.all
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
+
+User.active
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
+
+User.where(state: 'inactive')
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
+
+
+
+

现在:

+
+class User < ActiveRecord::Base
+  default_scope { where state: 'pending' }
+  scope :active, -> { where state: 'active' }
+  scope :inactive, -> { where state: 'inactive' }
+end
+
+User.all
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
+
+User.active
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'active'
+
+User.where(state: 'inactive')
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'inactive'
+
+
+
+

如果想使用以前的行为,要使用 unscopedunscoperewhereexceptdefault_scope 定义的条件移除。

+
+class User < ActiveRecord::Base
+  default_scope { where state: 'pending' }
+  scope :active, -> { unscope(where: :state).where(state: 'active') }
+  scope :inactive, -> { rewhere state: 'inactive' }
+end
+
+User.all
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
+
+User.active
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
+
+User.inactive
+# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
+
+
+
+

4.13 使用字符串渲染内容

Rails 4.1 为 render 引入了 :plain:html:body 选项。现在,建议使用这三个选项渲染字符串内容,因为这样可以指定响应的内容类型。

+
    +
  • render :plain 把内容类型设为 text/plain

  • +
  • render :html 把内容类型设为 text/html

  • +
  • render :body 不设定内容类型首部

  • +
+

从安全角度来看,如果响应主体中没有任何标记,应该使用 render :plain,因为多数浏览器会转义响应中不安全的内容。

未来的版本会弃用 render :text。所以,请开始使用更精准的 :plain:html:body 选项。使用 render :text 可能有安全风险,因为发送的内容类型是 text/html

4.14 PostgreSQL 的 json 和 hstore 数据类型

Rails 4.1 把 jsonhstore 列映射成键为字符串的 Ruby 散列。之前的版本使用 HashWithIndifferentAccess。这意味着,不再支持使用符号访问。建立在 jsonhstore 列之上的 store_accessors 也是如此。确保要始终使用字符串键。

4.15 ActiveSupport::Callbacks 明确要求使用块

现在,Rails 4.1 明确要求调用 ActiveSupport::Callbacks.set_callback 时传入一个块。之所以这样要求,是因为 4.1 版大范围重写了 ActiveSupport::Callbacks

+
+# Rails 4.0
+set_callback :save, :around, ->(r, &block) { stuff; result = block.call; stuff }
+
+# Rails 4.1
+set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff }
+
+
+
+

5 从 Rails 3.2 升级到 4.0

如果你的应用目前使用的版本低于 3.2.x,应该先升级到 3.2,再升级到 4.0。

下述说明针对升级到 Rails 4.0。

5.1 HTTP PATCH

现在,Rails 4.0 使用 PATCH 作为更新 REST 式资源(在 config/routes.rb 中声明)的主要 HTTP 动词。update 动作仍然在用,而且 PUT 请求继续交给 update 动作处理。因此,如果你只使用 REST 式路由,无需做任何修改。

+
+resources :users
+
+
+
+
+
+<%= form_for @user do |f| %>
+
+
+
+
+
+class UsersController < ApplicationController
+  def update
+    # 无需修改,首选 PATCH,但是 PUT 依然能用
+  end
+end
+
+
+
+

然而,如果使用 form_for 更新资源,而且用的是使用 PUT HTTP 方法的自定义路由,要做修改:

+
+resources :users, do
+  put :update_name, on: :member
+end
+
+
+
+
+
+<%= form_for [ :update_name, @user ] do |f| %>
+
+
+
+
+
+class UsersController < ApplicationController
+  def update_name
+    # 需要修改,因为 form_for 会尝试使用不存在的 PATCH 路由
+  end
+end
+
+
+
+

如果动作不在公开的 API 中,可以直接修改 HTTP 方法,把 put 路由改用 patch

在 Rails 4 中,针对 /users/:idPUT 请求交给 update 动作处理。因此,如果 API 使用 PUT 请求,依然能用。路由器也会把针对 /users/:idPATCH 请求交给 update 动作处理。

+
+resources :users do
+  patch :update_name, on: :member
+end
+
+
+
+

如果动作在公开的 API 中,不能修改所用的 HTTP 方法,此时可以修改表单,让它使用 PUT 方法:

+
+<%= form_for [ :update_name, @user ], method: :put do |f| %>
+
+
+
+

关于 PATCH 请求,以及为什么这样改,请阅读 Rails 博客中的这篇文章

5.1.1 关于媒体类型

PATCH 动词规范的勘误指出,PATCH 请求应该使用“diff”媒体类型JSON Patch 就是这样的格式。虽然 Rails 原生不支持 JSON Patch,不过添加这一支持也不难:

+
+# 在控制器中
+def update
+  respond_to do |format|
+    format.json do
+      # 执行局部更新
+      @article.update params[:article]
+    end
+
+    format.json_patch do
+      # 执行复杂的更新
+    end
+  end
+end
+
+# 在 config/initializers/json_patch.rb 文件中
+Mime::Type.register 'application/json-patch+json', :json_patch
+
+
+
+

JSON Patch 最近才收录到 RFC 中,因此还没有多少好的 Ruby 库。Aaron Patterson 开发的 hana 是一个,但是没有支持规范最近的几项修改。

5.2 Gemfile

Rails 4.0 删除了 Gemfileassets 分组。升级时,要把那一行删除。此外,还要更新应用配置(config/application.rb):

+
+# Require the gems listed in Gemfile, including any gems
+# you've limited to :test, :development, or :production.
+Bundler.require(*Rails.groups)
+
+
+
+

5.3 vendor/plugins

Rails 4.0 不再支持从 vendor/plugins 目录中加载插件。插件应该制成 gem,添加到 Gemfile 中。如果不想制成 gem,可以移到其他位置,例如 lib/my_plugin/*,然后添加相应的初始化脚本 config/initializers/my_plugin.rb

5.4 Active Record

+
    +
  • Rails 4.0 从 Active Record 中删除了标识映射(identity map),因为与关联有些不一致。如果你启动了这个功能,要把这个没有作用的配置删除:config.active_record.identity_map

  • +
  • 关联集合的 delete 方法的参数现在除了记录之外还可以使用 IntegerString,基本与 destroy 方法一样。以前,传入这样的参数时会抛出 ActiveRecord::AssociationTypeMismatch 异常。从 Rails 4.0 开始,delete 在删除记录之前会自动查找指定 ID 对应的记录。

  • +
  • 在 Rails 4.0 中,如果修改了列或表的名称,相关的索引也会重命名。现在无需编写迁移重命名索引了。

  • +
  • Rails 4.0 把 serialized_attributesattr_readonly 改成只有类方法版本了。别再使用实例方法版本了,因为已经弃用。应该把实例方法版本改成类方法版本,例如把 self.serialized_attributes 改成 self.class.serialized_attributes

  • +
  • 使用默认的编码器时,把 nil 赋值给序列化的属性在数据库中保存的是 NULL,而不是通过 YAML ("--- \n…​\n") 传递 nil 值。

  • +
  • Rails 4.0 删除了 attr_accessibleattr_protected,换成了健壮参数(strong parameter)。平滑升级可以使用 protected_attributes gem。

  • +
  • 如果不使用 protected_attributes gem,可以把与它有关的选项都删除,例如 whitelist_attributesmass_assignment_sanitizer

  • +
  • +

    Rails 4.0 要求作用域使用可调用的对象,如 Proc 或 lambda:

    +
    +
    +scope :active, where(active: true)
    +
    +# 变成
    +scope :active, -> { where active: true }
    +
    +
    +
    +
  • +
  • Rails 4.0 弃用了 ActiveRecord::Fixtures,改成了 ActiveRecord::FixtureSet

  • +
  • Rails 4.0 弃用了 ActiveRecord::TestCase,改成了 ActiveSupport::TestCase

  • +
  • Rails 4.0 弃用了以前基于散列的查找方法 API。这意味着,不能再给查找方法传入选项了。例如,Book.find(:all, conditions: { name: '1984' }) 已经弃用,改成了 Book.where(name: '1984')

  • +
  • +

    除了 find_by_…​find_by_…​!,其他动态查找方法都弃用了。新旧变化如下:

    +
      +
    • find_all_by_…​ 变成 where(…​) +
    • +
    • find_last_by_…​ 变成 where(…​).last +
    • +
    • scoped_by_…​ 变成 where(…​) +
    • +
    • find_or_initialize_by_…​ 变成 find_or_initialize_by(…​) +
    • +
    • find_or_create_by_…​ 变成 find_or_create_by(…​) +
    • +
    +
  • +
  • 注意,where(…​) 返回一个关系,而不像旧的查找方法那样返回一个数组。如果需要使用数组,调用 where(…​).to_a

  • +
  • 等价的方法所执行的 SQL 语句可能与以前的实现不同。

  • +
  • 如果想使用旧的查找方法,可以使用 activerecord-deprecated_finders gem。

  • +
  • +

    Rails 4.0 修改了 has_and_belongs_to_many 关联默认的联结表名,把第二个表名中的相同前缀去掉。现有的 has_and_belongs_to_many 关联,如果表名中有共用的前缀,要使用 join_table 选项指定。例如:

    +
    +
    +CatalogCategory < ActiveRecord::Base
    +  has_and_belongs_to_many :catalog_products, join_table: 'catalog_categories_catalog_products'
    +end
    +
    +CatalogProduct < ActiveRecord::Base
    +  has_and_belongs_to_many :catalog_categories, join_table: 'catalog_categories_catalog_products'
    +end
    +
    +
    +
    +
  • +
  • 注意,前缀含命名空间,因此 Catalog::CategoryCatalog::Product,或者 Catalog::CategoryCatalogProduct 之间的关联也要以同样的方式修改。

  • +
+

5.5 Active Resource

Rails 4.0 把 Active Resource 提取出来,制成了单独的 gem。如果想继续使用这个功能,把 activeresource gem 添加到 Gemfile 中。

5.6 Active Model

+
    +
  • Rails 4.0 修改了 ActiveModel::Validations::ConfirmationValidator 错误的依附方式。现在,如果二次确认验证失败,错误依附到 :#{attribute}_confirmation 上,而不是 attribute

  • +
  • +

    Rails 4.0 把 ActiveModel::Serializers::JSON.include_root_in_json 的默认值改成 false 了。现在 Active Model 序列化程序和 Active Record 对象具有相同的默认行为。这意味着,可以把 config/initializers/wrap_parameters.rb 文件中的下述选项注释掉或删除:

    +
    +
    +# Disable root element in JSON by default.
    +# ActiveSupport.on_load(:active_record) do
    +#   self.include_root_in_json = false
    +# end
    +
    +
    +
    +
  • +
+

5.7 Action Pack

+
    +
  • +

    Rails 4.0 引入了 ActiveSupport::KeyGenerator,使用它生成和验证签名 cookie 等。Rails 3.x 生成的现有签名 cookie,如果有 secret_token,并且添加了 secret_key_base,会自动升级。

    +
    +
    +# config/initializers/secret_token.rb
    +Myapp::Application.config.secret_token = 'existing secret token'
    +Myapp::Application.config.secret_key_base = 'new secret key base'
    +
    +
    +
    +

    注意,完全升级到 Rails 4.x,而且确定不再降级到 Rails 3.x之后再设定 secret_key_base。这是因为使用 Rails 4.x 中的新 secret_key_base 签名的 cookie 与 Rails 3.x 不兼容。你可以留着 secret_token,不设定新的 secret_key_base,把弃用消息忽略,等到完全升级好了再改。

    +

    如果使用外部应用或 JavaScript 读取 Rails 应用的签名会话 cookie(或一般的签名 cookie),解耦之后才应该设定 secret_key_base

    +
  • +
  • +

    如果设定了 secret_key_base,Rails 4.0 会加密基于 cookie 的会话内容。Rails 3.x 签名基于 cookie 的会话,但是不加密。签名的 cookie 是“安全的”,因为会确认是不是由应用生成的,无法篡改。然而,终端用户能看到内容,而加密后则无法查看,而且性能没有重大损失。

    +

    改成加密会话 cookie 的详情参见 #9978 拉取请求

    +
  • +
  • Rails 4.0 删除了 ActionController::Base.asset_path 选项,改用 Asset Pipeline 功能。

  • +
  • Rails 4.0 弃用了 ActionController::Base.page_cache_extension 选项,换成 ActionController::Base.default_static_extension

  • +
  • Rails 4.0 从 Action Pack 中删除了动作和页面缓存。如果想在控制器中使用 caches_action,要添加 actionpack-action_caching gem,想使用 caches_page,要添加 actionpack-page_caching gem。

  • +
  • Rails 4.0 删除了 XML 参数解析器。若想使用,要添加 actionpack-xml_parser gem。

  • +
  • Rails 4.0 修改了默认的 layout 查找集,使用返回 nil 的符号或 proc。如果不想使用布局,返回 false

  • +
  • Rails 4.0 把默认的 memcached 客户端由 memcache-client 改成了 dalli。若想升级,只需把 gem 'dalli' 添加到 Gemfile 中。

  • +
  • Rails 4.0 弃用了控制器中的 dom_iddom_class 方法(在视图中可以继续使用)。若想使用,要引入 ActionView::RecordIdentifier 模块。

  • +
  • Rails 4.0 弃用了 link_to 辅助方法的 :confirm 选项。现在应该使用 data 属性(如 data: { confirm: 'Are you sure?' })。基于这个辅助方法的辅助方法(如 link_to_iflink_to_unless)也受影响。

  • +
  • Rails 4.0 改变了 assert_generatesassert_recognizesassert_routing 的工作方式。现在,这三个断言抛出 Assertion,而不是 ActionController::RoutingError

  • +
  • +

    如果具名路由的名称有冲突,Rails 4.0 抛出 ArgumentError。自己定义具名路由,或者由 resources 生成都可能触发这一错误。下面两例中的 example_path 路由有冲突:

    +
    +
    +get 'one' => 'test#example', as: :example
    +get 'two' => 'test#example', as: :example
    +
    +resources :examples
    +get 'clashing/:id' => 'test#example', as: :example
    +
    +
    +
    +

    在第一例中,可以为两个路由起不同的名称。在第二例中,可以使用 resources 方法提供的 onlyexcept 选项,限制生成的路由。详情参见路由指南

    +
  • +
  • +

    Rails 4.0 还改变了含有 Unicode 字符的路由的处理方式。现在,可以直接在路由中使用 Unicode 字符。如果以前这样做过,要做修改。例如:

    +
    +
    +get Rack::Utils.escape('こんにちは'), controller: 'welcome', action: 'index'
    +
    +
    +
    +

    要改成:

    +
    +
    +get 'こんにちは', controller: 'welcome', action: 'index'
    +
    +
    +
    +
  • +
  • +

    Rails 4.0 要求使用 match 定义的路由必须指定请求方法。例如:

    +
    +
    +# Rails 3.x
    +match '/' => 'root#index'
    +
    +# 改成
    +match '/' => 'root#index', via: :get
    +
    +# 或
    +get '/' => 'root#index'
    +
    +
    +
    +
  • +
  • +

    Rails 4.0 删除了 ActionDispatch::BestStandardsSupport 中间件。根据这篇文章<!DOCTYPE html> 就能触发标准模式。此外,ChromeFrame 首部移到 config.action_dispatch.default_headers 中了。

    +

    注意,还必须把对这个中间件的引用从应用的代码中删除,例如:

    +
    +
    +# 抛出异常
    +config.middleware.insert_before(Rack::Lock, ActionDispatch::BestStandardsSupport)
    +
    +
    +
    +

    此外,还要把环境配置中的 config.action_dispatch.best_standards_support 选项删除(如果有的话)。

    +
  • +
  • 在 Rails 4.0 中,预先编译好的静态资源不再自动从 vendor/assetslib/assets 中复制 JS 和 CSS 之外的静态文件。Rails 应用和引擎开发者应该把静态资源文件放在 app/assets 目录中,或者配置 config.assets.precompile 选项。

  • +
  • 在 Rails 4.0 中,如果动作无法处理请求的格式,抛出 ActionController::UnknownFormat 异常。默认情况下,这个异常的处理方式是返回“406 Not Acceptable”响应,不过现在可以覆盖。在 Rails 3 中始终返回“406 Not Acceptable”响应,不可覆盖。

  • +
  • 在 Rails 4.0 中,如果 ParamsParser 无法解析请求参数,抛出 ActionDispatch::ParamsParser::ParseError 异常。你应该捕获这个异常,而不是具体的异常,如 MultiJson::DecodeError

  • +
  • 在 Rails 4.0 中,如果挂载引擎的 URL 有前缀,SCRIPT_NAME 能正确嵌套。现在不用设定 default_url_options[:script_name] 选项覆盖 URL 前缀了。

  • +
  • Rails 4.0 弃用了 ActionController::Integration,改成了 ActionDispatch::Integration

  • +
  • Rails 4.0 弃用了 ActionController::IntegrationTest,改成了 ActionDispatch::IntegrationTest

  • +
  • Rails 4.0 弃用了 ActionController::PerformanceTest,改成了 ActionDispatch::PerformanceTest

  • +
  • Rails 4.0 弃用了 ActionController::AbstractRequest,改成了 ActionDispatch::Request

  • +
  • Rails 4.0 弃用了 ActionController::Request,改成了 ActionDispatch::Request

  • +
  • Rails 4.0 弃用了 ActionController::AbstractResponse,改成了 ActionDispatch::Response

  • +
  • Rails 4.0 弃用了 ActionController::Response,改成了 ActionDispatch::Response

  • +
  • Rails 4.0 弃用了 ActionController::Routing,改成了 ActionDispatch::Routing

  • +
+

5.8 Active Support

Rails 4.0 删除了 ERB::Util#json_escape 的别名 j,因为已经把它用作 ActionView::Helpers::JavaScriptHelper#escape_javascript 的别名。

5.9 辅助方法的加载顺序

Rails 4.0 改变了从不同目录中加载辅助方法的顺序。以前,先找到所有目录,然后按字母表顺序排序。升级到 Rails 4.0 之后,辅助方法的目录顺序依旧,只在各自的目录中按字母表顺序加载。如果没有使用 helpers_path 参数,这一变化只影响从引擎中加载辅助方法的方式。如果看重顺序,升级后应该检查辅助方法是否可用。如果想修改加载引擎的顺序,可以使用 config.railties_order= 方法。

5.10 Active Record 观测器和 Action Controller 清洁器

ActiveRecord::ObserverActionController::Caching::Sweeper 提取到 rails-observers gem 中了。如果要使用它们,要添加 rails-observers gem。

5.11 sprockets-rails

+
    +
  • assets:precompile:primaryassets:precompile:all 删除了。改用 assets:precompile

  • +
  • +

    config.assets.compress 选项要改成 config.assets.js_compressor,例如:

    +
    +
    +config.assets.js_compressor = :uglifier
    +
    +
    +
    +
  • +
+

5.12 sass-rails

+
    +
  • +asset-url 不再接受两个参数。例如,asset-url("http://github.com/rails.png%22,%20image) 变成了 asset-url("http://github.com/rails.png")
  • +
+

英语原文还有从 Rails 3.0 升级到 3.1 及从 3.1 升级到 3.2 的说明,由于版本太旧,不再翻译,敬请谅解。——译者注

+ +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + diff --git a/working_with_javascript_in_rails.html b/working_with_javascript_in_rails.html new file mode 100644 index 0000000..d307a33 --- /dev/null +++ b/working_with_javascript_in_rails.html @@ -0,0 +1,517 @@ + + + + + + + +Ruby on Rails Guides + + + + + + + + + + + +
+
+ 更多内容 rubyonrails.org: + + More Ruby on Rails + + +
+
+ +
+ + + +
+
+
+

在 Rails 中使用 JavaScript

本文介绍 Rails 内建对 Ajax 和 JavaScript 等的支持,使用这些功能可以轻易地开发强大的 Ajax 动态应用。

本完本文后,您将学到:

+
    +
  • Ajax 基础知识;

  • +
  • 非侵入式 JavaScript;

  • +
  • 如何使用 Rails 内建的辅助方法;

  • +
  • 如何在服务器端处理 Ajax;

  • +
  • Turbolinks gem。

  • +
+

1 Ajax 简介

在理解 Ajax 之前,要先知道 Web 浏览器常规的工作原理。

在浏览器的地址栏中输入 http://localhost:3000 后,浏览器(客户端)会向服务器发起一个请求。然后浏览器处理响应,获取相关的静态资源文件,比如 JavaScript、样式表和图像,然后显示页面内容。点击链接后发生的事情也是如此:获取页面,获取静态资源,把全部内容放在一起,显示最终的网页。这个过程叫做“请求响应循环”。

JavaScript 也可以向服务器发起请求,并解析响应。而且还能更新网页中的内容。因此,JavaScript 程序员可以编写只更新部分内容的网页,而不用从服务器获取完整的页面数据。这是一种强大的技术,我们称之为 Ajax。

Rails 默认支持 CoffeeScript,后文所有的示例都用 CoffeeScript 编写。本文介绍的技术,在普通的 JavaScript 中也可以使用。

例如,下面这段 CoffeeScript 代码使用 jQuery 库发起一个 Ajax 请求:

+
+$.ajax(url: "/test").done (html) ->
+  $("#results").append html
+
+
+
+

这段代码从 /test 地址上获取数据,然后把结果追加到 div#results 元素中。

Rails 内建了很多使用这种技术开发应用的功能,基本上无需自己动手编写上述代码。后文介绍 Rails 如何为开发这种应用提供协助,不过都构建在这种简单的技术之上。

2 非侵入式 JavaScript

Rails 使用一种叫做“非侵入式 JavaScript”(Unobtrusive JavaScript)的技术把 JavaScript 依附到 DOM 上。非侵入式 JavaScript 是前端开发社区推荐的做法,但有些教程可能会使用其他方式。

下面是编写 JavaScript 最简单的方式,你可能见过,这叫做“行间 JavaScript”:

+
+<a href="#" onclick="this.style.backgroundColor='#990000'">Paint it red</a>
+
+
+
+

点击链接后,链接的背景会变成红色。这种用法的问题是,如果点击链接后想执行大量 JavaScript 代码怎么办?

+
+<a href="#" onclick="this.style.backgroundColor='#009900';this.style.color='#FFFFFF';">Paint it green</a>
+
+
+
+

太别扭了,不是吗?我们可以把处理点击的代码定义成一个函数,用 CoffeeScript 编写如下:

+
+@paintIt = (element, backgroundColor, textColor) ->
+  element.style.backgroundColor = backgroundColor
+  if textColor?
+    element.style.color = textColor
+
+
+
+

然后在页面中这么写:

+
+<a href="#" onclick="paintIt(this, '#990000')">Paint it red</a>
+
+
+
+

这种方法好点儿,但是如果很多链接需要同样的效果该怎么办呢?

+
+<a href="#" onclick="paintIt(this, '#990000')">Paint it red</a>
+<a href="#" onclick="paintIt(this, '#009900', '#FFFFFF')">Paint it green</a>
+<a href="#" onclick="paintIt(this, '#000099', '#FFFFFF')">Paint it blue</a>
+
+
+
+

这样非常不符合 DRY 原则。为了解决这个问题,我们可以使用“事件”。在链接上添加一个 data-* 属性,然后把处理程序绑定到拥有这个属性的点击事件上:

+
+@paintIt = (element, backgroundColor, textColor) ->
+  element.style.backgroundColor = backgroundColor
+  if textColor?
+    element.style.color = textColor
+
+$ ->
+  $("a[data-background-color]").click (e) ->
+    e.preventDefault()
+
+    backgroundColor = $(this).data("background-color")
+    textColor = $(this).data("text-color")
+    paintIt(this, backgroundColor, textColor)
+
+
+
+
+
+<a href="#" data-background-color="#990000">Paint it red</a>
+<a href="#" data-background-color="#009900" data-text-color="#FFFFFF">Paint it green</a>
+<a href="#" data-background-color="#000099" data-text-color="#FFFFFF">Paint it blue</a>
+
+
+
+

我们把这种方法称为“非侵入式 JavaScript”,因为 JavaScript 代码不再和 HTML 混合在一起。这样做正确分离了关注点,易于修改功能。我们可以轻易地把这种效果应用到其他链接上,只要添加相应的 data 属性即可。我们可以简化并拼接全部 JavaScript,然后在各个页面加载一个 JavaScript 文件,这样只在第一次请求时需要加载,后续请求都会直接从缓存中读取。“非侵入式 JavaScript”带来的好处太多了。

Rails 团队极力推荐使用这种方式编写 CoffeeScript(以及 JavaScript),而且你会发现很多代码库都采用了这种方式。

3 内置的辅助方法

Rails 提供了很多视图辅助方法协助你生成 HTML,如果想在元素上实现 Ajax 效果也没问题。

因为使用的是非侵入式 JavaScript,所以 Ajax 相关的辅助方法其实分成两部分,一部分是 JavaScript 代码,一部分是 Ruby 代码。

如果没有禁用 Asset Pipeline,rails.js 负责提供 JavaScript 代码,常规的 Ruby 视图辅助方法负责生成 DOM 标签。

3.1 form_for +

form_for 方法协助编写表单,可指定 :remote 选项,用法如下:

+
+<%= form_for(@article, remote: true) do |f| %>
+  ...
+<% end %>
+
+
+
+

生成的 HTML 如下:

+
+<form accept-charset="UTF-8" action="http://github.com/articles" class="new_article" data-remote="true" id="new_article" method="post">
+  ...
+</form>
+
+
+
+

注意 data-remote="true" 属性,现在这个表单不会通过常规的方式提交,而是通过 Ajax 提交。

或许你并不需要一个只能填写内容的表单,而是想在表单提交成功后做些事情。为此,我们要绑定 ajax:success 事件。处理表单提交失败的程序要绑定到 ajax:error 事件上。例如:

+
+$(document).ready ->
+  $("#new_article").on("ajax:success", (e, data, status, xhr) ->
+    $("#new_article").append xhr.responseText
+  ).on "ajax:error", (e, xhr, status, error) ->
+    $("#new_article").append "<p>ERROR</p>"
+
+
+
+

显然你需要的功能比这要复杂,上面的例子只是个入门。关于事件的更多内容请阅读 jquery-ujs 的维基

3.2 form_tag +

form_tag 方法的作用与 form_for 类似,也可指定 :remote 选项,如下所示:

+
+<%= form_tag('/articles', remote: true) do %>
+  ...
+<% end %>
+
+
+
+

生成的 HTML 如下:

+
+<form accept-charset="UTF-8" action="http://github.com/articles" data-remote="true" method="post">
+  ...
+</form>
+
+
+
+

其他用法都和 form_for 一样。详情参见文档。

link_to 方法用于生成链接,可以指定 :remote 选项,用法如下:

+
+<%= link_to "an article", @article, remote: true %>
+
+
+
+

生成的 HTML 如下:

+
+<a href="http://github.com/articles/1" data-remote="true">an article</a>
+
+
+
+

绑定的 Ajax 事件和 form_for 方法一样。下面举个例子。假如有一个文章列表,我们想只点击一个链接就删除所有文章。视图代码如下:

+
+<%= link_to "Delete article", @article, remote: true, method: :delete %>
+
+
+
+

CoffeeScript 代码如下:

+
+$ ->
+  $("a[data-remote]").on "ajax:success", (e, data, status, xhr) ->
+    alert "The article was deleted."
+
+
+
+

3.4 button_to +

button_to 方法用于生成按钮,可以指定 :remote 选项,用法如下:

+
+<%= button_to "An article", @article, remote: true %>
+
+
+
+

生成的 HTML 如下:

+
+<form action="http://github.com/articles/1" class="button_to" data-remote="true" method="post">
+  <input type="submit" value="An article" />
+</form>
+
+
+
+

因为生成的就是一个表单,所以 form_for 的全部信息都可使用。

4 服务器端处理

Ajax 不仅涉及客户端,服务器端也要做处理。Ajax 请求一般不返回 HTML,而是 JSON。下面详细说明处理过程。

4.1 一个简单的例子

假设在网页中要显示一系列用户,还有一个新建用户的表单。控制器的 index 动作如下所示:

+
+class UsersController < ApplicationController
+  def index
+    @users = User.all
+    @user = User.new
+  end
+  # ...
+
+
+
+

index 视图(app/views/users/index.html.erb)如下:

+
+<b>Users</b>
+
+<ul id="users">
+<%= render @users %>
+</ul>
+
+<br>
+
+<%= form_for(@user, remote: true) do |f| %>
+  <%= f.label :name %><br>
+  <%= f.text_field :name %>
+  <%= f.submit %>
+<% end %>
+
+
+
+

app/views/users/_user.html.erb 局部视图的内容如下:

+
+<li><%= user.name %></li>
+
+
+
+

index 页面的上部显示用户列表,下部显示新建用户的表单。

下部的表单会调用 UsersControllercreate 动作。因为表单的 remote 选项为 true,所以发给 UsersController 的是 Ajax 请求,使用 JavaScript 处理。要想处理这个请求,控制器的 create 动作应该这么写:

+
+# app/controllers/users_controller.rb
+# ......
+def create
+  @user = User.new(params[:user])
+
+  respond_to do |format|
+    if @user.save
+      format.html { redirect_to @user, notice: 'User was successfully created.' }
+      format.js   {}
+      format.json { render json: @user, status: :created, location: @user }
+    else
+      format.html { render action: "new" }
+      format.json { render json: @user.errors, status: :unprocessable_entity }
+    end
+  end
+end
+
+
+
+

注意,在 respond_to 块中使用了 format.js,这样控制器才能响应 Ajax 请求。然后还要新建 app/views/users/create.js.erb 视图文件,编写发送响应以及在客户端执行的 JavaScript 代码。

+
+$("<%= escape_javascript(render @user) %>").appendTo("#users");
+
+
+
+

Rails 提供了 Turbolinks 库,它使用 Ajax 渲染页面,在多数应用中可以提升页面加载速度。

5.1 Turbolinks 的工作原理

Turbolinks 为页面中所有的 <a> 元素添加一个点击事件处理程序。如果浏览器支持 PushState,Turbolinks 会发起 Ajax 请求,解析响应,然后使用响应主体替换原始页面的整个 <body> 元素。最后,使用 PushState 技术更改页面的 URL,让新页面可刷新,并且有个精美的 URL。

要想使用 Turbolinks,只需将其加入 Gemfile,然后在 app/assets/javascripts/application.js 中加入 //= require turbolinks

如果某个链接不想使用 Turbolinks,可以在链接中添加 data-turbolinks="false" 属性:

+
+<a href="http://github.com/..." data-turbolinks="false">No turbolinks here</a>.
+
+
+
+

5.2 页面内容变更事件

编写 CoffeeScript 代码时,经常需要在页面加载时做一些事情。在 jQuery 中,我们可以这么写:

+
+$(document).ready ->
+  alert "page has loaded!"
+
+
+
+

不过,Turbolinks 改变了常规的页面加载流程,不会触发这个事件。如果编写了类似上面的代码,要将其修改为:

+
+$(document).on "turbolinks:load", ->
+  alert "page has loaded!"
+
+
+
+

其他可用事件的详细信息,参阅 Turbolinks 的自述文件

6 其他资源

下面列出一些链接,可以帮助你进一步学习:

+ + + +

反馈

+

+ 我们鼓励您帮助提高本指南的质量。 +

+

+ 如果看到如何错字或错误,请反馈给我们。 + 您可以阅读我们的文档贡献指南。 +

+

+ 您还可能会发现内容不完整或不是最新版本。 + 请添加缺失文档到 master 分支。请先确认 Edge Guides 是否已经修复。 + 关于用语约定,请查看Ruby on Rails 指南指导。 +

+

+ 无论什么原因,如果你发现了问题但无法修补它,请创建 issue。 +

+

+ 最后,欢迎到 rubyonrails-docs 邮件列表参与任何有关 Ruby on Rails 文档的讨论。 +

+

中文翻译反馈

+

贡献:https://github.com/ruby-china/guides

+
+
+
+ +
+ + + + + + + + + From 44a9ecb1f64fd0dafd3e327cd582bc9a0f8aa015 Mon Sep 17 00:00:00 2001 From: Rei Date: Sun, 26 Feb 2017 20:35:47 +0800 Subject: [PATCH 02/17] update --- index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 9514145..75bc9c8 100644 --- a/index.html +++ b/index.html @@ -194,7 +194,8 @@

Ruby on Rails 指南 (v5.0.1)

-
Rails 同时提供 Kindle 版。
+
Rails 指南同时提供 Kindle 版。
+
如果需要 Epub、PDF 格式,可以购买安道维护的电子书
标记了这个图标的指南还在编写中,不会出现在指南索引。这些指南可能包含不完整的信息甚至错误。您可以帮忙检查并且提交评论和修正。
From dfbc04397ea4d393a7a69a374f33a94bc6a600b9 Mon Sep 17 00:00:00 2001 From: Rei Date: Sat, 4 Mar 2017 14:46:49 +0800 Subject: [PATCH 03/17] update --- action_cable_overview.html | 468 +++++++++- action_controller_overview.html | 2 +- active_record_querying.html | 2 +- active_support_core_extensions.html | 2 +- asset_pipeline.html | 1059 ++++++++++++++++++++++- command_line.html | 8 +- configuring.html | 2 +- engines.html | 1231 ++++++++++++++++++++++++++- initialization.html | 568 +++++++++++- security.html | 468 ++++++++-- 10 files changed, 3736 insertions(+), 74 deletions(-) diff --git a/action_cable_overview.html b/action_cable_overview.html index dfbe4db..222ec1b 100644 --- a/action_cable_overview.html +++ b/action_cable_overview.html @@ -175,14 +175,478 @@

Guides.rubyonrails.org<
-

Action Cable 概览

+

Action Cable 概览

本文介绍 Action Cable 的工作原理,以及在 Rails 应用中如何通过 WebSocket 实现实时功能。

读完本文后,您将学到:

+
    +
  • 如何设置 Action Cable;

  • +
  • 如何设置频道(channel);

  • +
  • Action Cable 的部署和架构设置。

  • +
+

1 简介

Action Cable 将 WebSocket 与 Rails 应用的其余部分无缝集成。有了 Action Cable,我们就可以用 Ruby 语言,以 Rails 风格实现实时功能,并且保持高性能和可扩展性。Action Cable 为此提供了全栈支持,包括客户端 JavaScript 框架和服务器端 Ruby 框架。同时,我们也能够通过 Action Cable 访问使用 Active Record 或其他 ORM 编写的所有模型。

2 Pub/Sub 是什么

Pub/Sub,也就是发布/订阅,是指在消息队列中,信息发送者(发布者)把数据发送给某一类接收者(订阅者),而不必单独指定接收者。Action Cable 通过发布/订阅的方式在服务器和多个客户端之间通信。

3 服务器端组件

3.1 连接

连接是客户端-服务器通信的基础。每当服务器接受一个 WebSocket,就会实例化一个连接对象。所有频道订阅(channel subscription)都是在继承连接对象的基础上创建的。连接本身并不处理身份验证和授权之外的任何应用逻辑。WebSocket 连接的客户端被称为连接用户(connection consumer)。每当用户新打开一个浏览器标签、窗口或设备,对应地都会新建一个用户-连接对(consumer-connection pair)。

连接是 ApplicationCable::Connection 类的实例。对连接的授权就是在这个类中完成的,对于能够识别的用户,才会继续建立连接。

3.1.1 连接设置
+
+# app/channels/application_cable/connection.rb
+module ApplicationCable
+  class Connection < ActionCable::Connection::Base
+    identified_by :current_user
+
+    def connect
+      self.current_user = find_verified_user
+    end
+
+    protected
+      def find_verified_user
+        if current_user = User.find_by(id: cookies.signed[:user_id])
+          current_user
+        else
+          reject_unauthorized_connection
+        end
+      end
+  end
+end
+
+
+
+

其中 identified_by 用于声明连接标识符,连接标识符稍后将用于查找指定连接。注意,在声明连接标识符的同时,在基于连接创建的频道实例上,会自动创建同名委托(delegate)。

上述例子假设我们已经在应用的其他部分完成了用户身份验证,并且在验证成功后设置了经过用户 ID 签名的 cookie。

尝试建立新连接时,会自动把 cookie 发送给连接实例,用于设置 current_user。通过使用 current_user 标识连接,我们稍后就能够检索指定用户打开的所有连接(如果删除用户或取消对用户的授权,该用户打开的所有连接都会断开)。

3.2 频道

和常规 MVC 中的控制器类似,频道用于封装逻辑工作单元。默认情况下,Rails 会把 ApplicationCable::Channel 类作为频道的父类,用于封装频道之间共享的逻辑。

3.2.1 父频道设置
+
+# app/channels/application_cable/channel.rb
+module ApplicationCable
+  class Channel < ActionCable::Channel::Base
+  end
+end
+
+
+
+

接下来我们要创建自己的频道类。例如,可以创建 ChatChannelAppearanceChannel 类:

+
+# app/channels/chat_channel.rb
+class ChatChannel < ApplicationCable::Channel
+end
+
+# app/channels/appearance_channel.rb
+class AppearanceChannel < ApplicationCable::Channel
+end
+
+
+
+

这样用户就可以订阅频道了,订阅一个或两个都行。

3.2.2 订阅

订阅频道的用户称为订阅者。用户创建的连接称为(频道)订阅。订阅基于连接用户(订阅者)发送的标识符创建,生成的消息将发送到这些订阅。

+
+# app/channels/chat_channel.rb
+class ChatChannel < ApplicationCable::Channel
+  # 当用户成为此频道的订阅者时调用
+  def subscribed
+  end
+end
+
+
+
+

4 客户端组件

4.1 连接

用户需要在客户端创建连接实例。下面这段由 Rails 默认生成的 JavaScript 代码,正是用于在客户端创建连接实例:

4.1.1 连接用户
+
+// app/assets/javascripts/cable.js
+//= require action_cable
+//= require_self
+//= require_tree ./channels
+
+(function() {
+  this.App || (this.App = {});
+
+  App.cable = ActionCable.createConsumer();
+}).call(this);
+
+
+
+

上述代码会创建连接用户,并将通过默认的 /cable 地址和服务器建立连接。我们还需要从现有订阅中至少选择一个感兴趣的订阅,否则将无法建立连接。

4.1.2 订阅者

一旦订阅了某个频道,用户也就成为了订阅者:

+
+# app/assets/javascripts/cable/subscriptions/chat.coffee
+App.cable.subscriptions.create { channel: "ChatChannel", room: "Best Room" }
+
+# app/assets/javascripts/cable/subscriptions/appearance.coffee
+App.cable.subscriptions.create { channel: "AppearanceChannel" }
+
+
+
+

上述代码创建了订阅,稍后我们还要描述如何处理接收到的数据。

作为订阅者,用户可以多次订阅同一个频道。例如,用户可以同时订阅多个聊天室:

+
+App.cable.subscriptions.create { channel: "ChatChannel", room: "1st Room" }
+App.cable.subscriptions.create { channel: "ChatChannel", room: "2nd Room" }
+
+
+
+

5 客户端-服务器的交互

5.1 流(stream)

频道把已发布内容(即广播)发送给订阅者,是通过所谓的“流”机制实现的。

+
+# app/channels/chat_channel.rb
+class ChatChannel < ApplicationCable::Channel
+  def subscribed
+    stream_from "chat_#{params[:room]}"
+  end
+end
+
+
+
+

有了和模型关联的流,就可以从模型和频道生成所需的广播。下面的例子用于订阅评论频道,以接收 Z2lkOi8vVGVzdEFwcC9Qb3N0LzE 这样的广播:

+
+class CommentsChannel < ApplicationCable::Channel
+  def subscribed
+    post = Post.find(params[:id])
+    stream_for post
+  end
+end
+
+
+
+

向评论频道发送广播的方式如下:

+
+CommentsChannel.broadcast_to(@post, @comment)
+
+
+
+

5.2 广播

广播是指发布/订阅的链接,也就是说,当频道订阅者使用流接收某个广播时,发布者发布的内容会被直接发送给订阅者。

广播也是时间相关的在线队列。如果用户未使用流(即未订阅频道),稍后就无法接收到广播。

在 Rails 应用的其他部分也可以发送广播:

+
+WebNotificationsChannel.broadcast_to(
+  current_user,
+  title: 'New things!',
+  body: 'All the news fit to print'
+)
+
+
+
+

调用 WebNotificationsChannel.broadcast_to 将向当前订阅适配器(默认为 Redis)的发布/订阅队列推送一条消息,并为每个用户设置不同的广播名。对于 ID 为 1 的用户,广播名是 web_notifications_1

通过调用 received 回调方法,频道会使用流把到达 web_notifications_1 的消息直接发送给客户端。

5.3 订阅

订阅频道的用户,称为订阅者。用户创建的连接称为(频道)订阅。订阅基于连接用户(订阅者)发送的标识符创建,收到的消息将被发送到这些订阅。

+
+# app/assets/javascripts/cable/subscriptions/chat.coffee
+# 假设我们已经获得了发送 Web 通知的权限
+App.cable.subscriptions.create { channel: "ChatChannel", room: "Best Room" },
+  received: (data) ->
+    @appendLine(data)
+
+  appendLine: (data) ->
+    html = @createLine(data)
+    $("[data-chat-room='Best Room']").append(html)
+
+  createLine: (data) ->
+    """
+    <article class="chat-line">
+      <span class="speaker">#{data["sent_by"]}</span>
+      <span class="body">#{data["body"]}</span>
+    </article>
+    """
+
+
+
+

5.4 向频道传递参数

创建订阅时,可以从客户端向服务器端传递参数。例如:

+
+# app/channels/chat_channel.rb
+class ChatChannel < ApplicationCable::Channel
+  def subscribed
+    stream_from "chat_#{params[:room]}"
+  end
+end
+
+
+
+

传递给 subscriptions.create 方法并作为第一个参数的对象,将成为频道的参数散列。其中必需包含 channel 关键字:

+
+# app/assets/javascripts/cable/subscriptions/chat.coffee
+App.cable.subscriptions.create { channel: "ChatChannel", room: "Best Room" },
+  received: (data) ->
+    @appendLine(data)
+
+  appendLine: (data) ->
+    html = @createLine(data)
+    $("[data-chat-room='Best Room']").append(html)
+
+  createLine: (data) ->
+    """
+    <article class="chat-line">
+      <span class="speaker">#{data["sent_by"]}</span>
+      <span class="body">#{data["body"]}</span>
+    </article>
+    """
+
+
+
+
+
+# 在应用的某个部分中调用,例如 NewCommentJob
+ChatChannel.broadcast_to(
+  "chat_#{room}",
+  sent_by: 'Paul',
+  body: 'This is a cool chat app.'
+)
+
+
+
+

5.5 消息重播

一个客户端向其他已连接客户端重播自己收到的消息,是一种常见用法。

+
+# app/channels/chat_channel.rb
+class ChatChannel < ApplicationCable::Channel
+  def subscribed
+    stream_from "chat_#{params[:room]}"
+  end
+
+  def receive(data)
+    ActionCable.server.broadcast("chat_#{params[:room]}", data)
+  end
+end
+
+
+
+
+
+# app/assets/javascripts/cable/subscriptions/chat.coffee
+App.chatChannel = App.cable.subscriptions.create { channel: "ChatChannel", room: "Best Room" },
+  received: (data) ->
+    # data => { sent_by: "Paul", body: "This is a cool chat app." }
+
+App.chatChannel.send({ sent_by: "Paul", body: "This is a cool chat app." })
+
+
+
+

所有已连接的客户端,包括发送消息的客户端在内,都将收到重播的消息。注意,重播时使用的参数与订阅频道时使用的参数相同。

6 全栈示例

本节的两个例子都需要进行下列设置:

+
    +
  1. 设置连接;

  2. +
  3. 设置父频道;

  4. +
  5. 连接用户。

  6. +
+

6.1 例 1:用户在线状态(user appearance)

下面是一个关于频道的简单例子,用于跟踪用户是否在线,以及用户所在的页面。(常用于显示用户在线状态,例如当用户在线时,在用户名旁边显示绿色小圆点。)

在服务器端创建在线状态频道(appearance channel):

+
+# app/channels/appearance_channel.rb
+class AppearanceChannel < ApplicationCable::Channel
+  def subscribed
+    current_user.appear
+  end
+
+  def unsubscribed
+    current_user.disappear
+  end
+
+  def appear(data)
+    current_user.appear(on: data['appearing_on'])
+  end
+
+  def away
+    current_user.away
+  end
+end
+
+
+
+

订阅创建后,会触发 subscribed 回调方法,这时可以提示说“当前用户上线了”。上线/下线 API 的后端可以是 Redis、数据库或其他解决方案。

在客户端创建在线状态频道订阅:

+
+# app/assets/javascripts/cable/subscriptions/appearance.coffee
+App.cable.subscriptions.create "AppearanceChannel",
+  # 当服务器上的订阅可用时调用
+  connected: ->
+    @install()
+    @appear()
+
+  # 当 WebSocket 连接关闭时调用
+  disconnected: ->
+    @uninstall()
+
+  # 当服务器拒绝订阅时调用
+  rejected: ->
+    @uninstall()
+
+  appear: ->
+    # 在服务器上调用 `AppearanceChannel#appear(data)`
+    @perform("appear", appearing_on: $("main").data("appearing-on"))
+
+  away: ->
+    # 在服务器上调用 `AppearanceChannel#away`
+    @perform("away")
+
+
+  buttonSelector = "[data-behavior~=appear_away]"
+
+  install: ->
+    $(document).on "page:change.appearance", =>
+      @appear()
+
+    $(document).on "click.appearance", buttonSelector, =>
+      @away()
+      false
+
+    $(buttonSelector).show()
+
+  uninstall: ->
+    $(document).off(".appearance")
+    $(buttonSelector).hide()
+
+
+
+
6.1.1 客户端-服务器交互
+
    +
  1. 客户端通过 App.cable = ActionCable.createConsumer("ws://cable.example.com")(位于 cable.js 文件中)连接到服务器服务器通过 current_user 标识此连接。

  2. +
  3. 客户端通过 App.cable.subscriptions.create(channel: "AppearanceChannel")(位于 appearance.coffee 文件中)订阅在线状态频道。

  4. +
  5. 服务器发现在线状态频道创建了一个新订阅,于是调用 subscribed 回调方法,也即在 current_user 对象上调用 appear 方法。

  6. +
  7. 客户端发现订阅创建成功,于是调用 connected 方法(位于 appearance.coffee 文件中),也即依次调用 @install@appear@appear 会调用服务器上的 AppearanceChannel#appear(data) 方法,同时提供 { appearing_on: $("main").data("appearing-on") } 数据散列。之所以能够这样做,是因为服务器端的频道实例会自动暴露类上声明的所有公共方法(回调除外),从而使远程过程能够通过订阅的 perform 方法调用它们。

  8. +
  9. 服务器接收向在线状态频道的 appear 动作发起的请求,此频道基于连接创建,连接由 current_user(位于 appearance_channel.rb 文件中)标识。服务器通过 :appearing_on 键从数据散列中检索数据,将其设置为 :on 键的值并传递给 current_user.appear

  10. +
+

6.2 例 2:接收新的 Web 通知

上一节中在线状态的例子,演示了如何把服务器功能暴露给客户端,以便在客户端通过 WebSocket 连接调用这些功能。但是 WebSocket 的伟大之处在于,它是一条双向通道。因此,在本节的例子中,我们要看一看服务器如何调用客户端上的动作。

本节所举的例子是一个 Web 通知频道(Web notification channel),允许我们在广播到正确的流时触发客户端 Web 通知。

创建服务器端 Web 通知频道:

+
+# app/channels/web_notifications_channel.rb
+class WebNotificationsChannel < ApplicationCable::Channel
+  def subscribed
+    stream_for current_user
+  end
+end
+
+
+
+

创建客户端 Web 通知频道订阅:

+
+# app/assets/javascripts/cable/subscriptions/web_notifications.coffee
+# 客户端假设我们已经获得了发送 Web 通知的权限
+App.cable.subscriptions.create "WebNotificationsChannel",
+  received: (data) ->
+    new Notification data["title"], body: data["body"]
+
+
+
+

在应用的其他部分向 Web 通知频道实例发送内容广播:

+
+# 在应用的某个部分中调用,例如 NewCommentJob
+WebNotificationsChannel.broadcast_to(
+  current_user,
+  title: 'New things!',
+  body: 'All the news fit to print'
+)
+
+
+
+

调用 WebNotificationsChannel.broadcast_to 将向当前订阅适配器的发布/订阅队列推送一条消息,并为每个用户设置不同的广播名。对于 ID 为 1 的用户,广播名是 web_notifications_1

通过调用 received 回调方法,频道会用流把到达 web_notifications_1 的消息直接发送给客户端。作为参数传递的数据散列,将作为第二个参数传递给服务器端的广播调用,数据在传输前使用 JSON 进行编码,到达服务器后由 received 解码。

6.3 更完整的例子

关于在 Rails 应用中设置 Action Cable 并添加频道的完整例子,参见 rails/actioncable-examples 仓库。

7 配置

使用 Action Cable 时,有两个选项必需配置:订阅适配器和允许的请求来源。

7.1 订阅适配器

默认情况下,Action Cable 会查找 config/cable.yml 这个配置文件。该文件必须为每个 Rails 环境指定适配器和 URL 地址。关于适配器的更多介绍,请参阅 依赖关系

+
+development:
+  adapter: async
+
+test:
+  adapter: async
+
+production:
+  adapter: redis
+  url: redis://10.10.3.153:6381
+
+
+
+

7.2 允许的请求来源

Action Cable 仅接受来自指定来源的请求。这些来源是在服务器配置文件中以数组的形式设置的,每个来源既可以是字符串,也可以是正则表达式。对于每个请求,都要对其来源进行检查,看是否和允许的请求来源相匹配。

+
+config.action_cable.allowed_request_origins = ['http://rubyonrails.com/', %r{http://ruby.*}]
+
+
+
+

若想禁用来源检查,允许任何来源的请求:

+
+config.action_cable.disable_request_forgery_protection = true
+
+
+
+

在开发环境中,Action Cable 默认允许来自 localhost:3000 的所有请求。

7.3 用户配置

要想配置 URL 地址,可以在 HTML 布局文件的 <head> 元素中添加 action_cable_meta_tag 标签。这个标签会使用环境配置文件中 config.action_cable.url 选项设置的 URL 地址或路径。

7.4 其他配置

另一个常见的配置选项,是应用于每个连接记录器的日志标签。下面是 Basecamp 使用的配置:

+
+config.action_cable.log_tags = [
+  -> request { request.env['bc.account_id'] || "no-account" },
+  :action_cable,
+  -> request { request.uuid }
+]
+
+
+
+

关于所有配置选项的完整列表,请参阅 ActionCable::Server::Configuration 类的 API 文档。

还要注意,服务器提供的数据库连接在数量上至少应该和职程(worker)相等。职程池的默认大小为 100,也就是说数据库连接数量至少为 100。职程池的大小可以通过 config/database.yml 文件中的 pool 属性设置。

8 运行独立的 Cable 服务器

8.1 和应用一起运行

Action Cable 可以和 Rails 应用一起运行。例如,要想监听 /websocket 上的 WebSocket 请求,可以通过 config.action_cable.mount_path 选项指定监听路径:

+
+# config/application.rb
+class Application < Rails::Application
+  config.action_cable.mount_path = '/websocket'
+end
+
+
+
+

在布局文件中调用 action_cable_meta_tag 后,就可以使用 App.cable = ActionCable.createConsumer() 连接到 Cable 服务器。可以通过 createConsumer 方法的第一个参数指定自定义路径(例如,App.cable = +ActionCable.createConsumer("/websocket"))。

对于我们创建的每个服务器实例,以及由服务器派生的每个职程,都会新建对应的 Action Cable 实例,通过 Redis 可以在不同连接之间保持消息同步。

8.2 独立运行

Cable 服务器可以和普通应用服务器分离。此时,Cable 服务器仍然是 Rack 应用,只不过是单独的 Rack 应用罢了。推荐的基本设置如下:

+
+# cable/config.ru
+require_relative 'config/environment'
+Rails.application.eager_load!
+
+run ActionCable.server
+
+
+
+

然后用 bin/cable 中的一个 binstub 命令启动服务器:

+
+#!/bin/bash
+bundle exec puma -p 28080 cable/config.ru
+
+
+
+

上述代码在 28080 端口上启动 Cable 服务器。

8.3 注意事项

WebSocket 服务器没有访问会话的权限,但可以访问 cookie,而在处理身份验证时需要用到 cookie。这篇文章介绍了如何使用 Devise 验证身份。

9 依赖关系

Action Cable 提供了用于处理发布/订阅内部逻辑的订阅适配器接口,默认包含异步、内联、PostgreSQL、事件 Redis 和非事件 Redis 适配器。新建 Rails 应用的默认适配器是异步(async)适配器。

对 Ruby gem 的依赖包括 websocket-drivernio4rconcurrent-ruby

10 部署

Action Cable 由 WebSocket 和线程组成。其中框架管道和用户指定频道的职程,都是通过 Ruby 提供的原生线程支持来处理的。这意味着,只要不涉及线程安全问题,我们就可以使用常规 Rails 线程模型的所有功能。

Action Cable 服务器实现了Rack 套接字劫持 API(Rack socket hijacking API),因此无论应用服务器是否是多线程的,都能够通过多线程模式管理内部连接。

因此,Action Cable 可以和流行的应用服务器一起使用,例如 Unicorn、Puma 和 Passenger。

反馈

diff --git a/action_controller_overview.html b/action_controller_overview.html index 63e853e..f527c1c 100644 --- a/action_controller_overview.html +++ b/action_controller_overview.html @@ -329,7 +329,7 @@

4.1 散

-

“[”和“]”这两个符号不允许出现在 URL 中,所以上面的地址会被编码成 /clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3。多数情况下,无需你费心,浏览器会代为编码,接收到这样的请求后,Rails 也会自动解码。如果你要手动向服务器发送这样的请求,就要留心了。

此时,params[:ids] 的值是 ["1", "2", "3"]。注意,参数的值始终是字符串,Rails 不会尝试转换类型。

默认情况下,基于安全考虑,参数中的 [nil][nil, nil, …​] 会替换成 []。详情参见 Ruby on Rails 安全指南

若想发送一个散列,要在方括号内指定键名:

+

“[”和“]”这两个符号不允许出现在 URL 中,所以上面的地址会被编码成 /clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3。多数情况下,无需你费心,浏览器会代为编码,接收到这样的请求后,Rails 也会自动解码。如果你要手动向服务器发送这样的请求,就要留心了。

此时,params[:ids] 的值是 ["1", "2", "3"]。注意,参数的值始终是字符串,Rails 不会尝试转换类型。

默认情况下,基于安全考虑,参数中的 [nil][nil, nil, …​] 会替换成 []。详情参见 Ruby on Rails 安全指南

若想发送一个散列,要在方括号内指定键名:

 <form accept-charset="UTF-8" action="http://github.com/clients" method="post">
   <input type="text" name="client[name]" value="Acme" />
diff --git a/active_record_querying.html b/active_record_querying.html
index a35b482..f98fc88 100644
--- a/active_record_querying.html
+++ b/active_record_querying.html
@@ -651,7 +651,7 @@ 
1.2.2.1
-

原因是出于参数的安全性考虑。把变量直接放入条件字符串会导致变量原封不动地传递给数据库,这意味着即使是恶意用户提交的变量也不会被转义。这样一来,整个数据库就处于风险之中,因为一旦恶意用户发现自己能够滥用数据库,他就可能做任何事情。所以,永远不要把参数直接放入条件字符串。

关于 SQL 注入的危险性的更多介绍,请参阅 安全指南

2.2.1 条件中的占位符

和问号占位符(?)类似,我们还可以在条件字符串中使用符号占位符,并通过散列提供符号对应的值:

+

原因是出于参数的安全性考虑。把变量直接放入条件字符串会导致变量原封不动地传递给数据库,这意味着即使是恶意用户提交的变量也不会被转义。这样一来,整个数据库就处于风险之中,因为一旦恶意用户发现自己能够滥用数据库,他就可能做任何事情。所以,永远不要把参数直接放入条件字符串。

关于 SQL 注入的危险性的更多介绍,请参阅 安全指南

2.2.1 条件中的占位符

和问号占位符(?)类似,我们还可以在条件字符串中使用符号占位符,并通过散列提供符号对应的值:

 Client.where("created_at >= :start_date AND created_at <= :end_date",
   {start_date: params[:start_date], end_date: params[:end_date]})
diff --git a/active_support_core_extensions.html b/active_support_core_extensions.html
index c3cc012..a94e468 100644
--- a/active_support_core_extensions.html
+++ b/active_support_core_extensions.html
@@ -1215,7 +1215,7 @@ 

active_support/core_ext/class/subclasses.rb 文件中定义。

5 String 的扩展

5.1 输出的安全性

5.1.1 引子

把数据插入 HTML 模板要格外小心。例如,不能原封不动地把 @review.title 内插到 HTML 页面中。假如标题是“Flanagan & Matz rules!”,得到的输出格式就不对,因为 & 会转义成“&”。更糟的是,如果应用编写不当,这可能留下严重的安全漏洞,因为用户可以注入恶意的 HTML,设定精心编造的标题。关于这个问题的详情,请阅读 安全指南对跨站脚本的说明。

5.1.2 安全字符串

Active Support 提出了安全字符串(对 HTML 而言)这一概念。安全字符串是对字符串做的一种标记,表示可以原封不动地插入 HTML。这种字符串是可信赖的,不管会不会转义。

默认,字符串被认为是不安全的:

+

返回的后代没有特定顺序。

active_support/core_ext/class/subclasses.rb 文件中定义。

5 String 的扩展

5.1 输出的安全性

5.1.1 引子

把数据插入 HTML 模板要格外小心。例如,不能原封不动地把 @review.title 内插到 HTML 页面中。假如标题是“Flanagan & Matz rules!”,得到的输出格式就不对,因为 & 会转义成“&”。更糟的是,如果应用编写不当,这可能留下严重的安全漏洞,因为用户可以注入恶意的 HTML,设定精心编造的标题。关于这个问题的详情,请阅读 安全指南对跨站脚本的说明。

5.1.2 安全字符串

Active Support 提出了安全字符串(对 HTML 而言)这一概念。安全字符串是对字符串做的一种标记,表示可以原封不动地插入 HTML。这种字符串是可信赖的,不管会不会转义。

默认,字符串被认为是不安全的:

 "".html_safe? # => false
 
diff --git a/asset_pipeline.html b/asset_pipeline.html
index e939177..2f4df76 100644
--- a/asset_pipeline.html
+++ b/asset_pipeline.html
@@ -5,7 +5,7 @@
 
 
 
-Ruby on Rails Guides
+The Asset Pipeline — Ruby on Rails Guides
 
 
 
@@ -173,16 +173,1067 @@ 

Guides.rubyonrails.org<
- +

The Asset Pipeline

This guide covers the asset pipeline.

After reading this guide, you will know:

+
    +
  • What the asset pipeline is and what it does.
  • +
  • How to properly organize your application assets.
  • +
  • The benefits of the asset pipeline.
  • +
  • How to add a pre-processor to the pipeline.
  • +
  • How to package assets with a gem.
  • +
+ + + -
-

Asset Pipeline

+

1 What is the Asset Pipeline?

The asset pipeline provides a framework to concatenate and minify or compress +JavaScript and CSS assets. It also adds the ability to write these assets in +other languages and pre-processors such as CoffeeScript, Sass and ERB. +It allows assets in your application to be automatically combined with assets +from other gems. For example, jquery-rails includes a copy of jquery.js +and enables AJAX features in Rails.

The asset pipeline is implemented by the +sprockets-rails gem, +and is enabled by default. You can disable it while creating a new application by +passing the --skip-sprockets option.

+
+rails new appname --skip-sprockets
+
+
+
+

Rails automatically adds the sass-rails, coffee-rails and uglifier +gems to your Gemfile, which are used by Sprockets for asset compression:

+
+gem 'sass-rails'
+gem 'uglifier'
+gem 'coffee-rails'
+
+
+
+

Using the --skip-sprockets option will prevent Rails from adding +them to your Gemfile, so if you later want to enable +the asset pipeline you will have to add those gems to your Gemfile. Also, +creating an application with the --skip-sprockets option will generate +a slightly different config/application.rb file, with a require statement +for the sprockets railtie that is commented-out. You will have to remove +the comment operator on that line to later enable the asset pipeline:

+
+# require "sprockets/railtie"
+
+
+
+

To set asset compression methods, set the appropriate configuration options +in production.rb - config.assets.css_compressor for your CSS and +config.assets.js_compressor for your JavaScript:

+
+config.assets.css_compressor = :yui
+config.assets.js_compressor = :uglifier
+
+
+
+

The sass-rails gem is automatically used for CSS compression if included +in the Gemfile and no config.assets.css_compressor option is set.

1.1 Main Features

The first feature of the pipeline is to concatenate assets, which can reduce the +number of requests that a browser makes to render a web page. Web browsers are +limited in the number of requests that they can make in parallel, so fewer +requests can mean faster loading for your application.

Sprockets concatenates all JavaScript files into one master .js file and all +CSS files into one master .css file. As you'll learn later in this guide, you +can customize this strategy to group files any way you like. In production, +Rails inserts an MD5 fingerprint into each filename so that the file is cached +by the web browser. You can invalidate the cache by altering this fingerprint, +which happens automatically whenever you change the file contents.

The second feature of the asset pipeline is asset minification or compression. +For CSS files, this is done by removing whitespace and comments. For JavaScript, +more complex processes can be applied. You can choose from a set of built in +options or specify your own.

The third feature of the asset pipeline is it allows coding assets via a +higher-level language, with precompilation down to the actual assets. Supported +languages include Sass for CSS, CoffeeScript for JavaScript, and ERB for both by +default.

1.2 What is Fingerprinting and Why Should I Care?

Fingerprinting is a technique that makes the name of a file dependent on the +contents of the file. When the file contents change, the filename is also +changed. For content that is static or infrequently changed, this provides an +easy way to tell whether two versions of a file are identical, even across +different servers or deployment dates.

When a filename is unique and based on its content, HTTP headers can be set to +encourage caches everywhere (whether at CDNs, at ISPs, in networking equipment, +or in web browsers) to keep their own copy of the content. When the content is +updated, the fingerprint will change. This will cause the remote clients to +request a new copy of the content. This is generally known as cache busting.

The technique sprockets uses for fingerprinting is to insert a hash of the +content into the name, usually at the end. For example a CSS file global.css

+
+global-908e25f4bf641868d8683022a5b62f54.css
+
+
+
+

This is the strategy adopted by the Rails asset pipeline.

Rails' old strategy was to append a date-based query string to every asset linked +with a built-in helper. In the source the generated code looked like this:

+
+/stylesheets/global.css?1309495796
+
+
+
+

The query string strategy has several disadvantages:

+
    +
  1. +

    Not all caches will reliably cache content where the filename only differs by +query parameters

    +

    Steve Souders recommends, +"...avoiding a querystring for cacheable resources". He found that in this +case 5-20% of requests will not be cached. Query strings in particular do not +work at all with some CDNs for cache invalidation.

    +
  2. +
  3. +

    The file name can change between nodes in multi-server environments.

    +

    The default query string in Rails 2.x is based on the modification time of +the files. When assets are deployed to a cluster, there is no guarantee that the +timestamps will be the same, resulting in different values being used depending +on which server handles the request.

    +
  4. +
  5. +

    Too much cache invalidation

    +

    When static assets are deployed with each new release of code, the mtime +(time of last modification) of all these files changes, forcing all remote +clients to fetch them again, even when the content of those assets has not changed.

    +
  6. +
+

Fingerprinting fixes these problems by avoiding query strings, and by ensuring +that filenames are consistent based on their content.

Fingerprinting is enabled by default for both the development and production +environments. You can enable or disable it in your configuration through the +config.assets.digest option.

More reading:

+ +

2 How to Use the Asset Pipeline

In previous versions of Rails, all assets were located in subdirectories of +public such as images, javascripts and stylesheets. With the asset +pipeline, the preferred location for these assets is now the app/assets +directory. Files in this directory are served by the Sprockets middleware.

Assets can still be placed in the public hierarchy. Any assets under public +will be served as static files by the application or web server when +config.public_file_server.enabled is set to true. You should use app/assets for +files that must undergo some pre-processing before they are served.

In production, Rails precompiles these files to public/assets by default. The +precompiled copies are then served as static assets by the web server. The files +in app/assets are never served directly in production.

2.1 Controller Specific Assets

When you generate a scaffold or a controller, Rails also generates a JavaScript +file (or CoffeeScript file if the coffee-rails gem is in the Gemfile) and a +Cascading Style Sheet file (or SCSS file if sass-rails is in the Gemfile) +for that controller. Additionally, when generating a scaffold, Rails generates +the file scaffolds.css (or scaffolds.scss if sass-rails is in the +Gemfile.)

For example, if you generate a ProjectsController, Rails will also add a new +file at app/assets/javascripts/projects.coffee and another at +app/assets/stylesheets/projects.scss. By default these files will be ready +to use by your application immediately using the require_tree directive. See +Manifest Files and Directives for more details +on require_tree.

You can also opt to include controller specific stylesheets and JavaScript files +only in their respective controllers using the following:

<%= javascript_include_tag params[:controller] %> or <%= stylesheet_link_tag +params[:controller] %>

When doing this, ensure you are not using the require_tree directive, as that +will result in your assets being included more than once.

When using asset precompilation, you will need to ensure that your +controller assets will be precompiled when loading them on a per page basis. By +default .coffee and .scss files will not be precompiled on their own. See +Precompiling Assets for more information on how +precompiling works.

You must have an ExecJS supported runtime in order to use CoffeeScript. +If you are using Mac OS X or Windows, you have a JavaScript runtime installed in +your operating system. Check ExecJS documentation to know all supported JavaScript runtimes.

You can also disable generation of controller specific asset files by adding the +following to your config/application.rb configuration:

+
+  config.generators do |g|
+    g.assets false
+  end
+
+
+
+

2.2 Asset Organization

Pipeline assets can be placed inside an application in one of three locations: +app/assets, lib/assets or vendor/assets.

+
    +
  • app/assets is for assets that are owned by the application, such as custom +images, JavaScript files or stylesheets.

  • +
  • lib/assets is for your own libraries' code that doesn't really fit into the +scope of the application or those libraries which are shared across applications.

  • +
  • vendor/assets is for assets that are owned by outside entities, such as +code for JavaScript plugins and CSS frameworks. Keep in mind that third party +code with references to other files also processed by the asset Pipeline (images, +stylesheets, etc.), will need to be rewritten to use helpers like asset_path.

  • +
+

If you are upgrading from Rails 3, please take into account that assets +under lib/assets or vendor/assets are available for inclusion via the +application manifests but no longer part of the precompile array. See +Precompiling Assets for guidance.

2.2.1 Search Paths

When a file is referenced from a manifest or a helper, Sprockets searches the +three default asset locations for it.

The default locations are: the images, javascripts and stylesheets +directories under the app/assets folder, but these subdirectories +are not special - any path under assets/* will be searched.

For example, these files:

+
+app/assets/javascripts/home.js
+lib/assets/javascripts/moovinator.js
+vendor/assets/javascripts/slider.js
+vendor/assets/somepackage/phonebox.js
+
+
+
+

would be referenced in a manifest like this:

+
+//= require home
+//= require moovinator
+//= require slider
+//= require phonebox
+
+
+
+

Assets inside subdirectories can also be accessed.

+
+app/assets/javascripts/sub/something.js
+
+
+
+

is referenced as:

+
+//= require sub/something
+
+
+
+

You can view the search path by inspecting +Rails.application.config.assets.paths in the Rails console.

Besides the standard assets/* paths, additional (fully qualified) paths can be +added to the pipeline in config/application.rb. For example:

+
+config.assets.paths << Rails.root.join("lib", "videoplayer", "flash")
+
+
+
+

Paths are traversed in the order they occur in the search path. By default, +this means the files in app/assets take precedence, and will mask +corresponding paths in lib and vendor.

It is important to note that files you want to reference outside a manifest must +be added to the precompile array or they will not be available in the production +environment.

2.2.2 Using Index Files

Sprockets uses files named index (with the relevant extensions) for a special +purpose.

For example, if you have a jQuery library with many modules, which is stored in +lib/assets/javascripts/library_name, the file lib/assets/javascripts/library_name/index.js serves as +the manifest for all files in this library. This file could include a list of +all the required files in order, or a simple require_tree directive.

The library as a whole can be accessed in the application manifest like so:

+
+//= require library_name
+
+
+
+

This simplifies maintenance and keeps things clean by allowing related code to +be grouped before inclusion elsewhere.

2.3 Coding Links to Assets

Sprockets does not add any new methods to access your assets - you still use the +familiar javascript_include_tag and stylesheet_link_tag:

+
+<%= stylesheet_link_tag "application", media: "all" %>
+<%= javascript_include_tag "application" %>
+
+
+
+

If using the turbolinks gem, which is included by default in Rails, then +include the 'data-turbolinks-track' option which causes turbolinks to check if +an asset has been updated and if so loads it into the page:

+
+<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => "reload" %>
+<%= javascript_include_tag "application", "data-turbolinks-track" => "reload" %>
+
+
+
+

In regular views you can access images in the public/assets/images directory +like this:

+
+<%= image_tag "rails.png" %>
+
+
+
+

Provided that the pipeline is enabled within your application (and not disabled +in the current environment context), this file is served by Sprockets. If a file +exists at public/assets/rails.png it is served by the web server.

Alternatively, a request for a file with an MD5 hash such as +public/assets/rails-af27b6a414e6da00003503148be9b409.png is treated the same +way. How these hashes are generated is covered in the In +Production section later on in this guide.

Sprockets will also look through the paths specified in config.assets.paths, +which includes the standard application paths and any paths added by Rails +engines.

Images can also be organized into subdirectories if required, and then can be +accessed by specifying the directory's name in the tag:

+
+<%= image_tag "icons/rails.png" %>
+
+
+
+

If you're precompiling your assets (see 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.

2.3.1 CSS and ERB

The asset pipeline automatically evaluates ERB. This means 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:

+
+.class { background-image: url(http://github.com/<%=%20asset_path%20'image.png'%20%>) }
+
+
+
+

This writes the path to the particular asset being referenced. In this example, +it would make sense to have an image in one of the asset load paths, such as +app/assets/images/image.png, which would be referenced here. If this image is +already available in public/assets as a fingerprinted file, then that path is +referenced.

If you want to use a data URI - +a method of embedding the image data directly into the CSS file - you can use +the asset_data_uri helper.

+
+#logo { background: url(http://github.com/<%=%20asset_data_uri%20'logo.png'%20%>) }
+
+
+
+

This inserts a correctly-formatted data URI into the CSS source.

Note that the closing tag cannot be of the style -%>.

2.3.2 CSS and Sass

When using the asset pipeline, paths to assets must be re-written and +sass-rails provides -url and -path helpers (hyphenated in Sass, +underscored in Ruby) for the following asset classes: image, font, video, audio, +JavaScript and stylesheet.

+
    +
  • +image-url("http://github.com/rails.png") returns url(http://github.com/assets/rails.png) +
  • +
  • +image-path("rails.png") returns "/assets/rails.png" +
  • +
+

The more generic form can also be used:

+
    +
  • +asset-url("http://github.com/rails.png") returns url(http://github.com/assets/rails.png) +
  • +
  • +asset-path("rails.png") returns "/assets/rails.png" +
  • +
+
2.3.3 JavaScript/CoffeeScript and ERB

If you add an erb extension to a JavaScript asset, making it something such as +application.js.erb, you can then use the asset_path helper in your +JavaScript code:

+
+$('#logo').attr({ src: "<%= asset_path('logo.png') %>" });
+
+
+
+

This writes the path to the particular asset being referenced.

Similarly, you can use the asset_path helper in CoffeeScript files with erb +extension (e.g., application.coffee.erb):

+
+$('#logo').attr src: "<%= asset_path('logo.png') %>"
+
+
+
+

2.4 Manifest Files and Directives

Sprockets uses manifest files to determine which assets to include and serve. +These manifest files contain directives - instructions that tell Sprockets +which files to require in order to build a single CSS or JavaScript file. With +these directives, Sprockets loads the files specified, processes them if +necessary, concatenates them into one single file and then compresses them +(based on value of Rails.application.config.assets.js_compressor). By serving +one file rather than many, the load time of pages can be greatly reduced because +the browser makes fewer requests. Compression also reduces file size, enabling +the browser to download them faster.

For example, a new Rails application includes a default +app/assets/javascripts/application.js file containing the following lines:

+
+// ...
+//= require jquery
+//= require jquery_ujs
+//= require_tree .
+
+
+
+

In JavaScript files, Sprockets directives begin with //=. In the above case, +the file is using the require and the require_tree directives. The require +directive is used to tell Sprockets the files you wish to require. Here, you are +requiring the files jquery.js and jquery_ujs.js that are available somewhere +in the search path for Sprockets. You need not supply the extensions explicitly. +Sprockets assumes you are requiring a .js file when done from within a .js +file.

The require_tree directive tells Sprockets to recursively include all +JavaScript files in the specified directory into the output. These paths must be +specified relative to the manifest file. You can also use the +require_directory directive which includes all JavaScript files only in the +directory specified, without recursion.

Directives are processed top to bottom, but the order in which files are +included by require_tree is unspecified. You should not rely on any particular +order among those. If you need to ensure some particular JavaScript ends up +above some other in the concatenated file, require the prerequisite file first +in the manifest. Note that the family of require directives prevents files +from being included twice in the output.

Rails also creates a default app/assets/stylesheets/application.css file +which contains these lines:

+
+/* ...
+*= require_self
+*= require_tree .
+*/
+
+
+
+

Rails creates both app/assets/javascripts/application.js and +app/assets/stylesheets/application.css regardless of whether the +--skip-sprockets option is used when creating a new rails application. This is +so you can easily add asset pipelining later if you like.

The directives that work in JavaScript files also work in stylesheets +(though obviously including stylesheets rather than JavaScript files). The +require_tree directive in a CSS manifest works the same way as the JavaScript +one, requiring all stylesheets from the current directory.

In this example, require_self is used. This puts the CSS contained within the +file (if any) at the precise location of the require_self call.

If you want to use multiple Sass files, you should generally use the Sass @import rule +instead of these Sprockets directives. When using Sprockets directives, Sass files exist within +their own scope, making variables or mixins only available within the document they were defined in.

You can do file globbing as well using @import "http://github.com/*", and @import "http://github.com/**/*" to add the whole tree which is equivalent to how require_tree works. Check the sass-rails documentation for more info and important caveats.

You can have as many manifest files as you need. For example, the admin.css +and admin.js manifest could contain the JS and CSS files that are used for the +admin section of an application.

The same remarks about ordering made above apply. In particular, you can specify +individual files and they are compiled in the order specified. For example, you +might concatenate three CSS files together this way:

+
+/* ...
+*= require reset
+*= require layout
+*= require chrome
+*/
+
+
+
+

2.5 Preprocessing

The file extensions used on an asset determine what preprocessing is applied. +When a controller or a scaffold is generated with the default Rails gemset, a +CoffeeScript file and a SCSS file are generated in place of a regular JavaScript +and CSS file. The example used before was a controller called "projects", which +generated an app/assets/javascripts/projects.coffee and an +app/assets/stylesheets/projects.scss file.

In development mode, or if the asset pipeline is disabled, when these files are +requested they are processed by the processors provided by the coffee-script +and sass gems and then sent back to the browser as JavaScript and CSS +respectively. When asset pipelining is enabled, these files are preprocessed and +placed in the public/assets directory for serving by either the Rails app or +web server.

Additional layers of preprocessing can be requested by adding other extensions, +where each extension is processed in a right-to-left manner. These should be +used in the order the processing should be applied. For example, a stylesheet +called app/assets/stylesheets/projects.scss.erb is first processed as ERB, +then SCSS, and finally served as CSS. The same applies to a JavaScript file - +app/assets/javascripts/projects.coffee.erb is processed as ERB, then +CoffeeScript, and served as JavaScript.

Keep in mind the order of these preprocessors is important. For example, if +you called your JavaScript file app/assets/javascripts/projects.erb.coffee +then it would be processed with the CoffeeScript interpreter first, which +wouldn't understand ERB and therefore you would run into problems.

3 In Development

In development mode, assets are served as separate files in the order they are +specified in the manifest file.

This manifest app/assets/javascripts/application.js:

+
+//= require core
+//= require projects
+//= require tickets
+
+
+
+

would generate this HTML:

+
+<script src="http://github.com/assets/core.js?body=1"></script>
+<script src="http://github.com/assets/projects.js?body=1"></script>
+<script src="http://github.com/assets/tickets.js?body=1"></script>
+
+
+
+

The body param is required by Sprockets.

3.1 Runtime Error Checking

By default the asset pipeline will check for potential errors in development mode during +runtime. To disable this behavior you can set:

+
+config.assets.raise_runtime_errors = false
+
+
+
+

When this option is true, the asset pipeline will check if all the assets loaded +in your application are included in the config.assets.precompile list. +If config.assets.digest is also true, the asset pipeline will require that +all requests for assets include digests.

3.2 Turning Digests Off

You can turn off digests by updating config/environments/development.rb to +include:

+
+config.assets.digest = false
+
+
+
+

When this option is true, digests will be generated for asset URLs.

3.3 Turning Debugging Off

You can turn off debug mode by updating config/environments/development.rb to +include:

+
+config.assets.debug = false
+
+
+
+

When debug mode is off, Sprockets concatenates and runs the necessary +preprocessors on all files. With debug mode turned off the manifest above would +generate instead:

+
+<script src="http://github.com/assets/application.js"></script>
+
+
+
+

Assets are compiled and cached on the first request after the server is started. +Sprockets sets a must-revalidate Cache-Control HTTP header to reduce request +overhead on subsequent requests - on these the browser gets a 304 (Not Modified) +response.

If any of the files in the manifest have changed between requests, the server +responds with a new compiled file.

Debug mode can also be enabled in Rails helper methods:

+
+<%= stylesheet_link_tag "application", debug: true %>
+<%= javascript_include_tag "application", debug: true %>
+
+
+
+

The :debug option is redundant if debug mode is already on.

You can also enable compression in development mode as a sanity check, and +disable it on-demand as required for debugging.

4 In Production

In the production environment Sprockets uses the fingerprinting scheme outlined +above. By default Rails assumes assets have been precompiled and will be +served as static assets by your web server.

During the precompilation phase an MD5 is generated from the contents of the +compiled files, and inserted into the filenames as they are written to disk. +These fingerprinted names are used by the Rails helpers in place of the manifest +name.

For example this:

+
+<%= javascript_include_tag "application" %>
+<%= stylesheet_link_tag "application" %>
+
+
+
+

generates something like this:

+
+<script src="http://github.com/assets/application-908e25f4bf641868d8683022a5b62f54.js"></script>
+<link href="http://github.com/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css" media="screen"
+rel="stylesheet" />
+
+
+
+

with the Asset Pipeline the :cache and :concat options aren't used +anymore, delete these options from the javascript_include_tag and +stylesheet_link_tag.

The fingerprinting behavior is controlled by the config.assets.digest +initialization option (which defaults to true).

Under normal circumstances the default config.assets.digest option +should not be changed. If there are no digests in the filenames, and far-future +headers are set, remote clients will never know to refetch the files when their +content changes.

4.1 Precompiling Assets

Rails comes bundled with a task to compile the asset manifests and other +files in the pipeline.

Compiled assets are written to the location specified in config.assets.prefix. +By default, this is the /assets directory.

You can call this task on the server during deployment to create compiled +versions of your assets directly on the server. See the next section for +information on compiling locally.

The task is:

+
+$ RAILS_ENV=production bin/rails assets:precompile
+
+
+
+

Capistrano (v2.15.1 and above) includes a recipe to handle this in deployment. +Add the following line to Capfile:

+
+load 'deploy/assets'
+
+
+
+

This links the folder specified in config.assets.prefix to shared/assets. +If you already use this shared folder you'll need to write your own deployment +task.

It is important that this folder is shared between deployments so that remotely +cached pages referencing the old compiled assets still work for the life of +the cached page.

The default matcher for compiling files includes application.js, +application.css and all non-JS/CSS files (this will include all image assets +automatically) from app/assets folders including your gems:

+
+[ Proc.new { |filename, path| path =~ /app\/assets/ && !%w(.js .css).include?(File.extname(filename)) },
+/application.(css|js)$/ ]
+
+
+
+

The matcher (and other members of the precompile array; see below) is +applied to final compiled file names. This means anything that compiles to +JS/CSS is excluded, as well as raw JS/CSS files; for example, .coffee and +.scss files are not automatically included as they compile to JS/CSS.

If you have other manifests or individual stylesheets and JavaScript files to +include, you can add them to the precompile array in config/initializers/assets.rb:

+
+Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
+
+
+
+

Always specify an expected compiled filename that ends with .js or .css, +even if you want to add Sass or CoffeeScript files to the precompile array.

The task also generates a manifest-md5hash.json that contains a list with +all your assets and their respective fingerprints. This is used by the Rails +helper methods to avoid handing the mapping requests back to Sprockets. A +typical manifest file looks like:

+
+{"files":{"application-723d1be6cc741a3aabb1cec24276d681.js":{"logical_path":"application.js","mtime":"2013-07-26T22:55:03-07:00","size":302506,
+"digest":"723d1be6cc741a3aabb1cec24276d681"},"application-12b3c7dd74d2e9df37e7cbb1efa76a6d.css":{"logical_path":"application.css","mtime":"2013-07-26T22:54:54-07:00","size":1560,
+"digest":"12b3c7dd74d2e9df37e7cbb1efa76a6d"},"application-1c5752789588ac18d7e1a50b1f0fd4c2.css":{"logical_path":"application.css","mtime":"2013-07-26T22:56:17-07:00","size":1591,
+"digest":"1c5752789588ac18d7e1a50b1f0fd4c2"},"favicon-a9c641bf2b81f0476e876f7c5e375969.ico":{"logical_path":"favicon.ico","mtime":"2013-07-26T23:00:10-07:00","size":1406,
+"digest":"a9c641bf2b81f0476e876f7c5e375969"},"my_image-231a680f23887d9dd70710ea5efd3c62.png":{"logical_path":"my_image.png","mtime":"2013-07-26T23:00:27-07:00","size":6646,
+"digest":"231a680f23887d9dd70710ea5efd3c62"}},"assets":{"application.js":
+"application-723d1be6cc741a3aabb1cec24276d681.js","application.css":
+"application-1c5752789588ac18d7e1a50b1f0fd4c2.css",
+"favicon.ico":"favicona9c641bf2b81f0476e876f7c5e375969.ico","my_image.png":
+"my_image-231a680f23887d9dd70710ea5efd3c62.png"}}
+
+
+
+

The default location for the manifest is the root of the location specified in +config.assets.prefix ('/assets' by default).

If there are missing precompiled files in production you will get an +Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError +exception indicating the name of the missing file(s).

4.1.1 Far-future Expires Header

Precompiled assets exist on the file system and are served directly by your web +server. They do not have far-future headers by default, so to get the benefit of +fingerprinting you'll have to update your server configuration to add those +headers.

For Apache:

+
+# The Expires* directives requires the Apache module
+# `mod_expires` to be enabled.
+<Location /assets/>
+  # Use of ETag is discouraged when Last-Modified is present
+  Header unset ETag
+  FileETag None
+  # RFC says only cache for 1 year
+  ExpiresActive On
+  ExpiresDefault "access plus 1 year"
+</Location>
+
+
+
+

For NGINX:

+
+location ~ ^/assets/ {
+  expires 1y;
+  add_header Cache-Control public;
+
+  add_header ETag "";
+}
+
+
+
+

4.2 Local Precompilation

There are several reasons why you might want to precompile your assets locally. +Among them are:

+
    +
  • You may not have write access to your production file system.
  • +
  • You may be deploying to more than one server, and want to avoid +duplication of work.
  • +
  • You may be doing frequent deploys that do not include asset changes.
  • +
+

Local compilation allows you to commit the compiled files into source control, +and deploy as normal.

There are three caveats:

+
    +
  • You must not run the Capistrano deployment task that precompiles assets.
  • +
  • You must ensure any necessary compressors or minifiers are +available on your development system.
  • +
  • You must change the following application configuration setting:
  • +
+

In config/environments/development.rb, place the following line:

+
+config.assets.prefix = "/dev-assets"
+
+
+
+

The prefix change makes Sprockets use a different URL for serving assets in +development mode, and pass all requests to Sprockets. The prefix is still set to +/assets in the production environment. Without this change, the application +would serve the precompiled assets from /assets in development, and you would +not see any local changes until you compile assets again.

In practice, this will allow you to precompile locally, have those files in your +working tree, and commit those files to source control when needed. Development +mode will work as expected.

4.3 Live Compilation

In some circumstances you may wish to use live compilation. In this mode all +requests for assets in the pipeline are handled by Sprockets directly.

To enable this option set:

+
+config.assets.compile = true
+
+
+
+

On the first request the assets are compiled and cached as outlined in +development above, and the manifest names used in the helpers are altered to +include the MD5 hash.

Sprockets also sets the Cache-Control HTTP header to max-age=31536000. This +signals all caches between your server and the client browser that this content +(the file served) can be cached for 1 year. The effect of this is to reduce the +number of requests for this asset from your server; the asset has a good chance +of being in the local browser cache or some intermediate cache.

This mode uses more memory, performs more poorly than the default and is not +recommended.

If you are deploying a production application to a system without any +pre-existing JavaScript runtimes, you may want to add one to your Gemfile:

+
+group :production do
+  gem 'therubyracer'
+end
+
+
+
+

4.4 CDNs

CDN stands for Content Delivery +Network, they are +primarily designed to cache assets all over the world so that when a browser +requests the asset, a cached copy will be geographically close to that browser. +If you are serving assets directly from your Rails server in production, the +best practice is to use a CDN in front of your application.

A common pattern for using a CDN is to set your production application as the +"origin" server. This means when a browser requests an asset from the CDN and +there is a cache miss, it will grab the file from your server on the fly and +then cache it. For example if you are running a Rails application on +example.com and have a CDN configured at mycdnsubdomain.fictional-cdn.com, +then when a request is made to mycdnsubdomain.fictional- +cdn.com/assets/smile.png, the CDN will query your server once at +example.com/assets/smile.png and cache the request. The next request to the +CDN that comes in to the same URL will hit the cached copy. When the CDN can +serve an asset directly the request never touches your Rails server. Since the +assets from a CDN are geographically closer to the browser, the request is +faster, and since your server doesn't need to spend time serving assets, it can +focus on serving application code as fast as possible.

4.4.1 Set up a CDN to Serve Static Assets

To set up your CDN you have to have your application running in production on +the internet at a publicly available URL, for example example.com. Next +you'll need to sign up for a CDN service from a cloud hosting provider. When you +do this you need to configure the "origin" of the CDN to point back at your +website example.com, check your provider for documentation on configuring the +origin server.

The CDN you provisioned should give you a custom subdomain for your application +such as mycdnsubdomain.fictional-cdn.com (note fictional-cdn.com is not a +valid CDN provider at the time of this writing). Now that you have configured +your CDN server, you need to tell browsers to use your CDN to grab assets +instead of your Rails server directly. You can do this by configuring Rails to +set your CDN as the asset host instead of using a relative path. To set your +asset host in Rails, you need to set config.action_controller.asset_host in +config/environments/production.rb:

+
+config.action_controller.asset_host = 'mycdnsubdomain.fictional-cdn.com'
+
+
+
+

You only need to provide the "host", this is the subdomain and root +domain, you do not need to specify a protocol or "scheme" such as http:// or +https://. When a web page is requested, the protocol in the link to your asset +that is generated will match how the webpage is accessed by default.

You can also set this value through an environment +variable to make running a +staging copy of your site easier:

+
+config.action_controller.asset_host = ENV['CDN_HOST']
+
+
+
+

Note: You would need to set CDN_HOST on your server to mycdnsubdomain +.fictional-cdn.com for this to work.

Once you have configured your server and your CDN when you serve a webpage that +has an asset:

+
+<%= asset_path('smile.png') %>
+
+
+
+

Instead of returning a path such as /assets/smile.png (digests are left out +for readability). The URL generated will have the full path to your CDN.

+
+http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
+
+
+
+

If the CDN has a copy of smile.png it will serve it to the browser and your +server doesn't even know it was requested. If the CDN does not have a copy it +will try to find it at the "origin" example.com/assets/smile.png and then store +it for future use.

If you want to serve only some assets from your CDN, you can use custom :host +option your asset helper, which overwrites value set in +config.action_controller.asset_host.

+
+<%= asset_path 'image.png', host: 'mycdnsubdomain.fictional-cdn.com' %>
+
+
+
+
4.4.2 Customize CDN Caching Behavior

A CDN works by caching content. If the CDN has stale or bad content, then it is +hurting rather than helping your application. The purpose of this section is to +describe general caching behavior of most CDNs, your specific provider may +behave slightly differently.

4.4.2.1 CDN Request Caching

While a CDN is described as being good for caching assets, in reality caches the +entire request. This includes the body of the asset as well as any headers. The +most important one being Cache-Control which tells the CDN (and web browsers) +how to cache contents. This means that if someone requests an asset that does +not exist /assets/i-dont-exist.png and your Rails application returns a 404, +then your CDN will likely cache the 404 page if a valid Cache-Control header +is present.

4.4.2.2 CDN Header Debugging

One way to check the headers are cached properly in your CDN is by using curl. You +can request the headers from both your server and your CDN to verify they are +the same:

+
+$ curl -I http://www.example/assets/application-
+d0e099e021c95eb0de3615fd1d8c4d83.css
+HTTP/1.1 200 OK
+Server: Cowboy
+Date: Sun, 24 Aug 2014 20:27:50 GMT
+Connection: keep-alive
+Last-Modified: Thu, 08 May 2014 01:24:14 GMT
+Content-Type: text/css
+Cache-Control: public, max-age=2592000
+Content-Length: 126560
+Via: 1.1 vegur
+
+
+
+

Versus the CDN copy.

+
+$ curl -I http://mycdnsubdomain.fictional-cdn.com/application-
+d0e099e021c95eb0de3615fd1d8c4d83.css
+HTTP/1.1 200 OK Server: Cowboy Last-
+Modified: Thu, 08 May 2014 01:24:14 GMT Content-Type: text/css
+Cache-Control:
+public, max-age=2592000
+Via: 1.1 vegur
+Content-Length: 126560
+Accept-Ranges:
+bytes
+Date: Sun, 24 Aug 2014 20:28:45 GMT
+Via: 1.1 varnish
+Age: 885814
+Connection: keep-alive
+X-Served-By: cache-dfw1828-DFW
+X-Cache: HIT
+X-Cache-Hits:
+68
+X-Timer: S1408912125.211638212,VS0,VE0
+
+
+
+

Check your CDN documentation for any additional information they may provide +such as X-Cache or for any additional headers they may add.

4.4.2.3 CDNs and the Cache-Control Header

The cache control +header is a W3C +specification that describes how a request can be cached. When no CDN is used, a +browser will use this information to cache contents. This is very helpful for +assets that are not modified so that a browser does not need to re-download a +website's CSS or JavaScript on every request. Generally we want our Rails server +to tell our CDN (and browser) that the asset is "public", that means any cache +can store the request. Also we commonly want to set max-age which is how long +the cache will store the object before invalidating the cache. The max-age +value is set to seconds with a maximum possible value of 31536000 which is one +year. You can do this in your rails application by setting

+
+config.public_file_server.headers = {
+  'Cache-Control' => 'public, max-age=31536000'
+}
+
+
+
+

Now when your application serves an asset in production, the CDN will store the +asset for up to a year. Since most CDNs also cache headers of the request, this +Cache-Control will be passed along to all future browsers seeking this asset, +the browser then knows that it can store this asset for a very long time before +needing to re-request it.

4.4.2.4 CDNs and URL based Cache Invalidation

Most CDNs will cache contents of an asset based on the complete URL. This means +that a request to

+
+http://mycdnsubdomain.fictional-cdn.com/assets/smile-123.png
+
+
+
+

Will be a completely different cache from

+
+http://mycdnsubdomain.fictional-cdn.com/assets/smile.png
+
+
+
+

If you want to set far future max-age in your Cache-Control (and you do), +then make sure when you change your assets that your cache is invalidated. For +example when changing the smiley face in an image from yellow to blue, you want +all visitors of your site to get the new blue face. When using a CDN with the +Rails asset pipeline config.assets.digest is set to true by default so that +each asset will have a different file name when it is changed. This way you +don't have to ever manually invalidate any items in your cache. By using a +different unique asset name instead, your users get the latest asset.

5 Customizing the Pipeline

5.1 CSS Compression

One of the options for compressing CSS is YUI. The YUI CSS +compressor provides +minification.

The following line enables YUI compression, and requires the yui-compressor +gem.

+
+config.assets.css_compressor = :yui
+
+
+
+

The other option for compressing CSS if you have the sass-rails gem installed is

+
+config.assets.css_compressor = :sass
+
+
+
+

5.2 JavaScript Compression

Possible options for JavaScript compression are :closure, :uglifier and +:yui. These require the use of the closure-compiler, uglifier or +yui-compressor gems, respectively.

The default Gemfile includes uglifier. +This gem wraps UglifyJS (written for +NodeJS) in Ruby. It compresses your code by removing white space and comments, +shortening local variable names, and performing other micro-optimizations such +as changing if and else statements to ternary operators where possible.

The following line invokes uglifier for JavaScript compression.

+
+config.assets.js_compressor = :uglifier
+
+
+
+

You will need an ExecJS +supported runtime in order to use uglifier. If you are using Mac OS X or +Windows you have a JavaScript runtime installed in your operating system.

5.3 Serving GZipped version of assets

By default, gzipped version of compiled assets will be generated, along +with the non-gzipped version of assets. Gzipped assets help reduce the transmission of +data over the wire. You can configure this by setting the gzip flag.

+
+config.assets.gzip = false # disable gzipped assets generation
+
+
+
+

5.4 Using Your Own Compressor

The compressor config settings for CSS and JavaScript also take any object. +This object must have a compress method that takes a string as the sole +argument and it must return a string.

+
+class Transformer
+  def compress(string)
+    do_something_returning_a_string(string)
+  end
+end
+
+
+
+

To enable this, pass a new object to the config option in application.rb:

+
+config.assets.css_compressor = Transformer.new
+
+
+
+

5.5 Changing the assets Path

The public path that Sprockets uses by default is /assets.

This can be changed to something else:

+
+config.assets.prefix = "/some_other_path"
+
+
+
+

This is a handy option if you are updating an older project that didn't use the +asset pipeline and already uses this path or you wish to use this path for +a new resource.

5.6 X-Sendfile Headers

The X-Sendfile header is a directive to the web server to ignore the response +from the application, and instead serve a specified file from disk. This option +is off by default, but can be enabled if your server supports it. When enabled, +this passes responsibility for serving the file to the web server, which is +faster. Have a look at send_file +on how to use this feature.

Apache and NGINX support this option, which can be enabled in +config/environments/production.rb:

+
+# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
+# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
+
+
+
+

If you are upgrading an existing application and intend to use this +option, take care to paste this configuration option only into production.rb +and any other environments you define with production behavior (not +application.rb).

For further details have a look at the docs of your production web server: +- Apache +- NGINX

6 Assets Cache Store

By default, Sprockets caches assets in tmp/cache/assets in development +and production environments. This can be changed as follows:

+
+config.assets.configure do |env|
+  env.cache = ActiveSupport::Cache.lookup_store(:memory_store,
+                                                { size: 32.megabytes })
+end
+
+
+
+

To disable the assets cache store:

+
+config.assets.configure do |env|
+  env.cache = ActiveSupport::Cache.lookup_store(:null_store)
+end
+
+
+
+

7 Adding Assets to Your Gems

Assets can also come from external sources in the form of gems.

A good example of this is the jquery-rails gem which comes with Rails as the +standard JavaScript library gem. This gem contains an engine class which +inherits from Rails::Engine. By doing this, Rails is informed that the +directory for this gem may contain assets and the app/assets, lib/assets and +vendor/assets directories of this engine are added to the search path of +Sprockets.

8 Making Your Library or Gem a Pre-Processor

As Sprockets uses Tilt as a generic +interface to different templating engines, your gem should just implement the +Tilt template protocol. Normally, you would subclass Tilt::Template and +reimplement the prepare method, which initializes your template, and the +evaluate method, which returns the processed source. The original source is +stored in data. Have a look at +Tilt::Template +sources to learn more.

+
+module BangBang
+  class Template < ::Tilt::Template
+    def prepare
+      # Do any initialization here
+    end
+
+    # Adds a "!" to original template.
+    def evaluate(scope, locals, &block)
+      "#{data}!"
+    end
+  end
+end
+
+
+
+

Now that you have a Template class, it's time to associate it with an +extension for template files:

+
+Sprockets.register_engine '.bang', BangBang::Template
+
+
+
+

9 Upgrading from Old Versions of Rails

There are a few issues when upgrading from Rails 3.0 or Rails 2.x. The first is +moving the files from public/ to the new locations. See Asset +Organization above for guidance on the correct locations +for different file types.

Next will be avoiding duplicate JavaScript files. Since jQuery is the default +JavaScript library from Rails 3.1 onwards, you don't need to copy jquery.js +into app/assets and it will be included automatically.

The third is updating the various environment files with the correct default +options.

In application.rb:

+
+# Version of your assets, change this if you want to expire all your assets
+config.assets.version = '1.0'
+
+# Change the path that assets are served from config.assets.prefix = "/assets"
+
+
+
+

In development.rb:

+
+# Expands the lines which load the assets
+config.assets.debug = true
+
+
+
+

And in production.rb:

+
+# Choose the compressors to use (if any)
+config.assets.js_compressor = :uglifier
+# config.assets.css_compressor = :yui
+
+# Don't fallback to assets pipeline if a precompiled asset is missed
+config.assets.compile = false
+
+# Generate digests for assets URLs. This is planned for deprecation.
+config.assets.digest = true
+
+# Precompile additional assets (application.js, application.css, and all
+# non-JS/CSS are already added)
+# config.assets.precompile += %w( search.js )
+
+
+
+

Rails 4 and above no longer set default config values for Sprockets in test.rb, so +test.rb now requires Sprockets configuration. The old defaults in the test +environment are: config.assets.compile = true, config.assets.compress = false, +config.assets.debug = false and config.assets.digest = false.

The following should also be added to your Gemfile:

+
+gem 'sass-rails',   "~> 3.2.3"
+gem 'coffee-rails', "~> 3.2.1"
+gem 'uglifier'
+
+
+
+

反馈

diff --git a/command_line.html b/command_line.html index 44ad27c..a4d9c5b 100644 --- a/command_line.html +++ b/command_line.html @@ -230,7 +230,7 @@

Rails 命令行

读完本文后,您将学到:

  • 如何启动开发服务器;

  • 如果在交互式 shell 中测试对象;

  • -

    阅读本文前请阅读getting_started.xml,掌握一些 Rails 基础知识。

    1 命令行基础

    有些命令在 Rails 开发过程中经常会用到,下面按照使用频率倒序列出:

    +

    阅读本文前请阅读Rails 入门,掌握一些 Rails 基础知识。

    1 命令行基础

    有些命令在 Rails 开发过程中经常会用到,下面按照使用频率倒序列出:

    • rails console

    • rails server

    • @@ -436,7 +436,7 @@

      Rails 命令行

      读完本文后,您将学到:

    -

    介绍一下单元测试。单元测试是用来测试和做断言的代码。在单元测试中,我们只关注代码的一小部分,例如模型中的一个方法,测试其输入和输出。单元测试是你的好伙伴,你逐渐会意识到,单元测试的程度越高,生活的质量越高。真的。关于单元测试的详情,参阅testing.xml

    我们来看一下 Rails 创建的界面。

    +

    介绍一下单元测试。单元测试是用来测试和做断言的代码。在单元测试中,我们只关注代码的一小部分,例如模型中的一个方法,测试其输入和输出。单元测试是你的好伙伴,你逐渐会意识到,单元测试的程度越高,生活的质量越高。真的。关于单元测试的详情,参阅Rails 应用测试指南

    我们来看一下 Rails 创建的界面。

     $ bin/rails server
     
    @@ -583,7 +583,7 @@ 

    2 bin/rails

    2.2 assets

    bin/rails assets:precompile 用于预编译 app/assets 文件夹中的静态资源文件。bin/rails assets:clean 用于把之前编译好的静态资源文件删除。滚动部署时应该执行 assets:clean,以防仍然链接旧的静态资源文件。

    如果想完全清空 public/assets 目录,可以使用 bin/rails assets:clobber

    2.3 db -

    bin/rails 命名空间 db: 中最常用的任务是 migratecreate,这两个任务会尝试运行所有迁移相关的任务(updownredoreset)。bin/rails db:version 在排查问题时很有用,它会输出数据库的当前版本。

    关于数据库迁移的进一步说明,参阅active_record_migrations.xml

    2.4 notes +

    bin/rails 命名空间 db: 中最常用的任务是 migratecreate,这两个任务会尝试运行所有迁移相关的任务(updownredoreset)。bin/rails db:version 在排查问题时很有用,它会输出数据库的当前版本。

    关于数据库迁移的进一步说明,参阅Active Record 迁移

    2.4 notes

    bin/rails notes 在代码中搜索以 FIXME、OPTIMIZE 或 TODO 开头的注释。搜索的文件类型包括 .builder.rb.rake.yml.yaml.ruby.css.js.erb,搜索的注解包括默认的和自定义的。

     $ bin/rails notes
    @@ -639,7 +639,7 @@ 

    2.2 assets

    2.5 routes

    rails routes 列出应用中定义的所有路由,可为解决路由问题提供帮助,还可以让你对应用中的所有 URL 有个整体了解。

    2.6 test -

    Rails 中的单元测试详情,参见testing.xml

    Rails 提供了一个名为 Minitest 的测试组件。Rails 的稳定性由测试决定。test: 命名空间中的任务可用于运行各种测试。

    2.7 tmp +

    Rails 中的单元测试详情,参见Rails 应用测试指南

    Rails 提供了一个名为 Minitest 的测试组件。Rails 的稳定性由测试决定。test: 命名空间中的任务可用于运行各种测试。

    2.7 tmp

    Rails.root/tmp 目录和 *nix 系统中的 /tmp 目录作用相同,用于存放临时文件,例如 PID 文件和缓存的动作等。

    tmp: 命名空间中的任务可以清理或创建 Rails.root/tmp 目录:

    • rails tmp:cache:clear 清空 tmp/cache 目录;

    • diff --git a/configuring.html b/configuring.html index b56dfca..edb66c3 100644 --- a/configuring.html +++ b/configuring.html @@ -517,7 +517,7 @@

      3.8 配置 Action Dispatch

    • config.action_dispatch.signed_cookie_salt 设定签名 cookie 的盐值。默认为 'signed cookie'

    • config.action_dispatch.encrypted_cookie_salt 设定加密 cookie 的盐值。默认为 'encrypted cookie'

    • config.action_dispatch.encrypted_signed_cookie_salt 设定签名加密 cookie 的盐值。默认为 'signed encrypted cookie'

    • -
    • config.action_dispatch.perform_deep_munge 配置是否在参数上调用 deep_munge 方法。详情参见 安全指南。默认为 true

    • +
    • config.action_dispatch.perform_deep_munge 配置是否在参数上调用 deep_munge 方法。详情参见 安全指南。默认为 true

    • config.action_dispatch.rescue_responses 设定异常与 HTTP 状态的对应关系。其值为一个散列,指定异常和状态之间的映射。默认的定义如下:

      diff --git a/engines.html b/engines.html index a31fa85..d915f4a 100644 --- a/engines.html +++ b/engines.html @@ -5,7 +5,7 @@ -Ruby on Rails Guides +Getting Started with Engines — Ruby on Rails Guides @@ -173,16 +173,1239 @@

      Guides.rubyonrails.org<
      - +

      Getting Started with Engines

      In this guide you will learn about engines and how they can be used to provide +additional functionality to their host applications through a clean and very +easy-to-use interface.

      After reading this guide, you will know:

      +
        +
      • What makes an engine.
      • +
      • How to generate an engine.
      • +
      • Building features for the engine.
      • +
      • Hooking the engine into an application.
      • +
      • Overriding engine functionality in the application.
      • +
      + + + -
      -

      引擎入门

      +

      1 What are engines?

      Engines can be considered miniature applications that provide functionality to +their host applications. A Rails application is actually just a "supercharged" +engine, with the Rails::Application class inheriting a lot of its behavior +from Rails::Engine.

      Therefore, engines and applications can be thought of almost the same thing, +just with subtle differences, as you'll see throughout this guide. Engines and +applications also share a common structure.

      Engines are also closely related to plugins. The two share a common lib +directory structure, and are both generated using the rails plugin new +generator. The difference is that an engine is considered a "full plugin" by +Rails (as indicated by the --full option that's passed to the generator +command). We'll actually be using the --mountable option here, which includes +all the features of --full, and then some. This guide will refer to these +"full plugins" simply as "engines" throughout. An engine can be a plugin, +and a plugin can be an engine.

      The engine that will be created in this guide will be called "blorgh". This +engine will provide blogging functionality to its host applications, allowing +for new articles and comments to be created. At the beginning of this guide, you +will be working solely within the engine itself, but in later sections you'll +see how to hook it into an application.

      Engines can also be isolated from their host applications. This means that an +application is able to have a path provided by a routing helper such as +articles_path and use an engine also that provides a path also called +articles_path, and the two would not clash. Along with this, controllers, models +and table names are also namespaced. You'll see how to do this later in this +guide.

      It's important to keep in mind at all times that the application should +always take precedence over its engines. An application is the object that +has final say in what goes on in its environment. The engine should +only be enhancing it, rather than changing it drastically.

      To see demonstrations of other engines, check out +Devise, an engine that provides +authentication for its parent applications, or +Forem, an engine that provides forum +functionality. There's also Spree which +provides an e-commerce platform, and +RefineryCMS, a CMS engine.

      Finally, engines would not have been possible without the work of James Adam, +Piotr Sarnacki, the Rails Core Team, and a number of other people. If you ever +meet them, don't forget to say thanks!

      2 Generating an engine

      To generate an engine, you will need to run the plugin generator and pass it +options as appropriate to the need. For the "blorgh" example, you will need to +create a "mountable" engine, running this command in a terminal:

      +
      +$ rails plugin new blorgh --mountable
      +
      +
      +
      +

      The full list of options for the plugin generator may be seen by typing:

      +
      +$ rails plugin --help
      +
      +
      +
      +

      The --mountable option tells the generator that you want to create a +"mountable" and namespace-isolated engine. This generator will provide the same +skeleton structure as would the --full option. The --full option tells the +generator that you want to create an engine, including a skeleton structure +that provides the following:

      +
        +
      • An app directory tree
      • +
      • +

        A config/routes.rb file:

        +
        +
        +Rails.application.routes.draw do
        +end
        +
        +
        +
        +
      • +
      • +

        A file at lib/blorgh/engine.rb, which is identical in function to a +standard Rails application's config/application.rb file:

        +
        +
        +module Blorgh
        +  class Engine < ::Rails::Engine
        +  end
        +end
        +
        +
        +
        +
      • +
      +

      The --mountable option will add to the --full option:

      +
        +
      • Asset manifest files (application.js and application.css)
      • +
      • A namespaced ApplicationController stub
      • +
      • A namespaced ApplicationHelper stub
      • +
      • A layout view template for the engine
      • +
      • +

        Namespace isolation to config/routes.rb:

        +
        +
        +Blorgh::Engine.routes.draw do
        +end
        +
        +
        +
        +
      • +
      • +

        Namespace isolation to lib/blorgh/engine.rb:

        +
        +
        +module Blorgh
        +  class Engine < ::Rails::Engine
        +    isolate_namespace Blorgh
        +  end
        +end
        +
        +
        +
        +
      • +
      +

      Additionally, the --mountable option tells the generator to mount the engine +inside the dummy testing application located at test/dummy by adding the +following to the dummy application's routes file at +test/dummy/config/routes.rb:

      +
      +mount Blorgh::Engine => "/blorgh"
      +
      +
      +
      +

      2.1 Inside an Engine

      2.1.1 Critical Files

      At the root of this brand new engine's directory lives a blorgh.gemspec file. +When you include the engine into an application later on, you will do so with +this line in the Rails application's Gemfile:

      +
      +gem 'blorgh', path: 'engines/blorgh'
      +
      +
      +
      +

      Don't forget to run bundle install as usual. By specifying it as a gem within +the Gemfile, Bundler will load it as such, parsing this blorgh.gemspec file +and requiring a file within the lib directory called lib/blorgh.rb. This +file requires the blorgh/engine.rb file (located at lib/blorgh/engine.rb) +and defines a base module called Blorgh.

      +
      +require "blorgh/engine"
      +
      +module Blorgh
      +end
      +
      +
      +
      +

      Some engines choose to use this file to put global configuration options +for their engine. It's a relatively good idea, so if you want to offer +configuration options, the file where your engine's module is defined is +perfect for that. Place the methods inside the module and you'll be good to go.

      Within lib/blorgh/engine.rb is the base class for the engine:

      +
      +module Blorgh
      +  class Engine < ::Rails::Engine
      +    isolate_namespace Blorgh
      +  end
      +end
      +
      +
      +
      +

      By inheriting from the Rails::Engine class, this gem notifies Rails that +there's an engine at the specified path, and will correctly mount the engine +inside the application, performing tasks such as adding the app directory of +the engine to the load path for models, mailers, controllers and views.

      The isolate_namespace method here deserves special notice. This call is +responsible for isolating the controllers, models, routes and other things into +their own namespace, away from similar components inside the application. +Without this, there is a possibility that the engine's components could "leak" +into the application, causing unwanted disruption, or that important engine +components could be overridden by similarly named things within the application. +One of the examples of such conflicts is helpers. Without calling +isolate_namespace, the engine's helpers would be included in an application's +controllers.

      It is highly recommended that the isolate_namespace line be left +within the Engine class definition. Without it, classes generated in an engine +may conflict with an application.

      What this isolation of the namespace means is that a model generated by a call +to bin/rails g model, such as bin/rails g model article, won't be called Article, but +instead be namespaced and called Blorgh::Article. In addition, the table for the +model is namespaced, becoming blorgh_articles, rather than simply articles. +Similar to the model namespacing, a controller called ArticlesController becomes +Blorgh::ArticlesController and the views for that controller will not be at +app/views/articles, but app/views/blorgh/articles instead. Mailers are namespaced +as well.

      Finally, routes will also be isolated within the engine. This is one of the most +important parts about namespacing, and is discussed later in the +Routes section of this guide.

      2.1.2 app Directory

      Inside the app directory are the standard assets, controllers, helpers, +mailers, models and views directories that you should be familiar with +from an application. The helpers, mailers and models directories are +empty, so they aren't described in this section. We'll look more into models in +a future section, when we're writing the engine.

      Within the app/assets directory, there are the images, javascripts and +stylesheets directories which, again, you should be familiar with due to their +similarity to an application. One difference here, however, is that each +directory contains a sub-directory with the engine name. Because this engine is +going to be namespaced, its assets should be too.

      Within the app/controllers directory there is a blorgh directory that +contains a file called application_controller.rb. This file will provide any +common functionality for the controllers of the engine. The blorgh directory +is where the other controllers for the engine will go. By placing them within +this namespaced directory, you prevent them from possibly clashing with +identically-named controllers within other engines or even within the +application.

      The ApplicationController class inside an engine is named just like a +Rails application in order to make it easier for you to convert your +applications into engines.

      Because of the way that Ruby does constant lookup you may run into a situation +where your engine controller is inheriting from the main application controller and +not your engine's application controller. Ruby is able to resolve the ApplicationController constant, and therefore the autoloading mechanism is not triggered. See the section When Constants Aren't Missed of the Autoloading and Reloading Constants guide for further details. The best way to prevent this from +happening is to use require_dependency to ensure that the engine's application +controller is loaded. For example:

      +
      +# app/controllers/blorgh/articles_controller.rb:
      +require_dependency "blorgh/application_controller"
      +
      +module Blorgh
      +  class ArticlesController < ApplicationController
      +    ...
      +  end
      +end
      +
      +
      +
      +

      Don't use require because it will break the automatic reloading of classes +in the development environment - using require_dependency ensures that classes are +loaded and unloaded in the correct manner.

      Lastly, the app/views directory contains a layouts folder, which contains a +file at blorgh/application.html.erb. This file allows you to specify a layout +for the engine. If this engine is to be used as a stand-alone engine, then you +would add any customization to its layout in this file, rather than the +application's app/views/layouts/application.html.erb file.

      If you don't want to force a layout on to users of the engine, then you can +delete this file and reference a different layout in the controllers of your +engine.

      2.1.3 bin Directory

      This directory contains one file, bin/rails, which enables you to use the +rails sub-commands and generators just like you would within an application. +This means that you will be able to generate new controllers and models for this +engine very easily by running commands like this:

      +
      +$ bin/rails g model
      +
      +
      +
      +

      Keep in mind, of course, that anything generated with these commands inside of +an engine that has isolate_namespace in the Engine class will be namespaced.

      2.1.4 test Directory

      The test directory is where tests for the engine will go. To test the engine, +there is a cut-down version of a Rails application embedded within it at +test/dummy. This application will mount the engine in the +test/dummy/config/routes.rb file:

      +
      +Rails.application.routes.draw do
      +  mount Blorgh::Engine => "/blorgh"
      +end
      +
      +
      +
      +

      This line mounts the engine at the path /blorgh, which will make it accessible +through the application only at that path.

      Inside the test directory there is the test/integration directory, where +integration tests for the engine should be placed. Other directories can be +created in the test directory as well. For example, you may wish to create a +test/models directory for your model tests.

      3 Providing engine functionality

      The engine that this guide covers provides submitting articles and commenting +functionality and follows a similar thread to the Getting Started +Guide, with some new twists.

      3.1 Generating an Article Resource

      The first thing to generate for a blog engine is the Article model and related +controller. To quickly generate this, you can use the Rails scaffold generator.

      +
      +$ bin/rails generate scaffold article title:string text:text
      +
      +
      +
      +

      This command will output this information:

      +
      +invoke  active_record
      +create    db/migrate/[timestamp]_create_blorgh_articles.rb
      +create    app/models/blorgh/article.rb
      +invoke    test_unit
      +create      test/models/blorgh/article_test.rb
      +create      test/fixtures/blorgh/articles.yml
      +invoke  resource_route
      + route    resources :articles
      +invoke  scaffold_controller
      +create    app/controllers/blorgh/articles_controller.rb
      +invoke    erb
      +create      app/views/blorgh/articles
      +create      app/views/blorgh/articles/index.html.erb
      +create      app/views/blorgh/articles/edit.html.erb
      +create      app/views/blorgh/articles/show.html.erb
      +create      app/views/blorgh/articles/new.html.erb
      +create      app/views/blorgh/articles/_form.html.erb
      +invoke    test_unit
      +create      test/controllers/blorgh/articles_controller_test.rb
      +invoke    helper
      +create      app/helpers/blorgh/articles_helper.rb
      +invoke  assets
      +invoke    js
      +create      app/assets/javascripts/blorgh/articles.js
      +invoke    css
      +create      app/assets/stylesheets/blorgh/articles.css
      +invoke  css
      +create    app/assets/stylesheets/scaffold.css
      +
      +
      +
      +

      The first thing that the scaffold generator does is invoke the active_record +generator, which generates a migration and a model for the resource. Note here, +however, that the migration is called create_blorgh_articles rather than the +usual create_articles. This is due to the isolate_namespace method called in +the Blorgh::Engine class's definition. The model here is also namespaced, +being placed at app/models/blorgh/article.rb rather than app/models/article.rb due +to the isolate_namespace call within the Engine class.

      Next, the test_unit generator is invoked for this model, generating a model +test at test/models/blorgh/article_test.rb (rather than +test/models/article_test.rb) and a fixture at test/fixtures/blorgh/articles.yml +(rather than test/fixtures/articles.yml).

      After that, a line for the resource is inserted into the config/routes.rb file +for the engine. This line is simply resources :articles, turning the +config/routes.rb file for the engine into this:

      +
      +Blorgh::Engine.routes.draw do
      +  resources :articles
      +end
      +
      +
      +
      +

      Note here that the routes are drawn upon the Blorgh::Engine object rather than +the YourApp::Application class. This is so that the engine routes are confined +to the engine itself and can be mounted at a specific point as shown in the +test directory section. It also causes the engine's routes to +be isolated from those routes that are within the application. The +Routes section of this guide describes it in detail.

      Next, the scaffold_controller generator is invoked, generating a controller +called Blorgh::ArticlesController (at +app/controllers/blorgh/articles_controller.rb) and its related views at +app/views/blorgh/articles. This generator also generates a test for the +controller (test/controllers/blorgh/articles_controller_test.rb) and a helper +(app/helpers/blorgh/articles_helper.rb).

      Everything this generator has created is neatly namespaced. The controller's +class is defined within the Blorgh module:

      +
      +module Blorgh
      +  class ArticlesController < ApplicationController
      +    ...
      +  end
      +end
      +
      +
      +
      +

      The ArticlesController class inherits from +Blorgh::ApplicationController, not the application's ApplicationController.

      The helper inside app/helpers/blorgh/articles_helper.rb is also namespaced:

      +
      +module Blorgh
      +  module ArticlesHelper
      +    ...
      +  end
      +end
      +
      +
      +
      +

      This helps prevent conflicts with any other engine or application that may have +an article resource as well.

      Finally, the assets for this resource are generated in two files: +app/assets/javascripts/blorgh/articles.js and +app/assets/stylesheets/blorgh/articles.css. You'll see how to use these a little +later.

      You can see what the engine has so far by running bin/rails db:migrate at the root +of our engine to run the migration generated by the scaffold generator, and then +running rails server in test/dummy. When you open +http://localhost:3000/blorgh/articles you will see the default scaffold that has +been generated. Click around! You've just generated your first engine's first +functions.

      If you'd rather play around in the console, rails console will also work just +like a Rails application. Remember: the Article model is namespaced, so to +reference it you must call it as Blorgh::Article.

      +
      +>> Blorgh::Article.find(1)
      +=> #<Blorgh::Article id: 1 ...>
      +
      +
      +
      +

      One final thing is that the articles resource for this engine should be the root +of the engine. Whenever someone goes to the root path where the engine is +mounted, they should be shown a list of articles. This can be made to happen if +this line is inserted into the config/routes.rb file inside the engine:

      +
      +root to: "articles#index"
      +
      +
      +
      +

      Now people will only need to go to the root of the engine to see all the articles, +rather than visiting /articles. This means that instead of +http://localhost:3000/blorgh/articles, you only need to go to +http://localhost:3000/blorgh now.

      3.2 Generating a Comments Resource

      Now that the engine can create new articles, it only makes sense to add +commenting functionality as well. To do this, you'll need to generate a comment +model, a comment controller and then modify the articles scaffold to display +comments and allow people to create new ones.

      From the application root, run the model generator. Tell it to generate a +Comment model, with the related table having two columns: an article_id integer +and text text column.

      +
      +$ bin/rails generate model Comment article_id:integer text:text
      +
      +
      +
      +

      This will output the following:

      +
      +invoke  active_record
      +create    db/migrate/[timestamp]_create_blorgh_comments.rb
      +create    app/models/blorgh/comment.rb
      +invoke    test_unit
      +create      test/models/blorgh/comment_test.rb
      +create      test/fixtures/blorgh/comments.yml
      +
      +
      +
      +

      This generator call will generate just the necessary model files it needs, +namespacing the files under a blorgh directory and creating a model class +called Blorgh::Comment. Now run the migration to create our blorgh_comments +table:

      +
      +$ bin/rails db:migrate
      +
      +
      +
      +

      To show the comments on an article, edit app/views/blorgh/articles/show.html.erb and +add this line before the "Edit" link:

      +
      +<h3>Comments</h3>
      +<%= render @article.comments %>
      +
      +
      +
      +

      This line will require there to be a has_many association for comments defined +on the Blorgh::Article model, which there isn't right now. To define one, open +app/models/blorgh/article.rb and add this line into the model:

      +
      +has_many :comments
      +
      +
      +
      +

      Turning the model into this:

      +
      +module Blorgh
      +  class Article < ApplicationRecord
      +    has_many :comments
      +  end
      +end
      +
      +
      +
      +

      Because the has_many is defined inside a class that is inside the +Blorgh module, Rails will know that you want to use the Blorgh::Comment +model for these objects, so there's no need to specify that using the +:class_name option here.

      Next, there needs to be a form so that comments can be created on an article. To +add this, put this line underneath the call to render @article.comments in +app/views/blorgh/articles/show.html.erb:

      +
      +<%= render "blorgh/comments/form" %>
      +
      +
      +
      +

      Next, the partial that this line will render needs to exist. Create a new +directory at app/views/blorgh/comments and in it a new file called +_form.html.erb which has this content to create the required partial:

      +
      +<h3>New comment</h3>
      +<%= form_for [@article, @article.comments.build] do |f| %>
      +  <p>
      +    <%= f.label :text %><br>
      +    <%= f.text_area :text %>
      +  </p>
      +  <%= f.submit %>
      +<% end %>
      +
      +
      +
      +

      When this form is submitted, it is going to attempt to perform a POST request +to a route of /articles/:article_id/comments within the engine. This route doesn't +exist at the moment, but can be created by changing the resources :articles line +inside config/routes.rb into these lines:

      +
      +resources :articles do
      +  resources :comments
      +end
      +
      +
      +
      +

      This creates a nested route for the comments, which is what the form requires.

      The route now exists, but the controller that this route goes to does not. To +create it, run this command from the application root:

      +
      +$ bin/rails g controller comments
      +
      +
      +
      +

      This will generate the following things:

      +
      +create  app/controllers/blorgh/comments_controller.rb
      +invoke  erb
      + exist    app/views/blorgh/comments
      +invoke  test_unit
      +create    test/controllers/blorgh/comments_controller_test.rb
      +invoke  helper
      +create    app/helpers/blorgh/comments_helper.rb
      +invoke  assets
      +invoke    js
      +create      app/assets/javascripts/blorgh/comments.js
      +invoke    css
      +create      app/assets/stylesheets/blorgh/comments.css
      +
      +
      +
      +

      The form will be making a POST request to /articles/:article_id/comments, which +will correspond with the create action in Blorgh::CommentsController. This +action needs to be created, which can be done by putting the following lines +inside the class definition in app/controllers/blorgh/comments_controller.rb:

      +
      +def create
      +  @article = Article.find(params[:article_id])
      +  @comment = @article.comments.create(comment_params)
      +  flash[:notice] = "Comment has been created!"
      +  redirect_to articles_path
      +end
      +
      +private
      +  def comment_params
      +    params.require(:comment).permit(:text)
      +  end
      +
      +
      +
      +

      This is the final step required to get the new comment form working. Displaying +the comments, however, is not quite right yet. If you were to create a comment +right now, you would see this error:

      +
      +Missing partial blorgh/comments/_comment with {:handlers=>[:erb, :builder],
      +:formats=>[:html], :locale=>[:en, :en]}. Searched in:   *
      +"/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views"   *
      +"/Users/ryan/Sites/side_projects/blorgh/app/views"
      +
      +
      +
      +

      The engine is unable to find the partial required for rendering the comments. +Rails looks first in the application's (test/dummy) app/views directory and +then in the engine's app/views directory. When it can't find it, it will throw +this error. The engine knows to look for blorgh/comments/_comment because the +model object it is receiving is from the Blorgh::Comment class.

      This partial will be responsible for rendering just the comment text, for now. +Create a new file at app/views/blorgh/comments/_comment.html.erb and put this +line inside it:

      +
      +<%= comment_counter + 1 %>. <%= comment.text %>
      +
      +
      +
      +

      The comment_counter local variable is given to us by the <%= render +@article.comments %> call, which will define it automatically and increment the +counter as it iterates through each comment. It's used in this example to +display a small number next to each comment when it's created.

      That completes the comment function of the blogging engine. Now it's time to use +it within an application.

      4 Hooking Into an Application

      Using an engine within an application is very easy. This section covers how to +mount the engine into an application and the initial setup required, as well as +linking the engine to a User class provided by the application to provide +ownership for articles and comments within the engine.

      4.1 Mounting the Engine

      First, the engine needs to be specified inside the application's Gemfile. If +there isn't an application handy to test this out in, generate one using the +rails new command outside of the engine directory like this:

      +
      +$ rails new unicorn
      +
      +
      +
      +

      Usually, specifying the engine inside the Gemfile would be done by specifying it +as a normal, everyday gem.

      +
      +gem 'devise'
      +
      +
      +
      +

      However, because you are developing the blorgh engine on your local machine, +you will need to specify the :path option in your Gemfile:

      +
      +gem 'blorgh', path: 'engines/blorgh'
      +
      +
      +
      +

      Then run bundle to install the gem.

      As described earlier, by placing the gem in the Gemfile it will be loaded when +Rails is loaded. It will first require lib/blorgh.rb from the engine, then +lib/blorgh/engine.rb, which is the file that defines the major pieces of +functionality for the engine.

      To make the engine's functionality accessible from within an application, it +needs to be mounted in that application's config/routes.rb file:

      +
      +mount Blorgh::Engine, at: "/blog"
      +
      +
      +
      +

      This line will mount the engine at /blog in the application. Making it +accessible at http://localhost:3000/blog when the application runs with rails +server.

      Other engines, such as Devise, handle this a little differently by making +you specify custom helpers (such as devise_for) in the routes. These helpers +do exactly the same thing, mounting pieces of the engines's functionality at a +pre-defined path which may be customizable.

      4.2 Engine setup

      The engine contains migrations for the blorgh_articles and blorgh_comments +table which need to be created in the application's database so that the +engine's models can query them correctly. To copy these migrations into the +application run the following command from the test/dummy directory of your Rails engine:

      +
      +$ bin/rails blorgh:install:migrations
      +
      +
      +
      +

      If you have multiple engines that need migrations copied over, use +railties:install:migrations instead:

      +
      +$ bin/rails railties:install:migrations
      +
      +
      +
      +

      This command, when run for the first time, will copy over all the migrations +from the engine. When run the next time, it will only copy over migrations that +haven't been copied over already. The first run for this command will output +something such as this:

      +
      +Copied migration [timestamp_1]_create_blorgh_articles.blorgh.rb from blorgh
      +Copied migration [timestamp_2]_create_blorgh_comments.blorgh.rb from blorgh
      +
      +
      +
      +

      The first timestamp ([timestamp_1]) will be the current time, and the second +timestamp ([timestamp_2]) will be the current time plus a second. The reason +for this is so that the migrations for the engine are run after any existing +migrations in the application.

      To run these migrations within the context of the application, simply run bin/rails +db:migrate. When accessing the engine through http://localhost:3000/blog, the +articles will be empty. This is because the table created inside the application is +different from the one created within the engine. Go ahead, play around with the +newly mounted engine. You'll find that it's the same as when it was only an +engine.

      If you would like to run migrations only from one engine, you can do it by +specifying SCOPE:

      +
      +bin/rails db:migrate SCOPE=blorgh
      +
      +
      +
      +

      This may be useful if you want to revert engine's migrations before removing it. +To revert all migrations from blorgh engine you can run code such as:

      +
      +bin/rails db:migrate SCOPE=blorgh VERSION=0
      +
      +
      +
      +

      4.3 Using a Class Provided by the Application

      4.3.1 Using a Model Provided by the Application

      When an engine is created, it may want to use specific classes from an +application to provide links between the pieces of the engine and the pieces of +the application. In the case of the blorgh engine, making articles and comments +have authors would make a lot of sense.

      A typical application might have a User class that would be used to represent +authors for an article or a comment. But there could be a case where the +application calls this class something different, such as Person. For this +reason, the engine should not hardcode associations specifically for a User +class.

      To keep it simple in this case, the application will have a class called User +that represents the users of the application (we'll get into making this +configurable further on). It can be generated using this command inside the +application:

      +
      +rails g model user name:string
      +
      +
      +
      +

      The bin/rails db:migrate command needs to be run here to ensure that our +application has the users table for future use.

      Also, to keep it simple, the articles form will have a new text field called +author_name, where users can elect to put their name. The engine will then +take this name and either create a new User object from it, or find one that +already has that name. The engine will then associate the article with the found or +created User object.

      First, the author_name text field needs to be added to the +app/views/blorgh/articles/_form.html.erb partial inside the engine. This can be +added above the title field with this code:

      +
      +<div class="field">
      +  <%= f.label :author_name %><br>
      +  <%= f.text_field :author_name %>
      +</div>
      +
      +
      +
      +

      Next, we need to update our Blorgh::ArticleController#article_params method to +permit the new form parameter:

      +
      +def article_params
      +  params.require(:article).permit(:title, :text, :author_name)
      +end
      +
      +
      +
      +

      The Blorgh::Article model should then have some code to convert the author_name +field into an actual User object and associate it as that article's author +before the article is saved. It will also need to have an attr_accessor set up +for this field, so that the setter and getter methods are defined for it.

      To do all this, you'll need to add the attr_accessor for author_name, the +association for the author and the before_validation call into +app/models/blorgh/article.rb. The author association will be hard-coded to the +User class for the time being.

      +
      +attr_accessor :author_name
      +belongs_to :author, class_name: "User"
      +
      +before_validation :set_author
      +
      +private
      +  def set_author
      +    self.author = User.find_or_create_by(name: author_name)
      +  end
      +
      +
      +
      +

      By representing the author association's object with the User class, a link +is established between the engine and the application. There needs to be a way +of associating the records in the blorgh_articles table with the records in the +users table. Because the association is called author, there should be an +author_id column added to the blorgh_articles table.

      To generate this new column, run this command within the engine:

      +
      +$ bin/rails g migration add_author_id_to_blorgh_articles author_id:integer
      +
      +
      +
      +

      Due to the migration's name and the column specification after it, Rails +will automatically know that you want to add a column to a specific table and +write that into the migration for you. You don't need to tell it any more than +this.

      This migration will need to be run on the application. To do that, it must first +be copied using this command:

      +
      +$ bin/rails blorgh:install:migrations
      +
      +
      +
      +

      Notice that only one migration was copied over here. This is because the first +two migrations were copied over the first time this command was run.

      +
      +NOTE Migration [timestamp]_create_blorgh_articles.blorgh.rb from blorgh has been skipped. Migration with the same name already exists.
      +NOTE Migration [timestamp]_create_blorgh_comments.blorgh.rb from blorgh has been skipped. Migration with the same name already exists.
      +Copied migration [timestamp]_add_author_id_to_blorgh_articles.blorgh.rb from blorgh
      +
      +
      +
      +

      Run the migration using:

      +
      +$ bin/rails db:migrate
      +
      +
      +
      +

      Now with all the pieces in place, an action will take place that will associate +an author - represented by a record in the users table - with an article, +represented by the blorgh_articles table from the engine.

      Finally, the author's name should be displayed on the article's page. Add this code +above the "Title" output inside app/views/blorgh/articles/show.html.erb:

      +
      +<p>
      +  <b>Author:</b>
      +  <%= @article.author.name %>
      +</p>
      +
      +
      +
      +
      4.3.2 Using a Controller Provided by the Application

      Because Rails controllers generally share code for things like authentication +and accessing session variables, they inherit from ApplicationController by +default. Rails engines, however are scoped to run independently from the main +application, so each engine gets a scoped ApplicationController. This +namespace prevents code collisions, but often engine controllers need to access +methods in the main application's ApplicationController. An easy way to +provide this access is to change the engine's scoped ApplicationController to +inherit from the main application's ApplicationController. For our Blorgh +engine this would be done by changing +app/controllers/blorgh/application_controller.rb to look like:

      +
      +module Blorgh
      +  class ApplicationController < ::ApplicationController
      +  end
      +end
      +
      +
      +
      +

      By default, the engine's controllers inherit from +Blorgh::ApplicationController. So, after making this change they will have +access to the main application's ApplicationController, as though they were +part of the main application.

      This change does require that the engine is run from a Rails application that +has an ApplicationController.

      4.4 Configuring an Engine

      This section covers how to make the User class configurable, followed by +general configuration tips for the engine.

      4.4.1 Setting Configuration Settings in the Application

      The next step is to make the class that represents a User in the application +customizable for the engine. This is because that class may not always be +User, as previously explained. To make this setting customizable, the engine +will have a configuration setting called author_class that will be used to +specify which class represents users inside the application.

      To define this configuration setting, you should use a mattr_accessor inside +the Blorgh module for the engine. Add this line to lib/blorgh.rb inside the +engine:

      +
      +mattr_accessor :author_class
      +
      +
      +
      +

      This method works like its brothers, attr_accessor and cattr_accessor, but +provides a setter and getter method on the module with the specified name. To +use it, it must be referenced using Blorgh.author_class.

      The next step is to switch the Blorgh::Article model over to this new setting. +Change the belongs_to association inside this model +(app/models/blorgh/article.rb) to this:

      +
      +belongs_to :author, class_name: Blorgh.author_class
      +
      +
      +
      +

      The set_author method in the Blorgh::Article model should also use this class:

      +
      +self.author = Blorgh.author_class.constantize.find_or_create_by(name: author_name)
      +
      +
      +
      +

      To save having to call constantize on the author_class result all the time, +you could instead just override the author_class getter method inside the +Blorgh module in the lib/blorgh.rb file to always call constantize on the +saved value before returning the result:

      +
      +def self.author_class
      +  @@author_class.constantize
      +end
      +
      +
      +
      +

      This would then turn the above code for set_author into this:

      +
      +self.author = Blorgh.author_class.find_or_create_by(name: author_name)
      +
      +
      +
      +

      Resulting in something a little shorter, and more implicit in its behavior. The +author_class method should always return a Class object.

      Since we changed the author_class method to return a Class instead of a +String, we must also modify our belongs_to definition in the Blorgh::Article +model:

      +
      +belongs_to :author, class_name: Blorgh.author_class.to_s
      +
      +
      +
      +

      To set this configuration setting within the application, an initializer should +be used. By using an initializer, the configuration will be set up before the +application starts and calls the engine's models, which may depend on this +configuration setting existing.

      Create a new initializer at config/initializers/blorgh.rb inside the +application where the blorgh engine is installed and put this content in it:

      +
      +Blorgh.author_class = "User"
      +
      +
      +
      +

      It's very important here to use the String version of the class, +rather than the class itself. If you were to use the class, Rails would attempt +to load that class and then reference the related table. This could lead to +problems if the table wasn't already existing. Therefore, a String should be +used and then converted to a class using constantize in the engine later on.

      Go ahead and try to create a new article. You will see that it works exactly in the +same way as before, except this time the engine is using the configuration +setting in config/initializers/blorgh.rb to learn what the class is.

      There are now no strict dependencies on what the class is, only what the API for +the class must be. The engine simply requires this class to define a +find_or_create_by method which returns an object of that class, to be +associated with an article when it's created. This object, of course, should have +some sort of identifier by which it can be referenced.

      4.4.2 General Engine Configuration

      Within an engine, there may come a time where you wish to use things such as +initializers, internationalization or other configuration options. The great +news is that these things are entirely possible, because a Rails engine shares +much the same functionality as a Rails application. In fact, a Rails +application's functionality is actually a superset of what is provided by +engines!

      If you wish to use an initializer - code that should run before the engine is +loaded - the place for it is the config/initializers folder. This directory's +functionality is explained in the Initializers +section of the Configuring guide, and works +precisely the same way as the config/initializers directory inside an +application. The same thing goes if you want to use a standard initializer.

      For locales, simply place the locale files in the config/locales directory, +just like you would in an application.

      5 Testing an engine

      When an engine is generated, there is a smaller dummy application created inside +it at test/dummy. This application is used as a mounting point for the engine, +to make testing the engine extremely simple. You may extend this application by +generating controllers, models or views from within the directory, and then use +those to test your engine.

      The test directory should be treated like a typical Rails testing environment, +allowing for unit, functional and integration tests.

      5.1 Functional Tests

      A matter worth taking into consideration when writing functional tests is that +the tests are going to be running on an application - the test/dummy +application - rather than your engine. This is due to the setup of the testing +environment; an engine needs an application as a host for testing its main +functionality, especially controllers. This means that if you were to make a +typical GET to a controller in a controller's functional test like this:

      +
      +module Blorgh
      +  class FooControllerTest < ActionDispatch::IntegrationTest
      +    include Engine.routes.url_helpers
      +
      +    def test_index
      +      get foos_url
      +      ...
      +    end
      +  end
      +end
      +
      +
      +
      +

      It may not function correctly. This is because the application doesn't know how +to route these requests to the engine unless you explicitly tell it how. To +do this, you must set the @routes instance variable to the engine's route set +in your setup code:

      +
      +module Blorgh
      +  class FooControllerTest < ActionDispatch::IntegrationTest
      +    include Engine.routes.url_helpers
      +
      +    setup do
      +      @routes = Engine.routes
      +    end
      +
      +    def test_index
      +      get foos_url
      +      ...
      +    end
      +  end
      +end
      +
      +
      +
      +

      This tells the application that you still want to perform a GET request to the +index action of this controller, but you want to use the engine's route to get +there, rather than the application's one.

      This also ensures that the engine's URL helpers will work as expected in your +tests.

      6 Improving engine functionality

      This section explains how to add and/or override engine MVC functionality in the +main Rails application.

      6.1 Overriding Models and Controllers

      Engine model and controller classes can be extended by open classing them in the +main Rails application (since model and controller classes are just Ruby classes +that inherit Rails specific functionality). Open classing an Engine class +redefines it for use in the main application. This is usually implemented by +using the decorator pattern.

      For simple class modifications, use Class#class_eval. For complex class +modifications, consider using ActiveSupport::Concern.

      6.1.1 A note on Decorators and Loading Code

      Because these decorators are not referenced by your Rails application itself, +Rails' autoloading system will not kick in and load your decorators. This means +that you need to require them yourself.

      Here is some sample code to do this:

      +
      +# lib/blorgh/engine.rb
      +module Blorgh
      +  class Engine < ::Rails::Engine
      +    isolate_namespace Blorgh
      +
      +    config.to_prepare do
      +      Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
      +        require_dependency(c)
      +      end
      +    end
      +  end
      +end
      +
      +
      +
      +

      This doesn't apply to just Decorators, but anything that you add in an engine +that isn't referenced by your main application.

      6.1.2 Implementing Decorator Pattern Using Class#class_eval

      Adding Article#time_since_created:

      +
      +# MyApp/app/decorators/models/blorgh/article_decorator.rb
      +
      +Blorgh::Article.class_eval do
      +  def time_since_created
      +    Time.current - created_at
      +  end
      +end
      +
      +
      +
      +
      +
      +# Blorgh/app/models/article.rb
      +
      +class Article < ApplicationRecord
      +  has_many :comments
      +end
      +
      +
      +
      +

      Overriding Article#summary:

      +
      +# MyApp/app/decorators/models/blorgh/article_decorator.rb
      +
      +Blorgh::Article.class_eval do
      +  def summary
      +    "#{title} - #{truncate(text)}"
      +  end
      +end
      +
      +
      +
      +
      +
      +# Blorgh/app/models/article.rb
      +
      +class Article < ApplicationRecord
      +  has_many :comments
      +  def summary
      +    "#{title}"
      +  end
      +end
      +
      +
      +
      +
      6.1.3 Implementing Decorator Pattern Using ActiveSupport::Concern

      Using Class#class_eval is great for simple adjustments, but for more complex +class modifications, you might want to consider using ActiveSupport::Concern. +ActiveSupport::Concern manages load order of interlinked dependent modules and +classes at run time allowing you to significantly modularize your code.

      Adding Article#time_since_created and Overriding Article#summary:

      +
      +# MyApp/app/models/blorgh/article.rb
      +
      +class Blorgh::Article < ApplicationRecord
      +  include Blorgh::Concerns::Models::Article
      +
      +  def time_since_created
      +    Time.current - created_at
      +  end
      +
      +  def summary
      +    "#{title} - #{truncate(text)}"
      +  end
      +end
      +
      +
      +
      +
      +
      +# Blorgh/app/models/article.rb
      +
      +class Article < ApplicationRecord
      +  include Blorgh::Concerns::Models::Article
      +end
      +
      +
      +
      +
      +
      +# Blorgh/lib/concerns/models/article.rb
      +
      +module Blorgh::Concerns::Models::Article
      +  extend ActiveSupport::Concern
      +
      +  # 'included do' causes the included code to be evaluated in the
      +  # context where it is included (article.rb), rather than being
      +  # executed in the module's context (blorgh/concerns/models/article).
      +  included do
      +    attr_accessor :author_name
      +    belongs_to :author, class_name: "User"
      +
      +    before_validation :set_author
      +
      +    private
      +      def set_author
      +        self.author = User.find_or_create_by(name: author_name)
      +      end
      +  end
      +
      +  def summary
      +    "#{title}"
      +  end
      +
      +  module ClassMethods
      +    def some_class_method
      +      'some class method string'
      +    end
      +  end
      +end
      +
      +
      +
      +

      6.2 Overriding Views

      When Rails looks for a view to render, it will first look in the app/views +directory of the application. If it cannot find the view there, it will check in +the app/views directories of all engines that have this directory.

      When the application is asked to render the view for Blorgh::ArticlesController's +index action, it will first look for the path +app/views/blorgh/articles/index.html.erb within the application. If it cannot +find it, it will look inside the engine.

      You can override this view in the application by simply creating a new file at +app/views/blorgh/articles/index.html.erb. Then you can completely change what +this view would normally output.

      Try this now by creating a new file at app/views/blorgh/articles/index.html.erb +and put this content in it:

      +
      +<h1>Articles</h1>
      +<%= link_to "New Article", new_article_path %>
      +<% @articles.each do |article| %>
      +  <h2><%= article.title %></h2>
      +  <small>By <%= article.author %></small>
      +  <%= simple_format(article.text) %>
      +  <hr>
      +<% end %>
      +
      +
      +
      +

      6.3 Routes

      Routes inside an engine are isolated from the application by default. This is +done by the isolate_namespace call inside the Engine class. This essentially +means that the application and its engines can have identically named routes and +they will not clash.

      Routes inside an engine are drawn on the Engine class within +config/routes.rb, like this:

      +
      +Blorgh::Engine.routes.draw do
      +  resources :articles
      +end
      +
      +
      +
      +

      By having isolated routes such as this, if you wish to link to an area of an +engine from within an application, you will need to use the engine's routing +proxy method. Calls to normal routing methods such as articles_path may end up +going to undesired locations if both the application and the engine have such a +helper defined.

      For instance, the following example would go to the application's articles_path +if that template was rendered from the application, or the engine's articles_path +if it was rendered from the engine:

      +
      +<%= link_to "Blog articles", articles_path %>
      +
      +
      +
      +

      To make this route always use the engine's articles_path routing helper method, +we must call the method on the routing proxy method that shares the same name as +the engine.

      +
      +<%= link_to "Blog articles", blorgh.articles_path %>
      +
      +
      +
      +

      If you wish to reference the application inside the engine in a similar way, use +the main_app helper:

      +
      +<%= link_to "Home", main_app.root_path %>
      +
      +
      +
      +

      If you were to use this inside an engine, it would always go to the +application's root. If you were to leave off the main_app "routing proxy" +method call, it could potentially go to the engine's or application's root, +depending on where it was called from.

      If a template rendered from within an engine attempts to use one of the +application's routing helper methods, it may result in an undefined method call. +If you encounter such an issue, ensure that you're not attempting to call the +application's routing methods without the main_app prefix from within the +engine.

      6.4 Assets

      Assets within an engine work in an identical way to a full application. Because +the engine class inherits from Rails::Engine, the application will know to +look up assets in the engine's 'app/assets' and 'lib/assets' directories.

      Like all of the other components of an engine, the assets should be namespaced. +This means that if you have an asset called style.css, it should be placed at +app/assets/stylesheets/[engine name]/style.css, rather than +app/assets/stylesheets/style.css. If this asset isn't namespaced, there is a +possibility that the host application could have an asset named identically, in +which case the application's asset would take precedence and the engine's one +would be ignored.

      Imagine that you did have an asset located at +app/assets/stylesheets/blorgh/style.css To include this asset inside an +application, just use stylesheet_link_tag and reference the asset as if it +were inside the engine:

      +
      +<%= stylesheet_link_tag "blorgh/style.css" %>
      +
      +
      +
      +

      You can also specify these assets as dependencies of other assets using Asset +Pipeline require statements in processed files:

      +
      +/*
      + *= require blorgh/style
      +*/
      +
      +
      +
      +

      Remember that in order to use languages like Sass or CoffeeScript, you +should add the relevant library to your engine's .gemspec.

      6.5 Separate Assets & Precompiling

      There are some situations where your engine's assets are not required by the +host application. For example, say that you've created an admin functionality +that only exists for your engine. In this case, the host application doesn't +need to require admin.css or admin.js. Only the gem's admin layout needs +these assets. It doesn't make sense for the host app to include +"blorgh/admin.css" in its stylesheets. In this situation, you should +explicitly define these assets for precompilation. This tells sprockets to add +your engine assets when bin/rails assets:precompile is triggered.

      You can define assets for precompilation in engine.rb:

      +
      +initializer "blorgh.assets.precompile" do |app|
      +  app.config.assets.precompile += %w(admin.css admin.js)
      +end
      +
      +
      +
      +

      For more information, read the Asset Pipeline guide.

      6.6 Other Gem Dependencies

      Gem dependencies inside an engine should be specified inside the .gemspec file +at the root of the engine. The reason is that the engine may be installed as a +gem. If dependencies were to be specified inside the Gemfile, these would not +be recognized by a traditional gem install and so they would not be installed, +causing the engine to malfunction.

      To specify a dependency that should be installed with the engine during a +traditional gem install, specify it inside the Gem::Specification block +inside the .gemspec file in the engine:

      +
      +s.add_dependency "moo"
      +
      +
      +
      +

      To specify a dependency that should only be installed as a development +dependency of the application, specify it like this:

      +
      +s.add_development_dependency "moo"
      +
      +
      +
      +

      Both kinds of dependencies will be installed when bundle install is run inside +of the application. The development dependencies for the gem will only be used +when the tests for the engine are running.

      Note that if you want to immediately require dependencies when the engine is +required, you should require them before the engine's initialization. For +example:

      +
      +require 'other_engine/engine'
      +require 'yet_another_engine/engine'
      +
      +module MyEngine
      +  class Engine < ::Rails::Engine
      +  end
      +end
      +
      +
      +
      +

      反馈

      diff --git a/initialization.html b/initialization.html index c0cc0fa..81c6304 100644 --- a/initialization.html +++ b/initialization.html @@ -175,14 +175,578 @@

      Guides.rubyonrails.org<

      -

      Rails 初始化过程

      +

      Rails 初始化过程

      本文介绍 Rails 初始化过程的内部细节,内容较深,建议 Rails 高级开发者阅读。

      读完本文后,您将学到:

      +
        +
      • 如何使用 rails server

      • +
      • Rails 初始化过程的时间表;

      • +
      • 引导过程中所需的不同文件的所在位置;

      • +
      • Rails::Server 接口的定义和使用方式。

      • +
      +

      本文介绍默认情况下,Rails 应用初始化过程中的每一个方法调用,详细解释各个步骤的具体细节。本文将聚焦于使用 rails server 启动 Rails 应用时发生的事情。

      除非另有说明,本文中出现的路径都是相对于 Rails 或 Rails 应用所在目录的相对路径。

      如果想一边阅读本文一边查看 Rails 源代码,推荐在 GitHub 中使用 t 快捷键打开文件查找器,以便快速查找相关文件。

      1 启动

      首先介绍 Rails 应用引导和初始化的过程。我们可以通过 rails consolerails server 命令启动 Rails 应用。

      1.1 railties/exe/rails 文件

      rails server 命令中的 rails 是位于加载路径中的 Ruby 可执行文件。这个文件包含如下内容:

      +
      +version = ">= 0"
      +load Gem.bin_path('railties', 'rails', version)
      +
      +
      +
      +

      在 Rails 控制台中运行上述代码,可以看到加载的是 railties/exe/rails 文件(译者注:在 Rails 5.0.1 中看到的是 rails 命令的使用帮助)。railties/exe/rails 文件的部分内容如下:

      +
      +require "rails/cli"
      +
      +
      +
      +

      railties/lib/rails/cli 文件又会调用 Rails::AppLoader.exec_app 方法。

      1.2 railties/lib/rails/app_loader.rb 文件

      exec_app 方法的主要作用是执行应用中的 bin/rails 文件。如果在当前文件夹中未找到 bin/rails 文件,就会继续在上层文件夹中查找,直到找到为止。因此,我们可以在 Rails 应用中的任何位置执行 rails 命令。

      执行 rails server 命令时,实际执行的是等价的下述命令:

      +
      +$ exec ruby bin/rails server
      +
      +
      +
      +

      1.3 bin/rails 文件

      此文件包含如下内容:

      +
      +#!/usr/bin/env ruby
      +APP_PATH = File.expand_path('../../config/application', __FILE__)
      +require_relative '../config/boot'
      +require 'rails/commands'
      +
      +
      +
      +

      其中 APP_PATH 常量稍后将在 rails/commands 中使用。所加载的 config/boot 是应用中的 config/boot.rb 文件,用于加载并设置 Bundler。

      1.4 config/boot.rb 文件

      此文件包含如下内容:

      +
      +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
      +
      +require 'bundler/setup' # 设置 Gemfile 中列出的所有 gem
      +
      +
      +
      +

      标准的 Rails 应用中包含 Gemfile 文件,用于声明应用的所有依赖关系。config/boot.rb 文件会把 ENV['BUNDLE_GEMFILE'] 设置为 Gemfile 文件的路径。如果 Gemfile 文件存在,就会加载 bundler/setup,Bundler 通过它设置 Gemfile 中依赖关系的加载路径。

      标准的 Rails 应用依赖多个 gem,包括:

      +
        +
      • actionmailer

      • +
      • actionpack

      • +
      • actionview

      • +
      • activemodel

      • +
      • activerecord

      • +
      • activesupport

      • +
      • activejob

      • +
      • arel

      • +
      • builder

      • +
      • bundler

      • +
      • erubis

      • +
      • i18n

      • +
      • mail

      • +
      • mime-types

      • +
      • rack

      • +
      • rack-cache

      • +
      • rack-mount

      • +
      • rack-test

      • +
      • rails

      • +
      • railties

      • +
      • rake

      • +
      • sqlite3

      • +
      • thor

      • +
      • tzinfo

      • +
      +

      1.5 rails/commands.rb 文件

      执行完 config/boot.rb 文件,下一步就要加载 rails/commands,其作用是扩展命令别名。在本例中(输入的命令为 rails server),ARGV 数组只包含将要传递的 server 命令:

      +
      +ARGV << '--help' if ARGV.empty?
      +
      +aliases = {
      +  "g"  => "generate",
      +  "d"  => "destroy",
      +  "c"  => "console",
      +  "s"  => "server",
      +  "db" => "dbconsole",
      +  "r"  => "runner",
      +  "t"  => "test"
      +}
      +
      +command = ARGV.shift
      +command = aliases[command] || command
      +
      +require 'rails/commands/commands_tasks'
      +
      +Rails::CommandsTasks.new(ARGV).run_command!(command)
      +
      +
      +
      +

      我们看到,如果 ARGV 为空,Rails 就会显示帮助信息。

      如果输入的命令使用的是 s 而不是 server,Rails 就会在上面定义的 aliases 散列中查找对应的命令。

      1.6 rails/commands/commands_tasks.rb 文件

      如果输入的是合法的 Rails 命令,Rails 就会通过 run_command! 方法调用命令的同名方法。如果 Rails 不能识别该命令,Rails 就会尝试执行同名的 Rake 任务。

      +
      +COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole application runner new version help)
      +
      +def run_command!(command)
      +  command = parse_command(command)
      +
      +  if COMMAND_WHITELIST.include?(command)
      +    send(command)
      +  else
      +    run_rake_task(command)
      +  end
      +end
      +
      +
      +
      +

      本例中输入的是 server 命令,因此 Rails 会进一步运行下述代码:

      +
      +def set_application_directory!
      +  Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
      +end
      +
      +def server
      +  set_application_directory!
      +  require_command!("server")
      +
      +  Rails::Server.new.tap do |server|
      +    # 当服务器完成环境设置后,就需要加载应用,
      +    # 否则传递给服务器的 `--environment` 选项就不会继续传递下去。
      +    require APP_PATH
      +    Dir.chdir(Rails.application.root)
      +    server.start
      +  end
      +end
      +
      +def require_command!(command)
      +  require "rails/commands/#{command}"
      +end
      +
      +
      +
      +

      仅当 config.ru 文件无法找到时,才会切换到 Rails 应用根目录(APP_PATH 所在文件夹的上一层文件夹,其中 APP_PATH 指向 config/application.rb 文件)。然后会加载 rails/commands/server,其作用是建立 Rails::Server 类。

      +
      +require 'fileutils'
      +require 'optparse'
      +require 'action_dispatch'
      +require 'rails'
      +
      +module Rails
      +  class Server < ::Rack::Server
      +
      +
      +
      +

      fileutilsoptparse 是 Ruby 标准库,分别提供了用于处理文件和解析选项的帮助方法。

      1.7 actionpack/lib/action_dispatch.rb 文件

      Action Dispatch 是 Rails 框架的路由组件,提供了路由、会话、常用中间件等功能。

      1.8 rails/commands/server.rb 文件

      此文件中定义的 Rails::Server 类,继承自 Rack::Server 类。当调用 Rails::Server.new 方法时,会调用此文件中定义的 initialize 方法:

      +
      +def initialize(*)
      +  super
      +  set_environment
      +end
      +
      +
      +
      +

      首先调用的 super 方法,会调用 Rack::Server 类的 initialize 方法。

      1.9 Rack: lib/rack/server.rb 文件

      Rack::Server 类负责为所有基于 Rack 的应用(包括 Rails)提供通用服务器接口。

      Rack::Server 类的 initialize 方法的作用是设置几个变量:

      +
      +def initialize(options = nil)
      +  @options = options
      +  @app = options[:app] if options && options[:app]
      +end
      +
      +
      +
      +

      在本例中,options 的值是 nil,因此这个方法什么也没做。

      super 方法完成 Rack::Server 类的 initialize 方法的调用后,程序执行流程重新回到 rails/commands/server.rb 文件中。此时,会在 Rails::Server 对象的上下文中调用 set_environment 方法。乍一看这个方法什么也没做:

      +
      +def set_environment
      +  ENV["RAILS_ENV"] ||= options[:environment]
      +end
      +
      +
      +
      +

      实际上,其中的 options 方法做了很多工作。options 方法在 Rack::Server 类中定义:

      +
      +def options
      +  @options ||= parse_options(ARGV)
      +end
      +
      +
      +
      +

      parse_options 方法的定义如下:

      +
      +def parse_options(args)
      +  options = default_options
      +
      +  # 请不要计算 CGI `ISINDEX` 参数的值。
      +  # http://www.meb.uni-bonn.de/docs/cgi/cl.html
      +  args.clear if ENV.include?("REQUEST_METHOD")
      +
      +  options.merge! opt_parser.parse!(args)
      +  options[:config] = ::File.expand_path(options[:config])
      +  ENV["RACK_ENV"] = options[:environment]
      +  options
      +end
      +
      +
      +
      +

      其中 default_options 方法的定义如下:

      +
      +def default_options
      +  environment  = ENV['RACK_ENV'] || 'development'
      +  default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
      +
      +  {
      +    :environment => environment,
      +    :pid         => nil,
      +    :Port        => 9292,
      +    :Host        => default_host,
      +    :AccessLog   => [],
      +    :config      => "config.ru"
      +  }
      +end
      +
      +
      +
      +

      ENV 散列中不存在 REQUEST_METHOD 键,因此可以跳过该行。下一行会合并 opt_parser 方法返回的选项,其中 opt_parser 方法在 Rack::Server 类中定义:

      +
      +def opt_parser
      +  Options.new
      +end
      +
      +
      +
      +

      Options 类在 Rack::Server 类中定义,但在 Rails::Server 类中被覆盖了,目的是为了接受不同参数。Options 类的 parse! 方法的定义,其开头部分如下:

      +
      +def parse!(args)
      +  args, options = args.dup, {}
      +
      +  opt_parser = OptionParser.new do |opts|
      +    opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
      +    opts.on("-p", "--port=port", Integer,
      +            "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
      +  ...
      +
      +
      +
      +

      此方法为 options 散列的键赋值,稍后 Rails 将使用此散列确定服务器的运行方式。initialize 方法运行完成后,程序执行流程会跳回 rails/server,然后加载之前设置的 APP_PATH

      1.10 config/application +

      执行 require APP_PATH 时,会加载 config/application.rb 文件(前文说过 APP_PATH 已经在 bin/rails 中定义)。这个文件也是应用的一部分,我们可以根据需要对文件内容进行修改。

      1.11 Rails::Server#start 方法

      config/application.rb 文件加载完成后,会调用 server.start 方法。这个方法的定义如下:

      +
      +def start
      +  print_boot_information
      +  trap(:INT) { exit }
      +  create_tmp_directories
      +  log_to_stdout if options[:log_stdout]
      +
      +  super
      +  ...
      +end
      +
      +private
      +
      +  def print_boot_information
      +    ...
      +    puts "=> Run `rails server -h` for more startup options"
      +  end
      +
      +  def create_tmp_directories
      +    %w(cache pids sockets).each do |dir_to_make|
      +      FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make))
      +    end
      +  end
      +
      +  def log_to_stdout
      +    wrapped_app # 对应用执行 touch 操作,以便设置记录器
      +
      +    console = ActiveSupport::Logger.new($stdout)
      +    console.formatter = Rails.logger.formatter
      +    console.level = Rails.logger.level
      +
      +    Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
      +  end
      +
      +
      +
      +

      这是 Rails 初始化过程中第一次输出信息。start 方法为 INT 信号创建了一个陷阱,只要在服务器运行时按下 CTRL-C,服务器进程就会退出。我们看到,上述代码会创建 tmp/cachetmp/pidstmp/sockets 文件夹。然后会调用 wrapped_app 方法,其作用是先创建 Rack 应用,再创建 ActiveSupport::Logger 类的实例。

      super 方法会调用 Rack::Server.start 方法,后者的定义如下:

      +
      +def start &blk
      +  if options[:warn]
      +    $-w = true
      +  end
      +
      +  if includes = options[:include]
      +    $LOAD_PATH.unshift(*includes)
      +  end
      +
      +  if library = options[:require]
      +    require library
      +  end
      +
      +  if options[:debug]
      +    $DEBUG = true
      +    require 'pp'
      +    p options[:server]
      +    pp wrapped_app
      +    pp app
      +  end
      +
      +  check_pid! if options[:pid]
      +
      +  # 对包装后的应用执行 touch 操作,以便在创建守护进程之前
      +  # 加载 `config.ru` 文件(例如在 `chdir` 等操作之前)
      +  wrapped_app
      +
      +  daemonize_app if options[:daemonize]
      +
      +  write_pid if options[:pid]
      +
      +  trap(:INT) do
      +    if server.respond_to?(:shutdown)
      +      server.shutdown
      +    else
      +      exit
      +    end
      +  end
      +
      +  server.run wrapped_app, options, &blk
      +end
      +
      +
      +
      +

      代码块最后一行中的 server.run 非常有意思。这里我们再次遇到了 wrapped_app 方法,这次我们要更深入地研究它(前文已经调用过 wrapped_app 方法,现在需要回顾一下)。

      +
      +@wrapped_app ||= build_app app
      +
      +
      +
      +

      其中 app 方法定义如下:

      +
      +def app
      +  @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
      +end
      +...
      +private
      +  def build_app_and_options_from_config
      +    if !::File.exist? options[:config]
      +      abort "configuration #{options[:config]} not found"
      +    end
      +
      +    app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
      +    self.options.merge! options
      +    app
      +  end
      +
      +  def build_app_from_string
      +    Rack::Builder.new_from_string(self.options[:builder])
      +  end
      +
      +
      +
      +

      options[:config] 的默认值为 config.ru,此文件包含如下内容:

      +
      +# 基于 Rack 的服务器使用此文件来启动应用。
      +
      +require ::File.expand_path('../config/environment', __FILE__)
      +run <%= app_const %>
      +
      +
      +
      +

      Rack::Builder.parse_file 方法读取 config.ru 文件的内容,并使用下述代码解析文件内容:

      +
      +app = new_from_string cfgfile, config
      +
      +...
      +
      +def self.new_from_string(builder_script, file="(rackup)")
      +  eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
      +    TOPLEVEL_BINDING, file, 0
      +end
      +
      +
      +
      +

      Rack::Builder 类的 initialize 方法会把接收到的代码块在 Rack::Builder 类的实例中执行,Rails 初始化过程中的大部分工作都在这一步完成。在 config.ru 文件中,加载 config/environment.rb 文件的这一行代码首先被执行:

      +
      +require ::File.expand_path('../config/environment', __FILE__)
      +
      +
      +
      +

      1.12 config/environment.rb 文件

      config.ru 文件(rails server)和 Passenger 都需要加载此文件。这两种运行服务器的方式直到这里才出现了交集,此前的一切工作都只是围绕 Rack 和 Rails 的设置进行的。

      此文件以加载 config/application.rb 文件开始:

      +
      +require File.expand_path('../application', __FILE__)
      +
      +
      +
      +

      1.13 config/application.rb 文件

      此文件会加载 config/boot.rb 文件:

      +
      +require File.expand_path('../boot', __FILE__)
      +
      +
      +
      +

      对于 rails server 这种启动服务器的方式,之前并未加载过 config/boot.rb 文件,因此这里会加载该文件;对于 Passenger,之前已经加载过该文件,这里就不会重复加载了。

      接下来,有趣的故事就要开始了!

      2 加载 Rails

      config/application.rb 文件的下一行是:

      +
      +require 'rails/all'
      +
      +
      +
      +

      2.1 railties/lib/rails/all.rb 文件

      此文件负责加载 Rails 中所有独立的框架:

      +
      +require "rails"
      +
      +%w(
      +  active_record/railtie
      +  action_controller/railtie
      +  action_view/railtie
      +  action_mailer/railtie
      +  active_job/railtie
      +  action_cable/engine
      +  rails/test_unit/railtie
      +  sprockets/railtie
      +).each do |railtie|
      +  begin
      +    require "#{railtie}"
      +  rescue LoadError
      +  end
      +end
      +
      +
      +
      +

      这些框架加载完成后,就可以在 Rails 应用中使用了。这里不会深入介绍每个框架,而是鼓励读者自己动手试验和探索。

      现在,我们只需记住,Rails 的常见功能,例如 Rails 引擎、I18n 和 Rails 配置,都在这里定义好了。

      2.2 回到 config/environment.rb 文件

      config/application.rb 文件的其余部分定义了 Rails::Application 的配置,当应用的初始化全部完成后就会使用这些配置。当 config/application.rb 文件完成了 Rails 的加载和应用命名空间的定义后,程序执行流程再次回到 config/environment.rb 文件。在这里会通过 rails/application.rb 文件中定义的 Rails.application.initialize! 方法完成应用的初始化。

      2.3 railties/lib/rails/application.rb 文件

      initialize! 方法的定义如下:

      +
      +def initialize!(group=:default) #:nodoc:
      +  raise "Application has been already initialized." if @initialized
      +  run_initializers(group, self)
      +  @initialized = true
      +  self
      +end
      +
      +
      +
      +

      我们看到,一个应用只能初始化一次。railties/lib/rails/initializable.rb 文件中定义的 run_initializers 方法负责运行初始化程序:

      +
      +def run_initializers(group=:default, *args)
      +  return if instance_variable_defined?(:@ran)
      +  initializers.tsort_each do |initializer|
      +    initializer.run(*args) if initializer.belongs_to?(group)
      +  end
      +  @ran = true
      +end
      +
      +
      +
      +

      run_initializers 方法的代码比较复杂,Rails 会遍历所有类的祖先,以查找能够响应 initializers 方法的类。对于找到的类,首先按名称排序,然后依次调用 initializers 方法。例如,Engine 类通过为所有的引擎提供 initializers 方法而使它们可用。

      railties/lib/rails/application.rb 文件中定义的 Rails::Application 类,定义了 bootstraprailtiefinisher 初始化程序。bootstrap 初始化程序负责完成应用初始化的准备工作(例如初始化记录器),而 finisher 初始化程序(例如创建中间件栈)总是最后运行。railtie 初始化程序在 Rails::Application 类自身中定义,在 bootstrap 之后、finishers 之前运行。

      应用初始化完成后,程序执行流程再次回到 Rack::Server 类。

      2.4 Rack: lib/rack/server.rb 文件

      程序执行流程上一次离开此文件是在定义 app 方法时:

      +
      +def app
      +  @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
      +end
      +...
      +private
      +  def build_app_and_options_from_config
      +    if !::File.exist? options[:config]
      +      abort "configuration #{options[:config]} not found"
      +    end
      +
      +    app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
      +    self.options.merge! options
      +    app
      +  end
      +
      +  def build_app_from_string
      +    Rack::Builder.new_from_string(self.options[:builder])
      +  end
      +
      +
      +
      +

      此时,app 就是 Rails 应用本身(一个中间件),接下来 Rack 会调用所有已提供的中间件:

      +
      +def build_app(app)
      +  middleware[options[:environment]].reverse_each do |middleware|
      +    middleware = middleware.call(self) if middleware.respond_to?(:call)
      +    next unless middleware
      +    klass = middleware.shift
      +    app = klass.new(app, *middleware)
      +  end
      +  app
      +end
      +
      +
      +
      +

      记住,在 Server#start 方法定义的最后一行代码中,通过 wrapped_app 方法调用了 build_app 方法。让我们回顾一下这行代码:

      +
      +server.run wrapped_app, options, &blk
      +
      +
      +
      +

      此时,server.run 方法的实现方式取决于我们所使用的服务器。例如,如果使用的是 Puma,run 方法的实现方式如下:

      +
      +...
      +DEFAULT_OPTIONS = {
      +  :Host => '0.0.0.0',
      +  :Port => 8080,
      +  :Threads => '0:16',
      +  :Verbose => false
      +}
      +
      +def self.run(app, options = {})
      +  options  = DEFAULT_OPTIONS.merge(options)
      +
      +  if options[:Verbose]
      +    app = Rack::CommonLogger.new(app, STDOUT)
      +  end
      +
      +  if options[:environment]
      +    ENV['RACK_ENV'] = options[:environment].to_s
      +  end
      +
      +  server   = ::Puma::Server.new(app)
      +  min, max = options[:Threads].split(':', 2)
      +
      +  puts "Puma #{::Puma::Const::PUMA_VERSION} starting..."
      +  puts "* Min threads: #{min}, max threads: #{max}"
      +  puts "* Environment: #{ENV['RACK_ENV']}"
      +  puts "* Listening on tcp://#{options[:Host]}:#{options[:Port]}"
      +
      +  server.add_tcp_listener options[:Host], options[:Port]
      +  server.min_threads = min
      +  server.max_threads = max
      +  yield server if block_given?
      +
      +  begin
      +    server.run.join
      +  rescue Interrupt
      +    puts "* Gracefully stopping, waiting for requests to finish"
      +    server.stop(true)
      +    puts "* Goodbye!"
      +  end
      +
      +end
      +
      +
      +
      +

      我们不会深入介绍服务器配置本身,不过这已经是 Rails 初始化过程的最后一步了。

      本文高度概括的介绍,旨在帮助读者理解 Rails 应用的代码何时执行、如何执行,从而使读者成为更优秀的 Rails 开发者。要想掌握更多这方面的知识,Rails 源代码本身也许是最好的研究对象。

      反馈

      diff --git a/security.html b/security.html index c91d44c..171465b 100644 --- a/security.html +++ b/security.html @@ -188,8 +188,8 @@

      Chapters

    • 会话劫持
    • 会话安全指南
    • 会话存储
    • -
    • 对 CookieStore 会话的重放攻击(replay attack)
    • -
    • 会话固定攻击(session fixation)
    • +
    • 对 CookieStore 会话的重放攻击
    • +
    • 会话固定攻击
    • 会话固定攻击的对策
    • 会话过期
    @@ -207,7 +207,7 @@

    Chapters

    @@ -231,7 +231,30 @@

    Chapters

  • 提升权限
  • -
  • 注入
  • +
  • +注入攻击 + + +
  • +
  • 生成不安全的查询
  • +
  • 默认首部
  • +
  • +环境安全 + + +
  • +
  • 其他资源
  • @@ -242,7 +265,7 @@

    Chapters

    -

    Ruby on Rails 安全指南

    本文介绍 Web 应用中常见的安全问题,以及如何在 Rails 中避免这些问题。

    读完本文后,您将学到:

    +

    Ruby on Rails 安全指南

    本文介绍 Web 应用常见的安全问题,以及如何在 Rails 中规避。

    读完本文后,您将学到:

    • 所有需要强调的安全对策;

    • Rails 中会话的概念,应该在会话中保存什么内容,以及常见的攻击方式;

    • @@ -251,40 +274,39 @@

      Ruby on Rails 安全指南

      本文介绍 Web 应用中常见的安全

    • 如何管理用户:登录、退出,以及不同层次上的攻击方式;

    • 最常见的注入攻击方式。

    -

    1 简介

    Web 应用框架的作用是帮助开发者创建 Web 应用。其中一些框架还能帮助我们提高 Web 应用的安全性。事实上,框架之间无所谓谁更安全,对于许多框架来说,只要使用正确,我们都能开发出安全的应用。Ruby on Rails 提供了一些十分智能的辅助方法,例如,用于防止 SQL 注入的辅助方法,极大减少了这一安全风险。

    一般来说,并不存在什么即插即用的安全机制。安全性取决于开发者如何使用框架,有时也取决于开发方式。安全性还取决于 Web 应用环境的各个层面,包括后端存储、Web 服务器和 Web 应用自身等(甚至包括其他 Web应用)。

    不过,据高德纳咨询公司(Gartner Group)估计,75% 的攻击发生在 Web 应用层面,报告称“在进行了安全审计的 300 个网站中,97% 存在被攻击的风险”。这是因为针对 Web 应用的攻击相对来说更容易实施,其工作原理和具体操作都比较简单,即使是非专业人士也能发起攻击。

    针对 Web 应用的安全威胁包括账户劫持、绕过访问控制、读取或修改敏感数据,以及显示欺诈信息等。有时,攻击者还会安装木马程序或使用垃圾邮件群发软件,以便获取经济利益,或者通过篡改公司资源来损害品牌形象。为了防止这些攻击,最大限度降低或消除攻击造成的影响,首先我们必须全面了解各种攻击方式,只有这样才能找出正确对策——这正是本文的主要目的。

    为了开发安全的 Web 应用,我们必须从各个层面紧跟安全形势,做到知己知彼。为此,我们可以订阅安全相关的邮件列表,阅读相关博客,同时养成及时更新并定期进行安全检查的习惯(请参阅其他资源一节)。这些工作都是手动完成的,只有这样我们才能发现潜在安全隐患。

    2 会话

    从会话入手来了解安全问题是一个很好的切入点,因为会话对于特定攻击十分脆弱。

    2.1 会话是什么

    HTTP 是无状态协议,会话使其有状态。

    大多数应用需要跟踪特定用户的某些状态,例如购物车里的商品、当前登录用户的 ID 等。如果没有会话,就需要为每一次请求标识用户甚至进行身份验证。当新用户访问应用时,Rails 会自动新建会话,如果用户曾经访问过应用,就会加载已有会话。

    会话通常由值的散列和会话 ID(通常为 32 个字符的字符串)组成,其中会话 ID 用于标识散列。发送到客户端浏览器的每个 Cookie 都包含会话 ID,另一方面,客户端浏览器发送到服务器的每个请求也包含会话 ID。在 Rails 中,我们可以使用 session 方法保存和取回值:

    +

    1 简介

    Web 应用框架的作用是帮助开发者创建 Web 应用。其中一些框架还能帮助我们提高 Web 应用的安全性。事实上,框架之间无所谓谁更安全,对许多框架来说,只要使用正确,我们都能开发出安全的应用。Ruby on Rails 提供了一些十分智能的辅助方法,例如,用于防止 SQL 注入的辅助方法,极大减少了这一安全风险。

    一般来说,并不存在什么即插即用的安全机制。安全性取决于开发者如何使用框架,有时也取决于开发方式。安全性还取决于 Web 应用环境的各个层面,包括后端存储、Web 服务器和 Web 应用自身等(甚至包括其他 Web 应用)。

    不过,据高德纳咨询公司(Gartner Group)估计,75% 的攻击发生在 Web 应用层面,报告称“在进行了安全审计的 300 个网站中,97% 存在被攻击的风险”。这是因为针对 Web 应用的攻击相对来说更容易实施,其工作原理和具体操作都比较简单,即使是非专业人士也能发起攻击。

    针对 Web 应用的安全威胁包括账户劫持、绕过访问控制、读取或修改敏感数据,以及显示欺诈信息等。有时,攻击者还会安装木马程序或使用垃圾邮件群发软件,以便获取经济利益,或者通过篡改公司资源来损害品牌形象。为了防止这些攻击,最大限度地降低或消除攻击造成的影响,首先我们必须全面了解各种攻击方式,只有这样才能找出正确对策——这正是本文的主要目的。

    为了开发安全的 Web 应用,我们必须从各个层面紧跟安全形势,做到知己知彼。为此,我们可以订阅安全相关的邮件列表,阅读相关博客,同时养成及时更新并定期进行安全检查的习惯(请参阅 其他资源)。这些工作都是手动完成的,只有这样我们才能发现潜在的安全隐患。

    2 会话

    从会话入手来了解安全问题是一个很好的切入点,因为会话对于特定攻击十分脆弱。

    2.1 会话是什么

    HTTP 是无状态协议,会话使其有状态。

    大多数应用需要跟踪特定用户的某些状态,例如购物车里的商品、当前登录用户的 ID 等。如果没有会话,就需要为每一次请求标识用户甚至进行身份验证。当新用户访问应用时,Rails 会自动新建会话,如果用户曾经访问过应用,就会加载已有会话。

    会话通常由值的哈希和会话 ID(通常为 32 个字符的字符串)组成,其中会话 ID 用于标识哈希值。发送到客户端浏览器的每个 cookie 都包含会话 ID,另一方面,客户端浏览器发送到服务器的每个请求也包含会话 ID。在 Rails 中,我们可以使用 session 方法保存和取回值:

     session[:user_id] = @current_user.id
     User.find(session[:user_id])
     
     
    -

    2.2 会话 ID

    会话 ID 是长度为 32 字节的 MD5 散列值。

    会话 ID 由随机字符串的散列值组成。这个随机字符串包含当前时间,一个 0 到 1 之间的随机数,Ruby 解析器的进程 ID(基本上也是一个随机数),以及一个常量字符串。目前 Rails 会话 ID 还无法暴力破解。尽管直接破解 MD5 很难,但存在 MD5 碰撞的可能性,理论上可以创建具有相同散列值的另一个输入文本。不过到目前为止,这个问题还未产生安全影响。

    2.3 会话劫持

    通过窃取用户的会话 ID,攻击者能够以受害者的身份使用 Web 应用。

    很多 Web 应用都有身份验证系统:用户提供用户名和密码,Web 应用在验证后把对应的用户 ID 储存到会话散列中。之后,会话就可以合法使用了。对于每个请求,应用都会通过识别会话中储存的用户 ID 来加载用户,从而避免了重新进行身份验证。Cookie 中的会话 ID 用于标识会话。

    因此,Cookie 提供了 Web 应用的临时身份验证。只要得到了他人的 Cookie,任何人都能以该用户的身份使用 Web 应用,这可能导致严重的后果。下面介绍几种劫持会话的方式及其对策:

    +

    2.2 会话 ID

    会话 ID 是长度为 32 字节的 MD5 哈希值。

    会话 ID 由随机字符串的哈希值组成。这个随机字符串包含当前时间、一个 0 到 1 之间的随机数、Ruby 解析器的进程 ID(基本上也是一个随机数),以及一个常量字符串。目前 Rails 会话 ID 还无法暴力破解。尽管直接破解 MD5 很难,但存在 MD5 碰撞的可能性,理论上可以创建具有相同哈希值的另一个输入文本。不过到目前为止,这个问题还未产生安全影响。

    2.3 会话劫持

    通过窃取用户的会话 ID,攻击者能够以受害者的身份使用 Web 应用。

    很多 Web 应用都有身份验证系统:用户提供用户名和密码,Web 应用在验证后把对应的用户 ID 储存到会话散列中。之后,会话就可以合法使用了。对于每个请求,应用都会通过识别会话中储存的用户 ID 来加载用户,从而避免了重新进行身份验证。cookie 中的会话 ID 用于标识会话。

    因此,cookie 提供了 Web 应用的临时身份验证。只要得到了他人的 cookie,任何人都能以该用户的身份使用 Web 应用,这可能导致严重的后果。下面介绍几种劫持会话的方式及其对策:

      -
    • 在不安全的网络中嗅探 Cookie。无线局域网就是一个例子。在未加密的无线局域网中,监听所有已连接客户端的流量极其容易。因此,Web 应用开发者应该通过 SSL 提供安全连接。在 Rails 3.1 和更高版本中,可以在应用配置文件中设置强制使用 SSL 连接:
    • -
    +
  • +

    在不安全的网络中嗅探 cookie。无线局域网就是一个例子。在未加密的无线局域网中,监听所有已连接客户端的流量极其容易。因此,Web 应用开发者应该通过 SSL 提供安全连接。在 Rails 3.1 和更高版本中,可以在应用配置文件中设置强制使用 SSL 连接:

     config.force_ssl = true
     
     
    - -
      -
    • 大多数人在使用公共终端后不会清除 Cookie。因此,如果最后一个用户没有退出 Web 应用,后续用户就能以该用户的身份继续使用。因此,Web 应用一定要提供“退出”按钮,并且要尽可能显眼。

    • -
    • 很多跨站脚本(XSS)攻击的目标是获取用户 Cookie。更多介绍请参阅跨站脚本攻击一节。

    • -
    • 有的攻击者不窃取 Cookie,而是篡改用户 Cookie 中的会话 ID。这种攻击方式被称为固定会话攻击,后文会详细介绍。

    • + +
    • 大多数人在使用公共终端后不会清除 cookie。因此,如果最后一个用户没有退出 Web 应用,后续用户就能以该用户的身份继续使用。因此,Web 应用一定要提供“退出”按钮,并且要尽可能显眼。

    • +
    • 很多跨站脚本(XSS)攻击的目标是获取用户 cookie。更多介绍请参阅 跨站脚本(XSS)

    • +
    • 有的攻击者不窃取 cookie,而是篡改用户 cookie 中的会话 ID。这种攻击方式被称为固定会话攻击,后文会详细介绍。

    大多数攻击者的主要目标是赚钱。根据赛门铁克《互联网安全威胁报告》,被窃取的银行登录账户的黑市价格从 10 到 1000 美元不等(取决于账户余额),信用卡卡号为 0.40 到 20 美元,在线拍卖网站的账户为 1 到 8 美元,电子邮件账户密码为 4 到 30 美元。

    2.4 会话安全指南

    下面是一些关于会话安全的一般性指南。

      -
    • 不要在会话中储存大型对象,而应该把它们储存在数据库中,并将其 ID 保存在会话中。这么做可以避免同步问题,并且不会导致会话存储空间耗尽(会话存储空间的大小取决于其类型,详见后文)。如果不这么做,当修改了对象结构时,用户 Cookie 中保存的仍然是对象的旧版本。通过在服务器端储存会话,我们可以轻而易举地清除会话,而在客户端储存会话,要想清除会话就很麻烦了。

    • -
    • 关键数据不应该储存在会话中。如果用户清除了 Cookie 或关闭了浏览器,这些关键数据就会丢失。并且在客户端储存会话,还会导致用户能够读取关键数据。

    • +
    • 不要在会话中储存大型对象,而应该把它们储存在数据库中,并将其 ID 保存在会话中。这么做可以避免同步问题,并且不会导致会话存储空间耗尽(会话存储空间的大小取决于其类型,详见后文)。如果不这么做,当修改了对象结构时,用户 cookie 中保存的仍然是对象的旧版本。通过在服务器端储存会话,我们可以轻而易举地清除会话,而在客户端储存会话,要想清除会话就很麻烦了。

    • +
    • 关键数据不应该储存在会话中。如果用户清除了 cookie 或关闭了浏览器,这些关键数据就会丢失。而且,在客户端储存会话,用户还能读取关键数据。

    -

    2.5 会话存储

    Rails 提供了几种会话散列的存储机制。其中最重要的是 ActionDispatch::Session::CookieStore

    Rails 2 引入了一种新的默认会话存储机制——CookieStore。CookieStore 把会话散列直接储存在客户端的 Cookie 中。无需会话 ID,服务器就可以从 Cookie 中取回会话散列。这么做可以显著提高程序的运行速度,但也存在争议,因为这种存储机制具有下列安全隐患:

    +

    2.5 会话存储

    Rails 提供了几种会话散列的存储机制。其中最重要的是 ActionDispatch::Session::CookieStore

    Rails 2 引入了一种新的默认会话存储机制——CookieStore。CookieStore 把会话散列直接储存在客户端的 cookie 中。无需会话 ID,服务器就可以从 cookie 中取回会话散列。这么做可以显著提高应用的运行速度,但也存在争议,因为这种存储机制具有下列安全隐患:

      -
    • Cookie 的大小被严格限制为 4 KB。这个限制本身没问题,因为如前文所述,本来就不应该在会话中储存大量数据。在会话中储存当前用户的数据库 ID 一般没问题。

    • -
    • 客户端可以看到储存在会话中的所有内容,因为数据是以明文形式储存的(实际上是 Base64 编码,因此没有加密)。因此,我们不应该在会话中储存隐私数据。为了防止会话散列被篡改,应该根据服务器端密令(secrets.secret_token)计算会话的摘要(digest),然后把这个摘要添加到 Cookie 的末尾。

    • +
    • cookie 的大小被严格限制为 4 KB。这个限制本身没问题,因为如前文所述,本来就不应该在会话中储存大量数据。在会话中储存当前用户的数据库 ID 一般没问题。

    • +
    • 客户端可以看到储存在会话中的所有内容,因为数据是以明文形式储存的(实际上是 Base64 编码,因此没有加密)。因此,我们不应该在会话中储存隐私数据。为了防止会话散列被篡改,应该根据服务器端密令(secrets.secret_token)计算会话的摘要(digest),然后把这个摘要添加到 cookie 的末尾。

    -

    不过,从 Rails 4 开始,默认存储机制是 EncryptedCookieStore。EncryptedCookieStore 会先对会话进行加密,再储存到 Cookie 中。这么做可以防止用户访问和篡改 Cookie 的内容。因此,会话也成为储存数据的更安全的地方。加密时需要使用 config/secrets.yml 文件中储存的服务器端密钥 secrets.secret_key_base

    这意味着 EncryptedCookieStore 存储机制的安全性由密钥(以及摘要算法,出于兼容性考虑默认为 SHA1 算法)决定。因此,密钥不能随意取值,例如从字典中找一个单词,或少于 30 个字符,应该使用 rails secret 生成密钥。

    secrets.secret_key_base 用于指定密钥,在应用中会话使用这个密钥来验证已知密钥,以防止篡改。在创建应用时,config/secrets.yml 文件中储存的 secrets.secret_key_base 是一个随机密钥,例如:

    +

    不过,从 Rails 4 开始,默认存储机制是 EncryptedCookieStore。EncryptedCookieStore 会先对会话进行加密,再储存到 cookie 中。这么做可以防止用户访问和篡改 cookie 的内容。因此,会话也成为储存数据的更安全的地方。加密时需要使用 config/secrets.yml 文件中储存的服务器端密钥 secrets.secret_key_base

    这意味着 EncryptedCookieStore 存储机制的安全性由密钥(以及摘要算法,出于兼容性考虑默认为 SHA1 算法)决定。因此,密钥不能随意取值,例如从字典中找一个单词,或少于 30 个字符,而应该使用 rails secret 命令生成。

    secrets.secret_key_base 用于指定密钥,在应用中会话使用这个密钥来验证已知密钥,以防被篡改。在创建应用时,config/secrets.yml 文件中储存的 secrets.secret_key_base 是一个随机密钥,例如:

     development:
       secret_key_base: a75d...
    @@ -297,19 +319,19 @@ 

    2.5 会话存储

    2.6 对 CookieStore 会话的重放攻击(replay attack)
  • 重放攻击是使用 CookieStore 时必须注意的另一种攻击方式。

    重放攻击的工作原理如下:

    +

    Rails 老版本中的 CookieStore 使用的是 secret_token,而不是 EncryptedCookieStore 所使用的 secret_key_base。更多介绍请参阅升级文档。

    如果应用的密钥泄露了(例如应用开放了源代码),强烈建议更换密钥。

    2.6 对 CookieStore 会话的重放攻击

    重放攻击(replay attack)是使用 CookieStore 时必须注意的另一种攻击方式。

    重放攻击的工作原理如下:

    • 用户获得的信用额度保存在会话中(信用额度实际上不应该保存在会话中,这里只是出于演示目的才这样做);

    • 用户使用部分信用额度购买商品;

    • 减少后的信用额度仍然保存在会话中;

    • -
    • 用户先前复制了第一步中的 Cookie,并用这个 Cookie 替换浏览器中的当前 Cookie;

    • +
    • 用户先前复制了第一步中的 cookie,并用这个 cookie 替换浏览器中的当前 cookie;

    • 用户重新获得了消费前的信用额度。

    -

    在会话中包含随机数可以防止重放攻击。每个随机数验证一次后就会失效,服务器必须跟踪所有有效的随机数。当有多个应用服务器时,情况会变得更复杂,因为我们不能把随机数储存在数据库中,否则就违背了使用 CookieStore 的初衷(避免访问数据库)。

    因此,防止重放攻击的最佳方案,不是把这类敏感数据储存在会话中,而是把它们储存在数据库中。回到上面的例子,我们可以把信用额度储存在数据库中,而把当前用户的 ID 储存在会话中。

    2.7 会话固定攻击(session fixation)

    除了窃取用户的会话 ID 之外,攻击者还可以直接使用已知的会话 ID。这种攻击方式被称为会话固定攻击。

    session fixation

    会话固定攻击的关键是强制用户的浏览器使用攻击者已知的会话 ID,这样攻击者就无需窃取会话 ID。会话固定攻击的工作原理如下:

    +

    在会话中包含随机数可以防止重放攻击。每个随机数验证一次后就会失效,服务器必须跟踪所有有效的随机数。当有多个应用服务器时,情况会变得更复杂,因为我们不能把随机数储存在数据库中,否则就违背了使用 CookieStore 的初衷(避免访问数据库)。

    因此,防止重放攻击的最佳方案,不是把这类敏感数据储存在会话中,而是把它们储存在数据库中。回到上面的例子,我们可以把信用额度储存在数据库中,而把当前用户的 ID 储存在会话中。

    2.7 会话固定攻击

    除了窃取用户的会话 ID 之外,攻击者还可以直接使用已知的会话 ID。这种攻击方式被称为会话固定(session fixation)攻击。

    session fixation

    会话固定攻击的关键是强制用户的浏览器使用攻击者已知的会话 ID,这样攻击者就无需窃取会话 ID。会话固定攻击的工作原理如下:

    各个中间件的作用参见 内部中间件栈

    其他插件,包括 Active Record,可能会添加额外的中间件。一般来说,这些中间件对要构建的应用类型一无所知,可以在只提供 API 的 Rails 应用中使用。

    可以通过下述命令列出应用中的所有中间件:

    @@ -430,6 +432,7 @@ 

    目录

  • ActionController::Rescue:提供 rescue_from
  • ActionController::Instrumentation:提供 Action Controller 定义的监测钩子(详情参见 Action Controller)。
  • ActionController::ParamsWrapper:把参数散列放到一个嵌套散列中,这样在发送 POST 请求时无需指定根元素。
  • +
  • ActionController::Head:返回只有首部没有内容的响应。
  • 其他插件可能会添加额外的模块。ActionController::API 引入的模块可以在 Rails 控制台中列出:

    diff --git a/contributing_to_ruby_on_rails.html b/contributing_to_ruby_on_rails.html
    index 2165014..a5109e1 100644
    --- a/contributing_to_ruby_on_rails.html
    +++ b/contributing_to_ruby_on_rails.html
    @@ -279,8 +279,7 @@ 

    目录

    如果你的评论只是说“+1”,其他评审很难严肃对待。你要表明你花时间审查拉取请求了。

    3 为 Rails 文档做贡献

    Ruby on Rails 主要有两份文档:这份指南,帮你学习 Ruby on Rails;API,作为参考资料。

    你可以帮助改进这份 Rails 指南,把它变得更简单、更为一致,也更易于理解。你可以添加缺少的信息、更正错误、修正错别字或者针对最新的 Rails 开发版做更新。

    为此,可以向 Rails 项目发送拉取请求。

    如果你想为文档做贡献,请阅读API 文档指导方针Ruby on Rails 指南指导方针

    为了减轻 CI 服务器的压力,关于文档的提交消息中应该包含 [ci skip],跳过构建步骤。只修改文档的提交一定要这么做。

    4 翻译 Rails 指南

    我们欢迎人们自发把 Rails 指南翻译成其他语言。翻译时请遵照下述步骤:

      -
    • 派生项目 https://github.com/rails/rails -
    • +
    • 派生 https://github.com/rails/rails 项目
    • 为你的语言添加一个文件夹,例如针对意大利语的 guides/source/it-IT
    • 把 guides/source 中的内容复制到你创建的文件夹中,然后翻译
    • 不要翻译 HTML 文件,因为那是自动生成的
    • diff --git a/getting_started.html b/getting_started.html index b9cbb3d..40d6aef 100644 --- a/getting_started.html +++ b/getting_started.html @@ -1129,7 +1129,7 @@

      目录

    -

    在上面的代码中,link_to 辅助方法生成“Destroy”链接的用法有点不同,其中第二个参数是具名路由(named route),还有一些选项作为其他参数。method: :deletedata: { confirm: 'Are you sure?' } 选项用于设置链接的 HTML5 属性,这样点击链接后 Rails 会先向用户显示一个确认对话框,然后用 delete 方法发起请求。这些操作是通过 JavaScript 脚本 jquery_ujs 实现的,这个脚本在生成应用骨架时已经被自动包含在了应用的布局中(app/views/layouts/application.html.erb)。如果没有这个脚本,确认对话框就无法显示。

    确认对话框

    关于 jQuery 非侵入式适配器(jQuery UJS)的更多介绍,请参阅在 Rails 中使用 JavaScript

    恭喜你!现在你已经可以创建、显示、列出、更新和删除文章了!

    通常 Rails 鼓励用资源对象来代替手动声明路由。关于路由的更多介绍,请参阅Rails 路由全解

    6 添加第二个模型

    现在是为应用添加第二个模型的时候了。这个模型用于处理文章评论。

    6.1 生成模型

    接下来将要使用的生成器,和之前用于创建 Article 模型的一样。这次我们要创建 Comment 模型,用于保存文章评论。在终端中执行下面的命令:

    +

    在上面的代码中,link_to 辅助方法生成“Destroy”链接的用法有点不同,其中第二个参数是具名路由(named route),还有一些选项作为其他参数。method: :deletedata: { confirm: 'Are you sure?' } 选项用于设置链接的 HTML5 属性,这样点击链接后 Rails 会先向用户显示一个确认对话框,然后用 delete 方法发起请求。这些操作是通过 JavaScript 脚本 rails-ujs 实现的,这个脚本在生成应用骨架时已经被自动包含在了应用的布局中(app/views/layouts/application.html.erb)。如果没有这个脚本,确认对话框就无法显示。

    确认对话框

    关于非侵入式 JavaScript 的更多介绍,请参阅在 Rails 中使用 JavaScript

    恭喜你!现在你已经可以创建、显示、列出、更新和删除文章了!

    通常 Rails 鼓励用资源对象来代替手动声明路由。关于路由的更多介绍,请参阅Rails 路由全解

    6 添加第二个模型

    现在是为应用添加第二个模型的时候了。这个模型用于处理文章评论。

    6.1 生成模型

    接下来将要使用的生成器,和之前用于创建 Article 模型的一样。这次我们要创建 Comment 模型,用于保存文章评论。在终端中执行下面的命令:

     $ bin/rails generate model Comment commenter:string body:text article:references
     
    diff --git a/rails_on_rack.html b/rails_on_rack.html
    index c6dccf1..8448f63 100644
    --- a/rails_on_rack.html
    +++ b/rails_on_rack.html
    @@ -285,6 +285,8 @@ 

    目录

    use Rack::Runtime use Rack::MethodOverride use ActionDispatch::RequestId +use ActionDispatch::RemoteIp +use Sprockets::Rails::QuietAssets use Rails::Rack::Logger use ActionDispatch::ShowExceptions use WebConsole::Middleware @@ -299,7 +301,7 @@

    目录

    use Rack::Head use Rack::ConditionalGet use Rack::ETag -run Rails.application.routes +run MyApp.application.routes
    @@ -365,7 +367,7 @@

    目录

    -

    3.3 内部中间件栈

    Action Controller 的大部分功能都实现成中间件。下面概述它们的作用。

    Rack::Sendfile

    在服务器端设定 X-Sendfile 首部。通过 config.action_dispatch.x_sendfile_header 选项配置。

    ActionDispatch::Static

    用于伺服 public 目录中的静态文件。如果把 config.public_file_server.enabled 设为 false,禁用这个中间件。

    Rack::Lock

    env["rack.multithread"] 设为 false,把应用包装到 Mutex 中。

    ActionDispatch::Executor

    用于在开发环境中以线程安全方式重新加载代码。

    ActiveSupport::Cache::Strategy::LocalCache::Middleware

    用于缓存内存。这个缓存对线程不安全。

    Rack::Runtime

    设定 X-Runtime 首部,包含执行请求的用时(单位为秒)。

    Rack::MethodOverride

    如果设定了 params[:_method],允许覆盖请求方法。PUTDELETE 两个 HTTP 方法就是通过这个中间件提供支持的。

    ActionDispatch::RequestId

    在响应中设定唯一的 X-Request-Id 首部,并启用 ActionDispatch::Request#request_id 方法。

    Rails::Rack::Logger

    通知日志,请求开始了。请求完毕后,清空所有相关日志。

    ActionDispatch::ShowExceptions

    拯救应用返回的所有异常,调用处理异常的应用,把异常包装成对终端用户友好的格式。

    ActionDispatch::DebugExceptions

    如果是本地请求,负责在日志中记录异常,并显示调试页面。

    ActionDispatch::RemoteIp

    检查 IP 欺骗攻击。

    ActionDispatch::Reloader

    提供准备和清理回调,目的是在开发环境中协助重新加载代码。

    ActionDispatch::Callbacks

    提供回调,在分派请求前后执行。

    ActiveRecord::Migration::CheckPending

    检查有没有待运行的迁移,如果有,抛出 ActiveRecord::PendingMigrationError

    ActionDispatch::Cookies

    为请求设定 cookie。

    ActionDispatch::Session::CookieStore

    负责把会话存储在 cookie 中。

    ActionDispatch::Flash

    设置闪现消息的键。仅当为 config.action_controller.session_store 设定值时才启用。

    Rack::Head

    把 HEAD 请求转换成 GET 请求,然后伺服 GET 请求。

    Rack::ConditionalGet

    支持“条件 GET 请求”,如果页面没变,服务器不做响应。

    Rack::ETag

    为所有字符串主体添加 ETag 首部。ETag 用于验证缓存。

    在自定义的 Rack 栈中可以使用上述任何一个中间件。

    4 资源

    4.1 学习 Rack

    +

    3.3 内部中间件栈

    Action Controller 的大部分功能都实现成中间件。下面概述它们的作用。

    Rack::Sendfile

    在服务器端设定 X-Sendfile 首部。通过 config.action_dispatch.x_sendfile_header 选项配置。

    ActionDispatch::Static

    用于伺服 public 目录中的静态文件。如果把 config.public_file_server.enabled 设为 false,禁用这个中间件。

    Rack::Lock

    env["rack.multithread"] 设为 false,把应用包装到 Mutex 中。

    ActionDispatch::Executor

    用于在开发环境中以线程安全方式重新加载代码。

    ActiveSupport::Cache::Strategy::LocalCache::Middleware

    用于缓存内存。这个缓存对线程不安全。

    Rack::Runtime

    设定 X-Runtime 首部,包含执行请求的用时(单位为秒)。

    Rack::MethodOverride

    如果设定了 params[:_method],允许覆盖请求方法。PUTDELETE 两个 HTTP 方法就是通过这个中间件提供支持的。

    ActionDispatch::RequestId

    在响应中设定唯一的 X-Request-Id 首部,并启用 ActionDispatch::Request#request_id 方法。

    ActionDispatch::RemoteIp

    检查 IP 欺骗攻击。

    Sprockets::Rails::QuietAssets:在日志中输出对静态资源的请求。

    Rails::Rack::Logger

    通知日志,请求开始了。请求完毕后,清空所有相关日志。

    ActionDispatch::ShowExceptions

    拯救应用返回的所有异常,调用处理异常的应用,把异常包装成对终端用户友好的格式。

    ActionDispatch::DebugExceptions

    如果是本地请求,负责在日志中记录异常,并显示调试页面。

    ActionDispatch::Reloader

    提供准备和清理回调,目的是在开发环境中协助重新加载代码。

    ActionDispatch::Callbacks

    提供回调,在分派请求前后执行。

    ActiveRecord::Migration::CheckPending

    检查有没有待运行的迁移,如果有,抛出 ActiveRecord::PendingMigrationError

    ActionDispatch::Cookies

    为请求设定 cookie。

    ActionDispatch::Session::CookieStore

    负责把会话存储在 cookie 中。

    ActionDispatch::Flash

    设置闪现消息的键。仅当为 config.action_controller.session_store 设定值时才启用。

    Rack::Head

    把 HEAD 请求转换成 GET 请求,然后伺服 GET 请求。

    Rack::ConditionalGet

    支持“条件 GET 请求”,如果页面没变,服务器不做响应。

    Rack::ETag

    为所有字符串主体添加 ETag 首部。ETag 用于验证缓存。

    在自定义的 Rack 栈中可以使用上述任何一个中间件。

    4 资源

    4.1 学习 Rack

    • Rack 官方网站
    • diff --git a/security.html b/security.html index e297966..82ae96b 100644 --- a/security.html +++ b/security.html @@ -698,7 +698,7 @@

      目录

      -

      该蠕虫利用了雅虎 HTML/JavaScript 过滤器的漏洞,这个过滤器用于过滤 HTML 标签中的所有 targetonload 属性(原因是这两个属性的值可以是 JavaScript)。因为这个过滤器只会执行一次,上述例子中 onload 属性中的蠕虫代码并没有被过滤掉。这个例子很好地诠释了黑名单永远做不到万无一失,也说明了 Web 应用为什么通常都会禁止输入 HTML/JavaScript。

      另一个用于概念验证的网页邮箱蠕虫是 Ndjua,这是一个针对四个意大利网页邮箱服务的跨域名蠕虫。更多介绍请阅读 Rosario Valotta 的论文。刚刚介绍的这两个蠕虫,其目的都是为了搜集电子邮件地址,一些从事网络犯罪的黑客可以利用这些邮件地址获取非法收益。

      2006 年 12 月,在一次针对 MySpace 的钓鱼攻击中,黑客窃取了 34,000 个真实用户名和密码。这次攻击的原理是,创建名为“login_home_index_html”的个人信息页面,并使其 URL 地址看起来十分正常,同时通过精心设计的 HTML 和 CSS,隐藏 MySpace 的真正内容,并显示攻击者创建的登录表单。

      7.4 CSS 注入

      CSS 注入实际上是 JavaScript 注入,因为有的浏览器(如 IE、某些版本的 Safari 和其他浏览器)允许在 CSS 中使用 JavaScript。因此,在允许 Web 应用使用自定义 CSS 时,请三思而后行。

      著名的 MySpace Samy 蠕虫是解释 CSS 注入攻击原理的最好例子。这个蠕虫只需访问用户的个人信息页面就能向 Samy(攻击者)发送好友请求。在短短几个小时内,Samy 就收到了超过一百万个好友请求,巨大的流量致使 MySpace 宕机。下面我们从技术角度来分析这个蠕虫。

      MySpace 禁用了很多标签,但允许使用 CSS。因此,蠕虫的作者通过下面这种方式把 JavaScript 值入 CSS 中:

      +

      该蠕虫利用了雅虎 HTML/JavaScript 过滤器的漏洞,这个过滤器用于过滤 HTML 标签中的所有 targetonload 属性(原因是这两个属性的值可以是 JavaScript)。因为这个过滤器只会执行一次,上述例子中 onload 属性中的蠕虫代码并没有被过滤掉。这个例子很好地诠释了黑名单永远做不到万无一失,也说明了 Web 应用为什么通常都会禁止输入 HTML/JavaScript。

      另一个用于概念验证的网页邮箱蠕虫是 Ndjua,这是一个针对四个意大利网页邮箱服务的跨域名蠕虫。更多介绍请阅读 Rosario Valotta 的论文。刚刚介绍的这两个蠕虫,其目的都是为了搜集电子邮件地址,一些从事网络犯罪的黑客可以利用这些邮件地址获取非法收益。

      2006 年 12 月,在一次针对 MySpace 的钓鱼攻击中,黑客窃取了 34,000 个真实用户名和密码。这次攻击的原理是,创建名为“login_home_index_html”的个人信息页面,并使其 URL 地址看起来十分正常,同时通过精心设计的 HTML 和 CSS,隐藏 MySpace 的真正内容,并显示攻击者创建的登录表单。

      7.4 CSS 注入

      CSS 注入实际上是 JavaScript 注入,因为有的浏览器(如 IE、某些版本的 Safari 和其他浏览器)允许在 CSS 中使用 JavaScript。因此,在允许 Web 应用使用自定义 CSS 时,请三思而后行。

      著名的 MySpace Samy 蠕虫是解释 CSS 注入攻击原理的最好例子。这个蠕虫只需访问用户的个人信息页面就能向 Samy(攻击者)发送好友请求。在短短几个小时内,Samy 就收到了超过一百万个好友请求,巨大的流量致使 MySpace 宕机。下面我们从技术角度来分析这个蠕虫。

      MySpace 禁用了很多标签,但允许使用 CSS。因此,蠕虫的作者通过下面这种方式把 JavaScript 植入 CSS 中:

       <div style="background:url('/service/javascript:alert(1)')">
       
      diff --git a/testing.html b/testing.html
      index 967f20e..df1b53c 100644
      --- a/testing.html
      +++ b/testing.html
      @@ -809,11 +809,11 @@ 

      目录

      -

      模型测试没有专门的超类(如 ActionMailer::TestCase),而是继承自 ActiveSupport::TestCase

      5 系统测试

      系统测试是完整的浏览器测试,可用于测试应用的 JavaScript 和用户体验。系统测试建立在 Capybara 之上。

      系统测试可以在真实的浏览器中运行,也可以在无界面驱动中运行,用于测试用户与应用的交互。

      系统测试存放在应用的 test/system 目录中。Rails 为创建系统测试骨架提供了一个生成器:

      +

      模型测试没有专门的超类(如 ActionMailer::TestCase),而是继承自 ActiveSupport::TestCase

      5 系统测试

      系统测试用于测试用户与应用的交互,可以在真正的浏览器中运行,也可以在无界面浏览器中运行。系统测试建立在 Capybara 之上。

      系统测试存放在应用的 test/system 目录中。Rails 为创建系统测试骨架提供了一个生成器:

      -$ bin/rails generate system_test users_create
      +$ bin/rails generate system_test users
             invoke test_unit
      -      create test/system/users_creates_test.rb
      +      create test/system/users_test.rb
       
       
      @@ -821,11 +821,11 @@

      目录

       require "application_system_test_case"
       
      -class UsersCreatesTest < ApplicationSystemTestCase
      +class UsersTest < ApplicationSystemTestCase
         # test "visiting the index" do
      -  #   visit users_creates_url
      +  #   visit users_url
         #
      -  #   assert_selector "h1", text: "UsersCreate"
      +  #   assert_selector "h1", text: "Users"
         # end
       end
       
      @@ -842,7 +842,7 @@ 

      目录

      -

      驱动名称是 driven_by 必须的参数。driven_by 接受的可选参数有::using,指定使用的浏览器(仅供有界面的驱动使用,如 Selenium);:screen_size,修改截图的尺寸。

      +

      驱动名称是 driven_by 必须的参数。driven_by 接受的可选参数有::using,指定使用的浏览器(仅供 Selenium 使用);:screen_size,修改截图的尺寸;:options,设定驱动支持的选项。

       require "test_helper"
       
      @@ -852,7 +852,7 @@ 

      目录

      -

      如果所需的 Capybara 配置 Rails 提供的多,可以把所有配置都放在 application_system_test_case.rb 文件中。

      其他设置参见 Capybara 的文档

      5.2 截图辅助方法

      ScreenshotHelper 用于截取测试的截图。这有助于查看测试失败时的界面,或者以后通过截图调试。

      这个模块提供了两个方法:take_screenshottake_failed_screenshot。Rails 在 after_teardown 中调用了 take_failed_screenshot

      take_screenshot 辅助方法可以放在测试的任何位置,用于捕获浏览器的截图。

      5.3 编写系统测试

      下面我们为前面开发的博客应用添加一个系统测试。这个系统测试访问首页,然后新建一篇博客文章。

      如果使用的是脚手架生成器,已经自动创建了系统测试骨架。否则,先生成系统测试骨架:

      +

      如果所需的 Capybara 配置比 Rails 提供的多,可以把额外配置放在 application_system_test_case.rb 文件中。

      其他设置参见 Capybara 的文档

      5.2 截图辅助方法

      ScreenshotHelper 用于截取测试的截图。这有助于查看测试失败时的界面,或者以后通过截图调试。

      这个模块提供了两个方法:take_screenshottake_failed_screenshot。Rails 在 after_teardown 中调用了 take_failed_screenshot

      take_screenshot 辅助方法可以放在测试的任何位置,用于捕获浏览器的截图。

      5.3 编写系统测试

      下面我们为前面开发的博客应用添加一个系统测试。这个系统测试访问首页,然后新建一篇博客文章。

      如果使用的是脚手架生成器,已经自动创建了系统测试骨架。否则,先生成系统测试骨架:

       $ bin/rails generate system_test articles