From f2f318a39f9fca5d5bc3478cd616cbe5a2cce341 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 19 Apr 2021 09:56:14 +0900 Subject: [PATCH 01/42] Create collections ref. https://jekyllrb.com/docs/step-by-step/09-collections/ --- _config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_config.yml b/_config.yml index 8c73ed8251..38706f07f6 100644 --- a/_config.yml +++ b/_config.yml @@ -3,6 +3,8 @@ description: Ruby on Rails API Documentation. url: https://railsdoc.github.io source: src target_rails_version: 5.2.5 +collections: + - 6.0.3 plugins: - jekyll-include-cache - jekyll-redirect-from From d05181e3ae643c10302c2b015110a2ce6d984cf4 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 26 Apr 2021 00:39:31 +0900 Subject: [PATCH 02/42] Define collections --- _config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 38706f07f6..25debce519 100644 --- a/_config.yml +++ b/_config.yml @@ -4,7 +4,8 @@ url: https://railsdoc.github.io source: src target_rails_version: 5.2.5 collections: - - 6.0.3 + - 6.0 + - 5.2 plugins: - jekyll-include-cache - jekyll-redirect-from From 313ef55dbbf5be0401684dde3a0c68464b967ece Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 26 Apr 2021 00:39:42 +0900 Subject: [PATCH 03/42] Create mkdir rake task --- Rakefile | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index a19a0ab5b0..9f1bdad882 100644 --- a/Rakefile +++ b/Rakefile @@ -20,12 +20,19 @@ task :build do end task :switch_rails do - require 'yaml' - - config = YAML.load_file('./_config.yml') target_rails_version = config["target_rails_version"] - cd 'rails' do sh "git switch v#{target_rails_version} -c v#{target_rails_version}" end end + +task :mkdir do + config["collections"].each do |version| + mkdir version.to_s + end +end + +def config + require 'yaml' + YAML.load_file('./_config.yml') +end From f2eb681f24d4083fbaff2b8b57e37a58e991526b Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 04:04:26 +0900 Subject: [PATCH 04/42] Add: switch_rails method --- Rakefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index 9f1bdad882..81c61ef775 100644 --- a/Rakefile +++ b/Rakefile @@ -21,9 +21,7 @@ end task :switch_rails do target_rails_version = config["target_rails_version"] - cd 'rails' do - sh "git switch v#{target_rails_version} -c v#{target_rails_version}" - end + switch_rails(target_rails_version) end task :mkdir do @@ -36,3 +34,9 @@ def config require 'yaml' YAML.load_file('./_config.yml') end + +def switch_rails(version) + cd 'rails' do + sh "git switch v#{version} -C v#{version}" + end +end From 48722cf7c00dca12f7ba406a1bcdaf9bca701f1f Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 04:56:21 +0900 Subject: [PATCH 05/42] Define specific_version under version --- _config.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/_config.yml b/_config.yml index 25debce519..996f004804 100644 --- a/_config.yml +++ b/_config.yml @@ -4,8 +4,10 @@ url: https://railsdoc.github.io source: src target_rails_version: 5.2.5 collections: - - 6.0 - - 5.2 + - 6.0: + specific_version: "6.0.3" + - 5.2: + specific_version: "5.2.5" plugins: - jekyll-include-cache - jekyll-redirect-from From 7af781a3c8df91888cd5f7f06ed92a2b332fd8f8 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 04:56:45 +0900 Subject: [PATCH 06/42] Enhance switch_rails --- Rakefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 81c61ef775..f379a4944c 100644 --- a/Rakefile +++ b/Rakefile @@ -37,6 +37,7 @@ end def switch_rails(version) cd 'rails' do - sh "git switch v#{version} -C v#{version}" + sh "git reset --hard" + sh "git switch refs/tags/v#{version} -C v#{version}" end end From 6d8a637c22bf641ccb5dcdbc7f932e4ef73d0313 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 04:56:53 +0900 Subject: [PATCH 07/42] mkdir && switch_rails --- Rakefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index f379a4944c..425b32747b 100644 --- a/Rakefile +++ b/Rakefile @@ -25,8 +25,9 @@ task :switch_rails do end task :mkdir do - config["collections"].each do |version| - mkdir version.to_s + config["collections"].map(&:first).each do |version, detail| + mkdir version.to_s unless Dir.exist?(version.to_s) + switch_rails(detail["specific_version"]) end end From 251f8c7768a598e2ccf938c3c4e505e7758bd470 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 16:13:51 +0900 Subject: [PATCH 08/42] Update submodule: v6.0.3 --- rails | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rails b/rails index cb0a558f42..b738f1930f 160000 --- a/rails +++ b/rails @@ -1 +1 @@ -Subproject commit cb0a558f42fc6957fac4d2daa16771b72ff7da6e +Subproject commit b738f1930f3c82f51741ef7241c1fee691d7deb2 From 9536519cd5ea88f7394c7052b1a267822c55abda Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 16:13:58 +0900 Subject: [PATCH 09/42] Set frozen_string_literal --- Rakefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Rakefile b/Rakefile index 425b32747b..17069b0306 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + task :build do cd 'rails' do Bundler.with_unbundled_env do From 6687c24043c1a4e809cf231426623b580f9a3fc3 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 16:18:22 +0900 Subject: [PATCH 10/42] Change collection config format ref. https://jekyllrb.com/docs/step-by-step/09-collections/ --- _config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_config.yml b/_config.yml index 996f004804..dbc26c3137 100644 --- a/_config.yml +++ b/_config.yml @@ -4,10 +4,10 @@ url: https://railsdoc.github.io source: src target_rails_version: 5.2.5 collections: - - 6.0: - specific_version: "6.0.3" - - 5.2: - specific_version: "5.2.5" + 6.0: + specific_version: "6.0.3" + 5.2: + specific_version: "5.2.5" plugins: - jekyll-include-cache - jekyll-redirect-from From fc51f7480241f7ff4f3b672ca897e0fc13e93a2f Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 16:18:38 +0900 Subject: [PATCH 11/42] Use just each --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 17069b0306..11919eaa7a 100644 --- a/Rakefile +++ b/Rakefile @@ -27,7 +27,7 @@ task :switch_rails do end task :mkdir do - config["collections"].map(&:first).each do |version, detail| + config["collections"].each do |version, detail| mkdir version.to_s unless Dir.exist?(version.to_s) switch_rails(detail["specific_version"]) end From 95bdd73787d139efa0876884d579fa838310f8b1 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 16:41:12 +0900 Subject: [PATCH 12/42] Float to String ``` jekyll/collection.rb:163:in `sanitize_label': undefined method `gsub' for 6.0:Float (NoMethodError) ``` --- _config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_config.yml b/_config.yml index dbc26c3137..f969b4c522 100644 --- a/_config.yml +++ b/_config.yml @@ -4,9 +4,9 @@ url: https://railsdoc.github.io source: src target_rails_version: 5.2.5 collections: - 6.0: + "6.0": specific_version: "6.0.3" - 5.2: + "5.2": specific_version: "5.2.5" plugins: - jekyll-include-cache From 5d9f1aa6d6e7c67989768f1ee4b4a58bf91e688c Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 16:51:07 +0900 Subject: [PATCH 13/42] Create version directory inside src --- Rakefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index 11919eaa7a..27de6f76bf 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,7 @@ # frozen_string_literal: true +SOURCE_DIR = "src" + task :build do cd 'rails' do Bundler.with_unbundled_env do @@ -11,9 +13,9 @@ task :build do end copy_sources = Dir.glob('rails/doc/rdoc/*').reject { |path| path.end_with?("panel", "js", "created.rid") } - cp_r copy_sources, 'src/' + cp_r copy_sources, "#{SOURCE_DIR}/" - cd 'src' do + cd SOURCE_DIR do cp 'files/railties/RDOC_MAIN_rdoc.html', 'index.html' mv 'navigation.html', '_includes/navigation.html', force: true end @@ -28,7 +30,8 @@ end task :mkdir do config["collections"].each do |version, detail| - mkdir version.to_s unless Dir.exist?(version.to_s) + dir = "#{SOURCE_DIR}/#{version}" + mkdir dir unless Dir.exist?(dir) switch_rails(detail["specific_version"]) end end From a39ae06df16ec83e6eb8a32f22d45f0d50bdfce5 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 17:08:00 +0900 Subject: [PATCH 14/42] Add: generate_rails_rdoc, generate_src --- Rakefile | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Rakefile b/Rakefile index 27de6f76bf..3e087b8860 100644 --- a/Rakefile +++ b/Rakefile @@ -3,22 +3,8 @@ SOURCE_DIR = "src" task :build do - cd 'rails' do - Bundler.with_unbundled_env do - sh %(sed -i '' -e 's/sdoc.*$/sdoc", github: "toshimaru\\/sdoc", branch: "railsdoc"/g' ./Gemfile) - sh 'bundle install && bundle update sdoc' - rm_rf 'doc' - sh 'bundle exec rake rdoc' - end - end - - copy_sources = Dir.glob('rails/doc/rdoc/*').reject { |path| path.end_with?("panel", "js", "created.rid") } - cp_r copy_sources, "#{SOURCE_DIR}/" - - cd SOURCE_DIR do - cp 'files/railties/RDOC_MAIN_rdoc.html', 'index.html' - mv 'navigation.html', '_includes/navigation.html', force: true - end + generate_rails_rdoc + generate_src sh 'bundle exec jekyll build' end @@ -47,3 +33,24 @@ def switch_rails(version) sh "git switch refs/tags/v#{version} -C v#{version}" end end + +def generate_rails_rdoc + cd 'rails' do + Bundler.with_unbundled_env do + sh %(sed -i '' -e 's/sdoc.*$/sdoc", github: "toshimaru\\/sdoc", branch: "railsdoc"/g' ./Gemfile) + sh 'bundle install && bundle update sdoc' + rm_rf 'doc' + sh 'bundle exec rake rdoc' + end + end +end + +def generate_src + copy_sources = Dir.glob('rails/doc/rdoc/*').reject { |path| path.end_with?("panel", "js", "created.rid") } + cp_r copy_sources, "#{SOURCE_DIR}/" + + cd SOURCE_DIR do + cp 'files/railties/RDOC_MAIN_rdoc.html', 'index.html' + mv 'navigation.html', '_includes/navigation.html', force: true + end +end From e2281a54dd8309e13b8a2e6d0ba4b2e738d3b538 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 17:19:20 +0900 Subject: [PATCH 15/42] Add target_version to generate_src --- Rakefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index 3e087b8860..e49c152f0a 100644 --- a/Rakefile +++ b/Rakefile @@ -45,11 +45,12 @@ def generate_rails_rdoc end end -def generate_src +def generate_src(target_version: '') copy_sources = Dir.glob('rails/doc/rdoc/*').reject { |path| path.end_with?("panel", "js", "created.rid") } - cp_r copy_sources, "#{SOURCE_DIR}/" + target_dir = "#{SOURCE_DIR}/#{target_version}" + cp_r copy_sources, target_dir - cd SOURCE_DIR do + cd target_dir do cp 'files/railties/RDOC_MAIN_rdoc.html', 'index.html' mv 'navigation.html', '_includes/navigation.html', force: true end From 99f1ce75400e3f68c6b76398b8fd4353bb4e6573 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 17:56:28 +0900 Subject: [PATCH 16/42] Define INDEX_HTML --- Rakefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index e49c152f0a..432f8df805 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,7 @@ # frozen_string_literal: true SOURCE_DIR = "src" +INDEX_HTML = 'files/railties/RDOC_MAIN_rdoc.html' task :build do generate_rails_rdoc @@ -45,13 +46,13 @@ def generate_rails_rdoc end end -def generate_src(target_version: '') +def generate_src(target_version: nil) copy_sources = Dir.glob('rails/doc/rdoc/*').reject { |path| path.end_with?("panel", "js", "created.rid") } target_dir = "#{SOURCE_DIR}/#{target_version}" cp_r copy_sources, target_dir cd target_dir do - cp 'files/railties/RDOC_MAIN_rdoc.html', 'index.html' + cp INDEX_HTML, 'index.html' mv 'navigation.html', '_includes/navigation.html', force: true end end From be9cf8c9764fccd2d3fa6696f1e0264a5a0ff848 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Mon, 3 May 2021 18:10:26 +0900 Subject: [PATCH 17/42] mv navigation.html --- Rakefile | 7 +- src/5.2/index.html | 123 ++++++++++++++++++++++++++++++ src/_includes/navigation_5.2.html | 1 + 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 src/5.2/index.html create mode 100644 src/_includes/navigation_5.2.html diff --git a/Rakefile b/Rakefile index 432f8df805..639dfc20fa 100644 --- a/Rakefile +++ b/Rakefile @@ -53,6 +53,11 @@ def generate_src(target_version: nil) cd target_dir do cp INDEX_HTML, 'index.html' - mv 'navigation.html', '_includes/navigation.html', force: true + + if target_version.nil? + mv 'navigation.html', '_includes/navigation.html', force: true + else + mv 'navigation.html', "../_includes/navigation_#{target_version}.html", force: true + end end end diff --git a/src/5.2/index.html b/src/5.2/index.html new file mode 100644 index 0000000000..8a3399f93e --- /dev/null +++ b/src/5.2/index.html @@ -0,0 +1,123 @@ +--- +title: RDOC_MAIN.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Welcome to Rails

+ +

Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.

+ +

Understanding the MVC pattern is key to understanding Rails. MVC divides your application into three layers, each with a specific responsibility.

+ +

The Model layer represents your domain model (such as Account, Product, Person, Post, etc.) and encapsulates the business logic that is specific to your application. In Rails, database-backed model classes are derived from ActiveRecord::Base. Active Record allows you to present the data from database rows as objects and embellish these data objects with business logic methods. You can read more about Active Record in its README. Although most Rails models are backed by a database, models can also be ordinary Ruby classes, or Ruby classes that implement a set of interfaces as provided by the Active Model module. You can read more about Active Model in its README.

+ +

The Controller layer is responsible for handling incoming HTTP requests and providing a suitable response. Usually this means returning HTML, but Rails controllers can also generate XML, JSON, PDFs, mobile-specific views, and more. Controllers load and manipulate models, and render view templates in order to generate the appropriate HTTP response. In Rails, incoming requests are routed by Action Dispatch to an appropriate controller, and controller classes are derived from ActionController::Base. Action Dispatch and Action Controller are bundled together in Action Pack. You can read more about Action Pack in its README.

+ +

The View layer is composed of “templates” that are responsible for providing appropriate representations of your application's resources. Templates can come in a variety of formats, but most view templates are HTML with embedded Ruby code (ERB files). Views are typically rendered to generate a controller response, or to generate the body of an email. In Rails, View generation is handled by Action View. You can read more about Action View in its README.

+ +

Active Record, Active Model, Action Pack, and Action View can each be used independently outside Rails. In addition to that, Rails also comes with Action Mailer (README), a library to generate and send emails; Active Job (README), a framework for declaring jobs and making them run on a variety of queueing backends; Action Cable (README), a framework to integrate WebSockets with a Rails application; Active Storage (README), a library to attach cloud and local files to Rails applications; and Active Support (README), a collection of utility classes and standard library extensions that are useful for Rails, and may also be used independently outside Rails.

+ +

Getting Started

+
  1. +

    Install Rails at the command prompt if you haven't yet:

    + +
    $ gem install rails
    +
    +
  2. +

    At the command prompt, create a new Rails application:

    + +
    $ rails new myapp
    +
    + +

    where “myapp” is the application name.

    +
  3. +

    Change directory to myapp and start the web server:

    + +
    $ cd myapp
    +$ rails server
    +
    + +

    Run with --help or -h for options.

    +
  4. +

    Go to http://localhost:3000 and you'll see: “Yay! You’re on Rails!”

    +
  5. +

    Follow the guidelines to start developing your application. You may find the following resources handy:

    + +
+ +

Contributing

+ +

We encourage you to contribute to Ruby on Rails! Please check out the Contributing to Ruby on Rails guide for guidelines about how to proceed. Join us!

+ +

Trying to report a possible security vulnerability in Rails? Please check out our security policy for guidelines about how to proceed.

+ +

Everyone interacting in Rails and its sub-projects' codebases, issue trackers, chat rooms, and mailing lists is expected to follow the Rails code of conduct.

+ +

License

+ +

Ruby on Rails is released under the MIT License.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/_includes/navigation_5.2.html b/src/_includes/navigation_5.2.html new file mode 100644 index 0000000000..1289db0c60 --- /dev/null +++ b/src/_includes/navigation_5.2.html @@ -0,0 +1 @@ + \ No newline at end of file From 5f413b1ea2cfbb6fa70960257cc6200c894ff2a7 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Tue, 4 May 2021 12:52:38 +0900 Subject: [PATCH 18/42] =?UTF-8?q?collections=E2=86=92rails=5Fversions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index f969b4c522..5c2bfda5b9 100644 --- a/_config.yml +++ b/_config.yml @@ -3,7 +3,7 @@ description: Ruby on Rails API Documentation. url: https://railsdoc.github.io source: src target_rails_version: 5.2.5 -collections: +rails_versions: "6.0": specific_version: "6.0.3" "5.2": From 62d7516c0a75d475945a9efbe3f21443e958d768 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 11:17:08 +0900 Subject: [PATCH 19/42] main: Rails v6, sub: Rails v5 --- _config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_config.yml b/_config.yml index 5c2bfda5b9..cc81e3fa56 100644 --- a/_config.yml +++ b/_config.yml @@ -2,10 +2,10 @@ title: RailsDoc(β) description: Ruby on Rails API Documentation. url: https://railsdoc.github.io source: src -target_rails_version: 5.2.5 +target_rails_version: 6.0.3 rails_versions: - "6.0": - specific_version: "6.0.3" + # "6.0": + # specific_version: "6.0.3" "5.2": specific_version: "5.2.5" plugins: From 9628143f7a064eb07a8f2130bf0272ebdfe279c2 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 11:17:53 +0900 Subject: [PATCH 20/42] Create build_multi task --- Rakefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index 639dfc20fa..6b3653ae27 100644 --- a/Rakefile +++ b/Rakefile @@ -15,11 +15,15 @@ task :switch_rails do switch_rails(target_rails_version) end -task :mkdir do - config["collections"].each do |version, detail| +task :build_multi do + config["rails_versions"].each do |version, detail| dir = "#{SOURCE_DIR}/#{version}" mkdir dir unless Dir.exist?(dir) - switch_rails(detail["specific_version"]) + + bulid_version = detail["specific_version"] + switch_rails(bulid_version) + generate_rails_rdoc + generate_src(target_version: version) end end From 4b995621f5ad11784852e90ca080c47b54345141 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 11:50:48 +0900 Subject: [PATCH 21/42] Set scope for Rails 5.2 path --- _config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_config.yml b/_config.yml index cc81e3fa56..1c4d0a6fca 100644 --- a/_config.yml +++ b/_config.yml @@ -24,3 +24,7 @@ defaults: values: image: https://avatars.githubusercontent.com/u/4223 toc: true + - scope: + path: "5.2" + values: + version: 5.2 From ba9cce8c2c0a70713908f8e98df3b93c9d5316fc Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 11:51:54 +0900 Subject: [PATCH 22/42] Change navigation path --- Rakefile | 2 +- src/_includes/{navigation_5.2.html => navigation5.2.html} | 0 src/_layouts/default.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/_includes/{navigation_5.2.html => navigation5.2.html} (100%) diff --git a/Rakefile b/Rakefile index 6b3653ae27..6f573844c8 100644 --- a/Rakefile +++ b/Rakefile @@ -61,7 +61,7 @@ def generate_src(target_version: nil) if target_version.nil? mv 'navigation.html', '_includes/navigation.html', force: true else - mv 'navigation.html', "../_includes/navigation_#{target_version}.html", force: true + mv 'navigation.html', "../_includes/navigation#{target_version}.html", force: true end end end diff --git a/src/_includes/navigation_5.2.html b/src/_includes/navigation5.2.html similarity index 100% rename from src/_includes/navigation_5.2.html rename to src/_includes/navigation5.2.html diff --git a/src/_layouts/default.html b/src/_layouts/default.html index 862592e608..6727a89301 100644 --- a/src/_layouts/default.html +++ b/src/_layouts/default.html @@ -41,7 +41,7 @@
From 2bc59ec3cb0bec31565486c3c65235f643547940 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 12:38:30 +0900 Subject: [PATCH 23/42] Replace link path --- src/_includes/navigation5.2.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_includes/navigation5.2.html b/src/_includes/navigation5.2.html index 1289db0c60..73c90f908b 100644 --- a/src/_includes/navigation5.2.html +++ b/src/_includes/navigation5.2.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 8b3f31ae4fd50f677c37412a264a2c305d8552ad Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 14:22:20 +0900 Subject: [PATCH 24/42] Replace path --- Rakefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Rakefile b/Rakefile index 6f573844c8..f429d8c36b 100644 --- a/Rakefile +++ b/Rakefile @@ -61,6 +61,11 @@ def generate_src(target_version: nil) if target_version.nil? mv 'navigation.html', '_includes/navigation.html', force: true else + # Replace absolute path in navigation.html + content = File.read("navigation.html") + content.gsub!(" Date: Wed, 5 May 2021 14:29:34 +0900 Subject: [PATCH 25/42] Add files for Rails v5.2 --- src/5.2/classes/AbstractController.html | 122 + .../AbstractController/ActionNotFound.html | 66 + src/5.2/classes/AbstractController/Base.html | 747 +++++ .../classes/AbstractController/Caching.html | 188 ++ .../Caching/ClassMethods.html | 101 + .../Caching/ConfigMethods.html | 140 + .../AbstractController/Caching/Fragments.html | 369 +++ .../Caching/Fragments/ClassMethods.html | 117 + .../classes/AbstractController/Callbacks.html | 165 + .../Callbacks/ClassMethods.html | 635 ++++ .../classes/AbstractController/Collector.html | 106 + .../AbstractController/DoubleRenderError.html | 125 + .../classes/AbstractController/Helpers.html | 74 + .../Helpers/ClassMethods.html | 384 +++ .../Helpers/MissingHelperError.html | 115 + .../classes/AbstractController/Railties.html | 67 + .../Railties/RoutesHelpers.html | 110 + .../classes/AbstractController/Rendering.html | 438 +++ .../AbstractController/Translation.html | 213 ++ .../classes/AbstractController/UrlFor.html | 137 + .../UrlFor/ClassMethods.html | 146 + src/5.2/classes/ActionCable.html | 248 ++ src/5.2/classes/ActionCable/Channel.html | 98 + src/5.2/classes/ActionCable/Channel/Base.html | 861 ++++++ .../ActionCable/Channel/Broadcasting.html | 67 + .../Channel/Broadcasting/ClassMethods.html | 101 + .../ActionCable/Channel/Callbacks.html | 81 + .../Channel/Callbacks/ClassMethods.html | 282 ++ .../classes/ActionCable/Channel/Naming.html | 67 + .../Channel/Naming/ClassMethods.html | 106 + .../ActionCable/Channel/PeriodicTimers.html | 67 + .../Channel/PeriodicTimers/ClassMethods.html | 129 + .../classes/ActionCable/Channel/Streams.html | 262 ++ src/5.2/classes/ActionCable/Connection.html | 108 + .../ActionCable/Connection/Authorization.html | 115 + .../Authorization/UnauthorizedError.html | 60 + .../classes/ActionCable/Connection/Base.html | 503 +++ .../Connection/Identification.html | 118 + .../Identification/ClassMethods.html | 104 + .../Connection/InternalChannel.html | 60 + .../Connection/StreamEventLoop.html | 367 +++ .../Connection/TaggedLoggerProxy.html | 257 ++ src/5.2/classes/ActionCable/Helpers.html | 67 + .../Helpers/ActionCableHelper.html | 129 + .../ActionCable/RemoteConnections.html | 194 ++ .../RemoteConnections/RemoteConnection.html | 183 ++ .../InvalidIdentifiersError.html | 60 + src/5.2/classes/ActionCable/Server.html | 90 + src/5.2/classes/ActionCable/Server/Base.html | 511 ++++ .../ActionCable/Server/Broadcasting.html | 175 ++ .../Server/Broadcasting/Broadcaster.html | 185 ++ .../ActionCable/Server/Configuration.html | 272 ++ .../classes/ActionCable/Server/Worker.html | 75 + .../ActiveRecordConnectionManagement.html | 101 + .../ActionCable/SubscriptionAdapter.html | 89 + .../SubscriptionAdapter/Async.html | 73 + .../Async/AsyncSubscriberMap.html | 189 ++ .../ActionCable/SubscriptionAdapter/Base.html | 289 ++ .../SubscriptionAdapter/PostgreSQL.html | 73 + .../PostgreSQL/Listener.html | 337 ++ .../SubscriptionAdapter/Redis.html | 73 + .../SubscriptionAdapter/Redis/Listener.html | 366 +++ .../SubscriptionAdapter/SubscriberMap.html | 368 +++ src/5.2/classes/ActionCable/VERSION.html | 120 + src/5.2/classes/ActionController.html | 344 +++ src/5.2/classes/ActionController/API.html | 230 ++ .../ActionController/ApiRendering.html | 116 + src/5.2/classes/ActionController/Base.html | 463 +++ src/5.2/classes/ActionController/Caching.html | 94 + .../ActionController/ConditionalGet.html | 457 +++ .../ConditionalGet/ClassMethods.html | 112 + .../ContentSecurityPolicy.html | 89 + .../ContentSecurityPolicy/ClassMethods.html | 152 + src/5.2/classes/ActionController/Cookies.html | 54 + .../ActionController/DataStreaming.html | 232 ++ .../ActionController/EtagWithFlash.html | 74 + .../EtagWithTemplateDigest.html | 88 + src/5.2/classes/ActionController/Flash.html | 124 + .../ActionController/Flash/ClassMethods.html | 124 + .../classes/ActionController/ForceSSL.html | 200 ++ .../ForceSSL/ClassMethods.html | 157 + .../classes/ActionController/FormBuilder.html | 142 + .../FormBuilder/ClassMethods.html | 106 + src/5.2/classes/ActionController/Head.html | 138 + src/5.2/classes/ActionController/Helpers.html | 188 ++ .../Helpers/ClassMethods.html | 252 ++ .../ActionController/HttpAuthentication.html | 77 + .../HttpAuthentication/Basic.html | 454 +++ .../Basic/ControllerMethods.html | 192 ++ .../Basic/ControllerMethods/ClassMethods.html | 109 + .../HttpAuthentication/Digest.html | 673 ++++ .../Digest/ControllerMethods.html | 179 ++ .../HttpAuthentication/Token.html | 554 ++++ .../Token/ControllerMethods.html | 179 ++ .../ActionController/ImplicitRender.html | 72 + .../ActionController/Instrumentation.html | 398 +++ .../Instrumentation/ClassMethods.html | 54 + src/5.2/classes/ActionController/Live.html | 280 ++ .../ActionController/Live/ClassMethods.html | 107 + .../Live/ClientDisconnected.html | 60 + .../classes/ActionController/Live/SSE.html | 250 ++ .../ActionController/LiveTestResponse.html | 60 + .../ActionController/LogSubscriber.html | 423 +++ src/5.2/classes/ActionController/Metal.html | 702 +++++ .../ActionController/MimeResponds.html | 315 ++ .../MimeResponds/Collector.html | 365 +++ .../ActionController/MissingRenderer.html | 113 + .../ActionController/ParameterEncoding.html | 73 + .../ParameterEncoding/ClassMethods.html | 122 + .../ActionController/ParameterMissing.html | 73 + .../classes/ActionController/Parameters.html | 2653 ++++++++++++++++ .../ActionController/ParamsWrapper.html | 141 + .../ParamsWrapper/Options.html | 73 + .../ParamsWrapper/Options/ClassMethods.html | 229 ++ .../classes/ActionController/Railties.html | 67 + .../ActionController/Railties/Helpers.html | 114 + .../classes/ActionController/Redirecting.html | 231 ++ .../classes/ActionController/Renderer.html | 406 +++ .../classes/ActionController/Renderers.html | 333 ++ .../ActionController/Renderers/All.html | 74 + .../Renderers/ClassMethods.html | 157 + .../classes/ActionController/Rendering.html | 178 ++ .../Rendering/ClassMethods.html | 116 + .../RequestForgeryProtection.html | 1225 ++++++++ .../ClassMethods.html | 186 ++ .../ProtectionMethods.html | 71 + .../ProtectionMethods/Exception.html | 149 + .../ProtectionMethods/NullSession.html | 153 + .../ProtectionMethods/ResetSession.html | 149 + src/5.2/classes/ActionController/Rescue.html | 121 + .../classes/ActionController/Streaming.html | 212 ++ .../ActionController/StrongParameters.html | 221 ++ .../ActionController/TemplateAssertions.html | 103 + .../classes/ActionController/TestCase.html | 199 ++ .../ActionController/TestCase/Behavior.html | 772 +++++ .../TestCase/Behavior/ClassMethods.html | 236 ++ src/5.2/classes/ActionController/Testing.html | 54 + .../UnfilteredParameters.html | 71 + .../UnpermittedParameters.html | 71 + src/5.2/classes/ActionController/UrlFor.html | 160 + src/5.2/classes/ActionDispatch.html | 318 ++ .../ActionDispatch/AssertionResponse.html | 186 ++ .../classes/ActionDispatch/Assertions.html | 152 + .../Assertions/ResponseAssertions.html | 190 ++ .../Assertions/RoutingAssertions.html | 399 +++ src/5.2/classes/ActionDispatch/Callbacks.html | 255 ++ .../ActionDispatch/ContentSecurityPolicy.html | 481 +++ .../ContentSecurityPolicy/Middleware.html | 203 ++ .../ContentSecurityPolicy/Request.html | 395 +++ src/5.2/classes/ActionDispatch/Cookies.html | 466 +++ .../Cookies/ChainedCookieJars.html | 267 ++ .../ActionDispatch/DebugExceptions.html | 203 ++ .../classes/ActionDispatch/DebugLocks.html | 178 ++ .../ActionDispatch/ExceptionWrapper.html | 490 +++ src/5.2/classes/ActionDispatch/Executor.html | 155 + .../classes/ActionDispatch/FileHandler.html | 274 ++ src/5.2/classes/ActionDispatch/Flash.html | 179 ++ .../ActionDispatch/Flash/FlashHash.html | 869 ++++++ .../ActionDispatch/Flash/RequestMethods.html | 142 + src/5.2/classes/ActionDispatch/Http.html | 116 + .../classes/ActionDispatch/Http/Cache.html | 69 + .../ActionDispatch/Http/Cache/Request.html | 339 ++ .../ActionDispatch/Http/Cache/Response.html | 654 ++++ .../ActionDispatch/Http/FilterParameters.html | 442 +++ .../ActionDispatch/Http/FilterRedirect.html | 54 + .../classes/ActionDispatch/Http/Headers.html | 589 ++++ .../ActionDispatch/Http/MimeNegotiation.html | 682 +++++ .../ActionDispatch/Http/ParameterFilter.html | 149 + .../ActionDispatch/Http/Parameters.html | 255 ++ .../Http/Parameters/ClassMethods.html | 109 + .../Http/Parameters/ParseError.html | 113 + src/5.2/classes/ActionDispatch/Http/URL.html | 1056 +++++++ .../ActionDispatch/Http/UploadedFile.html | 397 +++ .../classes/ActionDispatch/Integration.html | 78 + .../Integration/RequestHelpers.html | 337 ++ .../ActionDispatch/Integration/Runner.html | 403 +++ .../ActionDispatch/Integration/Session.html | 628 ++++ .../ActionDispatch/IntegrationTest.html | 281 ++ .../IntegrationTest/Behavior.html | 183 ++ .../Behavior/ClassMethods.html | 183 ++ .../IntegrationTest/UrlOptions.html | 101 + src/5.2/classes/ActionDispatch/Journey.html | 111 + .../ActionDispatch/Journey/Format.html | 60 + .../ActionDispatch/Journey/Formatter.html | 73 + .../Formatter/RegexCaseComparator.html | 54 + .../ActionDispatch/Journey/Parser.html | 62 + .../classes/ActionDispatch/Journey/Route.html | 73 + .../Journey/Route/VerbMatchers.html | 69 + .../Journey/Route/VerbMatchers/All.html | 60 + .../Journey/Route/VerbMatchers/Unknown.html | 60 + .../ActionDispatch/MiddlewareStack.html | 656 ++++ .../MiddlewareStack/Middleware.html | 305 ++ .../ActionDispatch/PublicExceptions.html | 176 ++ .../ActionDispatch/RailsEntityStore.html | 322 ++ .../ActionDispatch/RailsEntityStore/Rack.html | 67 + .../RailsEntityStore/Rack/Cache.html | 67 + .../Rack/Cache/EntityStore.html | 72 + .../ActionDispatch/RailsMetaStore.html | 244 ++ .../ActionDispatch/RailsMetaStore/Rack.html | 67 + .../RailsMetaStore/Rack/Cache.html | 67 + .../RailsMetaStore/Rack/Cache/MetaStore.html | 72 + src/5.2/classes/ActionDispatch/Reloader.html | 68 + src/5.2/classes/ActionDispatch/RemoteIp.html | 235 ++ .../ActionDispatch/RemoteIp/GetIp.html | 333 ++ .../RemoteIp/IpSpoofAttackError.html | 60 + src/5.2/classes/ActionDispatch/Request.html | 1975 ++++++++++++ .../ActionDispatch/RequestEncoder.html | 73 + .../RequestEncoder/IdentityEncoder.html | 216 ++ src/5.2/classes/ActionDispatch/RequestId.html | 161 + src/5.2/classes/ActionDispatch/Response.html | 1769 +++++++++++ .../ActionDispatch/Response/RackBody.html | 350 +++ src/5.2/classes/ActionDispatch/Routing.html | 350 +++ .../Routing/ConsoleFormatter.html | 315 ++ .../Routing/HtmlTableFormatter.html | 316 ++ .../ActionDispatch/Routing/Mapper.html | 251 ++ .../ActionDispatch/Routing/Mapper/Base.html | 505 +++ .../Routing/Mapper/Concerns.html | 236 ++ .../Routing/Mapper/CustomUrls.html | 234 ++ .../Routing/Mapper/HttpHelpers.html | 272 ++ .../Routing/Mapper/Resources.html | 1077 +++++++ .../Routing/Mapper/Scoping.html | 514 ++++ .../ActionDispatch/Routing/PathRedirect.html | 172 ++ .../Routing/PolymorphicRoutes.html | 273 ++ .../ActionDispatch/Routing/Redirection.html | 148 + .../ActionDispatch/Routing/RouteSet.html | 88 + .../Routing/RouteSet/CustomUrlHelper.html | 60 + .../Routing/RouteSet/Dispatcher.html | 60 + .../Routing/RouteSet/Generator.html | 60 + .../Routing/RouteSet/MountedHelpers.html | 54 + .../RouteSet/NamedRouteCollection.html | 73 + .../NamedRouteCollection/UrlHelper.html | 73 + .../UrlHelper/OptimizedUrlHelper.html | 60 + .../Routing/RouteSet/StaticDispatcher.html | 60 + .../ActionDispatch/Routing/RouteWrapper.html | 462 +++ .../ActionDispatch/Routing/UrlFor.html | 488 +++ src/5.2/classes/ActionDispatch/SSL.html | 91 + src/5.2/classes/ActionDispatch/Session.html | 92 + .../Session/AbstractSecureStore.html | 129 + .../ActionDispatch/Session/AbstractStore.html | 82 + .../ActionDispatch/Session/CacheStore.html | 253 ++ .../ActionDispatch/Session/Compatibility.html | 189 ++ .../ActionDispatch/Session/CookieStore.html | 240 ++ .../Session/CookieStore/SessionId.html | 122 + .../ActionDispatch/Session/MemCacheStore.html | 141 + .../Session/StaleSessionCheck.html | 191 ++ .../ActionDispatch/ShowExceptions.html | 189 ++ src/5.2/classes/ActionDispatch/Static.html | 168 + .../ActionDispatch/SystemTestCase.html | 214 ++ .../classes/ActionDispatch/SystemTesting.html | 77 + .../SystemTesting/TestHelpers.html | 71 + .../TestHelpers/ScreenshotHelper.html | 168 + .../classes/ActionDispatch/TestProcess.html | 286 ++ .../TestProcess/FixtureFile.html | 113 + .../classes/ActionDispatch/TestRequest.html | 564 ++++ .../classes/ActionDispatch/TestResponse.html | 286 ++ src/5.2/classes/ActionMailer.html | 220 ++ src/5.2/classes/ActionMailer/Base.html | 1474 +++++++++ .../Base/LateAttachmentsProxy.html | 142 + src/5.2/classes/ActionMailer/Collector.html | 255 ++ .../classes/ActionMailer/DeliveryMethods.html | 73 + .../DeliveryMethods/ClassMethods.html | 114 + .../InlinePreviewInterceptor.html | 101 + .../classes/ActionMailer/LogSubscriber.html | 240 ++ src/5.2/classes/ActionMailer/MailHelper.html | 301 ++ .../classes/ActionMailer/MessageDelivery.html | 366 +++ .../NonInferrableMailerError.html | 109 + .../classes/ActionMailer/Parameterized.html | 158 + .../Parameterized/ClassMethods.html | 106 + src/5.2/classes/ActionMailer/Preview.html | 398 +++ src/5.2/classes/ActionMailer/Previews.html | 67 + .../ActionMailer/Previews/ClassMethods.html | 150 + src/5.2/classes/ActionMailer/Rescuable.html | 74 + src/5.2/classes/ActionMailer/TestCase.html | 89 + .../ActionMailer/TestCase/Behavior.html | 101 + .../TestCase/Behavior/ClassMethods.html | 194 ++ .../TestCase/ClearTestDeliveries.html | 54 + src/5.2/classes/ActionMailer/TestHelper.html | 392 +++ src/5.2/classes/ActionMailer/VERSION.html | 120 + src/5.2/classes/ActionView.html | 412 +++ src/5.2/classes/ActionView/Base.html | 290 ++ src/5.2/classes/ActionView/Context.html | 175 ++ src/5.2/classes/ActionView/Digestor.html | 258 ++ .../classes/ActionView/Digestor/Injected.html | 105 + .../classes/ActionView/Digestor/Missing.html | 105 + src/5.2/classes/ActionView/Digestor/Node.html | 317 ++ .../ActionView/Digestor/NullLogger.html | 142 + .../classes/ActionView/Digestor/Partial.html | 60 + .../PerExecutionDigestCacheExpiry.html | 101 + .../ActionView/FileSystemResolver.html | 299 ++ .../classes/ActionView/FixtureResolver.html | 170 ++ src/5.2/classes/ActionView/Helpers.html | 242 ++ .../ActionView/Helpers/ActiveModelHelper.html | 54 + .../Helpers/ActiveModelInstanceTag.html | 264 ++ .../ActionView/Helpers/AssetTagHelper.html | 801 +++++ .../ActionView/Helpers/AssetUrlHelper.html | 1536 ++++++++++ .../ActionView/Helpers/AtomFeedHelper.html | 217 ++ .../ActionView/Helpers/CacheHelper.html | 384 +++ .../ActionView/Helpers/CaptureHelper.html | 390 +++ .../classes/ActionView/Helpers/CspHelper.html | 110 + .../ActionView/Helpers/CsrfHelper.html | 149 + .../ActionView/Helpers/DateHelper.html | 1289 ++++++++ .../ActionView/Helpers/DebugHelper.html | 133 + .../ActionView/Helpers/FormBuilder.html | 1653 ++++++++++ .../ActionView/Helpers/FormHelper.html | 2273 ++++++++++++++ .../ActionView/Helpers/FormOptionsHelper.html | 1166 +++++++ .../ActionView/Helpers/FormTagHelper.html | 1972 ++++++++++++ .../ActionView/Helpers/JavaScriptHelper.html | 262 ++ .../ActionView/Helpers/NumberHelper.html | 665 ++++ .../NumberHelper/InvalidNumberError.html | 127 + .../Helpers/OutputSafetyHelper.html | 216 ++ .../ActionView/Helpers/RecordTagHelper.html | 54 + .../ActionView/Helpers/RenderingHelper.html | 220 ++ .../ActionView/Helpers/SanitizeHelper.html | 316 ++ .../classes/ActionView/Helpers/TagHelper.html | 462 +++ .../ActionView/Helpers/TextHelper.html | 831 +++++ .../ActionView/Helpers/TranslationHelper.html | 301 ++ .../classes/ActionView/Helpers/UrlHelper.html | 868 ++++++ .../Helpers/UrlHelper/ClassMethods.html | 101 + src/5.2/classes/ActionView/Layouts.html | 331 ++ .../ActionView/Layouts/ClassMethods.html | 142 + src/5.2/classes/ActionView/LogSubscriber.html | 533 ++++ src/5.2/classes/ActionView/LookupContext.html | 75 + .../LookupContext/DetailsCache.html | 168 + .../ActionView/LookupContext/ViewPaths.html | 518 ++++ src/5.2/classes/ActionView/NullResolver.html | 108 + .../classes/ActionView/PartialIteration.html | 211 ++ .../classes/ActionView/PartialRenderer.html | 461 +++ .../classes/ActionView/RecordIdentifier.html | 288 ++ src/5.2/classes/ActionView/Renderer.html | 220 ++ src/5.2/classes/ActionView/Rendering.html | 258 ++ .../ActionView/Rendering/ClassMethods.html | 116 + src/5.2/classes/ActionView/Resolver.html | 252 ++ .../classes/ActionView/Resolver/Cache.html | 73 + .../ActionView/Resolver/Cache/SmallCache.html | 107 + src/5.2/classes/ActionView/Resolver/Path.html | 278 ++ src/5.2/classes/ActionView/RoutingUrlFor.html | 213 ++ src/5.2/classes/ActionView/Template.html | 627 ++++ .../classes/ActionView/Template/Handlers.html | 83 + .../ActionView/Template/Handlers/Builder.html | 156 + .../ActionView/Template/Handlers/ERB.html | 265 ++ .../ActionView/Template/Handlers/Html.html | 107 + .../ActionView/Template/Handlers/Raw.html | 107 + .../classes/ActionView/Template/Types.html | 198 ++ .../ActionView/Template/Types/Type.html | 366 +++ src/5.2/classes/ActionView/TestCase.html | 100 + .../classes/ActionView/TestCase/Behavior.html | 443 +++ .../TestCase/Behavior/ClassMethods.html | 286 ++ .../ActionView/TestCase/Behavior/Locals.html | 126 + .../Behavior/RenderedViewsCollection.html | 275 ++ .../ActionView/TestCase/TestController.html | 207 ++ src/5.2/classes/ActionView/VERSION.html | 120 + src/5.2/classes/ActionView/ViewPaths.html | 242 ++ .../ActionView/ViewPaths/ClassMethods.html | 233 ++ src/5.2/classes/ActiveJob.html | 246 ++ src/5.2/classes/ActiveJob/Base.html | 183 ++ src/5.2/classes/ActiveJob/Callbacks.html | 104 + .../ActiveJob/Callbacks/ClassMethods.html | 384 +++ src/5.2/classes/ActiveJob/Core.html | 245 ++ .../classes/ActiveJob/Core/ClassMethods.html | 169 + .../ActiveJob/DeserializationError.html | 68 + src/5.2/classes/ActiveJob/Enqueuing.html | 151 + .../ActiveJob/Enqueuing/ClassMethods.html | 151 + src/5.2/classes/ActiveJob/Exceptions.html | 144 + .../ActiveJob/Exceptions/ClassMethods.html | 207 ++ src/5.2/classes/ActiveJob/Execution.html | 178 ++ .../ActiveJob/Execution/ClassMethods.html | 110 + src/5.2/classes/ActiveJob/QueueAdapter.html | 67 + .../ActiveJob/QueueAdapter/ClassMethods.html | 214 ++ src/5.2/classes/ActiveJob/QueueAdapters.html | 276 ++ .../ActiveJob/QueueAdapters/AsyncAdapter.html | 132 + .../QueueAdapters/BackburnerAdapter.html | 73 + .../QueueAdapters/DelayedJobAdapter.html | 73 + .../QueueAdapters/InlineAdapter.html | 73 + .../ActiveJob/QueueAdapters/QuAdapter.html | 75 + .../ActiveJob/QueueAdapters/QueAdapter.html | 75 + .../QueueAdapters/QueueClassicAdapter.html | 124 + .../QueueAdapters/ResqueAdapter.html | 75 + .../QueueAdapters/SidekiqAdapter.html | 75 + .../QueueAdapters/SneakersAdapter.html | 122 + .../QueueAdapters/SuckerPunchAdapter.html | 75 + .../ActiveJob/QueueAdapters/TestAdapter.html | 213 ++ src/5.2/classes/ActiveJob/QueueName.html | 117 + .../ActiveJob/QueueName/ClassMethods.html | 120 + src/5.2/classes/ActiveJob/QueuePriority.html | 117 + .../ActiveJob/QueuePriority/ClassMethods.html | 122 + .../classes/ActiveJob/SerializationError.html | 66 + src/5.2/classes/ActiveJob/TestCase.html | 74 + src/5.2/classes/ActiveJob/TestHelper.html | 743 +++++ .../TestHelper/TestQueueAdapter.html | 67 + .../TestQueueAdapter/ClassMethods.html | 179 ++ src/5.2/classes/ActiveJob/VERSION.html | 120 + src/5.2/classes/ActiveModel.html | 332 ++ .../ActiveModel/AttributeAssignment.html | 155 + .../classes/ActiveModel/AttributeMethods.html | 324 ++ .../AttributeMethods/ClassMethods.html | 622 ++++ src/5.2/classes/ActiveModel/Attributes.html | 67 + .../ActiveModel/Attributes/ClassMethods.html | 107 + src/5.2/classes/ActiveModel/Callbacks.html | 220 ++ src/5.2/classes/ActiveModel/Conversion.html | 293 ++ src/5.2/classes/ActiveModel/Dirty.html | 600 ++++ src/5.2/classes/ActiveModel/Errors.html | 1370 +++++++++ .../ActiveModel/ForbiddenAttributesError.html | 78 + src/5.2/classes/ActiveModel/Lint.html | 67 + src/5.2/classes/ActiveModel/Lint/Tests.html | 338 ++ .../ActiveModel/MissingAttributeError.html | 75 + src/5.2/classes/ActiveModel/Model.html | 247 ++ src/5.2/classes/ActiveModel/Name.html | 654 ++++ src/5.2/classes/ActiveModel/Naming.html | 411 +++ src/5.2/classes/ActiveModel/RangeError.html | 66 + .../classes/ActiveModel/SecurePassword.html | 87 + .../SecurePassword/ClassMethods.html | 185 ++ .../InstanceMethodsOnActivation.html | 220 ++ .../classes/ActiveModel/Serialization.html | 245 ++ src/5.2/classes/ActiveModel/Serializers.html | 67 + .../classes/ActiveModel/Serializers/JSON.html | 278 ++ .../ActiveModel/StrictValidationFailed.html | 80 + src/5.2/classes/ActiveModel/Translation.html | 240 ++ src/5.2/classes/ActiveModel/Type.html | 165 + .../classes/ActiveModel/Type/BigInteger.html | 60 + src/5.2/classes/ActiveModel/Type/Binary.html | 73 + src/5.2/classes/ActiveModel/Type/Boolean.html | 108 + src/5.2/classes/ActiveModel/Type/Decimal.html | 60 + src/5.2/classes/ActiveModel/Type/Float.html | 60 + src/5.2/classes/ActiveModel/Type/Helpers.html | 88 + .../Helpers/AcceptsMultiparameterTime.html | 60 + .../ActiveModel/Type/Helpers/Mutable.html | 54 + .../ActiveModel/Type/Helpers/Numeric.html | 54 + .../ActiveModel/Type/Helpers/TimeValue.html | 54 + .../ActiveModel/Type/Helpers/Timezone.html | 54 + src/5.2/classes/ActiveModel/Type/Integer.html | 60 + .../ActiveModel/Type/Registration.html | 60 + .../classes/ActiveModel/Type/Registry.html | 60 + src/5.2/classes/ActiveModel/Type/String.html | 60 + src/5.2/classes/ActiveModel/Type/Value.html | 548 ++++ .../ActiveModel/UnknownAttributeError.html | 147 + src/5.2/classes/ActiveModel/VERSION.html | 120 + .../classes/ActiveModel/ValidationError.html | 138 + src/5.2/classes/ActiveModel/Validations.html | 542 ++++ .../Validations/AcceptanceValidator.html | 75 + .../AttributeDefinition.html | 206 ++ .../LazilyDefineAttributes.html | 118 + .../ActiveModel/Validations/Callbacks.html | 101 + .../Validations/Callbacks/ClassMethods.html | 212 ++ .../ActiveModel/Validations/ClassMethods.html | 775 +++++ .../Validations/HelperMethods.html | 724 +++++ src/5.2/classes/ActiveModel/Validator.html | 343 +++ src/5.2/classes/ActiveRecord.html | 904 ++++++ .../ActiveRecord/ActiveRecordError.html | 68 + .../classes/ActiveRecord/AdapterNotFound.html | 66 + .../ActiveRecord/AdapterNotSpecified.html | 66 + .../classes/ActiveRecord/Aggregations.html | 73 + .../Aggregations/ClassMethods.html | 276 ++ .../ActiveRecord/AssociationRelation.html | 338 ++ .../ActiveRecord/AssociationTypeMismatch.html | 78 + .../classes/ActiveRecord/Associations.html | 146 + .../Associations/ClassMethods.html | 1626 ++++++++++ .../Associations/CollectionProxy.html | 2527 +++++++++++++++ .../ActiveRecord/AttributeAssignment.html | 68 + .../AttributeAssignmentError.html | 137 + .../ActiveRecord/AttributeMethods.html | 723 +++++ .../AttributeMethods/BeforeTypeCast.html | 188 ++ .../AttributeMethods/ClassMethods.html | 417 +++ .../ActiveRecord/AttributeMethods/Dirty.html | 598 ++++ .../AttributeMethods/PrimaryKey.html | 357 +++ .../PrimaryKey/ClassMethods.html | 294 ++ .../ActiveRecord/AttributeMethods/Query.html | 120 + .../ActiveRecord/AttributeMethods/Read.html | 110 + .../AttributeMethods/Serialization.html | 74 + .../Serialization/ClassMethods.html | 149 + .../ColumnNotSerializableError.html | 111 + .../AttributeMethods/TimeZoneConversion.html | 54 + .../ActiveRecord/AttributeMethods/Write.html | 110 + src/5.2/classes/ActiveRecord/Attributes.html | 73 + .../ActiveRecord/Attributes/ClassMethods.html | 318 ++ .../ActiveRecord/AutosaveAssociation.html | 427 +++ src/5.2/classes/ActiveRecord/Base.html | 528 ++++ src/5.2/classes/ActiveRecord/Batches.html | 436 +++ .../ActiveRecord/Batches/BatchEnumerator.html | 189 ++ .../classes/ActiveRecord/Calculations.html | 535 ++++ src/5.2/classes/ActiveRecord/Callbacks.html | 364 +++ .../ActiveRecord/CollectionCacheKey.html | 54 + .../ActiveRecord/ConfigurationError.html | 66 + .../ActiveRecord/ConnectionAdapters.html | 274 ++ .../ConnectionAdapters/AbstractAdapter.html | 2090 +++++++++++++ .../AbstractAdapter/Version.html | 161 + .../AbstractMysqlAdapter.html | 1596 ++++++++++ .../ConnectionAdapters/Column.html | 60 + .../ConnectionAdapters/ColumnMethods.html | 101 + .../ConnectionAdapters/ConnectionHandler.html | 621 ++++ .../ConnectionAdapters/ConnectionPool.html | 1132 +++++++ .../ConnectionPool/Queue.html | 375 +++ .../ConnectionPool/Reaper.html | 187 ++ .../ConnectionAdapters/DatabaseLimits.html | 491 +++ .../DatabaseStatements.html | 1549 ++++++++++ .../PartialQueryCollector.html | 231 ++ .../DetermineIfPreparableVisitor.html | 205 ++ .../ConnectionAdapters/MySQL.html | 94 + .../MySQL/ColumnMethods.html | 491 +++ .../MySQL/DatabaseStatements.html | 227 ++ .../ConnectionAdapters/MySQL/Table.html | 74 + .../MySQL/TableDefinition.html | 74 + .../ConnectionAdapters/Mysql2Adapter.html | 530 ++++ .../ConnectionAdapters/NullColumn.html | 60 + .../ConnectionAdapters/PostgreSQL.html | 148 + .../PostgreSQL/AlterTable.html | 164 + .../PostgreSQL/ColumnMethods.html | 1305 ++++++++ .../PostgreSQL/DatabaseStatements.html | 474 +++ .../ConnectionAdapters/PostgreSQL/OID.html | 113 + .../PostgreSQL/OID/Bit.html | 75 + .../PostgreSQL/OID/Bit/Data.html | 241 ++ .../PostgreSQL/Quoting.html | 218 ++ .../PostgreSQL/SchemaStatements.html | 1149 +++++++ .../ConnectionAdapters/PostgreSQL/Table.html | 74 + .../PostgreSQL/TableDefinition.html | 74 + .../ConnectionAdapters/PostgreSQLAdapter.html | 1883 ++++++++++++ .../PostgreSQLTypeMetadata.html | 336 ++ .../ConnectionAdapters/QueryCache.html | 444 +++ .../ConnectionPoolConfiguration.html | 224 ++ .../ConnectionAdapters/Quoting.html | 523 ++++ .../ConnectionAdapters/RealTransaction.html | 195 ++ .../ConnectionAdapters/SQLite3.html | 79 + .../SQLite3/TableDefinition.html | 139 + .../ConnectionAdapters/SQLite3Adapter.html | 1295 ++++++++ .../SavepointTransaction.html | 234 ++ .../ConnectionAdapters/Savepoints.html | 218 ++ .../ConnectionAdapters/SchemaCache.html | 713 +++++ .../ConnectionAdapters/SchemaStatements.html | 2719 +++++++++++++++++ .../ConnectionAdapters/SqlTypeMetadata.html | 60 + .../ConnectionAdapters/Table.html | 966 ++++++ .../ConnectionAdapters/TableDefinition.html | 612 ++++ .../ConnectionAdapters/TransactionState.html | 673 ++++ .../ActiveRecord/ConnectionHandling.html | 494 +++ .../ConnectionNotEstablished.html | 66 + .../ActiveRecord/ConnectionTimeoutError.html | 66 + src/5.2/classes/ActiveRecord/Core.html | 1011 ++++++ .../classes/ActiveRecord/CounterCache.html | 73 + .../CounterCache/ClassMethods.html | 366 +++ .../ActiveRecord/DangerousAttributeError.html | 66 + src/5.2/classes/ActiveRecord/Deadlocked.html | 66 + .../classes/ActiveRecord/DefineCallbacks.html | 74 + .../classes/ActiveRecord/DynamicMatchers.html | 71 + .../ActiveRecord/DynamicMatchers/FindBy.html | 149 + .../DynamicMatchers/FindByBang.html | 188 ++ .../ActiveRecord/DynamicMatchers/Method.html | 390 +++ .../EagerLoadPolymorphicError.html | 117 + src/5.2/classes/ActiveRecord/Enum.html | 263 ++ .../EnvironmentMismatchError.html | 115 + .../ExclusiveConnectionTimeoutError.html | 66 + src/5.2/classes/ActiveRecord/Explain.html | 54 + .../classes/ActiveRecord/FinderMethods.html | 1197 ++++++++ src/5.2/classes/ActiveRecord/FixtureSet.html | 1317 ++++++++ .../ActiveRecord/FixtureSet/ClassCache.html | 156 + .../ActiveRecord/ImmutableRelation.html | 77 + src/5.2/classes/ActiveRecord/Inheritance.html | 142 + .../Inheritance/ClassMethods.html | 482 +++ src/5.2/classes/ActiveRecord/Integration.html | 292 ++ .../Integration/ClassMethods.html | 135 + .../ActiveRecord/InvalidForeignKey.html | 66 + .../ActiveRecord/IrreversibleMigration.html | 139 + .../ActiveRecord/IrreversibleOrderError.html | 66 + .../ActiveRecord/LegacyYamlAdapter.html | 126 + .../LegacyYamlAdapter/Rails41.html | 108 + .../LegacyYamlAdapter/Rails420.html | 111 + .../classes/ActiveRecord/LockWaitTimeout.html | 66 + src/5.2/classes/ActiveRecord/Locking.html | 71 + .../ActiveRecord/Locking/Optimistic.html | 113 + .../Locking/Optimistic/ClassMethods.html | 278 ++ .../ActiveRecord/Locking/Pessimistic.html | 213 ++ .../classes/ActiveRecord/LogSubscriber.html | 280 ++ src/5.2/classes/ActiveRecord/Migration.html | 1638 ++++++++++ .../ActiveRecord/Migration/CheckPending.html | 161 + .../Migration/CommandRecorder.html | 366 +++ .../ActiveRecord/Migration/Compatibility.html | 71 + .../Migration/Compatibility/V4_2.html | 73 + .../Compatibility/V4_2/TableDefinition.html | 54 + .../Migration/Compatibility/V5_0.html | 73 + .../Compatibility/V5_0/TableDefinition.html | 54 + .../Migration/Compatibility/V5_1.html | 60 + .../ActiveRecord/MismatchedForeignKey.html | 140 + src/5.2/classes/ActiveRecord/ModelSchema.html | 551 ++++ .../ModelSchema/ClassMethods.html | 1009 ++++++ .../MultiparameterAssignmentErrors.html | 127 + .../ActiveRecord/NestedAttributes.html | 74 + .../NestedAttributes/ClassMethods.html | 406 +++ .../NestedAttributes/TooManyRecords.html | 60 + .../classes/ActiveRecord/NoDatabaseError.html | 66 + src/5.2/classes/ActiveRecord/NoTouching.html | 120 + .../ActiveRecord/NoTouching/ClassMethods.html | 114 + .../ActiveRecord/NotNullViolation.html | 66 + src/5.2/classes/ActiveRecord/Persistence.html | 1283 ++++++++ .../Persistence/ClassMethods.html | 409 +++ .../ActiveRecord/PredicateBuilder.html | 87 + .../PredicateBuilder/RangeHandler.html | 73 + .../RangeHandler/RangeWithBinds.html | 107 + .../PreparedStatementCacheExpired.html | 66 + .../PreparedStatementInvalid.html | 71 + src/5.2/classes/ActiveRecord/QueryCache.html | 209 ++ .../ActiveRecord/QueryCache/ClassMethods.html | 148 + .../classes/ActiveRecord/QueryCanceled.html | 66 + .../classes/ActiveRecord/QueryMethods.html | 1634 ++++++++++ .../ActiveRecord/QueryMethods/WhereChain.html | 182 ++ src/5.2/classes/ActiveRecord/Querying.html | 176 ++ src/5.2/classes/ActiveRecord/RangeError.html | 66 + .../classes/ActiveRecord/ReadOnlyRecord.html | 66 + .../ActiveRecord/ReadonlyAttributes.html | 67 + .../ReadonlyAttributes/ClassMethods.html | 140 + .../classes/ActiveRecord/RecordInvalid.html | 144 + .../ActiveRecord/RecordNotDestroyed.html | 135 + .../classes/ActiveRecord/RecordNotFound.html | 147 + .../classes/ActiveRecord/RecordNotSaved.html | 128 + .../classes/ActiveRecord/RecordNotUnique.html | 66 + src/5.2/classes/ActiveRecord/Reflection.html | 74 + .../ActiveRecord/Reflection/ClassMethods.html | 337 ++ .../Reflection/MacroReflection.html | 379 +++ src/5.2/classes/ActiveRecord/Relation.html | 1968 ++++++++++++ .../Relation/RecordFetchWarning.html | 111 + src/5.2/classes/ActiveRecord/Result.html | 552 ++++ src/5.2/classes/ActiveRecord/Rollback.html | 88 + .../classes/ActiveRecord/Sanitization.html | 67 + .../Sanitization/ClassMethods.html | 499 +++ src/5.2/classes/ActiveRecord/Schema.html | 144 + src/5.2/classes/ActiveRecord/Scoping.html | 101 + .../classes/ActiveRecord/Scoping/Default.html | 67 + .../Scoping/Default/ClassMethods.html | 207 ++ .../classes/ActiveRecord/Scoping/Named.html | 67 + .../Scoping/Named/ClassMethods.html | 273 ++ src/5.2/classes/ActiveRecord/SecureToken.html | 67 + .../SecureToken/ClassMethods.html | 161 + .../classes/ActiveRecord/Serialization.html | 126 + .../ActiveRecord/SerializationFailure.html | 66 + .../SerializationTypeMismatch.html | 66 + .../classes/ActiveRecord/SpawnMethods.html | 210 ++ .../ActiveRecord/StaleObjectError.html | 143 + .../ActiveRecord/StatementInvalid.html | 115 + .../ActiveRecord/StatementTimeout.html | 66 + src/5.2/classes/ActiveRecord/Store.html | 232 ++ .../ActiveRecord/Store/ClassMethods.html | 202 ++ .../ActiveRecord/SubclassNotFound.html | 66 + src/5.2/classes/ActiveRecord/Suppressor.html | 94 + .../ActiveRecord/Suppressor/ClassMethods.html | 105 + src/5.2/classes/ActiveRecord/Tasks.html | 73 + .../ActiveRecord/Tasks/DatabaseTasks.html | 1609 ++++++++++ .../classes/ActiveRecord/TestFixtures.html | 296 ++ .../TestFixtures/ClassMethods.html | 304 ++ src/5.2/classes/ActiveRecord/Timestamp.html | 98 + src/5.2/classes/ActiveRecord/TouchLater.html | 60 + .../TransactionIsolationError.html | 75 + .../TransactionRollbackError.html | 73 + .../classes/ActiveRecord/Transactions.html | 73 + .../Transactions/ClassMethods.html | 452 +++ src/5.2/classes/ActiveRecord/Translation.html | 68 + src/5.2/classes/ActiveRecord/Type.html | 302 ++ .../Type/AdapterSpecificRegistry.html | 60 + src/5.2/classes/ActiveRecord/Type/Date.html | 74 + .../classes/ActiveRecord/Type/DateTime.html | 74 + .../Type/DecorationRegistration.html | 60 + .../classes/ActiveRecord/Type/Internal.html | 67 + .../ActiveRecord/Type/Internal/Timezone.html | 140 + src/5.2/classes/ActiveRecord/Type/Json.html | 278 ++ .../ActiveRecord/Type/Registration.html | 60 + src/5.2/classes/ActiveRecord/Type/Time.html | 126 + .../ActiveRecord/TypeConflictError.html | 60 + .../UnknownAttributeReference.html | 80 + .../ActiveRecord/UnknownPrimaryKey.html | 134 + src/5.2/classes/ActiveRecord/VERSION.html | 122 + src/5.2/classes/ActiveRecord/Validations.html | 264 ++ .../Validations/ClassMethods.html | 447 +++ .../classes/ActiveRecord/ValueTooLong.html | 66 + .../WrappedDatabaseException.html | 66 + src/5.2/classes/ActiveStorage.html | 294 ++ src/5.2/classes/ActiveStorage/AnalyzeJob.html | 113 + src/5.2/classes/ActiveStorage/Analyzer.html | 287 ++ .../ActiveStorage/Analyzer/ImageAnalyzer.html | 174 ++ .../ActiveStorage/Analyzer/VideoAnalyzer.html | 176 ++ src/5.2/classes/ActiveStorage/Attached.html | 171 ++ .../ActiveStorage/Attached/Macros.html | 310 ++ .../classes/ActiveStorage/Attached/Many.html | 325 ++ .../classes/ActiveStorage/Attached/One.html | 341 +++ src/5.2/classes/ActiveStorage/Attachment.html | 154 + .../classes/ActiveStorage/BaseController.html | 66 + src/5.2/classes/ActiveStorage/BaseJob.html | 60 + src/5.2/classes/ActiveStorage/Blob.html | 904 ++++++ .../ActiveStorage/Blob/Analyzable.html | 196 ++ .../ActiveStorage/Blob/Identifiable.html | 143 + .../ActiveStorage/Blob/Representable.html | 342 +++ .../ActiveStorage/BlobsController.html | 114 + .../DirectUploadsController.html | 114 + .../classes/ActiveStorage/DiskController.html | 165 + .../classes/ActiveStorage/Downloading.html | 185 ++ src/5.2/classes/ActiveStorage/Filename.html | 534 ++++ .../classes/ActiveStorage/IntegrityError.html | 60 + .../ActiveStorage/InvariableError.html | 60 + .../classes/ActiveStorage/LogSubscriber.html | 375 +++ src/5.2/classes/ActiveStorage/Preview.html | 298 ++ .../Preview/UnprocessedError.html | 60 + src/5.2/classes/ActiveStorage/Previewer.html | 344 +++ .../Previewer/MuPDFPreviewer.html | 235 ++ .../Previewer/PopplerPDFPreviewer.html | 233 ++ .../Previewer/VideoPreviewer.html | 153 + src/5.2/classes/ActiveStorage/PurgeJob.html | 113 + .../RepresentationsController.html | 114 + src/5.2/classes/ActiveStorage/Service.html | 573 ++++ .../Service/AzureStorageService.html | 572 ++++ .../ActiveStorage/Service/DiskService.html | 557 ++++ .../ActiveStorage/Service/GCSService.html | 571 ++++ .../ActiveStorage/Service/MirrorService.html | 257 ++ .../ActiveStorage/Service/S3Service.html | 540 ++++ .../ActiveStorage/UnpreviewableError.html | 60 + .../ActiveStorage/UnrepresentableError.html | 60 + src/5.2/classes/ActiveStorage/VERSION.html | 120 + src/5.2/classes/ActiveStorage/Variant.html | 352 +++ src/5.2/classes/ActiveStorage/Variation.html | 360 +++ src/5.2/classes/ActiveSupport.html | 596 ++++ .../classes/ActiveSupport/ArrayInquirer.html | 136 + src/5.2/classes/ActiveSupport/Autoload.html | 338 ++ .../ActiveSupport/BacktraceCleaner.html | 372 +++ .../classes/ActiveSupport/Benchmarkable.html | 132 + src/5.2/classes/ActiveSupport/Cache.html | 257 ++ .../Cache/ConnectionPoolLike.html | 101 + .../ActiveSupport/Cache/FileStore.html | 407 +++ .../ActiveSupport/Cache/MemCacheStore.html | 327 ++ .../ActiveSupport/Cache/MemoryStore.html | 451 +++ .../ActiveSupport/Cache/NullStore.html | 266 ++ .../ActiveSupport/Cache/RedisCacheStore.html | 614 ++++ .../classes/ActiveSupport/Cache/Store.html | 1026 +++++++ .../classes/ActiveSupport/Cache/Strategy.html | 79 + .../Cache/Strategy/LocalCache.html | 163 + .../Cache/Strategy/LocalCache/LocalStore.html | 320 ++ .../ActiveSupport/CachingKeyGenerator.html | 156 + src/5.2/classes/ActiveSupport/Callbacks.html | 231 ++ .../ActiveSupport/Callbacks/ClassMethods.html | 378 +++ .../ActiveSupport/Callbacks/Conditionals.html | 67 + .../Callbacks/Conditionals/Value.html | 147 + .../ActiveSupport/Callbacks/Filters.html | 87 + .../Callbacks/Filters/After.html | 119 + .../Callbacks/Filters/Before.html | 113 + src/5.2/classes/ActiveSupport/Concern.html | 304 ++ .../classes/ActiveSupport/Concurrency.html | 73 + .../LoadInterlockAwareMonitor.html | 114 + .../ActiveSupport/Concurrency/ShareLock.html | 503 +++ .../classes/ActiveSupport/Configurable.html | 142 + .../Configurable/ClassMethods.html | 145 + .../Configurable/Configuration.html | 153 + .../ActiveSupport/CurrentAttributes.html | 448 +++ .../classes/ActiveSupport/Dependencies.html | 205 ++ .../Dependencies/ClassCache.html | 381 +++ .../ActiveSupport/Dependencies/Interlock.html | 388 +++ .../ActiveSupport/Dependencies/Loadable.html | 108 + .../Dependencies/WatchStack.html | 343 +++ .../classes/ActiveSupport/Deprecation.html | 264 ++ .../ActiveSupport/Deprecation/Behavior.html | 206 ++ .../DeprecatedConstantAccessor.html | 231 ++ .../Deprecation/DeprecatedConstantProxy.html | 178 ++ .../DeprecatedInstanceVariableProxy.html | 144 + .../Deprecation/DeprecatedObjectProxy.html | 124 + .../Deprecation/MethodWrapper.html | 183 ++ .../ActiveSupport/Deprecation/Reporting.html | 243 ++ .../ActiveSupport/DeprecationException.html | 66 + .../ActiveSupport/DescendantsTracker.html | 357 +++ src/5.2/classes/ActiveSupport/Duration.html | 1049 +++++++ .../ActiveSupport/Duration/ISO8601Parser.html | 73 + .../Duration/ISO8601Parser/ParsingError.html | 60 + .../ActiveSupport/EncryptedConfiguration.html | 232 ++ .../classes/ActiveSupport/EncryptedFile.html | 382 +++ .../EncryptedFile/MissingContentError.html | 107 + .../EncryptedFile/MissingKeyError.html | 109 + .../EventedFileUpdateChecker.html | 73 + .../EventedFileUpdateChecker/PathHelper.html | 60 + .../ActiveSupport/ExecutionWrapper.html | 368 +++ src/5.2/classes/ActiveSupport/Executor.html | 60 + .../ActiveSupport/FileUpdateChecker.html | 293 ++ src/5.2/classes/ActiveSupport/Gzip.html | 170 ++ .../classes/ActiveSupport/Gzip/Stream.html | 148 + .../HashWithIndifferentAccess.html | 2134 +++++++++++++ src/5.2/classes/ActiveSupport/Inflector.html | 1243 ++++++++ .../ActiveSupport/Inflector/Inflections.html | 601 ++++ .../Inflector/Inflections/Uncountables.html | 271 ++ .../ActiveSupport/InheritableOptions.html | 169 + src/5.2/classes/ActiveSupport/JSON.html | 234 ++ .../classes/ActiveSupport/KeyGenerator.html | 158 + .../classes/ActiveSupport/LazyLoadHooks.html | 175 ++ .../classes/ActiveSupport/LogSubscriber.html | 539 ++++ .../LogSubscriber/TestHelper.html | 185 ++ .../LogSubscriber/TestHelper/MockLogger.html | 267 ++ src/5.2/classes/ActiveSupport/Logger.html | 231 ++ .../ActiveSupport/Logger/SimpleFormatter.html | 113 + .../ActiveSupport/MessageEncryptor.html | 350 +++ .../MessageEncryptor/InvalidMessage.html | 60 + .../ActiveSupport/MessageVerifier.html | 437 +++ .../MessageVerifier/InvalidSignature.html | 60 + src/5.2/classes/ActiveSupport/Messages.html | 71 + .../ActiveSupport/Messages/Rotator.html | 69 + .../Messages/Rotator/Encryptor.html | 117 + .../Messages/Rotator/Verifier.html | 115 + src/5.2/classes/ActiveSupport/Multibyte.html | 167 + .../ActiveSupport/Multibyte/Chars.html | 937 ++++++ .../ActiveSupport/Multibyte/Unicode.html | 847 +++++ .../Multibyte/Unicode/Codepoint.html | 211 ++ .../Multibyte/Unicode/UnicodeDatabase.html | 312 ++ .../classes/ActiveSupport/Notifications.html | 479 +++ .../ActiveSupport/Notifications/Event.html | 298 ++ .../ActiveSupport/Notifications/Fanout.html | 461 +++ .../Notifications/Instrumenter.html | 297 ++ .../classes/ActiveSupport/NumberHelper.html | 639 ++++ .../ActiveSupport/NumericWithFormat.html | 218 ++ .../classes/ActiveSupport/OrderedHash.html | 318 ++ .../classes/ActiveSupport/OrderedOptions.html | 296 ++ .../ActiveSupport/PerThreadRegistry.html | 183 ++ .../classes/ActiveSupport/ProxyObject.html | 113 + .../ActiveSupport/RangeWithFormat.html | 205 ++ src/5.2/classes/ActiveSupport/Reloader.html | 401 +++ src/5.2/classes/ActiveSupport/Rescuable.html | 120 + .../ActiveSupport/Rescuable/ClassMethods.html | 208 ++ src/5.2/classes/ActiveSupport/SafeBuffer.html | 694 +++++ .../SafeBuffer/SafeConcatError.html | 113 + .../classes/ActiveSupport/SecurityUtils.html | 150 + .../classes/ActiveSupport/StringInquirer.html | 81 + src/5.2/classes/ActiveSupport/Subscriber.html | 432 +++ .../classes/ActiveSupport/TaggedLogging.html | 200 ++ src/5.2/classes/ActiveSupport/TestCase.html | 223 ++ src/5.2/classes/ActiveSupport/Testing.html | 99 + .../ActiveSupport/Testing/Assertions.html | 479 +++ .../ActiveSupport/Testing/ConstantLookup.html | 85 + .../ActiveSupport/Testing/Declarative.html | 115 + .../ActiveSupport/Testing/FileFixtures.html | 122 + .../ActiveSupport/Testing/Isolation.html | 162 + .../Testing/Isolation/Forking.html | 132 + .../Testing/Isolation/Subprocess.html | 153 + .../Testing/SetupAndTeardown.html | 147 + .../SetupAndTeardown/ClassMethods.html | 140 + .../ActiveSupport/Testing/TimeHelpers.html | 367 +++ .../classes/ActiveSupport/TimeWithZone.html | 2637 ++++++++++++++++ src/5.2/classes/ActiveSupport/TimeZone.html | 1547 ++++++++++ src/5.2/classes/ActiveSupport/VERSION.html | 120 + .../classes/ActiveSupport/XMLConverter.html | 73 + .../XMLConverter/DisallowedType.html | 113 + src/5.2/classes/ActiveSupport/XmlMini.html | 421 +++ .../ActiveSupport/XmlMini_LibXMLSAX.html | 67 + .../XmlMini_LibXMLSAX/HashBuilder.html | 410 +++ .../ActiveSupport/XmlMini_NokogiriSAX.html | 67 + .../XmlMini_NokogiriSAX/HashBuilder.html | 436 +++ src/5.2/classes/Array.html | 1420 +++++++++ src/5.2/classes/Benchmark.html | 108 + src/5.2/classes/BigDecimal.html | 113 + src/5.2/classes/Class.html | 354 +++ src/5.2/classes/Complex.html | 113 + src/5.2/classes/Date.html | 1446 +++++++++ src/5.2/classes/DateAndTime.html | 75 + src/5.2/classes/DateAndTime/Calculations.html | 2373 ++++++++++++++ .../classes/DateAndTime/Compatibility.html | 54 + src/5.2/classes/DateAndTime/Zones.html | 121 + src/5.2/classes/DateTime.html | 2097 +++++++++++++ src/5.2/classes/Delegator.html | 144 + src/5.2/classes/Digest.html | 67 + src/5.2/classes/Digest/UUID.html | 238 ++ src/5.2/classes/ERB.html | 73 + src/5.2/classes/ERB/Util.html | 310 ++ src/5.2/classes/Enumerable.html | 363 +++ src/5.2/classes/Exception.html | 107 + src/5.2/classes/FalseClass.html | 200 ++ src/5.2/classes/File.html | 153 + src/5.2/classes/Float.html | 60 + src/5.2/classes/Hash.html | 1923 ++++++++++++ src/5.2/classes/IO.html | 62 + src/5.2/classes/Integer.html | 358 +++ src/5.2/classes/Kernel.html | 321 ++ src/5.2/classes/LoadError.html | 107 + src/5.2/classes/LoggerSilence.html | 112 + src/5.2/classes/Method.html | 111 + src/5.2/classes/Mime.html | 221 ++ src/5.2/classes/Mime/AllType.html | 196 ++ src/5.2/classes/Mime/Mimes.html | 282 ++ src/5.2/classes/Mime/NullType.html | 156 + src/5.2/classes/Mime/Type.html | 992 ++++++ src/5.2/classes/Minitest.html | 224 ++ .../Minitest/SuppressedSummaryReporter.html | 107 + src/5.2/classes/Module.html | 1742 +++++++++++ src/5.2/classes/Module/Concerning.html | 260 ++ src/5.2/classes/Module/DelegationError.html | 66 + src/5.2/classes/NameError.html | 173 ++ src/5.2/classes/NilClass.html | 296 ++ src/5.2/classes/Numeric.html | 1333 ++++++++ src/5.2/classes/Object.html | 1013 ++++++ src/5.2/classes/PG.html | 69 + src/5.2/classes/PG/Connection.html | 66 + src/5.2/classes/Process.html | 56 + src/5.2/classes/Rails.html | 772 +++++ src/5.2/classes/Rails/API.html | 73 + src/5.2/classes/Rails/API/EdgeTask.html | 107 + src/5.2/classes/Rails/API/RepoTask.html | 186 ++ src/5.2/classes/Rails/API/StableTask.html | 107 + src/5.2/classes/Rails/API/Task.html | 444 +++ src/5.2/classes/Rails/AppBuilder.html | 1197 ++++++++ src/5.2/classes/Rails/Application.html | 1267 ++++++++ .../classes/Rails/Application/Bootstrap.html | 68 + .../Rails/Application/Configuration.html | 1047 +++++++ .../Application/DefaultMiddlewareStack.html | 241 ++ .../classes/Rails/Application/Finisher.html | 88 + .../Application/Finisher/InterlockHook.html | 140 + .../Rails/Application/Finisher/MutexHook.html | 188 ++ .../Rails/Application/RoutesReloader.html | 186 ++ src/5.2/classes/Rails/BacktraceCleaner.html | 180 ++ src/5.2/classes/Rails/Command.html | 362 +++ src/5.2/classes/Rails/Command/Actions.html | 306 ++ src/5.2/classes/Rails/Command/Base.html | 586 ++++ src/5.2/classes/Rails/Command/Helpers.html | 67 + .../classes/Rails/Command/Helpers/Editor.html | 54 + src/5.2/classes/Rails/Configuration.html | 71 + .../Configuration/MiddlewareStackProxy.html | 489 +++ src/5.2/classes/Rails/Console.html | 402 +++ .../Rails/Console/BacktraceCleaner.html | 103 + src/5.2/classes/Rails/ConsoleMethods.html | 276 ++ src/5.2/classes/Rails/DBConsole.html | 489 +++ src/5.2/classes/Rails/Engine.html | 1379 +++++++++ .../classes/Rails/Engine/Configuration.html | 437 +++ src/5.2/classes/Rails/Engine/Railties.html | 217 ++ src/5.2/classes/Rails/Engine/Updater.html | 147 + src/5.2/classes/Rails/Generators.html | 940 ++++++ src/5.2/classes/Rails/Generators/Actions.html | 1142 +++++++ .../classes/Rails/Generators/ActiveModel.html | 426 +++ src/5.2/classes/Rails/Generators/AppBase.html | 73 + .../Generators/AppBase/GemfileEntry.html | 276 ++ src/5.2/classes/Rails/Generators/Base.html | 1213 ++++++++ .../classes/Rails/Generators/Migration.html | 240 ++ .../classes/Rails/Generators/NamedBase.html | 1458 +++++++++ .../classes/Rails/Generators/TestCase.html | 117 + src/5.2/classes/Rails/Generators/Testing.html | 75 + .../Rails/Generators/Testing/Assertions.html | 545 ++++ .../Rails/Generators/Testing/Behaviour.html | 255 ++ .../Testing/Behaviour/ClassMethods.html | 188 ++ .../Generators/Testing/SetupAndTeardown.html | 54 + src/5.2/classes/Rails/Info.html | 236 ++ src/5.2/classes/Rails/Initializable.html | 166 + .../Rails/Initializable/ClassMethods.html | 225 ++ .../Rails/Initializable/Collection.html | 158 + .../Rails/Initializable/Initializer.html | 368 +++ src/5.2/classes/Rails/Paths.html | 69 + src/5.2/classes/Rails/Paths/Path.html | 665 ++++ src/5.2/classes/Rails/Paths/Root.html | 601 ++++ src/5.2/classes/Rails/PluginBuilder.html | 917 ++++++ src/5.2/classes/Rails/Rack.html | 69 + src/5.2/classes/Rails/Rack/Logger.html | 307 ++ src/5.2/classes/Rails/Railtie.html | 664 ++++ .../classes/Rails/Railtie/Configurable.html | 67 + .../Railtie/Configurable/ClassMethods.html | 218 ++ .../classes/Rails/Railtie/Configuration.html | 584 ++++ src/5.2/classes/Rails/Secrets.html | 73 + .../Rails/Secrets/MissingKeyError.html | 110 + src/5.2/classes/Rails/Server.html | 378 +++ src/5.2/classes/Rails/Server/Options.html | 107 + src/5.2/classes/Rails/VERSION.html | 124 + src/5.2/classes/Range.html | 115 + src/5.2/classes/Rational.html | 111 + src/5.2/classes/SecureRandom.html | 133 + .../classes/SourceAnnotationExtractor.html | 436 +++ src/5.2/classes/String.html | 2261 ++++++++++++++ src/5.2/classes/Symbol.html | 113 + src/5.2/classes/Time.html | 2434 +++++++++++++++ src/5.2/classes/TrueClass.html | 200 ++ src/5.2/classes/URI.html | 103 + src/5.2/files/actioncable/README_md.html | 523 ++++ .../lib/action_cable/channel/base_rb.html | 87 + .../action_cable/channel/broadcasting_rb.html | 82 + .../action_cable/channel/callbacks_rb.html | 82 + .../lib/action_cable/channel/naming_rb.html | 74 + .../channel/periodic_timers_rb.html | 74 + .../lib/action_cable/channel/streams_rb.html | 74 + .../lib/action_cable/channel_rb.html | 70 + .../connection/authorization_rb.html | 79 + .../lib/action_cable/connection/base_rb.html | 87 + .../connection/client_socket_rb.html | 78 + .../connection/identification_rb.html | 82 + .../connection/internal_channel_rb.html | 72 + .../connection/message_buffer_rb.html | 70 + .../connection/stream_event_loop_rb.html | 87 + .../action_cable/connection/stream_rb.html | 78 + .../connection/subscriptions_rb.html | 82 + .../connection/tagged_logger_proxy_rb.html | 77 + .../connection/web_socket_rb.html | 78 + .../lib/action_cable/connection_rb.html | 70 + .../lib/action_cable/engine_rb.html | 86 + .../lib/action_cable/gem_version_rb.html | 70 + .../helpers/action_cable_helper_rb.html | 72 + .../action_cable/remote_connections_rb.html | 87 + .../lib/action_cable/server/base_rb.html | 87 + .../action_cable/server/broadcasting_rb.html | 81 + .../action_cable/server/configuration_rb.html | 79 + .../action_cable/server/connections_rb.html | 70 + ...ctive_record_connection_management_rb.html | 81 + .../lib/action_cable/server/worker_rb.html | 89 + .../lib/action_cable/server_rb.html | 70 + .../subscription_adapter/async_rb.html | 87 + .../subscription_adapter/base_rb.html | 77 + .../channel_prefix_rb.html | 70 + .../subscription_adapter/inline_rb.html | 70 + .../subscription_adapter/postgresql_rb.html | 97 + .../subscription_adapter/redis_rb.html | 89 + .../subscriber_map_rb.html | 77 + .../action_cable/subscription_adapter_rb.html | 70 + .../lib/action_cable/version_rb.html | 68 + src/5.2/files/actionmailer/README_rdoc.html | 221 ++ .../lib/action_mailer/base_rb.html | 101 + .../lib/action_mailer/collector_rb.html | 87 + .../lib/action_mailer/delivery_job_rb.html | 76 + .../action_mailer/delivery_methods_rb.html | 80 + .../lib/action_mailer/gem_version_rb.html | 70 + .../inline_preview_interceptor_rb.html | 83 + .../lib/action_mailer/log_subscriber_rb.html | 83 + .../lib/action_mailer/mail_helper_rb.html | 70 + .../action_mailer/message_delivery_rb.html | 83 + .../lib/action_mailer/parameterized_rb.html | 72 + .../lib/action_mailer/preview_rb.html | 87 + .../lib/action_mailer/railtie_rb.html | 84 + .../lib/action_mailer/rescuable_rb.html | 70 + .../lib/action_mailer/test_case_rb.html | 93 + .../lib/action_mailer/test_helper_rb.html | 80 + .../lib/action_mailer/version_rb.html | 68 + src/5.2/files/actionpack/README_rdoc.html | 108 + .../abstract_controller/asset_paths_rb.html | 68 + .../lib/abstract_controller/base_rb.html | 93 + .../caching/fragments_rb.html | 76 + .../lib/abstract_controller/caching_rb.html | 76 + .../lib/abstract_controller/callbacks_rb.html | 72 + .../lib/abstract_controller/collector_rb.html | 80 + .../lib/abstract_controller/error_rb.html | 68 + .../lib/abstract_controller/helpers_rb.html | 87 + .../lib/abstract_controller/logger_rb.html | 76 + .../railties/routes_helpers_rb.html | 72 + .../lib/abstract_controller/rendering_rb.html | 91 + .../abstract_controller/translation_rb.html | 70 + .../lib/abstract_controller/url_for_rb.html | 72 + .../api/api_rendering_rb.html | 70 + .../lib/action_controller/api_rb.html | 87 + .../lib/action_controller/base_rb.html | 89 + .../lib/action_controller/caching_rb.html | 70 + .../action_controller/form_builder_rb.html | 72 + .../action_controller/log_subscriber_rb.html | 77 + .../metal/basic_implicit_render_rb.html | 68 + .../metal/conditional_get_rb.html | 80 + .../metal/content_security_policy_rb.html | 74 + .../action_controller/metal/cookies_rb.html | 70 + .../metal/data_streaming_rb.html | 80 + .../metal/etag_with_flash_rb.html | 70 + .../metal/etag_with_template_digest_rb.html | 72 + .../metal/exceptions_rb.html | 68 + .../lib/action_controller/metal/flash_rb.html | 72 + .../action_controller/metal/force_ssl_rb.html | 84 + .../lib/action_controller/metal/head_rb.html | 70 + .../action_controller/metal/helpers_rb.html | 74 + .../metal/http_authentication_rb.html | 96 + .../metal/implicit_render_rb.html | 70 + .../metal/instrumentation_rb.html | 84 + .../lib/action_controller/metal/live_rb.html | 97 + .../metal/mime_responds_rb.html | 87 + .../metal/parameter_encoding_rb.html | 72 + .../metal/params_wrapper_rb.html | 95 + .../metal/redirecting_rb.html | 72 + .../action_controller/metal/renderers_rb.html | 89 + .../action_controller/metal/rendering_rb.html | 74 + .../metal/request_forgery_protection_rb.html | 103 + .../action_controller/metal/rescue_rb.html | 70 + .../action_controller/metal/streaming_rb.html | 78 + .../metal/strong_parameters_rb.html | 113 + .../action_controller/metal/testing_rb.html | 70 + .../action_controller/metal/url_for_rb.html | 70 + .../lib/action_controller/metal_rb.html | 91 + .../lib/action_controller/railtie_rb.html | 88 + .../railties/helpers_rb.html | 72 + .../lib/action_controller/renderer_rb.html | 85 + .../template_assertions_rb.html | 70 + .../lib/action_controller/test_case_rb.html | 113 + .../lib/action_dispatch/http/cache_rb.html | 76 + .../http/content_security_policy_rb.html | 87 + .../http/filter_parameters_rb.html | 80 + .../http/filter_redirect_rb.html | 72 + .../lib/action_dispatch/http/headers_rb.html | 77 + .../http/mime_negotiation_rb.html | 84 + .../action_dispatch/http/mime_type_rb.html | 93 + .../action_dispatch/http/mime_types_rb.html | 74 + .../http/parameter_filter_rb.html | 85 + .../action_dispatch/http/parameters_rb.html | 85 + .../action_dispatch/http/rack_cache_rb.html | 101 + .../lib/action_dispatch/http/request_rb.html | 111 + .../lib/action_dispatch/http/response_rb.html | 91 + .../lib/action_dispatch/http/upload_rb.html | 77 + .../lib/action_dispatch/http/url_rb.html | 80 + .../action_dispatch/journey/formatter_rb.html | 89 + .../journey/gtg/builder_rb.html | 78 + .../journey/gtg/simulator_rb.html | 78 + .../journey/gtg/transition_table_rb.html | 80 + .../journey/nfa/builder_rb.html | 80 + .../action_dispatch/journey/nfa/dot_rb.html | 70 + .../journey/nfa/simulator_rb.html | 78 + .../journey/nfa/transition_table_rb.html | 78 + .../journey/nodes/node_rb.html | 78 + .../journey/parser_extras_rb.html | 87 + .../action_dispatch/journey/parser_rb.html | 91 + .../journey/path/pattern_rb.html | 70 + .../lib/action_dispatch/journey/route_rb.html | 83 + .../journey/router/utils_rb.html | 70 + .../action_dispatch/journey/router_rb.html | 88 + .../action_dispatch/journey/routes_rb.html | 70 + .../action_dispatch/journey/scanner_rb.html | 78 + .../action_dispatch/journey/visitors_rb.html | 77 + .../lib/action_dispatch/journey_rb.html | 71 + .../middleware/callbacks_rb.html | 75 + .../middleware/cookies_rb.html | 97 + .../middleware/debug_exceptions_rb.html | 101 + .../middleware/debug_locks_rb.html | 77 + .../middleware/exception_wrapper_rb.html | 85 + .../middleware/executor_rb.html | 83 + .../action_dispatch/middleware/flash_rb.html | 89 + .../middleware/public_exceptions_rb.html | 75 + .../middleware/reloader_rb.html | 75 + .../middleware/remote_ip_rb.html | 87 + .../middleware/request_id_rb.html | 85 + .../middleware/session/abstract_store_rb.html | 101 + .../middleware/session/cache_store_rb.html | 85 + .../middleware/session/cookie_store_rb.html | 91 + .../session/mem_cache_store_rb.html | 87 + .../middleware/show_exceptions_rb.html | 85 + .../action_dispatch/middleware/ssl_rb.html | 75 + .../action_dispatch/middleware/stack_rb.html | 87 + .../action_dispatch/middleware/static_rb.html | 89 + .../lib/action_dispatch/railtie_rb.html | 91 + .../action_dispatch/request/session_rb.html | 83 + .../lib/action_dispatch/request/utils_rb.html | 85 + .../action_dispatch/routing/endpoint_rb.html | 72 + .../action_dispatch/routing/inspector_rb.html | 91 + .../action_dispatch/routing/mapper_rb.html | 113 + .../routing/polymorphic_routes_rb.html | 72 + .../routing/redirection_rb.html | 99 + .../action_dispatch/routing/route_set_rb.html | 123 + .../routing/routes_proxy_rb.html | 78 + .../action_dispatch/routing/url_for_rb.html | 74 + .../lib/action_dispatch/routing_rb.html | 78 + .../action_dispatch/system_test_case_rb.html | 99 + .../system_testing/browser_rb.html | 70 + .../system_testing/driver_rb.html | 70 + .../system_testing/server_rb.html | 70 + .../test_helpers/screenshot_helper_rb.html | 74 + .../test_helpers/setup_and_teardown_rb.html | 72 + .../test_helpers/undef_methods_rb.html | 72 + .../testing/assertion_response_rb.html | 75 + .../testing/assertions/response_rb.html | 74 + .../testing/assertions/routing_rb.html | 94 + .../testing/assertions_rb.html | 78 + .../testing/integration_rb.html | 113 + .../testing/request_encoder_rb.html | 79 + .../testing/test_process_rb.html | 89 + .../testing/test_request_rb.html | 85 + .../testing/test_response_rb.html | 85 + src/5.2/files/actionview/README_rdoc.html | 99 + .../actionview/lib/action_view/base_rb.html | 99 + .../lib/action_view/buffers_rb.html | 76 + .../lib/action_view/context_rb.html | 70 + .../action_view/dependency_tracker_rb.html | 78 + .../lib/action_view/digestor_rb.html | 101 + .../actionview/lib/action_view/flows_rb.html | 78 + .../lib/action_view/gem_version_rb.html | 70 + .../helpers/active_model_helper_rb.html | 84 + .../helpers/asset_tag_helper_rb.html | 92 + .../helpers/asset_url_helper_rb.html | 80 + .../helpers/atom_feed_helper_rb.html | 80 + .../action_view/helpers/cache_helper_rb.html | 72 + .../helpers/capture_helper_rb.html | 80 + .../helpers/controller_helper_rb.html | 78 + .../action_view/helpers/csp_helper_rb.html | 72 + .../action_view/helpers/csrf_helper_rb.html | 72 + .../action_view/helpers/date_helper_rb.html | 99 + .../action_view/helpers/debug_helper_rb.html | 72 + .../action_view/helpers/form_helper_rb.html | 109 + .../helpers/form_options_helper_rb.html | 97 + .../helpers/form_tag_helper_rb.html | 86 + .../helpers/javascript_helper_rb.html | 80 + .../action_view/helpers/number_helper_rb.html | 93 + .../helpers/output_safety_helper_rb.html | 80 + .../helpers/record_tag_helper_rb.html | 72 + .../helpers/rendering_helper_rb.html | 72 + .../helpers/sanitize_helper_rb.html | 84 + .../action_view/helpers/tag_helper_rb.html | 82 + .../lib/action_view/helpers/tags/base_rb.html | 70 + .../helpers/tags/check_box_rb.html | 78 + .../helpers/tags/checkable_rb.html | 70 + .../tags/collection_check_boxes_rb.html | 78 + .../helpers/tags/collection_helpers_rb.html | 70 + .../tags/collection_radio_buttons_rb.html | 78 + .../helpers/tags/collection_select_rb.html | 70 + .../helpers/tags/color_field_rb.html | 70 + .../helpers/tags/date_field_rb.html | 70 + .../helpers/tags/date_select_rb.html | 78 + .../helpers/tags/datetime_field_rb.html | 70 + .../helpers/tags/datetime_local_field_rb.html | 70 + .../helpers/tags/datetime_select_rb.html | 70 + .../helpers/tags/email_field_rb.html | 70 + .../helpers/tags/file_field_rb.html | 70 + .../tags/grouped_collection_select_rb.html | 70 + .../helpers/tags/hidden_field_rb.html | 70 + .../action_view/helpers/tags/label_rb.html | 70 + .../helpers/tags/month_field_rb.html | 70 + .../helpers/tags/number_field_rb.html | 70 + .../helpers/tags/password_field_rb.html | 70 + .../helpers/tags/placeholderable_rb.html | 70 + .../helpers/tags/radio_button_rb.html | 78 + .../helpers/tags/range_field_rb.html | 70 + .../helpers/tags/search_field_rb.html | 70 + .../action_view/helpers/tags/select_rb.html | 70 + .../helpers/tags/tel_field_rb.html | 70 + .../helpers/tags/text_area_rb.html | 78 + .../helpers/tags/text_field_rb.html | 78 + .../helpers/tags/time_field_rb.html | 70 + .../helpers/tags/time_select_rb.html | 70 + .../helpers/tags/time_zone_select_rb.html | 72 + .../helpers/tags/translator_rb.html | 70 + .../helpers/tags/url_field_rb.html | 70 + .../helpers/tags/week_field_rb.html | 70 + .../lib/action_view/helpers/tags_rb.html | 70 + .../action_view/helpers/text_helper_rb.html | 82 + .../helpers/translation_helper_rb.html | 84 + .../action_view/helpers/url_helper_rb.html | 88 + .../lib/action_view/helpers_rb.html | 78 + .../lib/action_view/layouts_rb.html | 82 + .../lib/action_view/log_subscriber_rb.html | 83 + .../lib/action_view/lookup_context_rb.html | 93 + .../lib/action_view/model_naming_rb.html | 68 + .../lib/action_view/path_set_rb.html | 68 + .../lib/action_view/railtie_rb.html | 89 + .../lib/action_view/record_identifier_rb.html | 80 + .../renderer/abstract_renderer_rb.html | 70 + .../collection_caching_rb.html | 70 + .../renderer/partial_renderer_rb.html | 87 + .../lib/action_view/renderer/renderer_rb.html | 75 + .../streaming_template_renderer_rb.html | 76 + .../renderer/template_renderer_rb.html | 76 + .../lib/action_view/rendering_rb.html | 80 + .../lib/action_view/routing_url_for_rb.html | 86 + .../lib/action_view/template/error_rb.html | 83 + .../template/handlers/builder_rb.html | 87 + .../template/handlers/erb/erubi_rb.html | 87 + .../action_view/template/handlers/erb_rb.html | 79 + .../template/handlers/html_rb.html | 79 + .../action_view/template/handlers/raw_rb.html | 79 + .../lib/action_view/template/handlers_rb.html | 77 + .../lib/action_view/template/html_rb.html | 75 + .../lib/action_view/template/resolver_rb.html | 103 + .../lib/action_view/template/text_rb.html | 75 + .../lib/action_view/template/types_rb.html | 87 + .../lib/action_view/template_rb.html | 89 + .../lib/action_view/test_case_rb.html | 107 + .../lib/action_view/testing/resolvers_rb.html | 85 + .../lib/action_view/version_rb.html | 68 + .../lib/action_view/view_paths_rb.html | 72 + src/5.2/files/activejob/README_md.html | 163 + .../lib/active_job/arguments_rb.html | 87 + .../activejob/lib/active_job/base_rb.html | 101 + .../lib/active_job/callbacks_rb.html | 80 + .../lib/active_job/configured_job_rb.html | 68 + .../activejob/lib/active_job/core_rb.html | 72 + .../lib/active_job/enqueuing_rb.html | 80 + .../lib/active_job/exceptions_rb.html | 82 + .../lib/active_job/execution_rb.html | 82 + .../lib/active_job/gem_version_rb.html | 70 + .../activejob/lib/active_job/logging_rb.html | 84 + .../lib/active_job/queue_adapter_rb.html | 80 + .../queue_adapters/async_adapter_rb.html | 91 + .../queue_adapters/backburner_adapter_rb.html | 85 + .../delayed_job_adapter_rb.html | 85 + .../queue_adapters/inline_adapter_rb.html | 77 + .../queue_adapters/qu_adapter_rb.html | 85 + .../queue_adapters/que_adapter_rb.html | 85 + .../queue_classic_adapter_rb.html | 85 + .../queue_adapters/resque_adapter_rb.html | 93 + .../queue_adapters/sidekiq_adapter_rb.html | 85 + .../queue_adapters/sneakers_adapter_rb.html | 89 + .../sucker_punch_adapter_rb.html | 85 + .../queue_adapters/test_adapter_rb.html | 77 + .../lib/active_job/queue_adapters_rb.html | 70 + .../lib/active_job/queue_name_rb.html | 72 + .../lib/active_job/queue_priority_rb.html | 72 + .../activejob/lib/active_job/railtie_rb.html | 80 + .../lib/active_job/test_case_rb.html | 83 + .../lib/active_job/test_helper_rb.html | 86 + .../lib/active_job/translation_rb.html | 68 + .../activejob/lib/active_job/version_rb.html | 68 + src/5.2/files/activemodel/README_rdoc.html | 322 ++ .../attribute/user_provided_default_rb.html | 76 + .../active_model/attribute_assignment_rb.html | 78 + .../active_model/attribute_methods_rb.html | 87 + .../attribute_mutation_tracker_rb.html | 76 + .../lib/active_model/attribute_rb.html | 76 + .../attribute_set/builder_rb.html | 76 + .../attribute_set/yaml_encoder_rb.html | 68 + .../lib/active_model/attribute_set_rb.html | 80 + .../lib/active_model/attributes_rb.html | 84 + .../lib/active_model/callbacks_rb.html | 80 + .../lib/active_model/conversion_rb.html | 72 + .../lib/active_model/dirty_rb.html | 84 + .../lib/active_model/errors_rb.html | 95 + .../forbidden_attributes_protection_rb.html | 75 + .../lib/active_model/gem_version_rb.html | 70 + .../activemodel/lib/active_model/lint_rb.html | 72 + .../lib/active_model/model_rb.html | 70 + .../lib/active_model/naming_rb.html | 91 + .../lib/active_model/railtie_rb.html | 78 + .../lib/active_model/secure_password_rb.html | 82 + .../lib/active_model/serialization_rb.html | 80 + .../lib/active_model/serializers/json_rb.html | 82 + .../lib/active_model/translation_rb.html | 70 + .../lib/active_model/type/big_integer_rb.html | 78 + .../lib/active_model/type/binary_rb.html | 70 + .../lib/active_model/type/boolean_rb.html | 77 + .../lib/active_model/type/date_rb.html | 70 + .../lib/active_model/type/date_time_rb.html | 70 + .../lib/active_model/type/decimal_rb.html | 78 + .../lib/active_model/type/float_rb.html | 70 + .../accepts_multiparameter_time_rb.html | 79 + .../active_model/type/helpers/mutable_rb.html | 74 + .../active_model/type/helpers/numeric_rb.html | 74 + .../type/helpers/time_value_rb.html | 84 + .../type/helpers/timezone_rb.html | 82 + .../lib/active_model/type/helpers_rb.html | 71 + .../type/immutable_string_rb.html | 72 + .../lib/active_model/type/integer_rb.html | 70 + .../lib/active_model/type/registry_rb.html | 79 + .../lib/active_model/type/string_rb.html | 78 + .../lib/active_model/type/time_rb.html | 70 + .../lib/active_model/type/value_rb.html | 77 + .../activemodel/lib/active_model/type_rb.html | 104 + .../active_model/validations/absence_rb.html | 72 + .../validations/acceptance_rb.html | 83 + .../validations/callbacks_rb.html | 74 + .../validations/clusivity_rb.html | 78 + .../validations/confirmation_rb.html | 72 + .../validations/exclusion_rb.html | 80 + .../active_model/validations/format_rb.html | 72 + .../validations/helper_methods_rb.html | 72 + .../validations/inclusion_rb.html | 80 + .../active_model/validations/length_rb.html | 72 + .../validations/numericality_rb.html | 80 + .../active_model/validations/presence_rb.html | 72 + .../validations/validates_rb.html | 80 + .../lib/active_model/validations/with_rb.html | 80 + .../lib/active_model/validations_rb.html | 91 + .../lib/active_model/validator_rb.html | 83 + .../lib/active_model/version_rb.html | 68 + src/5.2/files/activerecord/README_rdoc.html | 271 ++ .../lib/active_record/aggregations_rb.html | 72 + .../association_relation_rb.html | 75 + .../associations/alias_tracker_rb.html | 78 + .../associations/association_rb.html | 78 + .../associations/association_scope_rb.html | 70 + .../belongs_to_association_rb.html | 70 + ...belongs_to_polymorphic_association_rb.html | 70 + .../associations/builder/association_rb.html | 86 + .../associations/builder/belongs_to_rb.html | 70 + .../builder/collection_association_rb.html | 78 + .../builder/has_and_belongs_to_many_rb.html | 70 + .../associations/builder/has_many_rb.html | 70 + .../associations/builder/has_one_rb.html | 70 + .../builder/singular_association_rb.html | 76 + .../collection_association_rb.html | 70 + .../associations/collection_proxy_rb.html | 77 + .../associations/foreign_association_rb.html | 70 + .../associations/has_many_association_rb.html | 70 + .../has_many_through_association_rb.html | 70 + .../associations/has_one_association_rb.html | 70 + .../has_one_through_association_rb.html | 70 + .../join_dependency/join_association_rb.html | 78 + .../join_dependency/join_base_rb.html | 78 + .../join_dependency/join_part_rb.html | 70 + .../associations/join_dependency_rb.html | 72 + .../preloader/association_rb.html | 70 + .../preloader/through_association_rb.html | 70 + .../associations/preloader_rb.html | 70 + .../associations/singular_association_rb.html | 70 + .../associations/through_association_rb.html | 70 + .../lib/active_record/associations_rb.html | 93 + .../attribute_assignment_rb.html | 78 + .../attribute_decorators_rb.html | 68 + .../before_type_cast_rb.html | 72 + .../attribute_methods/dirty_rb.html | 82 + .../attribute_methods/primary_key_rb.html | 82 + .../attribute_methods/query_rb.html | 83 + .../attribute_methods/read_rb.html | 72 + .../attribute_methods/serialization_rb.html | 81 + .../time_zone_conversion_rb.html | 72 + .../attribute_methods/write_rb.html | 72 + .../active_record/attribute_methods_rb.html | 82 + .../lib/active_record/attributes_rb.html | 82 + .../autosave_association_rb.html | 72 + .../lib/active_record/base_rb.html | 127 + .../lib/active_record/callbacks_rb.html | 70 + .../lib/active_record/coders/json_rb.html | 70 + .../active_record/coders/yaml_column_rb.html | 76 + .../collection_cache_key_rb.html | 72 + .../abstract/connection_pool_rb.html | 101 + .../abstract/database_limits_rb.html | 72 + .../abstract/database_statements_rb.html | 81 + .../abstract/query_cache_rb.html | 84 + .../abstract/quoting_rb.html | 84 + .../abstract/savepoints_rb.html | 72 + .../abstract/schema_creation_rb.html | 85 + .../abstract/schema_definitions_rb.html | 81 + .../abstract/schema_dumper_rb.html | 78 + .../abstract/schema_statements_rb.html | 86 + .../abstract/transaction_rb.html | 83 + .../abstract_adapter_rb.html | 107 + .../abstract_mysql_adapter_rb.html | 107 + .../connection_adapters/column_rb.html | 79 + .../connection_specification_rb.html | 80 + .../determine_if_preparable_visitor_rb.html | 72 + .../connection_adapters/mysql/column_rb.html | 72 + .../mysql/database_statements_rb.html | 76 + .../mysql/explain_pretty_printer_rb.html | 72 + .../connection_adapters/mysql/quoting_rb.html | 72 + .../mysql/schema_creation_rb.html | 72 + .../mysql/schema_definitions_rb.html | 83 + .../mysql/schema_dumper_rb.html | 72 + .../mysql/schema_statements_rb.html | 72 + .../mysql/type_metadata_rb.html | 72 + .../mysql2_adapter_rb.html | 91 + .../postgresql/column_rb.html | 70 + .../postgresql/database_statements_rb.html | 76 + .../postgresql/explain_pretty_printer_rb.html | 72 + .../postgresql/oid/array_rb.html | 76 + .../postgresql/oid/bit_rb.html | 83 + .../postgresql/oid/bit_varying_rb.html | 74 + .../postgresql/oid/bytea_rb.html | 76 + .../postgresql/oid/cidr_rb.html | 82 + .../postgresql/oid/date_rb.html | 74 + .../postgresql/oid/date_time_rb.html | 74 + .../postgresql/oid/decimal_rb.html | 74 + .../postgresql/oid/enum_rb.html | 74 + .../postgresql/oid/hstore_rb.html | 74 + .../postgresql/oid/inet_rb.html | 74 + .../postgresql/oid/jsonb_rb.html | 74 + .../postgresql/oid/legacy_point_rb.html | 74 + .../postgresql/oid/money_rb.html | 74 + .../postgresql/oid/oid_rb.html | 74 + .../postgresql/oid/point_rb.html | 74 + .../postgresql/oid/range_rb.html | 74 + .../postgresql/oid/specialized_string_rb.html | 74 + .../oid/type_map_initializer_rb.html | 74 + .../postgresql/oid/uuid_rb.html | 74 + .../postgresql/oid/vector_rb.html | 74 + .../postgresql/oid/xml_rb.html | 74 + .../postgresql/oid_rb.html | 124 + .../postgresql/quoting_rb.html | 85 + .../postgresql/referential_integrity_rb.html | 72 + .../postgresql/schema_creation_rb.html | 72 + .../postgresql/schema_definitions_rb.html | 85 + .../postgresql/schema_dumper_rb.html | 72 + .../postgresql/schema_statements_rb.html | 74 + .../postgresql/type_metadata_rb.html | 77 + .../postgresql/utils_rb.html | 74 + .../postgresql_adapter_rb.html | 127 + .../connection_adapters/schema_cache_rb.html | 77 + .../sql_type_metadata_rb.html | 77 + .../sqlite3/explain_pretty_printer_rb.html | 72 + .../sqlite3/quoting_rb.html | 72 + .../sqlite3/schema_creation_rb.html | 72 + .../sqlite3/schema_definitions_rb.html | 79 + .../sqlite3/schema_dumper_rb.html | 72 + .../sqlite3/schema_statements_rb.html | 72 + .../sqlite3_adapter_rb.html | 107 + .../statement_pool_rb.html | 70 + .../active_record/connection_handling_rb.html | 72 + .../lib/active_record/core_rb.html | 86 + .../lib/active_record/counter_cache_rb.html | 72 + .../active_record/define_callbacks_rb.html | 70 + .../active_record/dynamic_matchers_rb.html | 81 + .../lib/active_record/enum_rb.html | 80 + .../lib/active_record/errors_rb.html | 151 + .../lib/active_record/explain_rb.html | 78 + .../active_record/explain_registry_rb.html | 76 + .../active_record/explain_subscriber_rb.html | 80 + .../active_record/fixture_set/file_rb.html | 85 + .../lib/active_record/fixtures_rb.html | 107 + .../lib/active_record/gem_version_rb.html | 70 + .../lib/active_record/inheritance_rb.html | 82 + .../lib/active_record/integration_rb.html | 82 + .../active_record/internal_metadata_rb.html | 78 + .../active_record/legacy_yaml_adapter_rb.html | 76 + .../active_record/locking/optimistic_rb.html | 74 + .../active_record/locking/pessimistic_rb.html | 72 + .../lib/active_record/log_subscriber_rb.html | 75 + .../migration/command_recorder_rb.html | 77 + .../migration/compatibility_rb.html | 87 + .../migration/join_table_rb.html | 75 + .../lib/active_record/migration_rb.html | 99 + .../lib/active_record/model_schema_rb.html | 82 + .../active_record/nested_attributes_rb.html | 93 + .../lib/active_record/no_touching_rb.html | 72 + .../lib/active_record/null_relation_rb.html | 68 + .../lib/active_record/persistence_rb.html | 72 + .../lib/active_record/query_cache_rb.html | 77 + .../lib/active_record/querying_rb.html | 72 + .../lib/active_record/railtie_rb.html | 107 + .../railties/console_sandbox_rb.html | 68 + .../railties/controller_runtime_rb.html | 78 + .../active_record/readonly_attributes_rb.html | 72 + .../lib/active_record/reflection_rb.html | 93 + .../relation/batches/batch_enumerator_rb.html | 77 + .../active_record/relation/batches_rb.html | 85 + .../relation/calculations_rb.html | 72 + .../active_record/relation/delegation_rb.html | 72 + .../relation/finder_methods_rb.html | 80 + .../relation/from_clause_rb.html | 75 + .../lib/active_record/relation/merger_rb.html | 85 + .../predicate_builder/array_handler_rb.html | 75 + .../association_query_value_rb.html | 75 + .../predicate_builder/base_handler_rb.html | 75 + .../basic_object_handler_rb.html | 75 + .../polymorphic_array_value_rb.html | 75 + .../predicate_builder/range_handler_rb.html | 79 + .../relation_handler_rb.html | 75 + .../relation/predicate_builder_rb.html | 97 + .../relation/query_attribute_rb.html | 83 + .../relation/query_methods_rb.html | 103 + .../relation/record_fetch_warning_rb.html | 79 + .../relation/spawn_methods_rb.html | 89 + .../relation/where_clause_factory_rb.html | 75 + .../relation/where_clause_rb.html | 75 + .../lib/active_record/relation_rb.html | 77 + .../lib/active_record/result_rb.html | 75 + .../active_record/runtime_registry_rb.html | 76 + .../lib/active_record/sanitization_rb.html | 76 + .../lib/active_record/schema_dumper_rb.html | 76 + .../active_record/schema_migration_rb.html | 78 + .../lib/active_record/schema_rb.html | 75 + .../lib/active_record/scoping/default_rb.html | 74 + .../lib/active_record/scoping/named_rb.html | 86 + .../lib/active_record/scoping_rb.html | 78 + .../lib/active_record/secure_token_rb.html | 80 + .../lib/active_record/serialization_rb.html | 70 + .../lib/active_record/statement_cache_rb.html | 68 + .../lib/active_record/store_rb.html | 82 + .../lib/active_record/suppressor_rb.html | 72 + .../lib/active_record/table_metadata_rb.html | 68 + .../tasks/database_tasks_rb.html | 79 + .../tasks/mysql_database_tasks_rb.html | 70 + .../tasks/postgresql_database_tasks_rb.html | 80 + .../tasks/sqlite_database_tasks_rb.html | 78 + .../lib/active_record/timestamp_rb.html | 70 + .../lib/active_record/touch_later_rb.html | 72 + .../lib/active_record/transactions_rb.html | 72 + .../lib/active_record/translation_rb.html | 70 + .../type/adapter_specific_registry_rb.html | 91 + .../lib/active_record/type/date_rb.html | 77 + .../lib/active_record/type/date_time_rb.html | 77 + .../type/decimal_without_scale_rb.html | 70 + .../type/hash_lookup_type_map_rb.html | 70 + .../type/internal/timezone_rb.html | 74 + .../lib/active_record/type/json_rb.html | 81 + .../lib/active_record/type/serialized_rb.html | 72 + .../lib/active_record/type/text_rb.html | 70 + .../lib/active_record/type/time_rb.html | 77 + .../lib/active_record/type/type_map_rb.html | 78 + .../type/unsigned_integer_rb.html | 70 + .../type_caster/connection_rb.html | 68 + .../lib/active_record/type_caster/map_rb.html | 68 + .../lib/active_record/type_caster_rb.html | 78 + .../lib/active_record/type_rb.html | 102 + .../active_record/validations/absence_rb.html | 72 + .../validations/associated_rb.html | 72 + .../active_record/validations/length_rb.html | 72 + .../validations/presence_rb.html | 72 + .../validations/uniqueness_rb.html | 72 + .../lib/active_record/validations_rb.html | 93 + .../lib/active_record/version_rb.html | 68 + src/5.2/files/activestorage/README_md.html | 210 ++ .../active_storage/base_controller_rb.html | 81 + .../active_storage/blobs_controller_rb.html | 81 + .../direct_uploads_controller_rb.html | 81 + .../active_storage/disk_controller_rb.html | 81 + .../representations_controller_rb.html | 81 + .../concerns/active_storage/set_blob_rb.html | 68 + .../jobs/active_storage/analyze_job_rb.html | 81 + .../app/jobs/active_storage/base_job_rb.html | 75 + .../app/jobs/active_storage/purge_job_rb.html | 83 + .../models/active_storage/attachment_rb.html | 83 + .../active_storage/blob/analyzable_rb.html | 85 + .../active_storage/blob/identifiable_rb.html | 77 + .../active_storage/blob/representable_rb.html | 77 + .../app/models/active_storage/blob_rb.html | 94 + .../app/models/active_storage/current_rb.html | 68 + .../filename/parameters_rb.html | 75 + .../models/active_storage/filename_rb.html | 81 + .../app/models/active_storage/preview_rb.html | 101 + .../app/models/active_storage/variant_rb.html | 85 + .../models/active_storage/variation_rb.html | 99 + .../analyzer/image_analyzer_rb.html | 85 + .../analyzer/null_analyzer_rb.html | 75 + .../analyzer/video_analyzer_rb.html | 85 + .../lib/active_storage/analyzer_rb.html | 83 + .../active_storage/attached/macros_rb.html | 77 + .../lib/active_storage/attached/many_rb.html | 77 + .../lib/active_storage/attached/one_rb.html | 77 + .../lib/active_storage/attached_rb.html | 97 + .../lib/active_storage/downloading_rb.html | 78 + .../lib/active_storage/engine_rb.html | 103 + .../lib/active_storage/errors_rb.html | 79 + .../lib/active_storage/gem_version_rb.html | 70 + .../lib/active_storage/log_subscriber_rb.html | 83 + .../previewer/mupdf_previewer_rb.html | 77 + .../previewer/poppler_pdf_previewer_rb.html | 77 + .../previewer/video_previewer_rb.html | 77 + .../lib/active_storage/previewer_rb.html | 85 + .../service/azure_storage_service_rb.html | 89 + .../service/configurator_rb.html | 75 + .../service/disk_service_rb.html | 93 + .../service/gcs_service_rb.html | 89 + .../service/mirror_service_rb.html | 85 + .../active_storage/service/s3_service_rb.html | 87 + .../lib/active_storage/service_rb.html | 87 + .../lib/active_storage/version_rb.html | 68 + src/5.2/files/activesupport/README_rdoc.html | 99 + .../lib/active_support/all_rb.html | 67 + .../lib/active_support/array_inquirer_rb.html | 75 + .../active_support/backtrace_cleaner_rb.html | 75 + .../lib/active_support/benchmarkable_rb.html | 80 + .../lib/active_support/builder_rb.html | 63 + .../active_support/cache/file_store_rb.html | 93 + .../cache/mem_cache_store_rb.html | 91 + .../active_support/cache/memory_store_rb.html | 85 + .../active_support/cache/null_store_rb.html | 79 + .../cache/redis_cache_store_rb.html | 99 + .../strategy/local_cache_middleware_rb.html | 84 + .../cache/strategy/local_cache_rb.html | 93 + .../lib/active_support/cache_rb.html | 103 + .../lib/active_support/callbacks_rb.html | 111 + .../lib/active_support/concern_rb.html | 70 + .../load_interlock_aware_monitor_rb.html | 85 + .../concurrency/share_lock_rb.html | 87 + .../lib/active_support/configurable_rb.html | 93 + .../core_ext/array/access_rb.html | 68 + .../core_ext/array/conversions_rb.html | 93 + .../core_ext/array/extract_options_rb.html | 70 + .../core_ext/array/grouping_rb.html | 68 + .../core_ext/array/inquiry_rb.html | 83 + .../core_ext/array/prepend_and_append_rb.html | 68 + .../core_ext/array/wrap_rb.html | 68 + .../lib/active_support/core_ext/array_rb.html | 75 + .../active_support/core_ext/benchmark_rb.html | 76 + .../core_ext/big_decimal/conversions_rb.html | 78 + .../core_ext/big_decimal_rb.html | 63 + .../class/attribute_accessors_rb.html | 69 + .../core_ext/class/attribute_rb.html | 80 + .../core_ext/class/subclasses_rb.html | 68 + .../lib/active_support/core_ext/class_rb.html | 65 + .../core_ext/date/acts_like_rb.html | 76 + .../core_ext/date/blank_rb.html | 76 + .../core_ext/date/calculations_rb.html | 93 + .../core_ext/date/conversions_rb.html | 82 + .../core_ext/date/zones_rb.html | 78 + .../date_and_time/calculations_rb.html | 78 + .../date_and_time/compatibility_rb.html | 78 + .../core_ext/date_and_time/zones_rb.html | 72 + .../lib/active_support/core_ext/date_rb.html | 71 + .../core_ext/date_time/acts_like_rb.html | 78 + .../core_ext/date_time/blank_rb.html | 76 + .../core_ext/date_time/calculations_rb.html | 76 + .../core_ext/date_time/compatibility_rb.html | 78 + .../core_ext/date_time/conversions_rb.html | 91 + .../active_support/core_ext/date_time_rb.html | 71 + .../core_ext/digest/uuid_rb.html | 78 + .../active_support/core_ext/digest_rb.html | 63 + .../core_ext/enumerable_rb.html | 77 + .../core_ext/file/atomic_rb.html | 78 + .../lib/active_support/core_ext/file_rb.html | 63 + .../core_ext/hash/compact_rb.html | 68 + .../core_ext/hash/conversions_rb.html | 103 + .../core_ext/hash/deep_merge_rb.html | 68 + .../core_ext/hash/except_rb.html | 68 + .../core_ext/hash/indifferent_access_rb.html | 83 + .../active_support/core_ext/hash/keys_rb.html | 68 + .../core_ext/hash/reverse_merge_rb.html | 68 + .../core_ext/hash/slice_rb.html | 68 + .../core_ext/hash/transform_values_rb.html | 68 + .../lib/active_support/core_ext/hash_rb.html | 79 + .../core_ext/integer/inflections_rb.html | 83 + .../core_ext/integer/multiple_rb.html | 68 + .../core_ext/integer/time_rb.html | 85 + .../active_support/core_ext/integer_rb.html | 67 + .../core_ext/kernel/agnostics_rb.html | 68 + .../core_ext/kernel/concern_rb.html | 76 + .../core_ext/kernel/reporting_rb.html | 68 + .../core_ext/kernel/singleton_class_rb.html | 68 + .../active_support/core_ext/kernel_rb.html | 69 + .../core_ext/load_error_rb.html | 68 + .../active_support/core_ext/marshal_rb.html | 68 + .../core_ext/module/aliasing_rb.html | 68 + .../core_ext/module/anonymous_rb.html | 68 + .../core_ext/module/attr_internal_rb.html | 68 + .../attribute_accessors_per_thread_rb.html | 78 + .../module/attribute_accessors_rb.html | 78 + .../core_ext/module/concerning_rb.html | 83 + .../core_ext/module/delegation_rb.html | 80 + .../core_ext/module/deprecation_rb.html | 75 + .../core_ext/module/introspection_rb.html | 83 + .../core_ext/module/reachable_rb.html | 78 + .../core_ext/module/redefine_method_rb.html | 68 + .../core_ext/module/remove_method_rb.html | 76 + .../active_support/core_ext/module_rb.html | 85 + .../core_ext/name_error_rb.html | 68 + .../core_ext/numeric/bytes_rb.html | 68 + .../core_ext/numeric/conversions_rb.html | 82 + .../core_ext/numeric/inquiry_rb.html | 70 + .../core_ext/numeric/time_rb.html | 91 + .../active_support/core_ext/numeric_rb.html | 69 + .../core_ext/object/acts_like_rb.html | 68 + .../core_ext/object/blank_rb.html | 94 + .../core_ext/object/conversions_rb.html | 69 + .../core_ext/object/deep_dup_rb.html | 80 + .../core_ext/object/duplicable_rb.html | 94 + .../core_ext/object/inclusion_rb.html | 68 + .../object/instance_variables_rb.html | 68 + .../core_ext/object/json_rb.html | 149 + .../core_ext/object/to_param_rb.html | 63 + .../core_ext/object/to_query_rb.html | 86 + .../core_ext/object/try_rb.html | 87 + .../core_ext/object/with_options_rb.html | 83 + .../active_support/core_ext/object_rb.html | 85 + .../core_ext/range/compare_range_rb.html | 68 + .../core_ext/range/conversions_rb.html | 70 + .../core_ext/range/each_rb.html | 76 + .../core_ext/range/include_range_rb.html | 63 + .../range/include_time_with_zone_rb.html | 76 + .../core_ext/range/overlaps_rb.html | 68 + .../lib/active_support/core_ext/range_rb.html | 71 + .../active_support/core_ext/regexp_rb.html | 55 + .../core_ext/securerandom_rb.html | 76 + .../core_ext/string/access_rb.html | 68 + .../core_ext/string/behavior_rb.html | 68 + .../core_ext/string/conversions_rb.html | 78 + .../core_ext/string/exclude_rb.html | 68 + .../core_ext/string/filters_rb.html | 68 + .../core_ext/string/indent_rb.html | 68 + .../core_ext/string/inflections_rb.html | 85 + .../core_ext/string/inquiry_rb.html | 83 + .../core_ext/string/multibyte_rb.html | 83 + .../core_ext/string/output_safety_rb.html | 101 + .../core_ext/string/starts_ends_with_rb.html | 68 + .../core_ext/string/strip_rb.html | 68 + .../core_ext/string/zones_rb.html | 78 + .../active_support/core_ext/string_rb.html | 87 + .../core_ext/time/acts_like_rb.html | 76 + .../core_ext/time/calculations_rb.html | 93 + .../core_ext/time/compatibility_rb.html | 78 + .../core_ext/time/conversions_rb.html | 85 + .../core_ext/time/zones_rb.html | 87 + .../lib/active_support/core_ext/time_rb.html | 71 + .../lib/active_support/core_ext/uri_rb.html | 78 + .../lib/active_support/core_ext_rb.html | 55 + .../active_support/current_attributes_rb.html | 75 + .../dependencies/autoload_rb.html | 78 + .../dependencies/interlock_rb.html | 87 + .../lib/active_support/dependencies_rb.html | 117 + .../deprecation/behaviors_rb.html | 87 + .../deprecation/constant_accessor_rb.html | 85 + .../deprecation/instance_delegator_rb.html | 85 + .../deprecation/method_wrappers_rb.html | 87 + .../deprecation/proxy_wrappers_rb.html | 91 + .../deprecation/reporting_rb.html | 85 + .../lib/active_support/deprecation_rb.html | 97 + .../descendants_tracker_rb.html | 70 + .../lib/active_support/digest_rb.html | 68 + .../duration/iso8601_parser_rb.html | 89 + .../duration/iso8601_serializer_rb.html | 85 + .../lib/active_support/duration_rb.html | 91 + .../encrypted_configuration_rb.html | 91 + .../lib/active_support/encrypted_file_rb.html | 89 + .../evented_file_update_checker_rb.html | 91 + .../active_support/execution_wrapper_rb.html | 83 + .../lib/active_support/executor_rb.html | 83 + .../file_update_checker_rb.html | 83 + .../lib/active_support/gem_version_rb.html | 70 + .../lib/active_support/gzip_rb.html | 87 + .../hash_with_indifferent_access_rb.html | 85 + .../lib/active_support/i18n_railtie_rb.html | 67 + .../lib/active_support/i18n_rb.html | 71 + .../lib/active_support/inflections_rb.html | 76 + .../inflector/inflections_rb.html | 95 + .../active_support/inflector/methods_rb.html | 80 + .../inflector/transliterate_rb.html | 80 + .../lib/active_support/inflector_rb.html | 77 + .../lib/active_support/json/decoding_rb.html | 82 + .../lib/active_support/json/encoding_rb.html | 80 + .../lib/active_support/json_rb.html | 65 + .../lib/active_support/key_generator_rb.html | 87 + .../active_support/lazy_load_hooks_rb.html | 70 + .../log_subscriber/test_helper_rb.html | 91 + .../lib/active_support/log_subscriber_rb.html | 87 + .../lib/active_support/logger_rb.html | 89 + .../lib/active_support/logger_silence_rb.html | 80 + .../logger_thread_safe_level_rb.html | 78 + .../active_support/message_encryptor_rb.html | 95 + .../active_support/message_verifier_rb.html | 95 + .../active_support/messages/metadata_rb.html | 78 + .../messages/rotation_configuration_rb.html | 70 + .../active_support/messages/rotator_rb.html | 76 + .../active_support/multibyte/chars_rb.html | 93 + .../active_support/multibyte/unicode_rb.html | 81 + .../lib/active_support/multibyte_rb.html | 70 + .../notifications/fanout_rb.html | 87 + .../notifications/instrumenter_rb.html | 87 + .../lib/active_support/notifications_rb.html | 82 + .../number_helper/number_converter_rb.html | 86 + .../number_to_currency_converter_rb.html | 78 + .../number_to_delimited_converter_rb.html | 70 + .../number_to_human_converter_rb.html | 70 + .../number_to_human_size_converter_rb.html | 70 + .../number_to_percentage_converter_rb.html | 70 + .../number_to_phone_converter_rb.html | 70 + .../number_to_rounded_converter_rb.html | 70 + .../number_helper/rounding_helper_rb.html | 70 + .../lib/active_support/number_helper_rb.html | 70 + .../lib/active_support/option_merger_rb.html | 76 + .../lib/active_support/ordered_hash_rb.html | 83 + .../active_support/ordered_options_rb.html | 85 + .../per_thread_registry_rb.html | 78 + .../lib/active_support/proxy_object_rb.html | 75 + .../lib/active_support/rails_rb.html | 85 + .../lib/active_support/railtie_rb.html | 82 + .../lib/active_support/reloader_rb.html | 83 + .../lib/active_support/rescuable_rb.html | 84 + .../lib/active_support/security_utils_rb.html | 78 + .../active_support/string_inquirer_rb.html | 75 + .../lib/active_support/subscriber_rb.html | 89 + .../lib/active_support/tagged_logging_rb.html | 91 + .../lib/active_support/test_case_rb.html | 101 + .../active_support/testing/assertions_rb.html | 72 + .../active_support/testing/autorun_rb.html | 63 + .../testing/constant_lookup_rb.html | 82 + .../testing/declarative_rb.html | 72 + .../testing/deprecation_rb.html | 80 + .../testing/file_fixtures_rb.html | 72 + .../active_support/testing/isolation_rb.html | 88 + .../testing/method_call_assertions_rb.html | 80 + .../testing/setup_and_teardown_rb.html | 84 + .../lib/active_support/testing/stream_rb.html | 77 + .../testing/tagged_logging_rb.html | 70 + .../testing/time_helpers_rb.html | 86 + .../lib/active_support/time_rb.html | 92 + .../lib/active_support/time_with_zone_rb.html | 93 + .../active_support/values/time_zone_rb.html | 87 + .../lib/active_support/version_rb.html | 68 + .../lib/active_support/xml_mini/jdom_rb.html | 78 + .../active_support/xml_mini/libxml_rb.html | 80 + .../active_support/xml_mini/libxmlsax_rb.html | 89 + .../active_support/xml_mini/nokogiri_rb.html | 80 + .../xml_mini/nokogirisax_rb.html | 89 + .../lib/active_support/xml_mini/rexml_rb.html | 82 + .../lib/active_support/xml_mini_rb.html | 88 + src/5.2/files/railties/RDOC_MAIN_rdoc.html | 123 + src/5.2/files/railties/README_rdoc.html | 106 + .../lib/minitest/rails_plugin_rb.html | 89 + src/5.2/files/railties/lib/rails/all_rb.html | 63 + .../files/railties/lib/rails/api/task_rb.html | 93 + .../railties/lib/rails/app_loader_rb.html | 80 + .../railties/lib/rails/app_updater_rb.html | 84 + .../lib/rails/application/bootstrap_rb.html | 99 + .../rails/application/configuration_rb.html | 107 + .../default_middleware_stack_rb.html | 91 + .../lib/rails/application/finisher_rb.html | 83 + .../rails/application/routes_reloader_rb.html | 87 + .../lib/rails/application_controller_rb.html | 68 + .../railties/lib/rails/application_rb.html | 109 + .../lib/rails/backtrace_cleaner_rb.html | 83 + src/5.2/files/railties/lib/rails/cli_rb.html | 80 + .../rails/code_statistics_calculator_rb.html | 55 + .../lib/rails/code_statistics_rb.html | 65 + .../lib/rails/command/actions_rb.html | 72 + .../railties/lib/rails/command/base_rb.html | 93 + .../lib/rails/command/behavior_rb.html | 78 + .../command/environment_argument_rb.html | 80 + .../lib/rails/command/helpers/editor_rb.html | 82 + .../files/railties/lib/rails/command_rb.html | 88 + .../application/application_command_rb.html | 82 + .../commands/console/console_command_rb.html | 91 + .../credentials/credentials_command_rb.html | 90 + .../dbconsole/dbconsole_command_rb.html | 89 + .../commands/destroy/destroy_command_rb.html | 78 + .../encrypted/encrypted_command_rb.html | 92 + .../generate/generate_command_rb.html | 78 + .../rails/commands/help/help_command_rb.html | 70 + .../rails/commands/new/new_command_rb.html | 70 + .../commands/plugin/plugin_command_rb.html | 82 + .../rails/commands/rake/rake_command_rb.html | 78 + .../commands/runner/runner_command_rb.html | 70 + .../commands/secrets/secrets_command_rb.html | 80 + .../commands/server/server_command_rb.html | 101 + .../rails/commands/test/test_command_rb.html | 82 + .../commands/version/version_command_rb.html | 70 + .../files/railties/lib/rails/commands_rb.html | 76 + .../railties/lib/rails/configuration_rb.html | 91 + .../railties/lib/rails/console/app_rb.html | 84 + .../lib/rails/console/helpers_rb.html | 70 + .../railties/lib/rails/dev_caching_rb.html | 76 + .../lib/rails/engine/commands_rb.html | 63 + .../lib/rails/engine/configuration_rb.html | 87 + .../lib/rails/engine/railties_rb.html | 77 + .../railties/lib/rails/engine/updater_rb.html | 89 + .../files/railties/lib/rails/engine_rb.html | 107 + .../railties/lib/rails/gem_version_rb.html | 70 + .../actions/create_migration_rb.html | 82 + .../lib/rails/generators/actions_rb.html | 74 + .../lib/rails/generators/active_model_rb.html | 77 + .../lib/rails/generators/app_base_rb.html | 105 + .../lib/rails/generators/base_rb.html | 85 + .../css/assets/assets_generator_rb.html | 63 + .../css/scaffold/scaffold_generator_rb.html | 78 + .../controller/controller_generator_rb.html | 63 + .../erb/mailer/mailer_generator_rb.html | 63 + .../erb/scaffold/scaffold_generator_rb.html | 65 + .../railties/lib/rails/generators/erb_rb.html | 63 + .../generators/generated_attribute_rb.html | 78 + .../js/assets/assets_generator_rb.html | 63 + .../lib/rails/generators/migration_rb.html | 84 + .../rails/generators/model_helpers_rb.html | 78 + .../lib/rails/generators/named_base_rb.html | 89 + .../rails/app/app_generator_rb.html | 93 + .../application_record_generator_rb.html | 70 + .../rails/assets/assets_generator_rb.html | 70 + .../controller/controller_generator_rb.html | 70 + .../credentials/credentials_generator_rb.html | 86 + .../encrypted_file_generator_rb.html | 84 + .../encryption_key_file_generator_rb.html | 84 + .../generator/generator_generator_rb.html | 70 + .../rails/helper/helper_generator_rb.html | 70 + .../integration_test_generator_rb.html | 70 + .../master_key/master_key_generator_rb.html | 86 + .../migration/migration_generator_rb.html | 70 + .../rails/model/model_generator_rb.html | 78 + .../rails/plugin/plugin_generator_rb.html | 89 + .../rails/resource/resource_generator_rb.html | 80 + .../resource_route_generator_rb.html | 70 + .../rails/scaffold/scaffold_generator_rb.html | 78 + .../scaffold_controller_generator_rb.html | 78 + .../system_test/system_test_generator_rb.html | 70 + .../rails/task/task_generator_rb.html | 70 + .../rails/generators/resource_helpers_rb.html | 80 + .../lib/rails/generators/test_case_rb.html | 93 + .../controller/controller_generator_rb.html | 63 + .../generator/generator_generator_rb.html | 63 + .../test_unit/helper/helper_generator_rb.html | 63 + .../integration/integration_generator_rb.html | 63 + .../test_unit/job/job_generator_rb.html | 63 + .../test_unit/mailer/mailer_generator_rb.html | 63 + .../test_unit/model/model_generator_rb.html | 63 + .../test_unit/plugin/plugin_generator_rb.html | 63 + .../scaffold/scaffold_generator_rb.html | 65 + .../test_unit/system/system_generator_rb.html | 63 + .../lib/rails/generators/test_unit_rb.html | 63 + .../generators/testing/assertions_rb.html | 74 + .../generators/testing/behaviour_rb.html | 96 + .../testing/setup_and_teardown_rb.html | 74 + .../railties/lib/rails/generators_rb.html | 96 + .../lib/rails/info_controller_rb.html | 89 + src/5.2/files/railties/lib/rails/info_rb.html | 80 + .../railties/lib/rails/initializable_rb.html | 89 + .../lib/rails/mailers_controller_rb.html | 91 + .../files/railties/lib/rails/paths_rb.html | 79 + .../railties/lib/rails/plugin/test_rb.html | 78 + .../railties/lib/rails/rack/logger_rb.html | 97 + src/5.2/files/railties/lib/rails/rack_rb.html | 70 + .../lib/rails/railtie/configurable_rb.html | 87 + .../lib/rails/railtie/configuration_rb.html | 87 + .../files/railties/lib/rails/railtie_rb.html | 91 + .../lib/rails/ruby_version_check_rb.html | 55 + .../files/railties/lib/rails/secrets_rb.html | 93 + .../rails/source_annotation_extractor_rb.html | 84 + .../files/railties/lib/rails/tasks_rb.html | 63 + .../railties/lib/rails/test_help_rb.html | 103 + .../files/railties/lib/rails/version_rb.html | 70 + .../lib/rails/welcome_controller_rb.html | 76 + src/5.2/files/railties/lib/rails_rb.html | 102 + 1977 files changed, 368028 insertions(+) create mode 100644 src/5.2/classes/AbstractController.html create mode 100644 src/5.2/classes/AbstractController/ActionNotFound.html create mode 100644 src/5.2/classes/AbstractController/Base.html create mode 100644 src/5.2/classes/AbstractController/Caching.html create mode 100644 src/5.2/classes/AbstractController/Caching/ClassMethods.html create mode 100644 src/5.2/classes/AbstractController/Caching/ConfigMethods.html create mode 100644 src/5.2/classes/AbstractController/Caching/Fragments.html create mode 100644 src/5.2/classes/AbstractController/Caching/Fragments/ClassMethods.html create mode 100644 src/5.2/classes/AbstractController/Callbacks.html create mode 100644 src/5.2/classes/AbstractController/Callbacks/ClassMethods.html create mode 100644 src/5.2/classes/AbstractController/Collector.html create mode 100644 src/5.2/classes/AbstractController/DoubleRenderError.html create mode 100644 src/5.2/classes/AbstractController/Helpers.html create mode 100644 src/5.2/classes/AbstractController/Helpers/ClassMethods.html create mode 100644 src/5.2/classes/AbstractController/Helpers/MissingHelperError.html create mode 100644 src/5.2/classes/AbstractController/Railties.html create mode 100644 src/5.2/classes/AbstractController/Railties/RoutesHelpers.html create mode 100644 src/5.2/classes/AbstractController/Rendering.html create mode 100644 src/5.2/classes/AbstractController/Translation.html create mode 100644 src/5.2/classes/AbstractController/UrlFor.html create mode 100644 src/5.2/classes/AbstractController/UrlFor/ClassMethods.html create mode 100644 src/5.2/classes/ActionCable.html create mode 100644 src/5.2/classes/ActionCable/Channel.html create mode 100644 src/5.2/classes/ActionCable/Channel/Base.html create mode 100644 src/5.2/classes/ActionCable/Channel/Broadcasting.html create mode 100644 src/5.2/classes/ActionCable/Channel/Broadcasting/ClassMethods.html create mode 100644 src/5.2/classes/ActionCable/Channel/Callbacks.html create mode 100644 src/5.2/classes/ActionCable/Channel/Callbacks/ClassMethods.html create mode 100644 src/5.2/classes/ActionCable/Channel/Naming.html create mode 100644 src/5.2/classes/ActionCable/Channel/Naming/ClassMethods.html create mode 100644 src/5.2/classes/ActionCable/Channel/PeriodicTimers.html create mode 100644 src/5.2/classes/ActionCable/Channel/PeriodicTimers/ClassMethods.html create mode 100644 src/5.2/classes/ActionCable/Channel/Streams.html create mode 100644 src/5.2/classes/ActionCable/Connection.html create mode 100644 src/5.2/classes/ActionCable/Connection/Authorization.html create mode 100644 src/5.2/classes/ActionCable/Connection/Authorization/UnauthorizedError.html create mode 100644 src/5.2/classes/ActionCable/Connection/Base.html create mode 100644 src/5.2/classes/ActionCable/Connection/Identification.html create mode 100644 src/5.2/classes/ActionCable/Connection/Identification/ClassMethods.html create mode 100644 src/5.2/classes/ActionCable/Connection/InternalChannel.html create mode 100644 src/5.2/classes/ActionCable/Connection/StreamEventLoop.html create mode 100644 src/5.2/classes/ActionCable/Connection/TaggedLoggerProxy.html create mode 100644 src/5.2/classes/ActionCable/Helpers.html create mode 100644 src/5.2/classes/ActionCable/Helpers/ActionCableHelper.html create mode 100644 src/5.2/classes/ActionCable/RemoteConnections.html create mode 100644 src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection.html create mode 100644 src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection/InvalidIdentifiersError.html create mode 100644 src/5.2/classes/ActionCable/Server.html create mode 100644 src/5.2/classes/ActionCable/Server/Base.html create mode 100644 src/5.2/classes/ActionCable/Server/Broadcasting.html create mode 100644 src/5.2/classes/ActionCable/Server/Broadcasting/Broadcaster.html create mode 100644 src/5.2/classes/ActionCable/Server/Configuration.html create mode 100644 src/5.2/classes/ActionCable/Server/Worker.html create mode 100644 src/5.2/classes/ActionCable/Server/Worker/ActiveRecordConnectionManagement.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/Async.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/Async/AsyncSubscriberMap.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/Base.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL/Listener.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/Redis.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/Redis/Listener.html create mode 100644 src/5.2/classes/ActionCable/SubscriptionAdapter/SubscriberMap.html create mode 100644 src/5.2/classes/ActionCable/VERSION.html create mode 100644 src/5.2/classes/ActionController.html create mode 100644 src/5.2/classes/ActionController/API.html create mode 100644 src/5.2/classes/ActionController/ApiRendering.html create mode 100644 src/5.2/classes/ActionController/Base.html create mode 100644 src/5.2/classes/ActionController/Caching.html create mode 100644 src/5.2/classes/ActionController/ConditionalGet.html create mode 100644 src/5.2/classes/ActionController/ConditionalGet/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/ContentSecurityPolicy.html create mode 100644 src/5.2/classes/ActionController/ContentSecurityPolicy/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/Cookies.html create mode 100644 src/5.2/classes/ActionController/DataStreaming.html create mode 100644 src/5.2/classes/ActionController/EtagWithFlash.html create mode 100644 src/5.2/classes/ActionController/EtagWithTemplateDigest.html create mode 100644 src/5.2/classes/ActionController/Flash.html create mode 100644 src/5.2/classes/ActionController/Flash/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/ForceSSL.html create mode 100644 src/5.2/classes/ActionController/ForceSSL/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/FormBuilder.html create mode 100644 src/5.2/classes/ActionController/FormBuilder/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/Head.html create mode 100644 src/5.2/classes/ActionController/Helpers.html create mode 100644 src/5.2/classes/ActionController/Helpers/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication/Basic.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication/Digest.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication/Digest/ControllerMethods.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication/Token.html create mode 100644 src/5.2/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html create mode 100644 src/5.2/classes/ActionController/ImplicitRender.html create mode 100644 src/5.2/classes/ActionController/Instrumentation.html create mode 100644 src/5.2/classes/ActionController/Instrumentation/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/Live.html create mode 100644 src/5.2/classes/ActionController/Live/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/Live/ClientDisconnected.html create mode 100644 src/5.2/classes/ActionController/Live/SSE.html create mode 100644 src/5.2/classes/ActionController/LiveTestResponse.html create mode 100644 src/5.2/classes/ActionController/LogSubscriber.html create mode 100644 src/5.2/classes/ActionController/Metal.html create mode 100644 src/5.2/classes/ActionController/MimeResponds.html create mode 100644 src/5.2/classes/ActionController/MimeResponds/Collector.html create mode 100644 src/5.2/classes/ActionController/MissingRenderer.html create mode 100644 src/5.2/classes/ActionController/ParameterEncoding.html create mode 100644 src/5.2/classes/ActionController/ParameterEncoding/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/ParameterMissing.html create mode 100644 src/5.2/classes/ActionController/Parameters.html create mode 100644 src/5.2/classes/ActionController/ParamsWrapper.html create mode 100644 src/5.2/classes/ActionController/ParamsWrapper/Options.html create mode 100644 src/5.2/classes/ActionController/ParamsWrapper/Options/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/Railties.html create mode 100644 src/5.2/classes/ActionController/Railties/Helpers.html create mode 100644 src/5.2/classes/ActionController/Redirecting.html create mode 100644 src/5.2/classes/ActionController/Renderer.html create mode 100644 src/5.2/classes/ActionController/Renderers.html create mode 100644 src/5.2/classes/ActionController/Renderers/All.html create mode 100644 src/5.2/classes/ActionController/Renderers/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/Rendering.html create mode 100644 src/5.2/classes/ActionController/Rendering/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/RequestForgeryProtection.html create mode 100644 src/5.2/classes/ActionController/RequestForgeryProtection/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods.html create mode 100644 src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/Exception.html create mode 100644 src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html create mode 100644 src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/ResetSession.html create mode 100644 src/5.2/classes/ActionController/Rescue.html create mode 100644 src/5.2/classes/ActionController/Streaming.html create mode 100644 src/5.2/classes/ActionController/StrongParameters.html create mode 100644 src/5.2/classes/ActionController/TemplateAssertions.html create mode 100644 src/5.2/classes/ActionController/TestCase.html create mode 100644 src/5.2/classes/ActionController/TestCase/Behavior.html create mode 100644 src/5.2/classes/ActionController/TestCase/Behavior/ClassMethods.html create mode 100644 src/5.2/classes/ActionController/Testing.html create mode 100644 src/5.2/classes/ActionController/UnfilteredParameters.html create mode 100644 src/5.2/classes/ActionController/UnpermittedParameters.html create mode 100644 src/5.2/classes/ActionController/UrlFor.html create mode 100644 src/5.2/classes/ActionDispatch.html create mode 100644 src/5.2/classes/ActionDispatch/AssertionResponse.html create mode 100644 src/5.2/classes/ActionDispatch/Assertions.html create mode 100644 src/5.2/classes/ActionDispatch/Assertions/ResponseAssertions.html create mode 100644 src/5.2/classes/ActionDispatch/Assertions/RoutingAssertions.html create mode 100644 src/5.2/classes/ActionDispatch/Callbacks.html create mode 100644 src/5.2/classes/ActionDispatch/ContentSecurityPolicy.html create mode 100644 src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Middleware.html create mode 100644 src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Request.html create mode 100644 src/5.2/classes/ActionDispatch/Cookies.html create mode 100644 src/5.2/classes/ActionDispatch/Cookies/ChainedCookieJars.html create mode 100644 src/5.2/classes/ActionDispatch/DebugExceptions.html create mode 100644 src/5.2/classes/ActionDispatch/DebugLocks.html create mode 100644 src/5.2/classes/ActionDispatch/ExceptionWrapper.html create mode 100644 src/5.2/classes/ActionDispatch/Executor.html create mode 100644 src/5.2/classes/ActionDispatch/FileHandler.html create mode 100644 src/5.2/classes/ActionDispatch/Flash.html create mode 100644 src/5.2/classes/ActionDispatch/Flash/FlashHash.html create mode 100644 src/5.2/classes/ActionDispatch/Flash/RequestMethods.html create mode 100644 src/5.2/classes/ActionDispatch/Http.html create mode 100644 src/5.2/classes/ActionDispatch/Http/Cache.html create mode 100644 src/5.2/classes/ActionDispatch/Http/Cache/Request.html create mode 100644 src/5.2/classes/ActionDispatch/Http/Cache/Response.html create mode 100644 src/5.2/classes/ActionDispatch/Http/FilterParameters.html create mode 100644 src/5.2/classes/ActionDispatch/Http/FilterRedirect.html create mode 100644 src/5.2/classes/ActionDispatch/Http/Headers.html create mode 100644 src/5.2/classes/ActionDispatch/Http/MimeNegotiation.html create mode 100644 src/5.2/classes/ActionDispatch/Http/ParameterFilter.html create mode 100644 src/5.2/classes/ActionDispatch/Http/Parameters.html create mode 100644 src/5.2/classes/ActionDispatch/Http/Parameters/ClassMethods.html create mode 100644 src/5.2/classes/ActionDispatch/Http/Parameters/ParseError.html create mode 100644 src/5.2/classes/ActionDispatch/Http/URL.html create mode 100644 src/5.2/classes/ActionDispatch/Http/UploadedFile.html create mode 100644 src/5.2/classes/ActionDispatch/Integration.html create mode 100644 src/5.2/classes/ActionDispatch/Integration/RequestHelpers.html create mode 100644 src/5.2/classes/ActionDispatch/Integration/Runner.html create mode 100644 src/5.2/classes/ActionDispatch/Integration/Session.html create mode 100644 src/5.2/classes/ActionDispatch/IntegrationTest.html create mode 100644 src/5.2/classes/ActionDispatch/IntegrationTest/Behavior.html create mode 100644 src/5.2/classes/ActionDispatch/IntegrationTest/Behavior/ClassMethods.html create mode 100644 src/5.2/classes/ActionDispatch/IntegrationTest/UrlOptions.html create mode 100644 src/5.2/classes/ActionDispatch/Journey.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Format.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Formatter.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Formatter/RegexCaseComparator.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Parser.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Route.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/All.html create mode 100644 src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/Unknown.html create mode 100644 src/5.2/classes/ActionDispatch/MiddlewareStack.html create mode 100644 src/5.2/classes/ActionDispatch/MiddlewareStack/Middleware.html create mode 100644 src/5.2/classes/ActionDispatch/PublicExceptions.html create mode 100644 src/5.2/classes/ActionDispatch/RailsEntityStore.html create mode 100644 src/5.2/classes/ActionDispatch/RailsEntityStore/Rack.html create mode 100644 src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache.html create mode 100644 src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache/EntityStore.html create mode 100644 src/5.2/classes/ActionDispatch/RailsMetaStore.html create mode 100644 src/5.2/classes/ActionDispatch/RailsMetaStore/Rack.html create mode 100644 src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache.html create mode 100644 src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache/MetaStore.html create mode 100644 src/5.2/classes/ActionDispatch/Reloader.html create mode 100644 src/5.2/classes/ActionDispatch/RemoteIp.html create mode 100644 src/5.2/classes/ActionDispatch/RemoteIp/GetIp.html create mode 100644 src/5.2/classes/ActionDispatch/RemoteIp/IpSpoofAttackError.html create mode 100644 src/5.2/classes/ActionDispatch/Request.html create mode 100644 src/5.2/classes/ActionDispatch/RequestEncoder.html create mode 100644 src/5.2/classes/ActionDispatch/RequestEncoder/IdentityEncoder.html create mode 100644 src/5.2/classes/ActionDispatch/RequestId.html create mode 100644 src/5.2/classes/ActionDispatch/Response.html create mode 100644 src/5.2/classes/ActionDispatch/Response/RackBody.html create mode 100644 src/5.2/classes/ActionDispatch/Routing.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/ConsoleFormatter.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/HtmlTableFormatter.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Mapper.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Mapper/Base.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Mapper/Concerns.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Mapper/CustomUrls.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Mapper/Resources.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Mapper/Scoping.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/PathRedirect.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/PolymorphicRoutes.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/Redirection.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/CustomUrlHelper.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/Dispatcher.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/Generator.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/MountedHelpers.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper/OptimizedUrlHelper.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteSet/StaticDispatcher.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/RouteWrapper.html create mode 100644 src/5.2/classes/ActionDispatch/Routing/UrlFor.html create mode 100644 src/5.2/classes/ActionDispatch/SSL.html create mode 100644 src/5.2/classes/ActionDispatch/Session.html create mode 100644 src/5.2/classes/ActionDispatch/Session/AbstractSecureStore.html create mode 100644 src/5.2/classes/ActionDispatch/Session/AbstractStore.html create mode 100644 src/5.2/classes/ActionDispatch/Session/CacheStore.html create mode 100644 src/5.2/classes/ActionDispatch/Session/Compatibility.html create mode 100644 src/5.2/classes/ActionDispatch/Session/CookieStore.html create mode 100644 src/5.2/classes/ActionDispatch/Session/CookieStore/SessionId.html create mode 100644 src/5.2/classes/ActionDispatch/Session/MemCacheStore.html create mode 100644 src/5.2/classes/ActionDispatch/Session/StaleSessionCheck.html create mode 100644 src/5.2/classes/ActionDispatch/ShowExceptions.html create mode 100644 src/5.2/classes/ActionDispatch/Static.html create mode 100644 src/5.2/classes/ActionDispatch/SystemTestCase.html create mode 100644 src/5.2/classes/ActionDispatch/SystemTesting.html create mode 100644 src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers.html create mode 100644 src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers/ScreenshotHelper.html create mode 100644 src/5.2/classes/ActionDispatch/TestProcess.html create mode 100644 src/5.2/classes/ActionDispatch/TestProcess/FixtureFile.html create mode 100644 src/5.2/classes/ActionDispatch/TestRequest.html create mode 100644 src/5.2/classes/ActionDispatch/TestResponse.html create mode 100644 src/5.2/classes/ActionMailer.html create mode 100644 src/5.2/classes/ActionMailer/Base.html create mode 100644 src/5.2/classes/ActionMailer/Base/LateAttachmentsProxy.html create mode 100644 src/5.2/classes/ActionMailer/Collector.html create mode 100644 src/5.2/classes/ActionMailer/DeliveryMethods.html create mode 100644 src/5.2/classes/ActionMailer/DeliveryMethods/ClassMethods.html create mode 100644 src/5.2/classes/ActionMailer/InlinePreviewInterceptor.html create mode 100644 src/5.2/classes/ActionMailer/LogSubscriber.html create mode 100644 src/5.2/classes/ActionMailer/MailHelper.html create mode 100644 src/5.2/classes/ActionMailer/MessageDelivery.html create mode 100644 src/5.2/classes/ActionMailer/NonInferrableMailerError.html create mode 100644 src/5.2/classes/ActionMailer/Parameterized.html create mode 100644 src/5.2/classes/ActionMailer/Parameterized/ClassMethods.html create mode 100644 src/5.2/classes/ActionMailer/Preview.html create mode 100644 src/5.2/classes/ActionMailer/Previews.html create mode 100644 src/5.2/classes/ActionMailer/Previews/ClassMethods.html create mode 100644 src/5.2/classes/ActionMailer/Rescuable.html create mode 100644 src/5.2/classes/ActionMailer/TestCase.html create mode 100644 src/5.2/classes/ActionMailer/TestCase/Behavior.html create mode 100644 src/5.2/classes/ActionMailer/TestCase/Behavior/ClassMethods.html create mode 100644 src/5.2/classes/ActionMailer/TestCase/ClearTestDeliveries.html create mode 100644 src/5.2/classes/ActionMailer/TestHelper.html create mode 100644 src/5.2/classes/ActionMailer/VERSION.html create mode 100644 src/5.2/classes/ActionView.html create mode 100644 src/5.2/classes/ActionView/Base.html create mode 100644 src/5.2/classes/ActionView/Context.html create mode 100644 src/5.2/classes/ActionView/Digestor.html create mode 100644 src/5.2/classes/ActionView/Digestor/Injected.html create mode 100644 src/5.2/classes/ActionView/Digestor/Missing.html create mode 100644 src/5.2/classes/ActionView/Digestor/Node.html create mode 100644 src/5.2/classes/ActionView/Digestor/NullLogger.html create mode 100644 src/5.2/classes/ActionView/Digestor/Partial.html create mode 100644 src/5.2/classes/ActionView/Digestor/PerExecutionDigestCacheExpiry.html create mode 100644 src/5.2/classes/ActionView/FileSystemResolver.html create mode 100644 src/5.2/classes/ActionView/FixtureResolver.html create mode 100644 src/5.2/classes/ActionView/Helpers.html create mode 100644 src/5.2/classes/ActionView/Helpers/ActiveModelHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/ActiveModelInstanceTag.html create mode 100644 src/5.2/classes/ActionView/Helpers/AssetTagHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/AssetUrlHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/AtomFeedHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/CacheHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/CaptureHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/CspHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/CsrfHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/DateHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/DebugHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/FormBuilder.html create mode 100644 src/5.2/classes/ActionView/Helpers/FormHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/FormOptionsHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/FormTagHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/JavaScriptHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/NumberHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/NumberHelper/InvalidNumberError.html create mode 100644 src/5.2/classes/ActionView/Helpers/OutputSafetyHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/RecordTagHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/RenderingHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/SanitizeHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/TagHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/TextHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/TranslationHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/UrlHelper.html create mode 100644 src/5.2/classes/ActionView/Helpers/UrlHelper/ClassMethods.html create mode 100644 src/5.2/classes/ActionView/Layouts.html create mode 100644 src/5.2/classes/ActionView/Layouts/ClassMethods.html create mode 100644 src/5.2/classes/ActionView/LogSubscriber.html create mode 100644 src/5.2/classes/ActionView/LookupContext.html create mode 100644 src/5.2/classes/ActionView/LookupContext/DetailsCache.html create mode 100644 src/5.2/classes/ActionView/LookupContext/ViewPaths.html create mode 100644 src/5.2/classes/ActionView/NullResolver.html create mode 100644 src/5.2/classes/ActionView/PartialIteration.html create mode 100644 src/5.2/classes/ActionView/PartialRenderer.html create mode 100644 src/5.2/classes/ActionView/RecordIdentifier.html create mode 100644 src/5.2/classes/ActionView/Renderer.html create mode 100644 src/5.2/classes/ActionView/Rendering.html create mode 100644 src/5.2/classes/ActionView/Rendering/ClassMethods.html create mode 100644 src/5.2/classes/ActionView/Resolver.html create mode 100644 src/5.2/classes/ActionView/Resolver/Cache.html create mode 100644 src/5.2/classes/ActionView/Resolver/Cache/SmallCache.html create mode 100644 src/5.2/classes/ActionView/Resolver/Path.html create mode 100644 src/5.2/classes/ActionView/RoutingUrlFor.html create mode 100644 src/5.2/classes/ActionView/Template.html create mode 100644 src/5.2/classes/ActionView/Template/Handlers.html create mode 100644 src/5.2/classes/ActionView/Template/Handlers/Builder.html create mode 100644 src/5.2/classes/ActionView/Template/Handlers/ERB.html create mode 100644 src/5.2/classes/ActionView/Template/Handlers/Html.html create mode 100644 src/5.2/classes/ActionView/Template/Handlers/Raw.html create mode 100644 src/5.2/classes/ActionView/Template/Types.html create mode 100644 src/5.2/classes/ActionView/Template/Types/Type.html create mode 100644 src/5.2/classes/ActionView/TestCase.html create mode 100644 src/5.2/classes/ActionView/TestCase/Behavior.html create mode 100644 src/5.2/classes/ActionView/TestCase/Behavior/ClassMethods.html create mode 100644 src/5.2/classes/ActionView/TestCase/Behavior/Locals.html create mode 100644 src/5.2/classes/ActionView/TestCase/Behavior/RenderedViewsCollection.html create mode 100644 src/5.2/classes/ActionView/TestCase/TestController.html create mode 100644 src/5.2/classes/ActionView/VERSION.html create mode 100644 src/5.2/classes/ActionView/ViewPaths.html create mode 100644 src/5.2/classes/ActionView/ViewPaths/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob.html create mode 100644 src/5.2/classes/ActiveJob/Base.html create mode 100644 src/5.2/classes/ActiveJob/Callbacks.html create mode 100644 src/5.2/classes/ActiveJob/Callbacks/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/Core.html create mode 100644 src/5.2/classes/ActiveJob/Core/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/DeserializationError.html create mode 100644 src/5.2/classes/ActiveJob/Enqueuing.html create mode 100644 src/5.2/classes/ActiveJob/Enqueuing/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/Exceptions.html create mode 100644 src/5.2/classes/ActiveJob/Exceptions/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/Execution.html create mode 100644 src/5.2/classes/ActiveJob/Execution/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapter/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/AsyncAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/BackburnerAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/DelayedJobAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/InlineAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/QuAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/QueAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/QueueClassicAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/ResqueAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/SidekiqAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/SneakersAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/SuckerPunchAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueAdapters/TestAdapter.html create mode 100644 src/5.2/classes/ActiveJob/QueueName.html create mode 100644 src/5.2/classes/ActiveJob/QueueName/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/QueuePriority.html create mode 100644 src/5.2/classes/ActiveJob/QueuePriority/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/SerializationError.html create mode 100644 src/5.2/classes/ActiveJob/TestCase.html create mode 100644 src/5.2/classes/ActiveJob/TestHelper.html create mode 100644 src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter.html create mode 100644 src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter/ClassMethods.html create mode 100644 src/5.2/classes/ActiveJob/VERSION.html create mode 100644 src/5.2/classes/ActiveModel.html create mode 100644 src/5.2/classes/ActiveModel/AttributeAssignment.html create mode 100644 src/5.2/classes/ActiveModel/AttributeMethods.html create mode 100644 src/5.2/classes/ActiveModel/AttributeMethods/ClassMethods.html create mode 100644 src/5.2/classes/ActiveModel/Attributes.html create mode 100644 src/5.2/classes/ActiveModel/Attributes/ClassMethods.html create mode 100644 src/5.2/classes/ActiveModel/Callbacks.html create mode 100644 src/5.2/classes/ActiveModel/Conversion.html create mode 100644 src/5.2/classes/ActiveModel/Dirty.html create mode 100644 src/5.2/classes/ActiveModel/Errors.html create mode 100644 src/5.2/classes/ActiveModel/ForbiddenAttributesError.html create mode 100644 src/5.2/classes/ActiveModel/Lint.html create mode 100644 src/5.2/classes/ActiveModel/Lint/Tests.html create mode 100644 src/5.2/classes/ActiveModel/MissingAttributeError.html create mode 100644 src/5.2/classes/ActiveModel/Model.html create mode 100644 src/5.2/classes/ActiveModel/Name.html create mode 100644 src/5.2/classes/ActiveModel/Naming.html create mode 100644 src/5.2/classes/ActiveModel/RangeError.html create mode 100644 src/5.2/classes/ActiveModel/SecurePassword.html create mode 100644 src/5.2/classes/ActiveModel/SecurePassword/ClassMethods.html create mode 100644 src/5.2/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html create mode 100644 src/5.2/classes/ActiveModel/Serialization.html create mode 100644 src/5.2/classes/ActiveModel/Serializers.html create mode 100644 src/5.2/classes/ActiveModel/Serializers/JSON.html create mode 100644 src/5.2/classes/ActiveModel/StrictValidationFailed.html create mode 100644 src/5.2/classes/ActiveModel/Translation.html create mode 100644 src/5.2/classes/ActiveModel/Type.html create mode 100644 src/5.2/classes/ActiveModel/Type/BigInteger.html create mode 100644 src/5.2/classes/ActiveModel/Type/Binary.html create mode 100644 src/5.2/classes/ActiveModel/Type/Boolean.html create mode 100644 src/5.2/classes/ActiveModel/Type/Decimal.html create mode 100644 src/5.2/classes/ActiveModel/Type/Float.html create mode 100644 src/5.2/classes/ActiveModel/Type/Helpers.html create mode 100644 src/5.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime.html create mode 100644 src/5.2/classes/ActiveModel/Type/Helpers/Mutable.html create mode 100644 src/5.2/classes/ActiveModel/Type/Helpers/Numeric.html create mode 100644 src/5.2/classes/ActiveModel/Type/Helpers/TimeValue.html create mode 100644 src/5.2/classes/ActiveModel/Type/Helpers/Timezone.html create mode 100644 src/5.2/classes/ActiveModel/Type/Integer.html create mode 100644 src/5.2/classes/ActiveModel/Type/Registration.html create mode 100644 src/5.2/classes/ActiveModel/Type/Registry.html create mode 100644 src/5.2/classes/ActiveModel/Type/String.html create mode 100644 src/5.2/classes/ActiveModel/Type/Value.html create mode 100644 src/5.2/classes/ActiveModel/UnknownAttributeError.html create mode 100644 src/5.2/classes/ActiveModel/VERSION.html create mode 100644 src/5.2/classes/ActiveModel/ValidationError.html create mode 100644 src/5.2/classes/ActiveModel/Validations.html create mode 100644 src/5.2/classes/ActiveModel/Validations/AcceptanceValidator.html create mode 100644 src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/AttributeDefinition.html create mode 100644 src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/LazilyDefineAttributes.html create mode 100644 src/5.2/classes/ActiveModel/Validations/Callbacks.html create mode 100644 src/5.2/classes/ActiveModel/Validations/Callbacks/ClassMethods.html create mode 100644 src/5.2/classes/ActiveModel/Validations/ClassMethods.html create mode 100644 src/5.2/classes/ActiveModel/Validations/HelperMethods.html create mode 100644 src/5.2/classes/ActiveModel/Validator.html create mode 100644 src/5.2/classes/ActiveRecord.html create mode 100644 src/5.2/classes/ActiveRecord/ActiveRecordError.html create mode 100644 src/5.2/classes/ActiveRecord/AdapterNotFound.html create mode 100644 src/5.2/classes/ActiveRecord/AdapterNotSpecified.html create mode 100644 src/5.2/classes/ActiveRecord/Aggregations.html create mode 100644 src/5.2/classes/ActiveRecord/Aggregations/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/AssociationRelation.html create mode 100644 src/5.2/classes/ActiveRecord/AssociationTypeMismatch.html create mode 100644 src/5.2/classes/ActiveRecord/Associations.html create mode 100644 src/5.2/classes/ActiveRecord/Associations/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Associations/CollectionProxy.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeAssignment.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeAssignmentError.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/Dirty.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/Query.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/Read.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/Serialization.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ColumnNotSerializableError.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/TimeZoneConversion.html create mode 100644 src/5.2/classes/ActiveRecord/AttributeMethods/Write.html create mode 100644 src/5.2/classes/ActiveRecord/Attributes.html create mode 100644 src/5.2/classes/ActiveRecord/Attributes/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/AutosaveAssociation.html create mode 100644 src/5.2/classes/ActiveRecord/Base.html create mode 100644 src/5.2/classes/ActiveRecord/Batches.html create mode 100644 src/5.2/classes/ActiveRecord/Batches/BatchEnumerator.html create mode 100644 src/5.2/classes/ActiveRecord/Calculations.html create mode 100644 src/5.2/classes/ActiveRecord/Callbacks.html create mode 100644 src/5.2/classes/ActiveRecord/CollectionCacheKey.html create mode 100644 src/5.2/classes/ActiveRecord/ConfigurationError.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter/Version.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/Column.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/ColumnMethods.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionHandler.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Queue.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Reaper.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseLimits.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements/PartialQueryCollector.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/DetermineIfPreparableVisitor.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/ColumnMethods.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/DatabaseStatements.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/Table.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/TableDefinition.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/NullColumn.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/AlterTable.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/DatabaseStatements.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit/Data.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Table.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TableDefinition.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLTypeMetadata.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache/ConnectionPoolConfiguration.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/RealTransaction.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/TableDefinition.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/SavepointTransaction.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/Savepoints.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/SqlTypeMetadata.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/Table.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionAdapters/TransactionState.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionHandling.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionNotEstablished.html create mode 100644 src/5.2/classes/ActiveRecord/ConnectionTimeoutError.html create mode 100644 src/5.2/classes/ActiveRecord/Core.html create mode 100644 src/5.2/classes/ActiveRecord/CounterCache.html create mode 100644 src/5.2/classes/ActiveRecord/CounterCache/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/DangerousAttributeError.html create mode 100644 src/5.2/classes/ActiveRecord/Deadlocked.html create mode 100644 src/5.2/classes/ActiveRecord/DefineCallbacks.html create mode 100644 src/5.2/classes/ActiveRecord/DynamicMatchers.html create mode 100644 src/5.2/classes/ActiveRecord/DynamicMatchers/FindBy.html create mode 100644 src/5.2/classes/ActiveRecord/DynamicMatchers/FindByBang.html create mode 100644 src/5.2/classes/ActiveRecord/DynamicMatchers/Method.html create mode 100644 src/5.2/classes/ActiveRecord/EagerLoadPolymorphicError.html create mode 100644 src/5.2/classes/ActiveRecord/Enum.html create mode 100644 src/5.2/classes/ActiveRecord/EnvironmentMismatchError.html create mode 100644 src/5.2/classes/ActiveRecord/ExclusiveConnectionTimeoutError.html create mode 100644 src/5.2/classes/ActiveRecord/Explain.html create mode 100644 src/5.2/classes/ActiveRecord/FinderMethods.html create mode 100644 src/5.2/classes/ActiveRecord/FixtureSet.html create mode 100644 src/5.2/classes/ActiveRecord/FixtureSet/ClassCache.html create mode 100644 src/5.2/classes/ActiveRecord/ImmutableRelation.html create mode 100644 src/5.2/classes/ActiveRecord/Inheritance.html create mode 100644 src/5.2/classes/ActiveRecord/Inheritance/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Integration.html create mode 100644 src/5.2/classes/ActiveRecord/Integration/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/InvalidForeignKey.html create mode 100644 src/5.2/classes/ActiveRecord/IrreversibleMigration.html create mode 100644 src/5.2/classes/ActiveRecord/IrreversibleOrderError.html create mode 100644 src/5.2/classes/ActiveRecord/LegacyYamlAdapter.html create mode 100644 src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails41.html create mode 100644 src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails420.html create mode 100644 src/5.2/classes/ActiveRecord/LockWaitTimeout.html create mode 100644 src/5.2/classes/ActiveRecord/Locking.html create mode 100644 src/5.2/classes/ActiveRecord/Locking/Optimistic.html create mode 100644 src/5.2/classes/ActiveRecord/Locking/Optimistic/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Locking/Pessimistic.html create mode 100644 src/5.2/classes/ActiveRecord/LogSubscriber.html create mode 100644 src/5.2/classes/ActiveRecord/Migration.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/CheckPending.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/CommandRecorder.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/Compatibility.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2/TableDefinition.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0/TableDefinition.html create mode 100644 src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_1.html create mode 100644 src/5.2/classes/ActiveRecord/MismatchedForeignKey.html create mode 100644 src/5.2/classes/ActiveRecord/ModelSchema.html create mode 100644 src/5.2/classes/ActiveRecord/ModelSchema/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/MultiparameterAssignmentErrors.html create mode 100644 src/5.2/classes/ActiveRecord/NestedAttributes.html create mode 100644 src/5.2/classes/ActiveRecord/NestedAttributes/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/NestedAttributes/TooManyRecords.html create mode 100644 src/5.2/classes/ActiveRecord/NoDatabaseError.html create mode 100644 src/5.2/classes/ActiveRecord/NoTouching.html create mode 100644 src/5.2/classes/ActiveRecord/NoTouching/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/NotNullViolation.html create mode 100644 src/5.2/classes/ActiveRecord/Persistence.html create mode 100644 src/5.2/classes/ActiveRecord/Persistence/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/PredicateBuilder.html create mode 100644 src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler.html create mode 100644 src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler/RangeWithBinds.html create mode 100644 src/5.2/classes/ActiveRecord/PreparedStatementCacheExpired.html create mode 100644 src/5.2/classes/ActiveRecord/PreparedStatementInvalid.html create mode 100644 src/5.2/classes/ActiveRecord/QueryCache.html create mode 100644 src/5.2/classes/ActiveRecord/QueryCache/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/QueryCanceled.html create mode 100644 src/5.2/classes/ActiveRecord/QueryMethods.html create mode 100644 src/5.2/classes/ActiveRecord/QueryMethods/WhereChain.html create mode 100644 src/5.2/classes/ActiveRecord/Querying.html create mode 100644 src/5.2/classes/ActiveRecord/RangeError.html create mode 100644 src/5.2/classes/ActiveRecord/ReadOnlyRecord.html create mode 100644 src/5.2/classes/ActiveRecord/ReadonlyAttributes.html create mode 100644 src/5.2/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/RecordInvalid.html create mode 100644 src/5.2/classes/ActiveRecord/RecordNotDestroyed.html create mode 100644 src/5.2/classes/ActiveRecord/RecordNotFound.html create mode 100644 src/5.2/classes/ActiveRecord/RecordNotSaved.html create mode 100644 src/5.2/classes/ActiveRecord/RecordNotUnique.html create mode 100644 src/5.2/classes/ActiveRecord/Reflection.html create mode 100644 src/5.2/classes/ActiveRecord/Reflection/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Reflection/MacroReflection.html create mode 100644 src/5.2/classes/ActiveRecord/Relation.html create mode 100644 src/5.2/classes/ActiveRecord/Relation/RecordFetchWarning.html create mode 100644 src/5.2/classes/ActiveRecord/Result.html create mode 100644 src/5.2/classes/ActiveRecord/Rollback.html create mode 100644 src/5.2/classes/ActiveRecord/Sanitization.html create mode 100644 src/5.2/classes/ActiveRecord/Sanitization/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Schema.html create mode 100644 src/5.2/classes/ActiveRecord/Scoping.html create mode 100644 src/5.2/classes/ActiveRecord/Scoping/Default.html create mode 100644 src/5.2/classes/ActiveRecord/Scoping/Default/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Scoping/Named.html create mode 100644 src/5.2/classes/ActiveRecord/Scoping/Named/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/SecureToken.html create mode 100644 src/5.2/classes/ActiveRecord/SecureToken/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Serialization.html create mode 100644 src/5.2/classes/ActiveRecord/SerializationFailure.html create mode 100644 src/5.2/classes/ActiveRecord/SerializationTypeMismatch.html create mode 100644 src/5.2/classes/ActiveRecord/SpawnMethods.html create mode 100644 src/5.2/classes/ActiveRecord/StaleObjectError.html create mode 100644 src/5.2/classes/ActiveRecord/StatementInvalid.html create mode 100644 src/5.2/classes/ActiveRecord/StatementTimeout.html create mode 100644 src/5.2/classes/ActiveRecord/Store.html create mode 100644 src/5.2/classes/ActiveRecord/Store/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/SubclassNotFound.html create mode 100644 src/5.2/classes/ActiveRecord/Suppressor.html create mode 100644 src/5.2/classes/ActiveRecord/Suppressor/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Tasks.html create mode 100644 src/5.2/classes/ActiveRecord/Tasks/DatabaseTasks.html create mode 100644 src/5.2/classes/ActiveRecord/TestFixtures.html create mode 100644 src/5.2/classes/ActiveRecord/TestFixtures/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Timestamp.html create mode 100644 src/5.2/classes/ActiveRecord/TouchLater.html create mode 100644 src/5.2/classes/ActiveRecord/TransactionIsolationError.html create mode 100644 src/5.2/classes/ActiveRecord/TransactionRollbackError.html create mode 100644 src/5.2/classes/ActiveRecord/Transactions.html create mode 100644 src/5.2/classes/ActiveRecord/Transactions/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/Translation.html create mode 100644 src/5.2/classes/ActiveRecord/Type.html create mode 100644 src/5.2/classes/ActiveRecord/Type/AdapterSpecificRegistry.html create mode 100644 src/5.2/classes/ActiveRecord/Type/Date.html create mode 100644 src/5.2/classes/ActiveRecord/Type/DateTime.html create mode 100644 src/5.2/classes/ActiveRecord/Type/DecorationRegistration.html create mode 100644 src/5.2/classes/ActiveRecord/Type/Internal.html create mode 100644 src/5.2/classes/ActiveRecord/Type/Internal/Timezone.html create mode 100644 src/5.2/classes/ActiveRecord/Type/Json.html create mode 100644 src/5.2/classes/ActiveRecord/Type/Registration.html create mode 100644 src/5.2/classes/ActiveRecord/Type/Time.html create mode 100644 src/5.2/classes/ActiveRecord/TypeConflictError.html create mode 100644 src/5.2/classes/ActiveRecord/UnknownAttributeReference.html create mode 100644 src/5.2/classes/ActiveRecord/UnknownPrimaryKey.html create mode 100644 src/5.2/classes/ActiveRecord/VERSION.html create mode 100644 src/5.2/classes/ActiveRecord/Validations.html create mode 100644 src/5.2/classes/ActiveRecord/Validations/ClassMethods.html create mode 100644 src/5.2/classes/ActiveRecord/ValueTooLong.html create mode 100644 src/5.2/classes/ActiveRecord/WrappedDatabaseException.html create mode 100644 src/5.2/classes/ActiveStorage.html create mode 100644 src/5.2/classes/ActiveStorage/AnalyzeJob.html create mode 100644 src/5.2/classes/ActiveStorage/Analyzer.html create mode 100644 src/5.2/classes/ActiveStorage/Analyzer/ImageAnalyzer.html create mode 100644 src/5.2/classes/ActiveStorage/Analyzer/VideoAnalyzer.html create mode 100644 src/5.2/classes/ActiveStorage/Attached.html create mode 100644 src/5.2/classes/ActiveStorage/Attached/Macros.html create mode 100644 src/5.2/classes/ActiveStorage/Attached/Many.html create mode 100644 src/5.2/classes/ActiveStorage/Attached/One.html create mode 100644 src/5.2/classes/ActiveStorage/Attachment.html create mode 100644 src/5.2/classes/ActiveStorage/BaseController.html create mode 100644 src/5.2/classes/ActiveStorage/BaseJob.html create mode 100644 src/5.2/classes/ActiveStorage/Blob.html create mode 100644 src/5.2/classes/ActiveStorage/Blob/Analyzable.html create mode 100644 src/5.2/classes/ActiveStorage/Blob/Identifiable.html create mode 100644 src/5.2/classes/ActiveStorage/Blob/Representable.html create mode 100644 src/5.2/classes/ActiveStorage/BlobsController.html create mode 100644 src/5.2/classes/ActiveStorage/DirectUploadsController.html create mode 100644 src/5.2/classes/ActiveStorage/DiskController.html create mode 100644 src/5.2/classes/ActiveStorage/Downloading.html create mode 100644 src/5.2/classes/ActiveStorage/Filename.html create mode 100644 src/5.2/classes/ActiveStorage/IntegrityError.html create mode 100644 src/5.2/classes/ActiveStorage/InvariableError.html create mode 100644 src/5.2/classes/ActiveStorage/LogSubscriber.html create mode 100644 src/5.2/classes/ActiveStorage/Preview.html create mode 100644 src/5.2/classes/ActiveStorage/Preview/UnprocessedError.html create mode 100644 src/5.2/classes/ActiveStorage/Previewer.html create mode 100644 src/5.2/classes/ActiveStorage/Previewer/MuPDFPreviewer.html create mode 100644 src/5.2/classes/ActiveStorage/Previewer/PopplerPDFPreviewer.html create mode 100644 src/5.2/classes/ActiveStorage/Previewer/VideoPreviewer.html create mode 100644 src/5.2/classes/ActiveStorage/PurgeJob.html create mode 100644 src/5.2/classes/ActiveStorage/RepresentationsController.html create mode 100644 src/5.2/classes/ActiveStorage/Service.html create mode 100644 src/5.2/classes/ActiveStorage/Service/AzureStorageService.html create mode 100644 src/5.2/classes/ActiveStorage/Service/DiskService.html create mode 100644 src/5.2/classes/ActiveStorage/Service/GCSService.html create mode 100644 src/5.2/classes/ActiveStorage/Service/MirrorService.html create mode 100644 src/5.2/classes/ActiveStorage/Service/S3Service.html create mode 100644 src/5.2/classes/ActiveStorage/UnpreviewableError.html create mode 100644 src/5.2/classes/ActiveStorage/UnrepresentableError.html create mode 100644 src/5.2/classes/ActiveStorage/VERSION.html create mode 100644 src/5.2/classes/ActiveStorage/Variant.html create mode 100644 src/5.2/classes/ActiveStorage/Variation.html create mode 100644 src/5.2/classes/ActiveSupport.html create mode 100644 src/5.2/classes/ActiveSupport/ArrayInquirer.html create mode 100644 src/5.2/classes/ActiveSupport/Autoload.html create mode 100644 src/5.2/classes/ActiveSupport/BacktraceCleaner.html create mode 100644 src/5.2/classes/ActiveSupport/Benchmarkable.html create mode 100644 src/5.2/classes/ActiveSupport/Cache.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/ConnectionPoolLike.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/FileStore.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/MemCacheStore.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/MemoryStore.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/NullStore.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/RedisCacheStore.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/Store.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/Strategy.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache.html create mode 100644 src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache/LocalStore.html create mode 100644 src/5.2/classes/ActiveSupport/CachingKeyGenerator.html create mode 100644 src/5.2/classes/ActiveSupport/Callbacks.html create mode 100644 src/5.2/classes/ActiveSupport/Callbacks/ClassMethods.html create mode 100644 src/5.2/classes/ActiveSupport/Callbacks/Conditionals.html create mode 100644 src/5.2/classes/ActiveSupport/Callbacks/Conditionals/Value.html create mode 100644 src/5.2/classes/ActiveSupport/Callbacks/Filters.html create mode 100644 src/5.2/classes/ActiveSupport/Callbacks/Filters/After.html create mode 100644 src/5.2/classes/ActiveSupport/Callbacks/Filters/Before.html create mode 100644 src/5.2/classes/ActiveSupport/Concern.html create mode 100644 src/5.2/classes/ActiveSupport/Concurrency.html create mode 100644 src/5.2/classes/ActiveSupport/Concurrency/LoadInterlockAwareMonitor.html create mode 100644 src/5.2/classes/ActiveSupport/Concurrency/ShareLock.html create mode 100644 src/5.2/classes/ActiveSupport/Configurable.html create mode 100644 src/5.2/classes/ActiveSupport/Configurable/ClassMethods.html create mode 100644 src/5.2/classes/ActiveSupport/Configurable/Configuration.html create mode 100644 src/5.2/classes/ActiveSupport/CurrentAttributes.html create mode 100644 src/5.2/classes/ActiveSupport/Dependencies.html create mode 100644 src/5.2/classes/ActiveSupport/Dependencies/ClassCache.html create mode 100644 src/5.2/classes/ActiveSupport/Dependencies/Interlock.html create mode 100644 src/5.2/classes/ActiveSupport/Dependencies/Loadable.html create mode 100644 src/5.2/classes/ActiveSupport/Dependencies/WatchStack.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation/Behavior.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantAccessor.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantProxy.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation/DeprecatedInstanceVariableProxy.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation/DeprecatedObjectProxy.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation/MethodWrapper.html create mode 100644 src/5.2/classes/ActiveSupport/Deprecation/Reporting.html create mode 100644 src/5.2/classes/ActiveSupport/DeprecationException.html create mode 100644 src/5.2/classes/ActiveSupport/DescendantsTracker.html create mode 100644 src/5.2/classes/ActiveSupport/Duration.html create mode 100644 src/5.2/classes/ActiveSupport/Duration/ISO8601Parser.html create mode 100644 src/5.2/classes/ActiveSupport/Duration/ISO8601Parser/ParsingError.html create mode 100644 src/5.2/classes/ActiveSupport/EncryptedConfiguration.html create mode 100644 src/5.2/classes/ActiveSupport/EncryptedFile.html create mode 100644 src/5.2/classes/ActiveSupport/EncryptedFile/MissingContentError.html create mode 100644 src/5.2/classes/ActiveSupport/EncryptedFile/MissingKeyError.html create mode 100644 src/5.2/classes/ActiveSupport/EventedFileUpdateChecker.html create mode 100644 src/5.2/classes/ActiveSupport/EventedFileUpdateChecker/PathHelper.html create mode 100644 src/5.2/classes/ActiveSupport/ExecutionWrapper.html create mode 100644 src/5.2/classes/ActiveSupport/Executor.html create mode 100644 src/5.2/classes/ActiveSupport/FileUpdateChecker.html create mode 100644 src/5.2/classes/ActiveSupport/Gzip.html create mode 100644 src/5.2/classes/ActiveSupport/Gzip/Stream.html create mode 100644 src/5.2/classes/ActiveSupport/HashWithIndifferentAccess.html create mode 100644 src/5.2/classes/ActiveSupport/Inflector.html create mode 100644 src/5.2/classes/ActiveSupport/Inflector/Inflections.html create mode 100644 src/5.2/classes/ActiveSupport/Inflector/Inflections/Uncountables.html create mode 100644 src/5.2/classes/ActiveSupport/InheritableOptions.html create mode 100644 src/5.2/classes/ActiveSupport/JSON.html create mode 100644 src/5.2/classes/ActiveSupport/KeyGenerator.html create mode 100644 src/5.2/classes/ActiveSupport/LazyLoadHooks.html create mode 100644 src/5.2/classes/ActiveSupport/LogSubscriber.html create mode 100644 src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper.html create mode 100644 src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper/MockLogger.html create mode 100644 src/5.2/classes/ActiveSupport/Logger.html create mode 100644 src/5.2/classes/ActiveSupport/Logger/SimpleFormatter.html create mode 100644 src/5.2/classes/ActiveSupport/MessageEncryptor.html create mode 100644 src/5.2/classes/ActiveSupport/MessageEncryptor/InvalidMessage.html create mode 100644 src/5.2/classes/ActiveSupport/MessageVerifier.html create mode 100644 src/5.2/classes/ActiveSupport/MessageVerifier/InvalidSignature.html create mode 100644 src/5.2/classes/ActiveSupport/Messages.html create mode 100644 src/5.2/classes/ActiveSupport/Messages/Rotator.html create mode 100644 src/5.2/classes/ActiveSupport/Messages/Rotator/Encryptor.html create mode 100644 src/5.2/classes/ActiveSupport/Messages/Rotator/Verifier.html create mode 100644 src/5.2/classes/ActiveSupport/Multibyte.html create mode 100644 src/5.2/classes/ActiveSupport/Multibyte/Chars.html create mode 100644 src/5.2/classes/ActiveSupport/Multibyte/Unicode.html create mode 100644 src/5.2/classes/ActiveSupport/Multibyte/Unicode/Codepoint.html create mode 100644 src/5.2/classes/ActiveSupport/Multibyte/Unicode/UnicodeDatabase.html create mode 100644 src/5.2/classes/ActiveSupport/Notifications.html create mode 100644 src/5.2/classes/ActiveSupport/Notifications/Event.html create mode 100644 src/5.2/classes/ActiveSupport/Notifications/Fanout.html create mode 100644 src/5.2/classes/ActiveSupport/Notifications/Instrumenter.html create mode 100644 src/5.2/classes/ActiveSupport/NumberHelper.html create mode 100644 src/5.2/classes/ActiveSupport/NumericWithFormat.html create mode 100644 src/5.2/classes/ActiveSupport/OrderedHash.html create mode 100644 src/5.2/classes/ActiveSupport/OrderedOptions.html create mode 100644 src/5.2/classes/ActiveSupport/PerThreadRegistry.html create mode 100644 src/5.2/classes/ActiveSupport/ProxyObject.html create mode 100644 src/5.2/classes/ActiveSupport/RangeWithFormat.html create mode 100644 src/5.2/classes/ActiveSupport/Reloader.html create mode 100644 src/5.2/classes/ActiveSupport/Rescuable.html create mode 100644 src/5.2/classes/ActiveSupport/Rescuable/ClassMethods.html create mode 100644 src/5.2/classes/ActiveSupport/SafeBuffer.html create mode 100644 src/5.2/classes/ActiveSupport/SafeBuffer/SafeConcatError.html create mode 100644 src/5.2/classes/ActiveSupport/SecurityUtils.html create mode 100644 src/5.2/classes/ActiveSupport/StringInquirer.html create mode 100644 src/5.2/classes/ActiveSupport/Subscriber.html create mode 100644 src/5.2/classes/ActiveSupport/TaggedLogging.html create mode 100644 src/5.2/classes/ActiveSupport/TestCase.html create mode 100644 src/5.2/classes/ActiveSupport/Testing.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/Assertions.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/ConstantLookup.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/Declarative.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/FileFixtures.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/Isolation.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/Isolation/Forking.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/Isolation/Subprocess.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown/ClassMethods.html create mode 100644 src/5.2/classes/ActiveSupport/Testing/TimeHelpers.html create mode 100644 src/5.2/classes/ActiveSupport/TimeWithZone.html create mode 100644 src/5.2/classes/ActiveSupport/TimeZone.html create mode 100644 src/5.2/classes/ActiveSupport/VERSION.html create mode 100644 src/5.2/classes/ActiveSupport/XMLConverter.html create mode 100644 src/5.2/classes/ActiveSupport/XMLConverter/DisallowedType.html create mode 100644 src/5.2/classes/ActiveSupport/XmlMini.html create mode 100644 src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX.html create mode 100644 src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX/HashBuilder.html create mode 100644 src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX.html create mode 100644 src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX/HashBuilder.html create mode 100644 src/5.2/classes/Array.html create mode 100644 src/5.2/classes/Benchmark.html create mode 100644 src/5.2/classes/BigDecimal.html create mode 100644 src/5.2/classes/Class.html create mode 100644 src/5.2/classes/Complex.html create mode 100644 src/5.2/classes/Date.html create mode 100644 src/5.2/classes/DateAndTime.html create mode 100644 src/5.2/classes/DateAndTime/Calculations.html create mode 100644 src/5.2/classes/DateAndTime/Compatibility.html create mode 100644 src/5.2/classes/DateAndTime/Zones.html create mode 100644 src/5.2/classes/DateTime.html create mode 100644 src/5.2/classes/Delegator.html create mode 100644 src/5.2/classes/Digest.html create mode 100644 src/5.2/classes/Digest/UUID.html create mode 100644 src/5.2/classes/ERB.html create mode 100644 src/5.2/classes/ERB/Util.html create mode 100644 src/5.2/classes/Enumerable.html create mode 100644 src/5.2/classes/Exception.html create mode 100644 src/5.2/classes/FalseClass.html create mode 100644 src/5.2/classes/File.html create mode 100644 src/5.2/classes/Float.html create mode 100644 src/5.2/classes/Hash.html create mode 100644 src/5.2/classes/IO.html create mode 100644 src/5.2/classes/Integer.html create mode 100644 src/5.2/classes/Kernel.html create mode 100644 src/5.2/classes/LoadError.html create mode 100644 src/5.2/classes/LoggerSilence.html create mode 100644 src/5.2/classes/Method.html create mode 100644 src/5.2/classes/Mime.html create mode 100644 src/5.2/classes/Mime/AllType.html create mode 100644 src/5.2/classes/Mime/Mimes.html create mode 100644 src/5.2/classes/Mime/NullType.html create mode 100644 src/5.2/classes/Mime/Type.html create mode 100644 src/5.2/classes/Minitest.html create mode 100644 src/5.2/classes/Minitest/SuppressedSummaryReporter.html create mode 100644 src/5.2/classes/Module.html create mode 100644 src/5.2/classes/Module/Concerning.html create mode 100644 src/5.2/classes/Module/DelegationError.html create mode 100644 src/5.2/classes/NameError.html create mode 100644 src/5.2/classes/NilClass.html create mode 100644 src/5.2/classes/Numeric.html create mode 100644 src/5.2/classes/Object.html create mode 100644 src/5.2/classes/PG.html create mode 100644 src/5.2/classes/PG/Connection.html create mode 100644 src/5.2/classes/Process.html create mode 100644 src/5.2/classes/Rails.html create mode 100644 src/5.2/classes/Rails/API.html create mode 100644 src/5.2/classes/Rails/API/EdgeTask.html create mode 100644 src/5.2/classes/Rails/API/RepoTask.html create mode 100644 src/5.2/classes/Rails/API/StableTask.html create mode 100644 src/5.2/classes/Rails/API/Task.html create mode 100644 src/5.2/classes/Rails/AppBuilder.html create mode 100644 src/5.2/classes/Rails/Application.html create mode 100644 src/5.2/classes/Rails/Application/Bootstrap.html create mode 100644 src/5.2/classes/Rails/Application/Configuration.html create mode 100644 src/5.2/classes/Rails/Application/DefaultMiddlewareStack.html create mode 100644 src/5.2/classes/Rails/Application/Finisher.html create mode 100644 src/5.2/classes/Rails/Application/Finisher/InterlockHook.html create mode 100644 src/5.2/classes/Rails/Application/Finisher/MutexHook.html create mode 100644 src/5.2/classes/Rails/Application/RoutesReloader.html create mode 100644 src/5.2/classes/Rails/BacktraceCleaner.html create mode 100644 src/5.2/classes/Rails/Command.html create mode 100644 src/5.2/classes/Rails/Command/Actions.html create mode 100644 src/5.2/classes/Rails/Command/Base.html create mode 100644 src/5.2/classes/Rails/Command/Helpers.html create mode 100644 src/5.2/classes/Rails/Command/Helpers/Editor.html create mode 100644 src/5.2/classes/Rails/Configuration.html create mode 100644 src/5.2/classes/Rails/Configuration/MiddlewareStackProxy.html create mode 100644 src/5.2/classes/Rails/Console.html create mode 100644 src/5.2/classes/Rails/Console/BacktraceCleaner.html create mode 100644 src/5.2/classes/Rails/ConsoleMethods.html create mode 100644 src/5.2/classes/Rails/DBConsole.html create mode 100644 src/5.2/classes/Rails/Engine.html create mode 100644 src/5.2/classes/Rails/Engine/Configuration.html create mode 100644 src/5.2/classes/Rails/Engine/Railties.html create mode 100644 src/5.2/classes/Rails/Engine/Updater.html create mode 100644 src/5.2/classes/Rails/Generators.html create mode 100644 src/5.2/classes/Rails/Generators/Actions.html create mode 100644 src/5.2/classes/Rails/Generators/ActiveModel.html create mode 100644 src/5.2/classes/Rails/Generators/AppBase.html create mode 100644 src/5.2/classes/Rails/Generators/AppBase/GemfileEntry.html create mode 100644 src/5.2/classes/Rails/Generators/Base.html create mode 100644 src/5.2/classes/Rails/Generators/Migration.html create mode 100644 src/5.2/classes/Rails/Generators/NamedBase.html create mode 100644 src/5.2/classes/Rails/Generators/TestCase.html create mode 100644 src/5.2/classes/Rails/Generators/Testing.html create mode 100644 src/5.2/classes/Rails/Generators/Testing/Assertions.html create mode 100644 src/5.2/classes/Rails/Generators/Testing/Behaviour.html create mode 100644 src/5.2/classes/Rails/Generators/Testing/Behaviour/ClassMethods.html create mode 100644 src/5.2/classes/Rails/Generators/Testing/SetupAndTeardown.html create mode 100644 src/5.2/classes/Rails/Info.html create mode 100644 src/5.2/classes/Rails/Initializable.html create mode 100644 src/5.2/classes/Rails/Initializable/ClassMethods.html create mode 100644 src/5.2/classes/Rails/Initializable/Collection.html create mode 100644 src/5.2/classes/Rails/Initializable/Initializer.html create mode 100644 src/5.2/classes/Rails/Paths.html create mode 100644 src/5.2/classes/Rails/Paths/Path.html create mode 100644 src/5.2/classes/Rails/Paths/Root.html create mode 100644 src/5.2/classes/Rails/PluginBuilder.html create mode 100644 src/5.2/classes/Rails/Rack.html create mode 100644 src/5.2/classes/Rails/Rack/Logger.html create mode 100644 src/5.2/classes/Rails/Railtie.html create mode 100644 src/5.2/classes/Rails/Railtie/Configurable.html create mode 100644 src/5.2/classes/Rails/Railtie/Configurable/ClassMethods.html create mode 100644 src/5.2/classes/Rails/Railtie/Configuration.html create mode 100644 src/5.2/classes/Rails/Secrets.html create mode 100644 src/5.2/classes/Rails/Secrets/MissingKeyError.html create mode 100644 src/5.2/classes/Rails/Server.html create mode 100644 src/5.2/classes/Rails/Server/Options.html create mode 100644 src/5.2/classes/Rails/VERSION.html create mode 100644 src/5.2/classes/Range.html create mode 100644 src/5.2/classes/Rational.html create mode 100644 src/5.2/classes/SecureRandom.html create mode 100644 src/5.2/classes/SourceAnnotationExtractor.html create mode 100644 src/5.2/classes/String.html create mode 100644 src/5.2/classes/Symbol.html create mode 100644 src/5.2/classes/Time.html create mode 100644 src/5.2/classes/TrueClass.html create mode 100644 src/5.2/classes/URI.html create mode 100644 src/5.2/files/actioncable/README_md.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/channel/base_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/channel/broadcasting_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/channel/callbacks_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/channel/naming_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/channel/periodic_timers_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/channel/streams_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/channel_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/authorization_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/base_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/client_socket_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/identification_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/internal_channel_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/message_buffer_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/stream_event_loop_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/stream_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/subscriptions_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/tagged_logger_proxy_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection/web_socket_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/connection_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/engine_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/gem_version_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/helpers/action_cable_helper_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/remote_connections_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/server/base_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/server/broadcasting_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/server/configuration_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/server/connections_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/server/worker/active_record_connection_management_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/server/worker_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/server_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter/async_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter/base_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter/channel_prefix_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter/inline_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter/postgresql_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter/redis_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter/subscriber_map_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/subscription_adapter_rb.html create mode 100644 src/5.2/files/actioncable/lib/action_cable/version_rb.html create mode 100644 src/5.2/files/actionmailer/README_rdoc.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/base_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/collector_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/delivery_job_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/delivery_methods_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/gem_version_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/inline_preview_interceptor_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/log_subscriber_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/mail_helper_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/message_delivery_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/parameterized_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/preview_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/railtie_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/rescuable_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/test_case_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/test_helper_rb.html create mode 100644 src/5.2/files/actionmailer/lib/action_mailer/version_rb.html create mode 100644 src/5.2/files/actionpack/README_rdoc.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/asset_paths_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/base_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/caching/fragments_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/caching_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/callbacks_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/collector_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/error_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/helpers_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/logger_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/railties/routes_helpers_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/rendering_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/translation_rb.html create mode 100644 src/5.2/files/actionpack/lib/abstract_controller/url_for_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/api/api_rendering_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/api_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/base_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/caching_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/form_builder_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/log_subscriber_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/basic_implicit_render_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/conditional_get_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/content_security_policy_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/cookies_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/data_streaming_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/etag_with_flash_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/etag_with_template_digest_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/exceptions_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/flash_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/force_ssl_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/head_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/helpers_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/http_authentication_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/implicit_render_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/instrumentation_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/live_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/mime_responds_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/parameter_encoding_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/params_wrapper_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/redirecting_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/renderers_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/rendering_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/request_forgery_protection_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/rescue_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/streaming_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/strong_parameters_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/testing_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal/url_for_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/metal_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/railtie_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/railties/helpers_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/renderer_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/template_assertions_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_controller/test_case_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/cache_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/content_security_policy_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/filter_parameters_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/filter_redirect_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/headers_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/mime_negotiation_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/mime_type_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/mime_types_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/parameter_filter_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/parameters_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/rack_cache_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/request_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/response_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/upload_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/http/url_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/formatter_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/builder_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/simulator_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/transition_table_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/builder_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/dot_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/simulator_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/transition_table_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/nodes/node_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/parser_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/path/pattern_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/route_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/router/utils_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/router_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/routes_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/scanner_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey/visitors_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/journey_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/callbacks_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/cookies_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_exceptions_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_locks_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/exception_wrapper_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/executor_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/flash_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/public_exceptions_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/reloader_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/request_id_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/session/abstract_store_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cache_store_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cookie_store_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/session/mem_cache_store_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/show_exceptions_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/ssl_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/stack_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/middleware/static_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/railtie_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/request/session_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/request/utils_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/endpoint_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/inspector_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/mapper_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/polymorphic_routes_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/redirection_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/route_set_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/routes_proxy_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing/url_for_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/routing_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/system_test_case_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/system_testing/browser_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/system_testing/driver_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/system_testing/server_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/undef_methods_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/assertion_response_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/response_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/routing_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/assertions_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/integration_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/request_encoder_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/test_process_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/test_request_rb.html create mode 100644 src/5.2/files/actionpack/lib/action_dispatch/testing/test_response_rb.html create mode 100644 src/5.2/files/actionview/README_rdoc.html create mode 100644 src/5.2/files/actionview/lib/action_view/base_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/buffers_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/context_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/dependency_tracker_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/digestor_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/flows_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/gem_version_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/active_model_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/asset_tag_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/asset_url_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/atom_feed_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/cache_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/capture_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/controller_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/csp_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/csrf_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/date_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/debug_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/form_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/form_options_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/form_tag_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/javascript_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/number_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/output_safety_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/record_tag_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/rendering_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/sanitize_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tag_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/base_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/check_box_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/checkable_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/collection_check_boxes_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/collection_helpers_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/collection_radio_buttons_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/collection_select_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/color_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/date_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/date_select_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_local_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_select_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/email_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/file_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/grouped_collection_select_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/hidden_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/label_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/month_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/number_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/password_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/placeholderable_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/radio_button_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/range_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/search_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/select_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/tel_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/text_area_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/text_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/time_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/time_select_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/time_zone_select_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/translator_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/url_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags/week_field_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/tags_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/text_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/translation_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers/url_helper_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/helpers_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/layouts_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/log_subscriber_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/lookup_context_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/model_naming_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/path_set_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/railtie_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/record_identifier_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/renderer/abstract_renderer_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/renderer/partial_renderer/collection_caching_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/renderer/partial_renderer_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/renderer/renderer_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/renderer/streaming_template_renderer_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/renderer/template_renderer_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/rendering_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/routing_url_for_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/error_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/handlers/builder_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/handlers/erb/erubi_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/handlers/erb_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/handlers/html_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/handlers/raw_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/handlers_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/html_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/resolver_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/text_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template/types_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/template_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/test_case_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/testing/resolvers_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/version_rb.html create mode 100644 src/5.2/files/actionview/lib/action_view/view_paths_rb.html create mode 100644 src/5.2/files/activejob/README_md.html create mode 100644 src/5.2/files/activejob/lib/active_job/arguments_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/base_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/callbacks_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/configured_job_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/core_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/enqueuing_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/exceptions_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/execution_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/gem_version_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/logging_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/async_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/backburner_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/delayed_job_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/inline_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/qu_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/que_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/queue_classic_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/resque_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/sidekiq_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/sneakers_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/sucker_punch_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters/test_adapter_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_adapters_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_name_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/queue_priority_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/railtie_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/test_case_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/test_helper_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/translation_rb.html create mode 100644 src/5.2/files/activejob/lib/active_job/version_rb.html create mode 100644 src/5.2/files/activemodel/README_rdoc.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute/user_provided_default_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute_assignment_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute_methods_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute_mutation_tracker_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute_set/builder_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute_set/yaml_encoder_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attribute_set_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/attributes_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/callbacks_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/conversion_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/dirty_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/errors_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/forbidden_attributes_protection_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/gem_version_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/lint_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/model_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/naming_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/railtie_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/secure_password_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/serialization_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/serializers/json_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/translation_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/big_integer_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/binary_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/boolean_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/date_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/date_time_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/decimal_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/float_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/helpers/mutable_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/helpers/numeric_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/helpers/time_value_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/helpers/timezone_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/helpers_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/immutable_string_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/integer_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/registry_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/string_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/time_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type/value_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/type_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/absence_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/acceptance_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/callbacks_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/clusivity_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/confirmation_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/exclusion_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/format_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/helper_methods_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/inclusion_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/length_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/numericality_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/presence_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/validates_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations/with_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validations_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/validator_rb.html create mode 100644 src/5.2/files/activemodel/lib/active_model/version_rb.html create mode 100644 src/5.2/files/activerecord/README_rdoc.html create mode 100644 src/5.2/files/activerecord/lib/active_record/aggregations_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/association_relation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/alias_tracker_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/association_scope_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/belongs_to_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/belongs_to_polymorphic_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/builder/association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/builder/belongs_to_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/builder/collection_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/builder/has_many_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/builder/has_one_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/builder/singular_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/collection_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/collection_proxy_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/foreign_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/has_many_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/has_many_through_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/has_one_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/has_one_through_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_base_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_part_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/join_dependency_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/preloader/association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/preloader/through_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/preloader_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/singular_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations/through_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/associations_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_assignment_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_decorators_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/before_type_cast_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/dirty_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/primary_key_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/query_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/read_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/serialization_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/time_zone_conversion_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods/write_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attribute_methods_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/attributes_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/autosave_association_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/base_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/callbacks_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/coders/json_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/coders/yaml_column_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/collection_cache_key_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_limits_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_statements_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/query_cache_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/quoting_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/savepoints_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_creation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_statements_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/transaction_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_adapter_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/column_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/connection_specification_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/column_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/database_statements_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/quoting_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_creation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_statements_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/type_metadata_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql2_adapter_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/column_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/database_statements_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/array_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_varying_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/inet_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/legacy_point_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/money_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/oid_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/point_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/range_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/quoting_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/utils_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql_adapter_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/schema_cache_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sql_type_metadata_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/quoting_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_creation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3_adapter_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_adapters/statement_pool_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/connection_handling_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/core_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/counter_cache_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/define_callbacks_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/dynamic_matchers_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/enum_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/errors_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/explain_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/explain_registry_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/explain_subscriber_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/fixture_set/file_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/fixtures_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/gem_version_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/inheritance_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/integration_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/internal_metadata_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/legacy_yaml_adapter_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/locking/optimistic_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/locking/pessimistic_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/log_subscriber_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/migration/command_recorder_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/migration/compatibility_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/migration/join_table_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/migration_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/model_schema_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/nested_attributes_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/no_touching_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/null_relation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/persistence_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/query_cache_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/querying_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/railtie_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/railties/console_sandbox_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/railties/controller_runtime_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/readonly_attributes_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/reflection_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/batches/batch_enumerator_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/batches_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/calculations_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/delegation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/finder_methods_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/from_clause_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/merger_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/array_handler_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/association_query_value_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/base_handler_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/range_handler_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/relation_handler_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/predicate_builder_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/query_attribute_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/query_methods_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/spawn_methods_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/where_clause_factory_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation/where_clause_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/relation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/result_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/runtime_registry_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/sanitization_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/schema_dumper_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/schema_migration_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/schema_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/scoping/default_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/scoping/named_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/scoping_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/secure_token_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/serialization_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/statement_cache_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/store_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/suppressor_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/table_metadata_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/tasks/database_tasks_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/tasks/mysql_database_tasks_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/tasks/postgresql_database_tasks_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/tasks/sqlite_database_tasks_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/timestamp_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/touch_later_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/transactions_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/translation_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/adapter_specific_registry_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/date_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/date_time_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/decimal_without_scale_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/hash_lookup_type_map_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/internal/timezone_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/json_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/serialized_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/text_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/time_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/type_map_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type/unsigned_integer_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type_caster/connection_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type_caster/map_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type_caster_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/type_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/validations/absence_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/validations/associated_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/validations/length_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/validations/presence_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/validations/uniqueness_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/validations_rb.html create mode 100644 src/5.2/files/activerecord/lib/active_record/version_rb.html create mode 100644 src/5.2/files/activestorage/README_md.html create mode 100644 src/5.2/files/activestorage/app/controllers/active_storage/base_controller_rb.html create mode 100644 src/5.2/files/activestorage/app/controllers/active_storage/blobs_controller_rb.html create mode 100644 src/5.2/files/activestorage/app/controllers/active_storage/direct_uploads_controller_rb.html create mode 100644 src/5.2/files/activestorage/app/controllers/active_storage/disk_controller_rb.html create mode 100644 src/5.2/files/activestorage/app/controllers/active_storage/representations_controller_rb.html create mode 100644 src/5.2/files/activestorage/app/controllers/concerns/active_storage/set_blob_rb.html create mode 100644 src/5.2/files/activestorage/app/jobs/active_storage/analyze_job_rb.html create mode 100644 src/5.2/files/activestorage/app/jobs/active_storage/base_job_rb.html create mode 100644 src/5.2/files/activestorage/app/jobs/active_storage/purge_job_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/attachment_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/blob/analyzable_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/blob/identifiable_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/blob/representable_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/blob_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/current_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/filename/parameters_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/filename_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/preview_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/variant_rb.html create mode 100644 src/5.2/files/activestorage/app/models/active_storage/variation_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/analyzer/image_analyzer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/analyzer/null_analyzer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/analyzer/video_analyzer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/analyzer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/attached/macros_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/attached/many_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/attached/one_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/attached_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/downloading_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/engine_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/errors_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/gem_version_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/log_subscriber_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/previewer/mupdf_previewer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/previewer/poppler_pdf_previewer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/previewer/video_previewer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/previewer_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/service/azure_storage_service_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/service/configurator_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/service/disk_service_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/service/gcs_service_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/service/mirror_service_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/service/s3_service_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/service_rb.html create mode 100644 src/5.2/files/activestorage/lib/active_storage/version_rb.html create mode 100644 src/5.2/files/activesupport/README_rdoc.html create mode 100644 src/5.2/files/activesupport/lib/active_support/all_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/array_inquirer_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/backtrace_cleaner_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/benchmarkable_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/builder_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache/file_store_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache/mem_cache_store_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache/memory_store_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache/null_store_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache/redis_cache_store_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_middleware_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/cache_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/callbacks_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/concern_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/concurrency/share_lock_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/configurable_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array/access_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array/extract_options_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array/grouping_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array/inquiry_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array/prepend_and_append_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array/wrap_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/array_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/benchmark_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_accessors_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/class/subclasses_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/class_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date/acts_like_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date/blank_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date/calculations_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date/zones_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/calculations_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/compatibility_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/zones_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_time/acts_like_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_time/blank_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_time/calculations_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_time/compatibility_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_time/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/date_time_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/digest/uuid_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/digest_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/enumerable_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/file/atomic_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/file_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/compact_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/except_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/indifferent_access_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/keys_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/reverse_merge_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/slice_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash/transform_values_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/hash_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/integer/inflections_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/integer/multiple_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/integer/time_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/integer_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/kernel/agnostics_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/kernel/concern_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/kernel/reporting_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/kernel/singleton_class_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/kernel_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/load_error_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/marshal_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/aliasing_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/anonymous_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/attr_internal_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/concerning_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/delegation_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/deprecation_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/introspection_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/reachable_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/redefine_method_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module/remove_method_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/module_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/name_error_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/numeric/bytes_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/numeric/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/numeric/inquiry_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/numeric/time_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/numeric_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/acts_like_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/blank_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/deep_dup_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/duplicable_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/inclusion_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/instance_variables_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/json_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/to_param_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/to_query_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/try_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object/with_options_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/object_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/range/compare_range_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/range/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/range/each_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/range/include_range_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/range/include_time_with_zone_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/range/overlaps_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/range_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/regexp_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/securerandom_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/access_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/behavior_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/exclude_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/filters_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/indent_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/inflections_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/inquiry_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/multibyte_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/output_safety_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/starts_ends_with_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/strip_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string/zones_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/string_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/time/acts_like_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/time/calculations_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/time/compatibility_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/time/conversions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/time/zones_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/time_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext/uri_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/core_ext_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/current_attributes_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/dependencies/autoload_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/dependencies/interlock_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/dependencies_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/deprecation/behaviors_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/deprecation/constant_accessor_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/deprecation/instance_delegator_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/deprecation/method_wrappers_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/deprecation/proxy_wrappers_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/deprecation/reporting_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/deprecation_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/descendants_tracker_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/digest_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/duration/iso8601_parser_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/duration/iso8601_serializer_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/duration_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/encrypted_configuration_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/encrypted_file_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/evented_file_update_checker_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/execution_wrapper_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/executor_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/file_update_checker_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/gem_version_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/gzip_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/hash_with_indifferent_access_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/i18n_railtie_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/i18n_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/inflections_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/inflector/inflections_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/inflector/methods_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/inflector/transliterate_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/inflector_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/json/decoding_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/json/encoding_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/json_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/key_generator_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/lazy_load_hooks_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/log_subscriber/test_helper_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/log_subscriber_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/logger_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/logger_silence_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/logger_thread_safe_level_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/message_encryptor_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/message_verifier_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/messages/metadata_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/messages/rotation_configuration_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/messages/rotator_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/multibyte/chars_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/multibyte/unicode_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/multibyte_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/notifications/fanout_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/notifications/instrumenter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/notifications_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_to_currency_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_to_delimited_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_size_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_to_percentage_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_to_phone_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/number_to_rounded_converter_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper/rounding_helper_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/number_helper_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/option_merger_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/ordered_hash_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/ordered_options_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/per_thread_registry_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/proxy_object_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/rails_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/railtie_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/reloader_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/rescuable_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/security_utils_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/string_inquirer_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/subscriber_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/tagged_logging_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/test_case_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/assertions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/autorun_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/constant_lookup_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/declarative_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/deprecation_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/file_fixtures_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/isolation_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/method_call_assertions_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/setup_and_teardown_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/stream_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/tagged_logging_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/testing/time_helpers_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/time_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/time_with_zone_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/values/time_zone_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/version_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/xml_mini/jdom_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/xml_mini/libxml_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/xml_mini/libxmlsax_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/xml_mini/nokogiri_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/xml_mini/nokogirisax_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/xml_mini/rexml_rb.html create mode 100644 src/5.2/files/activesupport/lib/active_support/xml_mini_rb.html create mode 100644 src/5.2/files/railties/RDOC_MAIN_rdoc.html create mode 100644 src/5.2/files/railties/README_rdoc.html create mode 100644 src/5.2/files/railties/lib/minitest/rails_plugin_rb.html create mode 100644 src/5.2/files/railties/lib/rails/all_rb.html create mode 100644 src/5.2/files/railties/lib/rails/api/task_rb.html create mode 100644 src/5.2/files/railties/lib/rails/app_loader_rb.html create mode 100644 src/5.2/files/railties/lib/rails/app_updater_rb.html create mode 100644 src/5.2/files/railties/lib/rails/application/bootstrap_rb.html create mode 100644 src/5.2/files/railties/lib/rails/application/configuration_rb.html create mode 100644 src/5.2/files/railties/lib/rails/application/default_middleware_stack_rb.html create mode 100644 src/5.2/files/railties/lib/rails/application/finisher_rb.html create mode 100644 src/5.2/files/railties/lib/rails/application/routes_reloader_rb.html create mode 100644 src/5.2/files/railties/lib/rails/application_controller_rb.html create mode 100644 src/5.2/files/railties/lib/rails/application_rb.html create mode 100644 src/5.2/files/railties/lib/rails/backtrace_cleaner_rb.html create mode 100644 src/5.2/files/railties/lib/rails/cli_rb.html create mode 100644 src/5.2/files/railties/lib/rails/code_statistics_calculator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/code_statistics_rb.html create mode 100644 src/5.2/files/railties/lib/rails/command/actions_rb.html create mode 100644 src/5.2/files/railties/lib/rails/command/base_rb.html create mode 100644 src/5.2/files/railties/lib/rails/command/behavior_rb.html create mode 100644 src/5.2/files/railties/lib/rails/command/environment_argument_rb.html create mode 100644 src/5.2/files/railties/lib/rails/command/helpers/editor_rb.html create mode 100644 src/5.2/files/railties/lib/rails/command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/application/application_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/console/console_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/credentials/credentials_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/dbconsole/dbconsole_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/destroy/destroy_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/encrypted/encrypted_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/generate/generate_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/help/help_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/new/new_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/plugin/plugin_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/rake/rake_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/runner/runner_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/secrets/secrets_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/server/server_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/test/test_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands/version/version_command_rb.html create mode 100644 src/5.2/files/railties/lib/rails/commands_rb.html create mode 100644 src/5.2/files/railties/lib/rails/configuration_rb.html create mode 100644 src/5.2/files/railties/lib/rails/console/app_rb.html create mode 100644 src/5.2/files/railties/lib/rails/console/helpers_rb.html create mode 100644 src/5.2/files/railties/lib/rails/dev_caching_rb.html create mode 100644 src/5.2/files/railties/lib/rails/engine/commands_rb.html create mode 100644 src/5.2/files/railties/lib/rails/engine/configuration_rb.html create mode 100644 src/5.2/files/railties/lib/rails/engine/railties_rb.html create mode 100644 src/5.2/files/railties/lib/rails/engine/updater_rb.html create mode 100644 src/5.2/files/railties/lib/rails/engine_rb.html create mode 100644 src/5.2/files/railties/lib/rails/gem_version_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/actions/create_migration_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/actions_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/active_model_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/app_base_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/base_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/css/assets/assets_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/css/scaffold/scaffold_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/erb/controller/controller_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/erb/mailer/mailer_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/erb/scaffold/scaffold_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/erb_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/generated_attribute_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/js/assets/assets_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/migration_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/model_helpers_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/named_base_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/app/app_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/application_record/application_record_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/assets/assets_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/controller/controller_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/credentials/credentials_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/generator/generator_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/helper/helper_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/integration_test/integration_test_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/master_key/master_key_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/migration/migration_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/model/model_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/plugin/plugin_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/resource/resource_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/resource_route/resource_route_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/scaffold/scaffold_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/system_test/system_test_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/rails/task/task_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/resource_helpers_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_case_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/controller/controller_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/generator/generator_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/helper/helper_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/integration/integration_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/job/job_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/mailer/mailer_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/model/model_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/plugin/plugin_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit/system/system_generator_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/test_unit_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/testing/assertions_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/testing/behaviour_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators/testing/setup_and_teardown_rb.html create mode 100644 src/5.2/files/railties/lib/rails/generators_rb.html create mode 100644 src/5.2/files/railties/lib/rails/info_controller_rb.html create mode 100644 src/5.2/files/railties/lib/rails/info_rb.html create mode 100644 src/5.2/files/railties/lib/rails/initializable_rb.html create mode 100644 src/5.2/files/railties/lib/rails/mailers_controller_rb.html create mode 100644 src/5.2/files/railties/lib/rails/paths_rb.html create mode 100644 src/5.2/files/railties/lib/rails/plugin/test_rb.html create mode 100644 src/5.2/files/railties/lib/rails/rack/logger_rb.html create mode 100644 src/5.2/files/railties/lib/rails/rack_rb.html create mode 100644 src/5.2/files/railties/lib/rails/railtie/configurable_rb.html create mode 100644 src/5.2/files/railties/lib/rails/railtie/configuration_rb.html create mode 100644 src/5.2/files/railties/lib/rails/railtie_rb.html create mode 100644 src/5.2/files/railties/lib/rails/ruby_version_check_rb.html create mode 100644 src/5.2/files/railties/lib/rails/secrets_rb.html create mode 100644 src/5.2/files/railties/lib/rails/source_annotation_extractor_rb.html create mode 100644 src/5.2/files/railties/lib/rails/tasks_rb.html create mode 100644 src/5.2/files/railties/lib/rails/test_help_rb.html create mode 100644 src/5.2/files/railties/lib/rails/version_rb.html create mode 100644 src/5.2/files/railties/lib/rails/welcome_controller_rb.html create mode 100644 src/5.2/files/railties/lib/rails_rb.html diff --git a/src/5.2/classes/AbstractController.html b/src/5.2/classes/AbstractController.html new file mode 100644 index 0000000000..7f6036bf87 --- /dev/null +++ b/src/5.2/classes/AbstractController.html @@ -0,0 +1,122 @@ +--- +title: AbstractController +layout: default +--- + diff --git a/src/5.2/classes/AbstractController/ActionNotFound.html b/src/5.2/classes/AbstractController/ActionNotFound.html new file mode 100644 index 0000000000..fe44207771 --- /dev/null +++ b/src/5.2/classes/AbstractController/ActionNotFound.html @@ -0,0 +1,66 @@ +--- +title: AbstractController::ActionNotFound +layout: default +--- +
+ +
+
+ +
+ +

Raised when a non-existing controller action is triggered.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Base.html b/src/5.2/classes/AbstractController/Base.html new file mode 100644 index 0000000000..3299f6a14b --- /dev/null +++ b/src/5.2/classes/AbstractController/Base.html @@ -0,0 +1,747 @@ +--- +title: AbstractController::Base +layout: default +--- +
+ +
+
+ +
+ +

AbstractController::Base is a low-level API. Nobody should be using it directly, and subclasses (like ActionController::Base) are expected to provide their own render method, since rendering means different things depending on the context.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + abstract
+ [R] + abstract?
+ + + + +

Class Public methods

+ +
+

+ + abstract!() + +

+ + +
+

Define a controller as abstract. See internal_methods for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 40
+def abstract!
+  @abstract = true
+end
+
+
+ +
+ +
+

+ + action_methods() + +

+ + +
+

A list of method names that should be considered actions. This includes all public instance methods on a controller, less any internal methods (see internal_methods), adding back in any methods that are internal, but still exist on the class itself.

+ +

Returns

+
  • +

    Set - A set of all methods that should be considered actions.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 74
+def action_methods
+  @action_methods ||= begin
+    # All public instance methods of this class, including ancestors
+    methods = (public_instance_methods(true) -
+      # Except for public instance methods of Base and its ancestors
+      internal_methods +
+      # Be sure to include shadowed public instance methods of this class
+      public_instance_methods(false)).uniq.map(&:to_s)
+
+    methods.to_set
+  end
+end
+
+
+ +
+ +
+

+ + clear_action_methods!() + +

+ + +
+

action_methods are cached and there is sometimes a need to refresh them. ::clear_action_methods! allows you to do that, so next time you run action_methods, they will be recalculated.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 90
+def clear_action_methods!
+  @action_methods = nil
+end
+
+
+ +
+ +
+

+ + controller_path() + +

+ + +
+

Returns the full controller name, underscored, without the ending Controller.

+ +
class MyApp::MyPostsController < AbstractController::Base
+
+end
+
+MyApp::MyPostsController.controller_path # => "my_app/my_posts"
+
+ +

Returns

+
  • +

    String

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 104
+def controller_path
+  @controller_path ||= name.sub(/Controller$/, "".freeze).underscore unless anonymous?
+end
+
+
+ +
+ +
+

+ + internal_methods() + +

+ + +
+

A list of all internal methods for a controller. This finds the first abstract superclass of a controller, and gets a list of all public instance methods on that abstract class. Public instance methods of a controller would normally be considered action methods, so methods declared on abstract classes are being removed. (ActionController::Metal and ActionController::Base are defined as abstract)

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 59
+def internal_methods
+  controller = self
+
+  controller = controller.superclass until controller.abstract?
+  controller.public_instance_methods(true)
+end
+
+
+ +
+ +
+

+ + method_added(name) + +

+ + +
+

Refresh the cached action_methods when a new action_method is added.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 109
+def method_added(name)
+  super
+  clear_action_methods!
+end
+
+
+ +
+ +
+

+ + supports_path?() + +

+ + +
+

Returns true if the given controller is capable of rendering a path. A subclass of AbstractController::Base may return false. An Email controller for example does not support paths, only full URLs.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 172
+def self.supports_path?
+  true
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + action_methods() + +

+ + +
+

Delegates to the class' ::action_methods

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 143
+def action_methods
+  self.class.action_methods
+end
+
+
+ +
+ +
+

+ + action_name + +

+ + +
+

Returns the name of the action this controller is processing.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 25
+attr_internal :action_name
+
+
+
+ +
+ +
+

+ + available_action?(action_name) + +

+ + +
+

Returns true if a method for the action is available and can be dispatched, false otherwise.

+ +

Notice that action_methods.include?("foo") may return false and available_action?("foo") returns true because this method considers actions that are also available through other means, for example, implicit render ones.

+ +

Parameters

+
  • +

    action_name - The name of an action to be tested

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 157
+def available_action?(action_name)
+  _find_action_name(action_name)
+end
+
+
+ +
+ +
+

+ + controller_path() + +

+ + +
+

Delegates to the class' ::controller_path

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 138
+def controller_path
+  self.class.controller_path
+end
+
+
+ +
+ +
+

+ + formats + +

+ + +
+

Returns the formats that can be processed by the controller.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 29
+attr_internal :formats
+
+
+
+ +
+ +
+

+ + performed?() + +

+ + +
+

Tests if a response body is set. Used to determine if the process_action callback needs to be terminated in AbstractController::Callbacks.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 164
+def performed?
+  response_body
+end
+
+
+ +
+ +
+

+ + process(action, *args) + +

+ + +
+

Calls the action going through the entire action dispatch stack.

+ +

The actual method that is called is determined by calling method_for_action. If no method can handle the action, then an AbstractController::ActionNotFound error is raised.

+ +

Returns

+
  • +

    self

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 125
+def process(action, *args)
+  @_action_name = action.to_s
+
+  unless action_name = _find_action_name(@_action_name)
+    raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}"
+  end
+
+  @_response_body = nil
+
+  process_action(action_name, *args)
+end
+
+
+ +
+ +
+

+ + response_body + +

+ + +
+

Returns the body of the HTTP response sent by the controller.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/base.rb, line 21
+attr_internal :response_body
+
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Caching.html b/src/5.2/classes/AbstractController/Caching.html new file mode 100644 index 0000000000..c50f98d623 --- /dev/null +++ b/src/5.2/classes/AbstractController/Caching.html @@ -0,0 +1,188 @@ +--- +title: AbstractController::Caching +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + view_cache_dependencies() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching.rb, line 52
+def view_cache_dependencies
+  self.class._view_cache_dependencies.map { |dep| instance_exec(&dep) }.compact
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + cache(key, options = {}, &block) + +

+ + +
+

Convenience accessor.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching.rb, line 58
+def cache(key, options = {}, &block) # :doc:
+  if cache_configured?
+    cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
+  else
+    yield
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Caching/ClassMethods.html b/src/5.2/classes/AbstractController/Caching/ClassMethods.html new file mode 100644 index 0000000000..1103ebb4d5 --- /dev/null +++ b/src/5.2/classes/AbstractController/Caching/ClassMethods.html @@ -0,0 +1,101 @@ +--- +title: AbstractController::Caching::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + view_cache_dependency(&dependency) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching.rb, line 47
+def view_cache_dependency(&dependency)
+  self._view_cache_dependencies += [dependency]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Caching/ConfigMethods.html b/src/5.2/classes/AbstractController/Caching/ConfigMethods.html new file mode 100644 index 0000000000..7303623c9b --- /dev/null +++ b/src/5.2/classes/AbstractController/Caching/ConfigMethods.html @@ -0,0 +1,140 @@ +--- +title: AbstractController::Caching::ConfigMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + cache_store() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching.rb, line 13
+def cache_store
+  config.cache_store
+end
+
+
+ +
+ +
+

+ + cache_store=(store) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching.rb, line 17
+def cache_store=(store)
+  config.cache_store = ActiveSupport::Cache.lookup_store(store)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Caching/Fragments.html b/src/5.2/classes/AbstractController/Caching/Fragments.html new file mode 100644 index 0000000000..5f96729ce3 --- /dev/null +++ b/src/5.2/classes/AbstractController/Caching/Fragments.html @@ -0,0 +1,369 @@ +--- +title: AbstractController::Caching::Fragments +layout: default +--- +
+ +
+
+ +
+ +

Fragment caching is used for caching various blocks within views without caching the entire action as a whole. This is useful when certain elements of an action change frequently or depend on complicated state while other parts rarely change or can be shared amongst multiple parties. The caching is done using the cache helper available in the Action View. See ActionView::Helpers::CacheHelper for more information.

+ +

While it's strongly recommended that you use key-based cache expiration (see links in CacheHelper for more information), it is also possible to manually expire caches. For example:

+ +
expire_fragment('name_of_cache')
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + combined_fragment_cache_key(key) + +

+ + +
+

Given a key (as described in expire_fragment), returns a key array suitable for use in reading, writing, or expiring a cached fragment. All keys begin with :views, followed by ENV or ENV if set, followed by any controller-wide key prefix values, ending with the specified key value.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 88
+def combined_fragment_cache_key(key)
+  head = self.class.fragment_cache_keys.map { |k| instance_exec(&k) }
+  tail = key.is_a?(Hash) ? url_for(key).split("://").last : key
+  [ :views, (ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]), *head, *tail ].compact
+end
+
+
+ +
+ +
+

+ + expire_fragment(key, options = nil) + +

+ + +
+

Removes fragments from the cache.

+ +

key can take one of three forms:

+
  • +

    String - This would normally take the form of a path, like pages/45/notes.

    +
  • +

    Hash - Treated as an implicit call to url_for, like { controller: 'pages', action: 'notes', id: 45}

    +
  • +

    Regexp - Will remove any fragment that matches, so %r{pages/\d*/notes} might remove all notes. Make sure you don't use anchors in the regex (^ or $) because the actual filename matched looks like ./cache/filename/path.cache. Note: Regexp expiration is only supported on caches that can iterate over all keys (unlike memcached).

    +
+ +

options is passed through to the cache store's delete method (or delete_matched, for Regexp keys).

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 148
+def expire_fragment(key, options = nil)
+  return unless cache_configured?
+  key = combined_fragment_cache_key(key) unless key.is_a?(Regexp)
+
+  instrument_fragment_cache :expire_fragment, key do
+    if key.is_a?(Regexp)
+      cache_store.delete_matched(key, options)
+    else
+      cache_store.delete(key, options)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + fragment_cache_key(key) + +

+ + +
+

Given a key (as described in expire_fragment), returns a key suitable for use in reading, writing, or expiring a cached fragment. All keys begin with views/, followed by any controller-wide key prefix values, ending with the specified key value. The key is expanded using ActiveSupport::Cache.expand_cache_key.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 69
+      def fragment_cache_key(key)
+        ActiveSupport::Deprecation.warn(<<-MSG.squish)
+          Calling fragment_cache_key directly is deprecated and will be removed in Rails 6.0.
+          All fragment accessors now use the combined_fragment_cache_key method that retains the key as an array,
+          such that the caching stores can interrogate the parts for cache versions used in
+          recyclable cache keys.
+        MSG
+
+        head = self.class.fragment_cache_keys.map { |k| instance_exec(&k) }
+        tail = key.is_a?(Hash) ? url_for(key).split("://").last : key
+        ActiveSupport::Cache.expand_cache_key([*head, *tail], :views)
+      end
+
+
+ +
+ +
+

+ + fragment_exist?(key, options = nil) + +

+ + +
+

Check if a cached fragment from the location signified by key exists (see expire_fragment for acceptable formats).

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 121
+def fragment_exist?(key, options = nil)
+  return unless cache_configured?
+  key = combined_fragment_cache_key(key)
+
+  instrument_fragment_cache :exist_fragment?, key do
+    cache_store.exist?(key, options)
+  end
+end
+
+
+ +
+ +
+

+ + read_fragment(key, options = nil) + +

+ + +
+

Reads a cached fragment from the location signified by key (see expire_fragment for acceptable formats).

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 109
+def read_fragment(key, options = nil)
+  return unless cache_configured?
+
+  key = combined_fragment_cache_key(key)
+  instrument_fragment_cache :read_fragment, key do
+    result = cache_store.read(key, options)
+    result.respond_to?(:html_safe) ? result.html_safe : result
+  end
+end
+
+
+ +
+ +
+

+ + write_fragment(key, content, options = nil) + +

+ + +
+

Writes content to the location signified by key (see expire_fragment for acceptable formats).

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 96
+def write_fragment(key, content, options = nil)
+  return content unless cache_configured?
+
+  key = combined_fragment_cache_key(key)
+  instrument_fragment_cache :write_fragment, key do
+    content = content.to_str
+    cache_store.write(key, content, options)
+  end
+  content
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Caching/Fragments/ClassMethods.html b/src/5.2/classes/AbstractController/Caching/Fragments/ClassMethods.html new file mode 100644 index 0000000000..b2c7f6251d --- /dev/null +++ b/src/5.2/classes/AbstractController/Caching/Fragments/ClassMethods.html @@ -0,0 +1,117 @@ +--- +title: AbstractController::Caching::Fragments::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + fragment_cache_key(value = nil, &key) + +

+ + +
+

Allows you to specify controller-wide key prefixes for cache fragments. Pass either a constant value, or a block which computes a value each time a cache key is generated.

+ +

For example, you may want to prefix all fragment cache keys with a global version identifier, so you can easily invalidate all caches.

+ +
class ApplicationController
+  fragment_cache_key "v1"
+end
+
+ +

When it's time to invalidate all fragments, simply change the string constant. Or, progressively roll out the cache invalidation using a computed value:

+ +
class ApplicationController
+  fragment_cache_key do
+    @account.id.odd? ? "v1" : "v2"
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 58
+def fragment_cache_key(value = nil, &key)
+  self.fragment_cache_keys += [key || -> { value }]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Callbacks.html b/src/5.2/classes/AbstractController/Callbacks.html new file mode 100644 index 0000000000..bab73ec080 --- /dev/null +++ b/src/5.2/classes/AbstractController/Callbacks.html @@ -0,0 +1,165 @@ +--- +title: AbstractController::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Abstract Controller Callbacks

+ +

Abstract Controller provides hooks during the life cycle of a controller action. Callbacks allow you to trigger logic during this cycle. Available callbacks are:

+
  • +

    after_action

    +
  • +

    append_after_action

    +
  • +

    append_around_action

    +
  • +

    append_before_action

    +
  • +

    around_action

    +
  • +

    before_action

    +
  • +

    prepend_after_action

    +
  • +

    prepend_around_action

    +
  • +

    prepend_before_action

    +
  • +

    skip_after_action

    +
  • +

    skip_around_action

    +
  • +

    skip_before_action

    +
+ +

NOTE: Calling the same callback multiple times will overwrite previous callback definitions.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + process_action(*args) + +

+ + +
+

Override AbstractController::Base#process_action to run the process_action callbacks around the normal behavior.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 40
+def process_action(*args)
+  run_callbacks(:process_action) do
+    super
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Callbacks/ClassMethods.html b/src/5.2/classes/AbstractController/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..2b6788d270 --- /dev/null +++ b/src/5.2/classes/AbstractController/Callbacks/ClassMethods.html @@ -0,0 +1,635 @@ +--- +title: AbstractController::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _insert_callbacks(callbacks, block = nil) + +

+ + +
+

Take callback names and an optional callback proc, normalize them, then call the block with each callback. This allows us to abstract the normalization across several methods that use it.

+ +

Parameters

+
  • +

    callbacks - An array of callbacks, with an optional options hash as the last parameter.

    +
  • +

    block - A proc that should be added to the callbacks.

    +
+ +

Block Parameters

+
  • +

    name - The callback to be added.

    +
  • +

    options - A hash of options to be used when adding the callback.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 91
+def _insert_callbacks(callbacks, block = nil)
+  options = callbacks.extract_options!
+  _normalize_callback_options(options)
+  callbacks.push(block) if block
+  callbacks.each do |callback|
+    yield callback, options
+  end
+end
+
+
+ +
+ +
+

+ + _normalize_callback_options(options) + +

+ + +
+

If :only or :except are used, convert the options into the :if and :unless options of ActiveSupport::Callbacks.

+ +

The basic idea is that :only => :index gets converted to :if => proc {|c| c.action_name == "index" }.

+ +

Note that :only has priority over :if in case they are used together.

+ +
only: :index, if: -> { true } # the :if option will be ignored.
+
+ +

Note that :if has priority over :except in case they are used together.

+ +
except: :index, if: -> { true } # the :except option will be ignored.
+
+ +

Options

+
  • +

    only - The callback should be run only for this action.

    +
  • +

    except - The callback should be run for all actions except this action.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 66
+def _normalize_callback_options(options)
+  _normalize_callback_option(options, :only, :if)
+  _normalize_callback_option(options, :except, :unless)
+end
+
+
+ +
+ +
+

+ + after_action(names, block) + + +

+ + +
+

Append a callback after actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 129
+      
+
+
+ +
+ +
+

+ + append_after_action(names, block) + + +

+ + +
+

Append a callback after actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 150
+      
+
+
+ +
+ +
+

+ + append_around_action(names, block) + + +

+ + +
+

Append a callback around actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 178
+      
+
+
+ +
+ +
+

+ + append_before_action(names, block) + + +

+ + +
+

Append a callback before actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 122
+      
+
+
+ +
+ +
+

+ + around_action(names, block) + + +

+ + +
+

Append a callback around actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 157
+      
+
+
+ +
+ +
+

+ + before_action(names, block) + + +

+ + +
+

Append a callback before actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 101
+      
+
+
+ +
+ +
+

+ + prepend_after_action(names, block) + + +

+ + +
+

Prepend a callback after actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 136
+      
+
+
+ +
+ +
+

+ + prepend_around_action(names, block) + + +

+ + +
+

Prepend a callback around actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 164
+      
+
+
+ +
+ +
+

+ + prepend_before_action(names, block) + + +

+ + +
+

Prepend a callback before actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 108
+      
+
+
+ +
+ +
+

+ + skip_after_action(names) + + +

+ + +
+

Skip a callback after actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 143
+      
+
+
+ +
+ +
+

+ + skip_around_action(names) + + +

+ + +
+

Skip a callback around actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 171
+      
+
+
+ +
+ +
+

+ + skip_before_action(names) + + +

+ + +
+

Skip a callback before actions. See _insert_callbacks for parameter details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/callbacks.rb, line 115
+      
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Collector.html b/src/5.2/classes/AbstractController/Collector.html new file mode 100644 index 0000000000..45c33b43df --- /dev/null +++ b/src/5.2/classes/AbstractController/Collector.html @@ -0,0 +1,106 @@ +--- +title: AbstractController::Collector +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + generate_method_for_mime(mime) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/collector.rb, line 7
+    def self.generate_method_for_mime(mime)
+      sym = mime.is_a?(Symbol) ? mime : mime.to_sym
+      class_eval <<-RUBY, __FILE__, __LINE__ + 1
+        def #{sym}(*args, &block)
+          custom(Mime[:#{sym}], *args, &block)
+        end
+      RUBY
+    end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/DoubleRenderError.html b/src/5.2/classes/AbstractController/DoubleRenderError.html new file mode 100644 index 0000000000..9825c56bd3 --- /dev/null +++ b/src/5.2/classes/AbstractController/DoubleRenderError.html @@ -0,0 +1,125 @@ +--- +title: AbstractController::DoubleRenderError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_MESSAGE="Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 12
+def initialize(message = nil)
+  super(message || DEFAULT_MESSAGE)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Helpers.html b/src/5.2/classes/AbstractController/Helpers.html new file mode 100644 index 0000000000..3fe3d7b517 --- /dev/null +++ b/src/5.2/classes/AbstractController/Helpers.html @@ -0,0 +1,74 @@ +--- +title: AbstractController::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Helpers/ClassMethods.html b/src/5.2/classes/AbstractController/Helpers/ClassMethods.html new file mode 100644 index 0000000000..5ff0147f84 --- /dev/null +++ b/src/5.2/classes/AbstractController/Helpers/ClassMethods.html @@ -0,0 +1,384 @@ +--- +title: AbstractController::Helpers::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + clear_helpers() + +

+ + +
+

Clears up all existing helpers in this class, only keeping the helper with the same name as this class.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/helpers.rb, line 117
+def clear_helpers
+  inherited_helper_methods = _helper_methods
+  self._helpers = Module.new
+  self._helper_methods = Array.new
+
+  inherited_helper_methods.each { |meth| helper_method meth }
+  default_helper_module! unless anonymous?
+end
+
+
+ +
+ +
+

+ + helper(*args, &block) + +

+ + +
+

The helper class method can take a series of helper module names, a block, or both.

+ +

Options

+ + +

When the argument is a module it will be included directly in the template class.

+ +
helper FooHelper # => includes FooHelper
+
+ +

When the argument is a string or symbol, the method will provide the “_helper” suffix, require the file and include the module in the template class. The second form illustrates how to include custom helpers when working with namespaced controllers, or other cases where the file containing the helper definition is not in one of Rails' standard load paths:

+ +
helper :foo             # => requires 'foo_helper' and includes FooHelper
+helper 'resources/foo'  # => requires 'resources/foo_helper' and includes Resources::FooHelper
+
+ +

Additionally, the helper class method can receive and evaluate a block, making the methods defined available to the template.

+ +
# One line
+helper { def hello() "Hello, world!" end }
+
+# Multi-line
+helper do
+  def foo(bar)
+    "#{bar} is the very best"
+  end
+end
+
+ +

Finally, all the above styles can be mixed together, and the helper method can be invoked with a mix of symbols, strings, modules and blocks.

+ +
helper(:three, BlindHelper) { def mice() 'mice' end }
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/helpers.rb, line 107
+def helper(*args, &block)
+  modules_for_helpers(args).each do |mod|
+    add_template_helper(mod)
+  end
+
+  _helpers.module_eval(&block) if block_given?
+end
+
+
+ +
+ +
+

+ + helper_method(*meths) + +

+ + +
+

Declare a controller method as a helper. For example, the following makes the current_user and logged_in? controller methods available to the view:

+ +
class ApplicationController < ActionController::Base
+  helper_method :current_user, :logged_in?
+
+  def current_user
+    @current_user ||= User.find_by(id: session[:user])
+  end
+
+  def logged_in?
+    current_user != nil
+  end
+end
+
+ +

In a view:

+ +
<% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
+
+ +

Parameters

+
  • +

    method[, method] - A name or names of a method on the controller to be made available on the view.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/helpers.rb, line 60
+      def helper_method(*meths)
+        meths.flatten!
+        self._helper_methods += meths
+
+        meths.each do |meth|
+          _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
+            def #{meth}(*args, &blk)                               # def current_user(*args, &blk)
+              controller.send(%(#{meth}), *args, &blk)             #   controller.send(:current_user, *args, &blk)
+            end                                                    # end
+          ruby_eval
+        end
+      end
+
+
+ +
+ +
+

+ + inherited(klass) + +

+ + +
+

When a class is inherited, wrap its helper module in a new module. This ensures that the parent class's module can be changed independently of the child class's.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/helpers.rb, line 32
+def inherited(klass)
+  helpers = _helpers
+  klass._helpers = Module.new { include helpers }
+  klass.class_eval { default_helper_module! } unless klass.anonymous?
+  super
+end
+
+
+ +
+ +
+

+ + modules_for_helpers(args) + +

+ + +
+

Returns a list of modules, normalized from the acceptable kinds of helpers with the following behavior:

+
String or Symbol +
+

:FooBar or “FooBar” becomes “foo_bar_helper”,

+
+ +

and “foo_bar_helper.rb” is loaded using require_dependency.

+
Module +
+

No further processing

+
+ +

After loading the appropriate files, the corresponding modules are returned.

+ +

Parameters

+
  • +

    args - An array of helpers

    +
+ +

Returns

+
  • +

    Array - A normalized list of modules for the list of helpers provided.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/helpers.rb, line 143
+def modules_for_helpers(args)
+  args.flatten.map! do |arg|
+    case arg
+    when String, Symbol
+      file_name = "#{arg.to_s.underscore}_helper"
+      begin
+        require_dependency(file_name)
+      rescue LoadError => e
+        raise AbstractController::Helpers::MissingHelperError.new(e, file_name)
+      end
+
+      mod_name = file_name.camelize
+      begin
+        mod_name.constantize
+      rescue LoadError
+        # dependencies.rb gives a similar error message but its wording is
+        # not as clear because it mentions autoloading. To the user all it
+        # matters is that a helper module couldn't be loaded, autoloading
+        # is an internal mechanism that should not leak.
+        raise NameError, "Couldn't find #{mod_name}, expected it to be defined in helpers/#{file_name}.rb"
+      end
+    when Module
+      arg
+    else
+      raise ArgumentError, "helper must be a String, Symbol, or Module"
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Helpers/MissingHelperError.html b/src/5.2/classes/AbstractController/Helpers/MissingHelperError.html new file mode 100644 index 0000000000..9657b70c48 --- /dev/null +++ b/src/5.2/classes/AbstractController/Helpers/MissingHelperError.html @@ -0,0 +1,115 @@ +--- +title: AbstractController::Helpers::MissingHelperError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(error, path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/helpers.rb, line 15
+def initialize(error, path)
+  @error = error
+  @path  = "helpers/#{path}.rb"
+  set_backtrace error.backtrace
+
+  if error.path =~ /^#{path}(\.rb)?$/
+    super("Missing helper file helpers/%s.rb" % path)
+  else
+    raise error
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Railties.html b/src/5.2/classes/AbstractController/Railties.html new file mode 100644 index 0000000000..8f9ef248ca --- /dev/null +++ b/src/5.2/classes/AbstractController/Railties.html @@ -0,0 +1,67 @@ +--- +title: AbstractController::Railties +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Railties/RoutesHelpers.html b/src/5.2/classes/AbstractController/Railties/RoutesHelpers.html new file mode 100644 index 0000000000..8ecde03c92 --- /dev/null +++ b/src/5.2/classes/AbstractController/Railties/RoutesHelpers.html @@ -0,0 +1,110 @@ +--- +title: AbstractController::Railties::RoutesHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + with(routes, include_path_helpers = true) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/railties/routes_helpers.rb, line 6
+def self.with(routes, include_path_helpers = true)
+  Module.new do
+    define_method(:inherited) do |klass|
+      super(klass)
+      if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
+        klass.include(namespace.railtie_routes_url_helpers(include_path_helpers))
+      else
+        klass.include(routes.url_helpers(include_path_helpers))
+      end
+    end
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Rendering.html b/src/5.2/classes/AbstractController/Rendering.html new file mode 100644 index 0000000000..1d8b86bcd1 --- /dev/null +++ b/src/5.2/classes/AbstractController/Rendering.html @@ -0,0 +1,438 @@ +--- +title: AbstractController::Rendering +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_PROTECTED_INSTANCE_VARIABLES=Set.new %i( +@_action_name @_response_body @_formats @_prefixes +)
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + render(*args, &block) + +

+ + +
+

Normalizes arguments, options and then delegates render_to_body and sticks the result in self.response_body.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 23
+def render(*args, &block)
+  options = _normalize_render(*args, &block)
+  rendered_body = render_to_body(options)
+  if options[:html]
+    _set_html_content_type
+  else
+    _set_rendered_content_type rendered_format
+  end
+  self.response_body = rendered_body
+end
+
+
+ +
+ +
+

+ + render_to_body(options = {}) + +

+ + +
+

Performs the actual template rendering.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 50
+def render_to_body(options = {})
+end
+
+
+ +
+ +
+

+ + render_to_string(*args, &block) + +

+ + +
+

Raw rendering of a template to a string.

+ +

It is similar to render, except that it does not set the response_body and it should be guaranteed to always return a string.

+ +

If a component extends the semantics of response_body (as ActionController extends it to be anything that responds to the method each), this method needs to be overridden in order to still return a string.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 44
+def render_to_string(*args, &block)
+  options = _normalize_render(*args, &block)
+  render_to_body(options)
+end
+
+
+ +
+ +
+

+ + rendered_format() + +

+ + +
+

Returns Content-Type of rendered content.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 54
+def rendered_format
+  Mime[:text]
+end
+
+
+ +
+ +
+

+ + view_assigns() + +

+ + +
+

This method should return a hash with assigns. You can overwrite this configuration per controller.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 64
+def view_assigns
+  protected_vars = _protected_ivars
+  variables      = instance_variables
+
+  variables.reject! { |s| protected_vars.include? s }
+  variables.each_with_object({}) { |name, hash|
+    hash[name.slice(1, name.length)] = instance_variable_get(name)
+  }
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + _normalize_args(action = nil, options = {}) + +

+ + +
+

Normalize args by converting render "foo" to render :action => "foo" and render "foo/bar" to render :file => "foo/bar".

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 78
+def _normalize_args(action = nil, options = {}) # :doc:
+  if action.respond_to?(:permitted?)
+    if action.permitted?
+      action
+    else
+      raise ArgumentError, "render parameters are not permitted"
+    end
+  elsif action.is_a?(Hash)
+    action
+  else
+    options
+  end
+end
+
+
+ +
+ +
+

+ + _normalize_options(options) + +

+ + +
+

Normalize options.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 93
+def _normalize_options(options) # :doc:
+  options
+end
+
+
+ +
+ +
+

+ + _process_options(options) + +

+ + +
+

Process extra options.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/rendering.rb, line 98
+def _process_options(options) # :doc:
+  options
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/Translation.html b/src/5.2/classes/AbstractController/Translation.html new file mode 100644 index 0000000000..bb8a0c1689 --- /dev/null +++ b/src/5.2/classes/AbstractController/Translation.html @@ -0,0 +1,213 @@ +--- +title: AbstractController::Translation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + l(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: localize +
+ + + +
+ +
+

+ + localize(*args) + +

+ + +
+

Delegates to I18n.localize. Also aliased as l.

+
+ + + +
+ Also aliased as: l +
+ + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/translation.rb, line 26
+def localize(*args)
+  I18n.localize(*args)
+end
+
+
+ +
+ +
+

+ + t(key, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: translate +
+ + + +
+ +
+

+ + translate(key, options = {}) + +

+ + +
+

Delegates to I18n.translate. Also aliased as t.

+ +

When the given key starts with a period, it will be scoped by the current controller and action. So if you call translate(".foo") from PeopleController#index, it will convert the call to I18n.translate("people.index.foo"). This makes it less repetitive to translate many keys within the same controller / action and gives you a simple framework for scoping them consistently.

+
+ + + +
+ Also aliased as: t +
+ + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/translation.rb, line 13
+def translate(key, options = {})
+  if key.to_s.first == "."
+    path = controller_path.tr("/", ".")
+    defaults = [:"#{path}#{key}"]
+    defaults << options[:default] if options[:default]
+    options[:default] = defaults.flatten
+    key = "#{path}.#{action_name}#{key}"
+  end
+  I18n.translate(key, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/UrlFor.html b/src/5.2/classes/AbstractController/UrlFor.html new file mode 100644 index 0000000000..ebf098c7cf --- /dev/null +++ b/src/5.2/classes/AbstractController/UrlFor.html @@ -0,0 +1,137 @@ +--- +title: AbstractController::UrlFor +layout: default +--- +
+ +
+
+ +
+ +

Includes url_for into the host class (e.g. an abstract controller or mailer). The class has to provide a RouteSet by implementing the _routes methods. Otherwise, an exception will be raised.

+ +

Note that this module is completely decoupled from HTTP - the only requirement is a valid _routes implementation.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _routes() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/url_for.rb, line 14
+def _routes
+  raise "In order to use #url_for, you must include routing helpers explicitly. " \
+        "For instance, `include Rails.application.routes.url_helpers`."
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/AbstractController/UrlFor/ClassMethods.html b/src/5.2/classes/AbstractController/UrlFor/ClassMethods.html new file mode 100644 index 0000000000..2dcea6430b --- /dev/null +++ b/src/5.2/classes/AbstractController/UrlFor/ClassMethods.html @@ -0,0 +1,146 @@ +--- +title: AbstractController::UrlFor::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _routes() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/url_for.rb, line 20
+def _routes
+  nil
+end
+
+
+ +
+ +
+

+ + action_methods() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/abstract_controller/url_for.rb, line 24
+def action_methods
+  @action_methods ||= begin
+    if _routes
+      super - _routes.named_routes.helper_names
+    else
+      super
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable.html b/src/5.2/classes/ActionCable.html new file mode 100644 index 0000000000..4340d921eb --- /dev/null +++ b/src/5.2/classes/ActionCable.html @@ -0,0 +1,248 @@ +--- +title: ActionCable +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Action Cable as a Gem::Version.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded Action Cable as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/version.rb, line 7
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel.html b/src/5.2/classes/ActionCable/Channel.html new file mode 100644 index 0000000000..0d6b918223 --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel.html @@ -0,0 +1,98 @@ +--- +title: ActionCable::Channel +layout: default +--- + diff --git a/src/5.2/classes/ActionCable/Channel/Base.html b/src/5.2/classes/ActionCable/Channel/Base.html new file mode 100644 index 0000000000..0fcd2becae --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Base.html @@ -0,0 +1,861 @@ +--- +title: ActionCable::Channel::Base +layout: default +--- +
+ +
+
+ +
+ +

The channel provides the basic structure of grouping behavior into logical units when communicating over the WebSocket connection. You can think of a channel like a form of controller, but one that's capable of pushing content to the subscriber in addition to simply responding to the subscriber's direct requests.

+ +

Channel instances are long-lived. A channel object will be instantiated when the cable consumer becomes a subscriber, and then lives until the consumer disconnects. This may be seconds, minutes, hours, or even days. That means you have to take special care not to do anything silly in a channel that would balloon its memory footprint or whatever. The references are forever, so they won't be released as is normally the case with a controller instance that gets thrown away after every request.

+ +

Long-lived channels (and connections) also mean you're responsible for ensuring that the data is fresh. If you hold a reference to a user record, but the name is changed while that reference is held, you may be sending stale data if you don't take precautions to avoid it.

+ +

The upside of long-lived channel instances is that you can use instance variables to keep reference to objects that future subscriber requests can interact with. Here's a quick example:

+ +
class ChatChannel < ApplicationCable::Channel
+  def subscribed
+    @room = Chat::Room[params[:room_number]]
+  end
+
+  def speak(data)
+    @room.speak data, user: current_user
+  end
+end
+
+ +

The speak action simply uses the Chat::Room object that was created when the channel was first subscribed to by the consumer when that subscriber wants to say something in the room.

+ +

Action processing

+ +

Unlike subclasses of ActionController::Base, channels do not follow a RESTful constraint form for their actions. Instead, Action Cable operates through a remote-procedure call model. You can declare any public method on the channel (optionally taking a data argument), and this method is automatically exposed as callable to the client.

+ +

Example:

+ +
class AppearanceChannel < ApplicationCable::Channel
+  def subscribed
+    @connection_token = generate_connection_token
+  end
+
+  def unsubscribed
+    current_user.disappear @connection_token
+  end
+
+  def appear(data)
+    current_user.appear @connection_token, on: data['appearing_on']
+  end
+
+  def away
+    current_user.away @connection_token
+  end
+
+  private
+    def generate_connection_token
+      SecureRandom.hex(36)
+    end
+end
+
+ +

In this example, the subscribed and unsubscribed methods are not callable methods, as they were already declared in ActionCable::Channel::Base, but #appear and #away are. #generate_connection_token is also not callable, since it's a private method. You'll see that appear accepts a data parameter, which it then uses as part of its model call. #away does not, since it's simply a trigger action.

+ +

Also note that in this example, current_user is available because it was marked as an identifying attribute on the connection. All such identifiers will automatically create a delegation method of the same name on the channel instance.

+ +

Rejecting subscription requests

+ +

A channel can reject a subscription request in the subscribed callback by invoking the reject method:

+ +
class ChatChannel < ApplicationCable::Channel
+  def subscribed
+    @room = Chat::Room[params[:room_number]]
+    reject unless current_user.can_access?(@room)
+  end
+end
+
+ +

In this example, the subscription will be rejected if the current_user does not have access to the chat room. On the client-side, the Channel#rejected callback will get invoked when the server rejects the subscription request.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + connection
+ [R] + identifier
+ [R] + params
+ + + + +

Class Public methods

+ +
+

+ + action_methods() + +

+ + +
+

A list of method names that should be considered actions. This includes all public instance methods on a channel, less any internal methods (defined on Base), adding back in any methods that are internal, but still exist on the class itself.

+ +

Returns

+
  • +

    Set - A set of all methods that should be considered actions.

    +
+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 115
+def action_methods
+  @action_methods ||= begin
+    # All public instance methods of this class, including ancestors
+    methods = (public_instance_methods(true) -
+      # Except for public instance methods of Base and its ancestors
+      ActionCable::Channel::Base.public_instance_methods(true) +
+      # Be sure to include shadowed public instance methods of this class
+      public_instance_methods(false)).uniq.map(&:to_s)
+    methods.to_set
+  end
+end
+
+
+ +
+ +
+

+ + new(connection, identifier, params = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 142
+def initialize(connection, identifier, params = {})
+  @connection = connection
+  @identifier = identifier
+  @params     = params
+
+  # When a channel is streaming via pubsub, we want to delay the confirmation
+  # transmission until pubsub subscription is confirmed.
+  #
+  # The counter starts at 1 because it's awaiting a call to #subscribe_to_channel
+  @defer_subscription_confirmation_counter = Concurrent::AtomicFixnum.new(1)
+
+  @reject_subscription = nil
+  @subscription_confirmation_sent = nil
+
+  delegate_connection_identifiers
+end
+
+
+ +
+ + +

Class Private methods

+ +
+

+ + clear_action_methods!() + +

+ + +
+

action_methods are cached and there is sometimes need to refresh them. ::clear_action_methods! allows you to do that, so next time you run action_methods, they will be recalculated.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 131
+def clear_action_methods! # :doc:
+  @action_methods = nil
+end
+
+
+ +
+ +
+

+ + method_added(name) + +

+ + +
+

Refresh the cached action_methods when a new action_method is added.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 136
+def method_added(name) # :doc:
+  super
+  clear_action_methods!
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + perform_action(data) + +

+ + +
+

Extract the action name from the passed data and process it via the channel. The process will ensure that the action requested is a public method on the channel declared by the user (so not one of the callbacks like subscribed).

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 162
+def perform_action(data)
+  action = extract_action(data)
+
+  if processable_action?(action)
+    payload = { channel_class: self.class.name, action: action, data: data }
+    ActiveSupport::Notifications.instrument("perform_action.action_cable", payload) do
+      dispatch_action(action, data)
+    end
+  else
+    logger.error "Unable to process #{action_signature(action, data)}"
+  end
+end
+
+
+ +
+ +
+

+ + subscribe_to_channel() + +

+ + +
+

This method is called after subscription has been added to the connection and confirms or rejects the subscription.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 177
+def subscribe_to_channel
+  run_callbacks :subscribe do
+    subscribed
+  end
+
+  reject_subscription if subscription_rejected?
+  ensure_confirmation_sent
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + defer_subscription_confirmation!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 226
+def defer_subscription_confirmation! # :doc:
+  @defer_subscription_confirmation_counter.increment
+end
+
+
+ +
+ +
+

+ + defer_subscription_confirmation?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 230
+def defer_subscription_confirmation? # :doc:
+  @defer_subscription_confirmation_counter.value > 0
+end
+
+
+ +
+ +
+

+ + ensure_confirmation_sent() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 220
+def ensure_confirmation_sent # :doc:
+  return if subscription_rejected?
+  @defer_subscription_confirmation_counter.decrement
+  transmit_subscription_confirmation unless defer_subscription_confirmation?
+end
+
+
+ +
+ +
+

+ + reject() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 238
+def reject # :doc:
+  @reject_subscription = true
+end
+
+
+ +
+ +
+

+ + subscribed() + +

+ + +
+

Called once a consumer has become a subscriber of the channel. Usually the place to setup any streams you want this channel to be sending to the subscriber.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 197
+def subscribed # :doc:
+  # Override in subclasses
+end
+
+
+ +
+ +
+

+ + subscription_confirmation_sent?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 234
+def subscription_confirmation_sent? # :doc:
+  @subscription_confirmation_sent
+end
+
+
+ +
+ +
+

+ + subscription_rejected?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 242
+def subscription_rejected? # :doc:
+  @reject_subscription
+end
+
+
+ +
+ +
+

+ + transmit(data, via: nil) + +

+ + +
+

Transmit a hash of data to the subscriber. The hash will automatically be wrapped in a JSON envelope with the proper channel identifier marked as the recipient.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 209
+def transmit(data, via: nil) # :doc:
+  status = "#{self.class.name} transmitting #{data.inspect.truncate(300)}"
+  status += " (via #{via})" if via
+  logger.debug(status)
+
+  payload = { channel_class: self.class.name, data: data, via: via }
+  ActiveSupport::Notifications.instrument("transmit.action_cable", payload) do
+    connection.transmit identifier: @identifier, message: data
+  end
+end
+
+
+ +
+ +
+

+ + unsubscribed() + +

+ + +
+

Called once a consumer has cut its cable connection. Can be used for cleaning up connections or marking users as offline or the like.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/base.rb, line 203
+def unsubscribed # :doc:
+  # Override in subclasses
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/Broadcasting.html b/src/5.2/classes/ActionCable/Channel/Broadcasting.html new file mode 100644 index 0000000000..408e557641 --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Broadcasting.html @@ -0,0 +1,67 @@ +--- +title: ActionCable::Channel::Broadcasting +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/Broadcasting/ClassMethods.html b/src/5.2/classes/ActionCable/Channel/Broadcasting/ClassMethods.html new file mode 100644 index 0000000000..1157268b1c --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Broadcasting/ClassMethods.html @@ -0,0 +1,101 @@ +--- +title: ActionCable::Channel::Broadcasting::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + broadcast_to(model, message) + +

+ + +
+

Broadcast a hash to a unique broadcasting for this model in this channel.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/broadcasting.rb, line 14
+def broadcast_to(model, message)
+  ActionCable.server.broadcast(broadcasting_for([ channel_name, model ]), message)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/Callbacks.html b/src/5.2/classes/ActionCable/Channel/Callbacks.html new file mode 100644 index 0000000000..b3f315063c --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Callbacks.html @@ -0,0 +1,81 @@ +--- +title: ActionCable::Channel::Callbacks +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/Callbacks/ClassMethods.html b/src/5.2/classes/ActionCable/Channel/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..2edaa2bb1f --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Callbacks/ClassMethods.html @@ -0,0 +1,282 @@ +--- +title: ActionCable::Channel::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + after_subscribe(*methods, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: on_subscribe +
+ + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/callbacks.rb, line 21
+def after_subscribe(*methods, &block)
+  set_callback(:subscribe, :after, *methods, &block)
+end
+
+
+ +
+ +
+

+ + after_unsubscribe(*methods, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: on_unsubscribe +
+ + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/callbacks.rb, line 30
+def after_unsubscribe(*methods, &block)
+  set_callback(:unsubscribe, :after, *methods, &block)
+end
+
+
+ +
+ +
+

+ + before_subscribe(*methods, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/callbacks.rb, line 17
+def before_subscribe(*methods, &block)
+  set_callback(:subscribe, :before, *methods, &block)
+end
+
+
+ +
+ +
+

+ + before_unsubscribe(*methods, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/callbacks.rb, line 26
+def before_unsubscribe(*methods, &block)
+  set_callback(:unsubscribe, :before, *methods, &block)
+end
+
+
+ +
+ +
+

+ + on_subscribe(*methods, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: after_subscribe +
+ + + +
+ +
+

+ + on_unsubscribe(*methods, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: after_unsubscribe +
+ + + +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/Naming.html b/src/5.2/classes/ActionCable/Channel/Naming.html new file mode 100644 index 0000000000..1ea3fac83c --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Naming.html @@ -0,0 +1,67 @@ +--- +title: ActionCable::Channel::Naming +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/Naming/ClassMethods.html b/src/5.2/classes/ActionCable/Channel/Naming/ClassMethods.html new file mode 100644 index 0000000000..b416f2ef36 --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Naming/ClassMethods.html @@ -0,0 +1,106 @@ +--- +title: ActionCable::Channel::Naming::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + channel_name() + +

+ + +
+

Returns the name of the channel, underscored, without the Channel ending. If the channel is in a namespace, then the namespaces are represented by single colon separators in the channel name.

+ +
ChatChannel.channel_name # => 'chat'
+Chats::AppearancesChannel.channel_name # => 'chats:appearances'
+FooChats::BarAppearancesChannel.channel_name # => 'foo_chats:bar_appearances'
+
+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/naming.rb, line 16
+def channel_name
+  @channel_name ||= name.sub(/Channel$/, "").gsub("::", ":").underscore
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/PeriodicTimers.html b/src/5.2/classes/ActionCable/Channel/PeriodicTimers.html new file mode 100644 index 0000000000..8d82923911 --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/PeriodicTimers.html @@ -0,0 +1,67 @@ +--- +title: ActionCable::Channel::PeriodicTimers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/PeriodicTimers/ClassMethods.html b/src/5.2/classes/ActionCable/Channel/PeriodicTimers/ClassMethods.html new file mode 100644 index 0000000000..8ea3bc7013 --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/PeriodicTimers/ClassMethods.html @@ -0,0 +1,129 @@ +--- +title: ActionCable::Channel::PeriodicTimers::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + periodically(callback_or_method_name = nil, every:, &block) + +

+ + +
+

Periodically performs a task on the channel, like updating an online user counter, polling a backend for new status messages, sending regular “heartbeat” messages, or doing some internal work and giving progress updates.

+ +

Pass a method name or lambda argument or provide a block to call. Specify the calling period in seconds using the every: keyword argument.

+ +
periodically :transmit_progress, every: 5.seconds
+
+periodically every: 3.minutes do
+  transmit action: :update_count, count: current_count
+end
+
+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/periodic_timers.rb, line 31
+def periodically(callback_or_method_name = nil, every:, &block)
+  callback =
+    if block_given?
+      raise ArgumentError, "Pass a block or provide a callback arg, not both" if callback_or_method_name
+      block
+    else
+      case callback_or_method_name
+      when Proc
+        callback_or_method_name
+      when Symbol
+        -> { __send__ callback_or_method_name }
+      else
+        raise ArgumentError, "Expected a Symbol method name or a Proc, got #{callback_or_method_name.inspect}"
+      end
+    end
+
+  unless every.kind_of?(Numeric) && every > 0
+    raise ArgumentError, "Expected every: to be a positive number of seconds, got #{every.inspect}"
+  end
+
+  self.periodic_timers += [[ callback, every: every ]]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Channel/Streams.html b/src/5.2/classes/ActionCable/Channel/Streams.html new file mode 100644 index 0000000000..90033d36c0 --- /dev/null +++ b/src/5.2/classes/ActionCable/Channel/Streams.html @@ -0,0 +1,262 @@ +--- +title: ActionCable::Channel::Streams +layout: default +--- +
+ +
+
+ +
+ +

Streams allow channels to route broadcastings to the subscriber. A broadcasting is, as discussed elsewhere, a pubsub queue where any data placed into it is automatically sent to the clients that are connected at that time. It's purely an online queue, though. If you're not streaming a broadcasting at the very moment it sends out an update, you will not get that update, even if you connect after it has been sent.

+ +

Most commonly, the streamed broadcast is sent straight to the subscriber on the client-side. The channel just acts as a connector between the two parties (the broadcaster and the channel subscriber). Here's an example of a channel that allows subscribers to get all new comments on a given page:

+ +
class CommentsChannel < ApplicationCable::Channel
+  def follow(data)
+    stream_from "comments_for_#{data['recording_id']}"
+  end
+
+  def unfollow
+    stop_all_streams
+  end
+end
+
+ +

Based on the above example, the subscribers of this channel will get whatever data is put into the, let's say, comments_for_45 broadcasting as soon as it's put there.

+ +

An example broadcasting for this channel looks like so:

+ +
ActionCable.server.broadcast "comments_for_45", author: 'DHH', content: 'Rails is just swell'
+
+ +

If you have a stream that is related to a model, then the broadcasting used can be generated from the model and channel. The following example would subscribe to a broadcasting like comments:Z2lkOi8vVGVzdEFwcC9Qb3N0LzE.

+ +
class CommentsChannel < ApplicationCable::Channel
+  def subscribed
+    post = Post.find(params[:id])
+    stream_for post
+  end
+end
+
+ +

You can then broadcast to this channel using:

+ +
CommentsChannel.broadcast_to(@post, @comment)
+
+ +

If you don't just want to parlay the broadcast unfiltered to the subscriber, you can also supply a callback that lets you alter what is sent out. The below example shows how you can use this to provide performance introspection in the process:

+ +
class ChatChannel < ApplicationCable::Channel
+  def subscribed
+    @room = Chat::Room[params[:room_number]]
+
+    stream_for @room, coder: ActiveSupport::JSON do |message|
+      if message['originated_at'].present?
+        elapsed_time = (Time.now.to_f - message['originated_at']).round(2)
+
+        ActiveSupport::Notifications.instrument :performance, measurement: 'Chat.message_delay', value: elapsed_time, action: :timing
+        logger.info "Message took #{elapsed_time}s to arrive"
+      end
+
+      transmit message
+    end
+  end
+end
+
+ +

You can stop streaming from all broadcasts by calling stop_all_streams.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + stop_all_streams() + +

+ + +
+

Unsubscribes all streams associated with this channel from the pubsub queue.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/streams.rb, line 106
+def stop_all_streams
+  streams.each do |broadcasting, callback|
+    pubsub.unsubscribe broadcasting, callback
+    logger.info "#{self.class.name} stopped streaming from #{broadcasting}"
+  end.clear
+end
+
+
+ +
+ +
+

+ + stream_for(model, callback = nil, coder: nil, &block) + +

+ + +
+

Start streaming the pubsub queue for the model in this channel. Optionally, you can pass a callback that'll be used instead of the default of just transmitting the updates straight to the subscriber.

+ +

Pass coder: ActiveSupport::JSON to decode messages as JSON before passing to the callback. Defaults to coder: nil which does no decoding, passes raw messages.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/streams.rb, line 101
+def stream_for(model, callback = nil, coder: nil, &block)
+  stream_from(broadcasting_for([ channel_name, model ]), callback || block, coder: coder)
+end
+
+
+ +
+ +
+

+ + stream_from(broadcasting, callback = nil, coder: nil, &block) + +

+ + +
+

Start streaming from the named broadcasting pubsub queue. Optionally, you can pass a callback that'll be used instead of the default of just transmitting the updates straight to the subscriber. Pass coder: ActiveSupport::JSON to decode messages as JSON before passing to the callback. Defaults to coder: nil which does no decoding, passes raw messages.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/channel/streams.rb, line 76
+def stream_from(broadcasting, callback = nil, coder: nil, &block)
+  broadcasting = String(broadcasting)
+
+  # Don't send the confirmation until pubsub#subscribe is successful
+  defer_subscription_confirmation!
+
+  # Build a stream handler by wrapping the user-provided callback with
+  # a decoder or defaulting to a JSON-decoding retransmitter.
+  handler = worker_pool_stream_handler(broadcasting, callback || block, coder: coder)
+  streams << [ broadcasting, handler ]
+
+  connection.server.event_loop.post do
+    pubsub.subscribe(broadcasting, handler, lambda do
+      ensure_confirmation_sent
+      logger.info "#{self.class.name} is streaming from #{broadcasting}"
+    end)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection.html b/src/5.2/classes/ActionCable/Connection.html new file mode 100644 index 0000000000..7b57b2339c --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection.html @@ -0,0 +1,108 @@ +--- +title: ActionCable::Connection +layout: default +--- + diff --git a/src/5.2/classes/ActionCable/Connection/Authorization.html b/src/5.2/classes/ActionCable/Connection/Authorization.html new file mode 100644 index 0000000000..a754aa4cad --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/Authorization.html @@ -0,0 +1,115 @@ +--- +title: ActionCable::Connection::Authorization +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + reject_unauthorized_connection() + +

+ + +
+

Closes the WebSocket connection if it is open and returns a 404 “File not Found” response.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/authorization.rb, line 9
+def reject_unauthorized_connection
+  logger.error "An unauthorized connection attempt was rejected"
+  raise UnauthorizedError
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection/Authorization/UnauthorizedError.html b/src/5.2/classes/ActionCable/Connection/Authorization/UnauthorizedError.html new file mode 100644 index 0000000000..01dbefd598 --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/Authorization/UnauthorizedError.html @@ -0,0 +1,60 @@ +--- +title: ActionCable::Connection::Authorization::UnauthorizedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection/Base.html b/src/5.2/classes/ActionCable/Connection/Base.html new file mode 100644 index 0000000000..8607338430 --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/Base.html @@ -0,0 +1,503 @@ +--- +title: ActionCable::Connection::Base +layout: default +--- +
+ +
+
+ +
+ +

For every WebSocket connection the Action Cable server accepts, a Connection object will be instantiated. This instance becomes the parent of all of the channel subscriptions that are created from there on. Incoming messages are then routed to these channel subscriptions based on an identifier sent by the Action Cable consumer. The Connection itself does not deal with any specific application logic beyond authentication and authorization.

+ +

Here's a basic example:

+ +
module ApplicationCable
+  class Connection < ActionCable::Connection::Base
+    identified_by :current_user
+
+    def connect
+      self.current_user = find_verified_user
+      logger.add_tags current_user.name
+    end
+
+    def disconnect
+      # Any cleanup work needed when the cable connection is cut.
+    end
+
+    private
+      def find_verified_user
+        User.find_by_identity(cookies.encrypted[:identity_id]) ||
+          reject_unauthorized_connection
+      end
+  end
+end
+
+ +

First, we declare that this connection can be identified by its current_user. This allows us to later be able to find all connections established for that current_user (and potentially disconnect them). You can declare as many identification indexes as you like. Declaring an identification means that an attr_accessor is automatically set for that key.

+ +

Second, we rely on the fact that the WebSocket connection is established with the cookies from the domain being sent along. This makes it easy to use signed cookies that were set when logging in via a web interface to authorize the WebSocket connection.

+ +

Finally, we add a tag to the connection-specific logger with the name of the current user to easily distinguish their messages in the log.

+ +

Pretty simple, eh?

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + env
+ [R] + logger
+ [R] + message_buffer
+ [R] + protocol
+ [R] + server
+ [R] + subscriptions
+ [R] + websocket

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ [R] + worker_pool
+ + + + +

Class Public methods

+ +
+

+ + new(server, env, coder: ActiveSupport::JSON) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/base.rb, line 53
+def initialize(server, env, coder: ActiveSupport::JSON)
+  @server, @env, @coder = server, env, coder
+
+  @worker_pool = server.worker_pool
+  @logger = new_tagged_logger
+
+  @websocket      = ActionCable::Connection::WebSocket.new(env, self, event_loop)
+  @subscriptions  = ActionCable::Connection::Subscriptions.new(self)
+  @message_buffer = ActionCable::Connection::MessageBuffer.new(self)
+
+  @_internal_subscriptions = nil
+  @started_at = Time.now
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + beat() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/base.rb, line 118
+def beat
+  transmit type: ActionCable::INTERNAL[:message_types][:ping], message: Time.now.to_i
+end
+
+
+ +
+ +
+

+ + close() + +

+ + +
+

Close the WebSocket connection.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/base.rb, line 98
+def close
+  websocket.close
+end
+
+
+ +
+ +
+

+ + send_async(method, *arguments) + +

+ + +
+

Invoke a method on the connection asynchronously through the pool of thread workers.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/base.rb, line 103
+def send_async(method, *arguments)
+  worker_pool.async_invoke(self, method, *arguments)
+end
+
+
+ +
+ +
+

+ + statistics() + +

+ + +
+

Return a basic hash of statistics for the connection keyed with identifier, started_at, subscriptions, and request_id. This can be returned by a health check against the connection.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/base.rb, line 109
+def statistics
+  {
+    identifier: connection_identifier,
+    started_at: @started_at,
+    subscriptions: subscriptions.identifiers,
+    request_id: @env["action_dispatch.request_id"]
+  }
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + cookies() + +

+ + +
+

The cookies of the request that initiated the WebSocket connection. Useful for performing authorization checks.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/base.rb, line 155
+def cookies # :doc:
+  request.cookie_jar
+end
+
+
+ +
+ +
+

+ + request() + +

+ + +
+

The request that initiated the WebSocket connection is available here. This gives access to the environment, cookies, etc.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/base.rb, line 147
+def request # :doc:
+  @request ||= begin
+    environment = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
+    ActionDispatch::Request.new(environment || env)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection/Identification.html b/src/5.2/classes/ActionCable/Connection/Identification.html new file mode 100644 index 0000000000..26bc48bb59 --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/Identification.html @@ -0,0 +1,118 @@ +--- +title: ActionCable::Connection::Identification +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + connection_identifier() + +

+ + +
+

Return a single connection identifier that combines the value of all the registered identifiers into a single gid.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/identification.rb, line 27
+def connection_identifier
+  unless defined? @connection_identifier
+    @connection_identifier = connection_gid identifiers.map { |id| instance_variable_get("@#{id}") }.compact
+  end
+
+  @connection_identifier
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection/Identification/ClassMethods.html b/src/5.2/classes/ActionCable/Connection/Identification/ClassMethods.html new file mode 100644 index 0000000000..509d00d64f --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/Identification/ClassMethods.html @@ -0,0 +1,104 @@ +--- +title: ActionCable::Connection::Identification::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + identified_by(*identifiers) + +

+ + +
+

Mark a key as being a connection identifier index that can then be used to find the specific connection again later. Common identifiers are current_user and current_account, but could be anything, really.

+ +

Note that anything marked as an identifier will automatically create a delegate by the same name on any channel instances created off the connection.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/identification.rb, line 20
+def identified_by(*identifiers)
+  Array(identifiers).each { |identifier| attr_accessor identifier }
+  self.identifiers += identifiers
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection/InternalChannel.html b/src/5.2/classes/ActionCable/Connection/InternalChannel.html new file mode 100644 index 0000000000..6cf0cc464c --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/InternalChannel.html @@ -0,0 +1,60 @@ +--- +title: ActionCable::Connection::InternalChannel +layout: default +--- +
+ +
+
+ +
+ +

Makes it possible for the RemoteConnection to disconnect a specific connection.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection/StreamEventLoop.html b/src/5.2/classes/ActionCable/Connection/StreamEventLoop.html new file mode 100644 index 0000000000..85443b168a --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/StreamEventLoop.html @@ -0,0 +1,367 @@ +--- +title: ActionCable::Connection::StreamEventLoop +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 9
+def initialize
+  @nio = @executor = @thread = nil
+  @map = {}
+  @stopping = false
+  @todo = Queue.new
+
+  @spawn_mutex = Mutex.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + attach(io, stream) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 29
+def attach(io, stream)
+  @todo << lambda do
+    @map[io] = @nio.register(io, :r)
+    @map[io].value = stream
+  end
+  wakeup
+end
+
+
+ +
+ +
+

+ + detach(io, stream) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 37
+def detach(io, stream)
+  @todo << lambda do
+    @nio.deregister io
+    @map.delete io
+    io.close
+  end
+  wakeup
+end
+
+
+ +
+ +
+

+ + post(task = nil, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 22
+def post(task = nil, &block)
+  task ||= block
+
+  spawn
+  @executor << task
+end
+
+
+ +
+ +
+

+ + stop() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 55
+def stop
+  @stopping = true
+  wakeup if @nio
+end
+
+
+ +
+ +
+

+ + timer(interval, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 18
+def timer(interval, &block)
+  Concurrent::TimerTask.new(execution_interval: interval, &block).tap(&:execute)
+end
+
+
+ +
+ +
+

+ + writes_pending(io) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 46
+def writes_pending(io)
+  @todo << lambda do
+    if monitor = @map[io]
+      monitor.interests = :rw
+    end
+  end
+  wakeup
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Connection/TaggedLoggerProxy.html b/src/5.2/classes/ActionCable/Connection/TaggedLoggerProxy.html new file mode 100644 index 0000000000..c760ba0fd6 --- /dev/null +++ b/src/5.2/classes/ActionCable/Connection/TaggedLoggerProxy.html @@ -0,0 +1,257 @@ +--- +title: ActionCable::Connection::TaggedLoggerProxy +layout: default +--- +
+ +
+
+ +
+ +

Allows the use of per-connection tags against the server logger. This wouldn't work using the traditional ActiveSupport::TaggedLogging enhanced Rails.logger, as that logger will reset the tags between requests. The connection is long-lived, so it needs its own set of tags for its independent duration.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + tags
+ + + + +

Class Public methods

+ +
+

+ + new(logger, tags:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 11
+def initialize(logger, tags:)
+  @logger = logger
+  @tags = tags.flatten
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_tags(*tags) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 16
+def add_tags(*tags)
+  @tags += tags.flatten
+  @tags = @tags.uniq
+end
+
+
+ +
+ +
+

+ + tag(logger) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 21
+def tag(logger)
+  if logger.respond_to?(:tagged)
+    current_tags = tags - logger.formatter.current_tags
+    logger.tagged(*current_tags) { yield }
+  else
+    yield
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + log(type, message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 37
+def log(type, message) # :doc:
+  tag(@logger) { @logger.send type, message }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Helpers.html b/src/5.2/classes/ActionCable/Helpers.html new file mode 100644 index 0000000000..5d4f7d9f15 --- /dev/null +++ b/src/5.2/classes/ActionCable/Helpers.html @@ -0,0 +1,67 @@ +--- +title: ActionCable::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Helpers/ActionCableHelper.html b/src/5.2/classes/ActionCable/Helpers/ActionCableHelper.html new file mode 100644 index 0000000000..1db264d871 --- /dev/null +++ b/src/5.2/classes/ActionCable/Helpers/ActionCableHelper.html @@ -0,0 +1,129 @@ +--- +title: ActionCable::Helpers::ActionCableHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + action_cable_meta_tag() + +

+ + +
+

Returns an “action-cable-url” meta tag with the value of the URL specified in your configuration. Ensure this is above your JavaScript tag:

+ +
<head>
+  <%= action_cable_meta_tag %>
+  <%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload' %>
+</head>
+
+ +

This is then used by Action Cable to determine the URL of your WebSocket server. Your CoffeeScript can then connect to the server without needing to specify the URL directly:

+ +
#= require cable
+@App = {}
+App.cable = Cable.createConsumer()
+
+ +

Make sure to specify the correct server location in each of your environment config files:

+ +
config.action_cable.mount_path = "/cable123"
+<%= action_cable_meta_tag %> would render:
+=> <meta name="action-cable-url" content="/cable123" />
+
+config.action_cable.url = "ws://actioncable.com"
+<%= action_cable_meta_tag %> would render:
+=> <meta name="action-cable-url" content="ws://actioncable.com" />
+
+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/helpers/action_cable_helper.rb, line 33
+def action_cable_meta_tag
+  tag "meta", name: "action-cable-url", content: (
+    ActionCable.server.config.url ||
+    ActionCable.server.config.mount_path ||
+    raise("No Action Cable URL configured -- please configure this at config.action_cable.url")
+  )
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/RemoteConnections.html b/src/5.2/classes/ActionCable/RemoteConnections.html new file mode 100644 index 0000000000..cb00b533db --- /dev/null +++ b/src/5.2/classes/ActionCable/RemoteConnections.html @@ -0,0 +1,194 @@ +--- +title: ActionCable::RemoteConnections +layout: default +--- +
+ +
+
+ +
+ +

If you need to disconnect a given connection, you can go through the RemoteConnections. You can find the connections you're looking for by searching for the identifier declared on the connection. For example:

+ +
module ApplicationCable
+  class Connection < ActionCable::Connection::Base
+    identified_by :current_user
+    ....
+  end
+end
+
+ActionCable.server.remote_connections.where(current_user: User.find(1)).disconnect
+
+ +

This will disconnect all the connections established for User.find(1), across all servers running on all machines, because it uses the internal channel that all of these servers are subscribed to.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + server
+ + + + +

Class Public methods

+ +
+

+ + new(server) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/remote_connections.rb, line 25
+def initialize(server)
+  @server = server
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + where(identifier) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/remote_connections.rb, line 29
+def where(identifier)
+  RemoteConnection.new(server, identifier)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection.html b/src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection.html new file mode 100644 index 0000000000..b9840a41a8 --- /dev/null +++ b/src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection.html @@ -0,0 +1,183 @@ +--- +title: ActionCable::RemoteConnections::RemoteConnection +layout: default +--- +
+ +
+
+ +
+ +

Represents a single remote connection found via ActionCable.server.remote_connections.where(*). Exists solely for the purpose of calling disconnect on that connection.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + server
+ + + + +

Class Public methods

+ +
+

+ + new(server, ids) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/remote_connections.rb, line 41
+def initialize(server, ids)
+  @server = server
+  set_identifier_instance_vars(ids)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + disconnect() + +

+ + +
+

Uses the internal channel to disconnect the connection.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/remote_connections.rb, line 47
+def disconnect
+  server.broadcast internal_channel, type: "disconnect"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection/InvalidIdentifiersError.html b/src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection/InvalidIdentifiersError.html new file mode 100644 index 0000000000..e53ce61666 --- /dev/null +++ b/src/5.2/classes/ActionCable/RemoteConnections/RemoteConnection/InvalidIdentifiersError.html @@ -0,0 +1,60 @@ +--- +title: ActionCable::RemoteConnections::RemoteConnection::InvalidIdentifiersError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Server.html b/src/5.2/classes/ActionCable/Server.html new file mode 100644 index 0000000000..e457da90bb --- /dev/null +++ b/src/5.2/classes/ActionCable/Server.html @@ -0,0 +1,90 @@ +--- +title: ActionCable::Server +layout: default +--- + diff --git a/src/5.2/classes/ActionCable/Server/Base.html b/src/5.2/classes/ActionCable/Server/Base.html new file mode 100644 index 0000000000..180900c000 --- /dev/null +++ b/src/5.2/classes/ActionCable/Server/Base.html @@ -0,0 +1,511 @@ +--- +title: ActionCable::Server::Base +layout: default +--- +
+ +
+
+ +
+ +

A singleton ActionCable::Server instance is available via ActionCable.server. It's used by the Rack process that starts the Action Cable server, but is also used by the user to reach the RemoteConnections object, which is used for finding and disconnecting connections across all servers.

+ +

Also, this is the server instance used for broadcasting. See Broadcasting for more information.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + mutex
+ + + + +

Class Public methods

+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 17
+def self.logger; config.logger; end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 22
+def initialize
+  @mutex = Monitor.new
+  @remote_connections = @event_loop = @worker_pool = @pubsub = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+

Called by Rack to setup the server.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 28
+def call(env)
+  setup_heartbeat_timer
+  config.connection_class.call.new(self, env).process
+end
+
+
+ +
+ +
+

+ + connection_identifiers() + +

+ + +
+

All of the identifiers applied to the connection class associated with this server.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 82
+def connection_identifiers
+  config.connection_class.call.identifiers
+end
+
+
+ +
+ +
+

+ + disconnect(identifiers) + +

+ + +
+

Disconnect all the connections identified by identifiers on this server or any others via RemoteConnections.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 34
+def disconnect(identifiers)
+  remote_connections.where(identifiers).disconnect
+end
+
+
+ +
+ +
+

+ + event_loop() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 57
+def event_loop
+  @event_loop || @mutex.synchronize { @event_loop ||= ActionCable::Connection::StreamEventLoop.new }
+end
+
+
+ +
+ +
+

+ + pubsub() + +

+ + +
+

Adapter used for all streams/broadcasting.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 77
+def pubsub
+  @pubsub || @mutex.synchronize { @pubsub ||= config.pubsub_adapter.new(self) }
+end
+
+
+ +
+ +
+

+ + remote_connections() + +

+ + +
+

Gateway to RemoteConnections. See that class for details.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 53
+def remote_connections
+  @remote_connections || @mutex.synchronize { @remote_connections ||= RemoteConnections.new(self) }
+end
+
+
+ +
+ +
+

+ + restart() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 38
+def restart
+  connections.each(&:close)
+
+  @mutex.synchronize do
+    # Shutdown the worker pool
+    @worker_pool.halt if @worker_pool
+    @worker_pool = nil
+
+    # Shutdown the pub/sub adapter
+    @pubsub.shutdown if @pubsub
+    @pubsub = nil
+  end
+end
+
+
+ +
+ +
+

+ + worker_pool() + +

+ + +
+

The worker pool is where we run connection callbacks and channel actions. We do as little as possible on the server's main thread. The worker pool is an executor service that's backed by a pool of threads working from a task queue. The thread pool size maxes out at 4 worker threads by default. Tune the size yourself with config.action_cable.worker_pool_size.

+ +

Using Active Record, Redis, etc within your channel actions means you'll get a separate connection from each thread in the worker pool. Plan your deployment accordingly: 5 servers each running 5 Puma workers each running an 8-thread worker pool means at least 200 database connections.

+ +

Also, ensure that your database connection pool size is as least as large as your worker pool size. Otherwise, workers may oversubscribe the database connection pool and block while they wait for other workers to release their connections. Use a smaller worker pool or a larger database connection pool instead.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/base.rb, line 72
+def worker_pool
+  @worker_pool || @mutex.synchronize { @worker_pool ||= ActionCable::Server::Worker.new(max_size: config.worker_pool_size) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Server/Broadcasting.html b/src/5.2/classes/ActionCable/Server/Broadcasting.html new file mode 100644 index 0000000000..30e5679af4 --- /dev/null +++ b/src/5.2/classes/ActionCable/Server/Broadcasting.html @@ -0,0 +1,175 @@ +--- +title: ActionCable::Server::Broadcasting +layout: default +--- +
+ +
+
+ +
+ +

Broadcasting is how other parts of your application can send messages to a channel's subscribers. As explained in Channel, most of the time, these broadcastings are streamed directly to the clients subscribed to the named broadcasting. Let's explain with a full-stack example:

+ +
class WebNotificationsChannel < ApplicationCable::Channel
+  def subscribed
+    stream_from "web_notifications_#{current_user.id}"
+  end
+end
+
+# Somewhere in your app this is called, perhaps from a NewCommentJob:
+ActionCable.server.broadcast \
+  "web_notifications_1", { title: "New things!", body: "All that's fit for print" }
+
+# Client-side CoffeeScript, which assumes you've already requested the right to send web notifications:
+App.cable.subscriptions.create "WebNotificationsChannel",
+  received: (data) ->
+    new Notification data['title'], body: data['body']
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + broadcast(broadcasting, message, coder: ActiveSupport::JSON) + +

+ + +
+

Broadcast a hash directly to a named broadcasting. This will later be JSON encoded.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/broadcasting.rb, line 24
+def broadcast(broadcasting, message, coder: ActiveSupport::JSON)
+  broadcaster_for(broadcasting, coder: coder).broadcast(message)
+end
+
+
+ +
+ +
+

+ + broadcaster_for(broadcasting, coder: ActiveSupport::JSON) + +

+ + +
+

Returns a broadcaster for a named broadcasting that can be reused. Useful when you have an object that may need multiple spots to transmit to a specific broadcasting over and over.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/broadcasting.rb, line 30
+def broadcaster_for(broadcasting, coder: ActiveSupport::JSON)
+  Broadcaster.new(self, String(broadcasting), coder: coder)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Server/Broadcasting/Broadcaster.html b/src/5.2/classes/ActionCable/Server/Broadcasting/Broadcaster.html new file mode 100644 index 0000000000..f37799cb6c --- /dev/null +++ b/src/5.2/classes/ActionCable/Server/Broadcasting/Broadcaster.html @@ -0,0 +1,185 @@ +--- +title: ActionCable::Server::Broadcasting::Broadcaster +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + broadcasting
+ [R] + coder
+ [R] + server
+ + + + +

Class Public methods

+ +
+

+ + new(server, broadcasting, coder:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/broadcasting.rb, line 38
+def initialize(server, broadcasting, coder:)
+  @server, @broadcasting, @coder = server, broadcasting, coder
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + broadcast(message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/broadcasting.rb, line 42
+def broadcast(message)
+  server.logger.debug "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect}"
+
+  payload = { broadcasting: broadcasting, message: message, coder: coder }
+  ActiveSupport::Notifications.instrument("broadcast.action_cable", payload) do
+    encoded = coder ? coder.encode(message) : message
+    server.pubsub.broadcast broadcasting, encoded
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Server/Configuration.html b/src/5.2/classes/ActionCable/Server/Configuration.html new file mode 100644 index 0000000000..60ce6d8aed --- /dev/null +++ b/src/5.2/classes/ActionCable/Server/Configuration.html @@ -0,0 +1,272 @@ +--- +title: ActionCable::Server::Configuration +layout: default +--- +
+ +
+
+ +
+ +

An instance of this configuration object is available via ActionCable.server.config, which allows you to tweak Action Cable configuration in a Rails config initializer.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + allow_same_origin_as_host
+ [RW] + allowed_request_origins
+ [RW] + cable
+ [RW] + connection_class
+ [RW] + disable_request_forgery_protection
+ [RW] + log_tags
+ [RW] + logger
+ [RW] + mount_path
+ [RW] + url
+ [RW] + worker_pool_size
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/configuration.rb, line 13
+def initialize
+  @log_tags = []
+
+  @connection_class = -> { ActionCable::Connection::Base }
+  @worker_pool_size = 4
+
+  @disable_request_forgery_protection = false
+  @allow_same_origin_as_host = true
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + pubsub_adapter() + +

+ + +
+

Returns constant of subscription adapter specified in config/cable.yml. If the adapter cannot be found, this will default to the Redis adapter. Also makes sure proper dependencies are required.

+
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/configuration.rb, line 26
+def pubsub_adapter
+  adapter = (cable.fetch("adapter") { "redis" })
+
+  # Require the adapter itself and give useful feedback about
+  #   1. Missing adapter gems and
+  #   2. Adapter gems' missing dependencies.
+  path_to_adapter = "action_cable/subscription_adapter/#{adapter}"
+  begin
+    require path_to_adapter
+  rescue LoadError => e
+    # We couldn't require the adapter itself. Raise an exception that
+    # points out config typos and missing gems.
+    if e.path == path_to_adapter
+      # We can assume that a non-builtin adapter was specified, so it's
+      # either misspelled or missing from Gemfile.
+      raise e.class, "Could not load the '#{adapter}' Action Cable pubsub adapter. Ensure that the adapter is spelled correctly in config/cable.yml and that you've added the necessary adapter gem to your Gemfile.", e.backtrace
+
+    # Bubbled up from the adapter require. Prefix the exception message
+    # with some guidance about how to address it and reraise.
+    else
+      raise e.class, "Error loading the '#{adapter}' Action Cable pubsub adapter. Missing a gem it depends on? #{e.message}", e.backtrace
+    end
+  end
+
+  adapter = adapter.camelize
+  adapter = "PostgreSQL" if adapter == "Postgresql"
+  "ActionCable::SubscriptionAdapter::#{adapter}".constantize
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Server/Worker.html b/src/5.2/classes/ActionCable/Server/Worker.html new file mode 100644 index 0000000000..61133c28b6 --- /dev/null +++ b/src/5.2/classes/ActionCable/Server/Worker.html @@ -0,0 +1,75 @@ +--- +title: ActionCable::Server::Worker +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/Server/Worker/ActiveRecordConnectionManagement.html b/src/5.2/classes/ActionCable/Server/Worker/ActiveRecordConnectionManagement.html new file mode 100644 index 0000000000..da550b0729 --- /dev/null +++ b/src/5.2/classes/ActionCable/Server/Worker/ActiveRecordConnectionManagement.html @@ -0,0 +1,101 @@ +--- +title: ActionCable::Server::Worker::ActiveRecordConnectionManagement +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + with_database_connections() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/server/worker/active_record_connection_management.rb, line 15
+def with_database_connections
+  connection.logger.tag(ActiveRecord::Base.logger) { yield }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter.html b/src/5.2/classes/ActionCable/SubscriptionAdapter.html new file mode 100644 index 0000000000..b04f4b01ab --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter.html @@ -0,0 +1,89 @@ +--- +title: ActionCable::SubscriptionAdapter +layout: default +--- + diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/Async.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/Async.html new file mode 100644 index 0000000000..65fc7d015e --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/Async.html @@ -0,0 +1,73 @@ +--- +title: ActionCable::SubscriptionAdapter::Async +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/Async/AsyncSubscriberMap.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/Async/AsyncSubscriberMap.html new file mode 100644 index 0000000000..30b11bc6ab --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/Async/AsyncSubscriberMap.html @@ -0,0 +1,189 @@ +--- +title: ActionCable::SubscriptionAdapter::Async::AsyncSubscriberMap +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(event_loop) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/async.rb, line 14
+def initialize(event_loop)
+  @event_loop = event_loop
+  super()
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_subscriber(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/async.rb, line 19
+def add_subscriber(*)
+  @event_loop.post { super }
+end
+
+
+ +
+ +
+

+ + invoke_callback(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/async.rb, line 23
+def invoke_callback(*)
+  @event_loop.post { super }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/Base.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/Base.html new file mode 100644 index 0000000000..c0f906bbd7 --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/Base.html @@ -0,0 +1,289 @@ +--- +title: ActionCable::SubscriptionAdapter::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + logger
+ [R] + server
+ + + + +

Class Public methods

+ +
+

+ + new(server) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 8
+def initialize(server)
+  @server = server
+  @logger = @server.logger
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + broadcast(channel, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 13
+def broadcast(channel, payload)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + shutdown() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 25
+def shutdown
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + subscribe(channel, message_callback, success_callback = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 17
+def subscribe(channel, message_callback, success_callback = nil)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + unsubscribe(channel, message_callback) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 21
+def unsubscribe(channel, message_callback)
+  raise NotImplementedError
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL.html new file mode 100644 index 0000000000..92f83624c4 --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL.html @@ -0,0 +1,73 @@ +--- +title: ActionCable::SubscriptionAdapter::PostgreSQL +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL/Listener.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL/Listener.html new file mode 100644 index 0000000000..745575fa6d --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL/Listener.html @@ -0,0 +1,337 @@ +--- +title: ActionCable::SubscriptionAdapter::PostgreSQL::Listener +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(adapter, event_loop) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 56
+def initialize(adapter, event_loop)
+  super()
+
+  @adapter = adapter
+  @event_loop = event_loop
+  @queue = Queue.new
+
+  @thread = Thread.new do
+    Thread.current.abort_on_exception = true
+    listen
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_channel(channel, on_success) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 100
+def add_channel(channel, on_success)
+  @queue.push([:listen, channel, on_success])
+end
+
+
+ +
+ +
+

+ + invoke_callback(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 108
+def invoke_callback(*)
+  @event_loop.post { super }
+end
+
+
+ +
+ +
+

+ + listen() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 69
+def listen
+  @adapter.with_connection do |pg_conn|
+    catch :shutdown do
+      loop do
+        until @queue.empty?
+          action, channel, callback = @queue.pop(true)
+
+          case action
+          when :listen
+            pg_conn.exec("LISTEN #{pg_conn.escape_identifier channel}")
+            @event_loop.post(&callback) if callback
+          when :unlisten
+            pg_conn.exec("UNLISTEN #{pg_conn.escape_identifier channel}")
+          when :shutdown
+            throw :shutdown
+          end
+        end
+
+        pg_conn.wait_for_notify(1) do |chan, pid, message|
+          broadcast(chan, message)
+        end
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + remove_channel(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 104
+def remove_channel(channel)
+  @queue.push([:unlisten, channel])
+end
+
+
+ +
+ +
+

+ + shutdown() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 95
+def shutdown
+  @queue.push([:shutdown])
+  Thread.pass while @thread.alive?
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/Redis.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/Redis.html new file mode 100644 index 0000000000..f4c08b0037 --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/Redis.html @@ -0,0 +1,73 @@ +--- +title: ActionCable::SubscriptionAdapter::Redis +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/Redis/Listener.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/Redis/Listener.html new file mode 100644 index 0000000000..b07e6a9424 --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/Redis/Listener.html @@ -0,0 +1,366 @@ +--- +title: ActionCable::SubscriptionAdapter::Redis::Listener +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(adapter, event_loop) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 61
+def initialize(adapter, event_loop)
+  super()
+
+  @adapter = adapter
+  @event_loop = event_loop
+
+  @subscribe_callbacks = Hash.new { |h, k| h[k] = [] }
+  @subscription_lock = Mutex.new
+
+  @raw_client = nil
+
+  @when_connected = []
+
+  @thread = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_channel(channel, on_success) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 128
+def add_channel(channel, on_success)
+  @subscription_lock.synchronize do
+    ensure_listener_running
+    @subscribe_callbacks[channel] << on_success
+    when_connected { send_command("subscribe", channel) }
+  end
+end
+
+
+ +
+ +
+

+ + invoke_callback(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 142
+def invoke_callback(*)
+  @event_loop.post { super }
+end
+
+
+ +
+ +
+

+ + listen(conn) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 77
+def listen(conn)
+  conn.without_reconnect do
+    original_client = conn.respond_to?(:_client) ? conn._client : conn.client
+
+    conn.subscribe("_action_cable_internal") do |on|
+      on.subscribe do |chan, count|
+        @subscription_lock.synchronize do
+          if count == 1
+            @raw_client = original_client
+
+            until @when_connected.empty?
+              @when_connected.shift.call
+            end
+          end
+
+          if callbacks = @subscribe_callbacks[chan]
+            next_callback = callbacks.shift
+            @event_loop.post(&next_callback) if next_callback
+            @subscribe_callbacks.delete(chan) if callbacks.empty?
+          end
+        end
+      end
+
+      on.message do |chan, message|
+        broadcast(chan, message)
+      end
+
+      on.unsubscribe do |chan, count|
+        if count == 0
+          @subscription_lock.synchronize do
+            @raw_client = nil
+          end
+        end
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + remove_channel(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 136
+def remove_channel(channel)
+  @subscription_lock.synchronize do
+    when_connected { send_command("unsubscribe", channel) }
+  end
+end
+
+
+ +
+ +
+

+ + shutdown() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 115
+def shutdown
+  @subscription_lock.synchronize do
+    return if @thread.nil?
+
+    when_connected do
+      send_command("unsubscribe")
+      @raw_client = nil
+    end
+  end
+
+  Thread.pass while @thread.alive?
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/SubscriptionAdapter/SubscriberMap.html b/src/5.2/classes/ActionCable/SubscriptionAdapter/SubscriberMap.html new file mode 100644 index 0000000000..eeda5f8f82 --- /dev/null +++ b/src/5.2/classes/ActionCable/SubscriptionAdapter/SubscriberMap.html @@ -0,0 +1,368 @@ +--- +title: ActionCable::SubscriptionAdapter::SubscriberMap +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 6
+def initialize
+  @subscribers = Hash.new { |h, k| h[k] = [] }
+  @sync = Mutex.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_channel(channel, on_success) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 47
+def add_channel(channel, on_success)
+  on_success.call if on_success
+end
+
+
+ +
+ +
+

+ + add_subscriber(channel, subscriber, on_success) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 11
+def add_subscriber(channel, subscriber, on_success)
+  @sync.synchronize do
+    new_channel = !@subscribers.key?(channel)
+
+    @subscribers[channel] << subscriber
+
+    if new_channel
+      add_channel channel, on_success
+    elsif on_success
+      on_success.call
+    end
+  end
+end
+
+
+ +
+ +
+

+ + broadcast(channel, message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 36
+def broadcast(channel, message)
+  list = @sync.synchronize do
+    return if !@subscribers.key?(channel)
+    @subscribers[channel].dup
+  end
+
+  list.each do |subscriber|
+    invoke_callback(subscriber, message)
+  end
+end
+
+
+ +
+ +
+

+ + invoke_callback(callback, message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 54
+def invoke_callback(callback, message)
+  callback.call message
+end
+
+
+ +
+ +
+

+ + remove_channel(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 51
+def remove_channel(channel)
+end
+
+
+ +
+ +
+

+ + remove_subscriber(channel, subscriber) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 25
+def remove_subscriber(channel, subscriber)
+  @sync.synchronize do
+    @subscribers[channel].delete(subscriber)
+
+    if @subscribers[channel].empty?
+      @subscribers.delete channel
+      remove_channel channel
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionCable/VERSION.html b/src/5.2/classes/ActionCable/VERSION.html new file mode 100644 index 0000000000..3dcae0acbd --- /dev/null +++ b/src/5.2/classes/ActionCable/VERSION.html @@ -0,0 +1,120 @@ +--- +title: ActionCable::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController.html b/src/5.2/classes/ActionController.html new file mode 100644 index 0000000000..9a7d8d3392 --- /dev/null +++ b/src/5.2/classes/ActionController.html @@ -0,0 +1,344 @@ +--- +title: ActionController +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + add_renderer(key, &block) + +

+ + +
+

See Renderers.add

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 7
+def self.add_renderer(key, &block)
+  Renderers.add(key, &block)
+end
+
+
+ +
+ +
+

+ + remove_renderer(key) + +

+ + +
+

See Renderers.remove

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 12
+def self.remove_renderer(key)
+  Renderers.remove(key)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/API.html b/src/5.2/classes/ActionController/API.html new file mode 100644 index 0000000000..bb0f1e8ce3 --- /dev/null +++ b/src/5.2/classes/ActionController/API.html @@ -0,0 +1,230 @@ +--- +title: ActionController::API +layout: default +--- +
+ +
+
+ +
+ +

API Controller is a lightweight version of ActionController::Base, created for applications that don't require all functionalities that a complete Rails controller provides, allowing you to create controllers with just the features that you need for API only applications.

+ +

An API Controller is different from a normal controller in the sense that by default it doesn't include a number of features that are usually required by browser access only: layouts and templates rendering, cookies, sessions, flash, assets, and so on. This makes the entire controller stack thinner, suitable for API applications. It doesn't mean you won't have such features if you need them: they're all available for you to include in your application, they're just not part of the default API controller stack.

+ +

Normally, ApplicationController is the only controller that inherits from ActionController::API. All other controllers in turn inherit from ApplicationController.

+ +

A sample controller could look like this:

+ +
class PostsController < ApplicationController
+  def index
+    posts = Post.all
+    render json: posts
+  end
+end
+
+ +

Request, response, and parameters objects all work the exact same way as ActionController::Base.

+ +

Renders

+ +

The default API Controller stack includes all renderers, which means you can use render :json and brothers freely in your controllers. Keep in mind that templates are not going to be rendered, so you need to ensure your controller is calling either render or redirect_to in all actions, otherwise it will return 204 No Content.

+ +
def show
+  post = Post.find(params[:id])
+  render json: post
+end
+
+ +

Redirects

+ +

Redirects are used to move from one action to another. You can use the redirect_to method in your controllers in the same way as in ActionController::Base. For example:

+ +
def create
+  redirect_to root_url and return if not_authorized?
+  # do stuff here
+end
+
+ +

Adding New Behavior

+ +

In some scenarios you may want to add back some functionality provided by ActionController::Base that is not present by default in ActionController::API, for instance MimeResponds. This module gives you the respond_to method. Adding it is quite simple, you just need to include the module in a specific controller or in ApplicationController in case you want it available in your entire application:

+ +
class ApplicationController < ActionController::API
+  include ActionController::MimeResponds
+end
+
+class PostsController < ApplicationController
+  def index
+    posts = Post.all
+
+    respond_to do |format|
+      format.json { render json: posts }
+      format.xml  { render xml: posts }
+    end
+  end
+end
+
+ +

Make sure to check the modules included in ActionController::Base if you want to use any other functionality that is not provided by ActionController::API out of the box.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
MODULES=[ +AbstractController::Rendering, + +UrlFor, +Redirecting, +ApiRendering, +Renderers::All, +ConditionalGet, +BasicImplicitRender, +StrongParameters, + +ForceSSL, +DataStreaming, + +# Before callbacks should also be executed as early as possible, so +# also include them at the bottom. +AbstractController::Callbacks, + +# Append rescue at the bottom to wrap as much as possible. +Rescue, + +# Add instrumentations hooks at the bottom, to ensure they instrument +# all the methods properly. +Instrumentation, + +# Params wrapper should come before instrumentation so they are +# properly showed in logs +ParamsWrapper +]
 
+ + + + + + +

Class Public methods

+ +
+

+ + without_modules(*modules) + +

+ + +
+

Shortcut helper that returns all the ActionController::API modules except the ones passed as arguments:

+ +
class MyAPIBaseController < ActionController::Metal
+  ActionController::API.without_modules(:ForceSSL, :UrlFor).each do |left|
+    include left
+  end
+end
+
+ +

This gives better control over what you want to exclude and makes it easier to create an API controller class, instead of listing the modules required manually.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/api.rb, line 104
+def self.without_modules(*modules)
+  modules = modules.map do |m|
+    m.is_a?(Symbol) ? ActionController.const_get(m) : m
+  end
+
+  MODULES - modules
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ApiRendering.html b/src/5.2/classes/ActionController/ApiRendering.html new file mode 100644 index 0000000000..32d3d8a6bd --- /dev/null +++ b/src/5.2/classes/ActionController/ApiRendering.html @@ -0,0 +1,116 @@ +--- +title: ActionController::ApiRendering +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + render_to_body(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/api/api_rendering.rb, line 11
+def render_to_body(options = {})
+  _process_options(options)
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Base.html b/src/5.2/classes/ActionController/Base.html new file mode 100644 index 0000000000..f6fdfa0edd --- /dev/null +++ b/src/5.2/classes/ActionController/Base.html @@ -0,0 +1,463 @@ +--- +title: ActionController::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed on request and then either it renders a template or redirects to another action. An action is defined as a public method on the controller, which will automatically be made accessible to the web-server through Rails Routes.

+ +

By default, only the ApplicationController in a Rails application inherits from ActionController::Base. All other controllers inherit from ApplicationController. This gives you one class to configure things such as request forgery protection and filtering of sensitive request parameters.

+ +

A sample controller could look like this:

+ +
class PostsController < ApplicationController
+  def index
+    @posts = Post.all
+  end
+
+  def create
+    @post = Post.create params[:post]
+    redirect_to posts_path
+  end
+end
+
+ +

Actions, by default, render a template in the app/views directory corresponding to the name of the controller and action after executing code in the action. For example, the index action of the PostsController would render the template app/views/posts/index.html.erb by default after populating the @posts instance variable.

+ +

Unlike index, the create action will not render a template. After performing its main purpose (creating a new post), it initiates a redirect instead. This redirect works by returning an external 302 Moved HTTP response that takes the user to the index action.

+ +

These two methods represent the two basic action archetypes used in Action Controllers: Get-and-show and do-and-redirect. Most actions are variations on these themes.

+ +

Requests

+ +

For every request, the router determines the value of the controller and action keys. These determine which controller and action are called. The remaining request parameters, the session (if one is available), and the full request with all the HTTP headers are made available to the action through accessor methods. Then the action is performed.

+ +

The full request object is available via the request accessor and is primarily used to query for HTTP headers:

+ +
def server_ip
+  location = request.env["REMOTE_ADDR"]
+  render plain: "This server hosted at #{location}"
+end
+
+ +

Parameters

+ +

All request parameters, whether they come from a query string in the URL or form data submitted through a POST request are available through the params method which returns a hash. For example, an action that was performed through /posts?category=All&limit=5 will include { "category" => "All", "limit" => "5" } in params.

+ +

It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:

+ +
<input type="text" name="post[name]" value="david">
+<input type="text" name="post[address]" value="hyacintvej">
+
+ +

A request coming from a form holding these inputs will include { "post" => { "name" => "david", "address" => "hyacintvej" } }. If the address input had been named post[address][street], the params would have included { "post" => { "address" => { "street" => "hyacintvej" } } }. There's no limit to the depth of the nesting.

+ +

Sessions

+ +

Sessions allow you to store objects in between requests. This is useful for objects that are not yet ready to be persisted, such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely they could be changed unknowingly. It's usually too much work to keep it all synchronized – something databases already excel at.

+ +

You can place objects in the session by using the session method, which accesses a hash:

+ +
session[:person] = Person.authenticate(user_name, password)
+
+ +

You can retrieve it again through the same hash:

+ +
Hello #{session[:person]}
+
+ +

For removing objects from the session, you can either assign a single key to nil:

+ +
# removes :person from session
+session[:person] = nil
+
+ +

or you can remove the entire session with reset_session.

+ +

Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted. This prevents the user from tampering with the session but also allows them to see its contents.

+ +

Do not put secret information in cookie-based sessions!

+ +

Responses

+ +

Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response object is generated automatically through the use of renders and redirects and requires no user intervention.

+ +

Renders

+ +

Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured. The controller passes objects to the view by assigning instance variables:

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

Which are then automatically available to the view:

+ +
Title: <%= @post.title %>
+
+ +

You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates will use the manual rendering methods:

+ +
def search
+  @results = Search.find(params[:query])
+  case @results.count
+    when 0 then render action: "no_results"
+    when 1 then render action: "show"
+    when 2..10 then render action: "show_many"
+  end
+end
+
+ +

Read more about writing ERB and Builder templates in ActionView::Base.

+ +

Redirects

+ +

Redirects are used to move from one action to another. For example, after a create action, which stores a blog entry to the database, we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're going to reuse (and redirect to) a show action that we'll assume has already been created. The code might look like this:

+ +
def create
+  @entry = Entry.new(params[:entry])
+  if @entry.save
+    # The entry was saved correctly, redirect to show
+    redirect_to action: 'show', id: @entry.id
+  else
+    # things didn't go so well, do something else
+  end
+end
+
+ +

In this case, after saving our new entry to the database, the user is redirected to the show method, which is then executed. Note that this is an external HTTP-level redirection which will cause the browser to make a second request (a GET to the show action), and not some internal re-routing which calls both “create” and then “show” within one request.

+ +

Learn more about redirect_to and what options you have in ActionController::Redirecting.

+ +

Calling multiple redirects or renders

+ +

An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:

+ +
def do_something
+  redirect_to action: "elsewhere"
+  render action: "overthere" # raises DoubleRenderError
+end
+
+ +

If you need to redirect on the condition of something, then be sure to add “and return” to halt execution.

+ +
def do_something
+  redirect_to(action: "elsewhere") and return if monkeys.nil?
+  render action: "overthere" # won't be called if monkeys is nil
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
MODULES=[ +AbstractController::Rendering, +AbstractController::Translation, +AbstractController::AssetPaths, + +Helpers, +UrlFor, +Redirecting, +ActionView::Layouts, +Rendering, +Renderers::All, +ConditionalGet, +EtagWithTemplateDigest, +EtagWithFlash, +Caching, +MimeResponds, +ImplicitRender, +StrongParameters, +ParameterEncoding, +Cookies, +Flash, +FormBuilder, +RequestForgeryProtection, +ContentSecurityPolicy, +ForceSSL, +Streaming, +DataStreaming, +HttpAuthentication::Basic::ControllerMethods, +HttpAuthentication::Digest::ControllerMethods, +HttpAuthentication::Token::ControllerMethods, + +# Before callbacks should also be executed as early as possible, so +# also include them at the bottom. +AbstractController::Callbacks, + +# Append rescue at the bottom to wrap as much as possible. +Rescue, + +# Add instrumentations hooks at the bottom, to ensure they instrument +# all the methods properly. +Instrumentation, + +# Params wrapper should come before instrumentation so they are +# properly showed in logs +ParamsWrapper +]
 
PROTECTED_IVARS=AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + %i( +@_params @_response @_request @_config @_url_options @_action_has_layout @_view_context_class +@_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime @_helper_proxy +)
 

Define some internal variables that should not be propagated to the view.

+ + + + + + +

Class Public methods

+ +
+

+ + make_response!(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/base.rb, line 267
+def self.make_response!(request)
+  ActionDispatch::Response.create.tap do |res|
+    res.request = request
+  end
+end
+
+
+ +
+ +
+

+ + without_modules(*modules) + +

+ + +
+

Shortcut helper that returns all the modules included in ActionController::Base except the ones passed as arguments:

+ +
class MyBaseController < ActionController::Metal
+  ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left|
+    include left
+  end
+end
+
+ +

This gives better control over what you want to exclude and makes it easier to create a bare controller class, instead of listing the modules required manually.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/base.rb, line 197
+def self.without_modules(*modules)
+  modules = modules.map do |m|
+    m.is_a?(Symbol) ? ActionController.const_get(m) : m
+  end
+
+  MODULES - modules
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + request + +

+ + +
+

Returns an ActionDispatch::Request instance that represents the current request.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/base.rb, line 174
+    
+
+
+ +
+ +
+

+ + response + +

+ + +
+

Returns an ActionDispatch::Response that represents the current response.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/base.rb, line 180
+    
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Caching.html b/src/5.2/classes/ActionController/Caching.html new file mode 100644 index 0000000000..cf04744302 --- /dev/null +++ b/src/5.2/classes/ActionController/Caching.html @@ -0,0 +1,94 @@ +--- +title: ActionController::Caching +layout: default +--- +
+ +
+
+ +
+ +

Caching is a cheap way of speeding up slow applications by keeping the result of calculations, renderings, and database calls around for subsequent requests.

+ +

You can read more about each approach by clicking the modules below.

+ +

Note: To turn off all caching provided by Action Controller, set

+ +
config.action_controller.perform_caching = false
+
+ +

Caching stores

+ +

All the caching stores from ActiveSupport::Cache are available to be used as backends for Action Controller caching.

+ +

Configuration examples (FileStore is the default):

+ +
config.action_controller.cache_store = :memory_store
+config.action_controller.cache_store = :file_store, '/path/to/cache/directory'
+config.action_controller.cache_store = :mem_cache_store, 'localhost'
+config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new('localhost:11211')
+config.action_controller.cache_store = MyOwnStore.new('parameter')
+
+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ConditionalGet.html b/src/5.2/classes/ActionController/ConditionalGet.html new file mode 100644 index 0000000000..aafe8e586f --- /dev/null +++ b/src/5.2/classes/ActionController/ConditionalGet.html @@ -0,0 +1,457 @@ +--- +title: ActionController::ConditionalGet +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + expires_in(seconds, options = {}) + +

+ + +
+

Sets an HTTP 1.1 Cache-Control header. Defaults to issuing a private instruction, so that intermediate caches must not cache the response.

+ +
expires_in 20.minutes
+expires_in 3.hours, public: true
+expires_in 3.hours, public: true, must_revalidate: true
+
+ +

This method will overwrite an existing Cache-Control header. See www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.

+ +

The method will also ensure an HTTP Date header for client compatibility.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 234
+def expires_in(seconds, options = {})
+  response.cache_control.merge!(
+    max_age: seconds,
+    public: options.delete(:public),
+    must_revalidate: options.delete(:must_revalidate)
+  )
+  options.delete(:private)
+
+  response.cache_control[:extras] = options.map { |k, v| "#{k}=#{v}" }
+  response.date = Time.now unless response.date?
+end
+
+
+ +
+ +
+

+ + expires_now() + +

+ + +
+

Sets an HTTP 1.1 Cache-Control header of no-cache. This means the resource will be marked as stale, so clients must always revalidate. Intermediate/browser caches may still store the asset.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 249
+def expires_now
+  response.cache_control.replace(no_cache: true)
+end
+
+
+ +
+ +
+

+ + fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, template: nil) + +

+ + +
+

Sets the etag, last_modified, or both on the response and renders a 304 Not Modified response if the request is already fresh.

+ +

Parameters:

+
  • +

    :etag Sets a “weak” ETag validator on the response. See the :weak_etag option.

    +
  • +

    :weak_etag Sets a “weak” ETag validator on the response. Requests that set If-None-Match header may return a 304 Not Modified response if it matches the ETag exactly. A weak ETag indicates semantic equivalence, not byte-for-byte equality, so they're good for caching HTML pages in browser caches. They can't be used for responses that must be byte-identical, like serving Range requests within a PDF file.

    +
  • +

    :strong_etag Sets a “strong” ETag validator on the response. Requests that set If-None-Match header may return a 304 Not Modified response if it matches the ETag exactly. A strong ETag implies exact equality: the response must match byte for byte. This is necessary for doing Range requests within a large video or PDF file, for example, or for compatibility with some CDNs that don't support weak ETags.

    +
  • +

    :last_modified Sets a “weak” last-update validator on the response. Subsequent requests that set If-Modified-Since may return a 304 Not Modified response if last_modified <= If-Modified-Since.

    +
  • +

    :public By default the Cache-Control header is private, set this to true if you want your application to be cacheable by other devices (proxy caches).

    +
  • +

    :template By default, the template digest for the current controller/action is included in ETags. If the action renders a different template, you can include its digest instead. If the action doesn't render a template at all, you can pass template: false to skip any attempt to check for a template digest.

    +
+ +

Example:

+ +
def show
+  @article = Article.find(params[:id])
+  fresh_when(etag: @article, last_modified: @article.updated_at, public: true)
+end
+
+ +

This will render the show template if the request isn't sending a matching ETag or If-Modified-Since header and just a 304 Not Modified response if there's a match.

+ +

You can also just pass a record. In this case last_modified will be set by calling updated_at and etag by passing the object itself.

+ +
def show
+  @article = Article.find(params[:id])
+  fresh_when(@article)
+end
+
+ +

You can also pass an object that responds to maximum, such as a collection of active records. In this case last_modified will be set by calling maximum(:updated_at) on the collection (the timestamp of the most recently updated record) and the etag by passing the object itself.

+ +
def index
+  @articles = Article.all
+  fresh_when(@articles)
+end
+
+ +

When passing a record or a collection, you can still set the public header:

+ +
def show
+  @article = Article.find(params[:id])
+  fresh_when(@article, public: true)
+end
+
+ +

When rendering a different template than the default controller/action style, you can indicate which digest to include in the ETag:

+ +
before_action { fresh_when @article, template: 'widgets/show' }
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 105
+def fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, template: nil)
+  weak_etag ||= etag || object unless strong_etag
+  last_modified ||= object.try(:updated_at) || object.try(:maximum, :updated_at)
+
+  if strong_etag
+    response.strong_etag = combine_etags strong_etag,
+      last_modified: last_modified, public: public, template: template
+  elsif weak_etag || template
+    response.weak_etag = combine_etags weak_etag,
+      last_modified: last_modified, public: public, template: template
+  end
+
+  response.last_modified = last_modified if last_modified
+  response.cache_control[:public] = true if public
+
+  head :not_modified if request.fresh?(response)
+end
+
+
+ +
+ +
+

+ + http_cache_forever(public: false) + +

+ + +
+

Cache or yield the block. The cache is supposed to never expire.

+ +

You can use this method when you have an HTTP response that never changes, and the browser and proxies should cache it indefinitely.

+
  • +

    public: By default, HTTP responses are private, cached only on the user's web browser. To allow proxies to cache the response, set true to indicate that they can serve the cached response to all users.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 261
+def http_cache_forever(public: false)
+  expires_in 100.years, public: public
+
+  yield if stale?(etag: request.fullpath,
+                  last_modified: Time.new(2011, 1, 1).utc,
+                  public: public)
+end
+
+
+ +
+ +
+

+ + stale?(object = nil, **freshness_kwargs) + +

+ + +
+

Sets the etag and/or last_modified on the response and checks it against the client request. If the request doesn't match the options provided, the request is considered stale and should be generated from scratch. Otherwise, it's fresh and we don't need to generate anything and a reply of 304 Not Modified is sent.

+ +

Parameters:

+
  • +

    :etag Sets a “weak” ETag validator on the response. See the :weak_etag option.

    +
  • +

    :weak_etag Sets a “weak” ETag validator on the response. Requests that set If-None-Match header may return a 304 Not Modified response if it matches the ETag exactly. A weak ETag indicates semantic equivalence, not byte-for-byte equality, so they're good for caching HTML pages in browser caches. They can't be used for responses that must be byte-identical, like serving Range requests within a PDF file.

    +
  • +

    :strong_etag Sets a “strong” ETag validator on the response. Requests that set If-None-Match header may return a 304 Not Modified response if it matches the ETag exactly. A strong ETag implies exact equality: the response must match byte for byte. This is necessary for doing Range requests within a large video or PDF file, for example, or for compatibility with some CDNs that don't support weak ETags.

    +
  • +

    :last_modified Sets a “weak” last-update validator on the response. Subsequent requests that set If-Modified-Since may return a 304 Not Modified response if last_modified <= If-Modified-Since.

    +
  • +

    :public By default the Cache-Control header is private, set this to true if you want your application to be cacheable by other devices (proxy caches).

    +
  • +

    :template By default, the template digest for the current controller/action is included in ETags. If the action renders a different template, you can include its digest instead. If the action doesn't render a template at all, you can pass template: false to skip any attempt to check for a template digest.

    +
+ +

Example:

+ +
def show
+  @article = Article.find(params[:id])
+
+  if stale?(etag: @article, last_modified: @article.updated_at)
+    @statistics = @article.really_expensive_call
+    respond_to do |format|
+      # all the supported formats
+    end
+  end
+end
+
+ +

You can also just pass a record. In this case last_modified will be set by calling updated_at and etag by passing the object itself.

+ +
def show
+  @article = Article.find(params[:id])
+
+  if stale?(@article)
+    @statistics = @article.really_expensive_call
+    respond_to do |format|
+      # all the supported formats
+    end
+  end
+end
+
+ +

You can also pass an object that responds to maximum, such as a collection of active records. In this case last_modified will be set by calling +maximum(:updated_at)+ on the collection (the timestamp of the most recently updated record) and the etag by passing the object itself.

+ +
def index
+  @articles = Article.all
+
+  if stale?(@articles)
+    @statistics = @articles.really_expensive_call
+    respond_to do |format|
+      # all the supported formats
+    end
+  end
+end
+
+ +

When passing a record or a collection, you can still set the public header:

+ +
def show
+  @article = Article.find(params[:id])
+
+  if stale?(@article, public: true)
+    @statistics = @article.really_expensive_call
+    respond_to do |format|
+      # all the supported formats
+    end
+  end
+end
+
+ +

When rendering a different template than the default controller/action style, you can indicate which digest to include in the ETag:

+ +
def show
+  super if stale? @article, template: 'widgets/show'
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 218
+def stale?(object = nil, **freshness_kwargs)
+  fresh_when(object, **freshness_kwargs)
+  !request.fresh?(response)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ConditionalGet/ClassMethods.html b/src/5.2/classes/ActionController/ConditionalGet/ClassMethods.html new file mode 100644 index 0000000000..3b2ee41c49 --- /dev/null +++ b/src/5.2/classes/ActionController/ConditionalGet/ClassMethods.html @@ -0,0 +1,112 @@ +--- +title: ActionController::ConditionalGet::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + etag(&etagger) + +

+ + +
+

Allows you to consider additional controller-wide information when generating an ETag. For example, if you serve pages tailored depending on who's logged in at the moment, you may want to add the current user id to be part of the ETag to prevent unauthorized displaying of cached pages.

+ +
class InvoicesController < ApplicationController
+  etag { current_user.try :id }
+
+  def show
+    # Etag will differ even for the same invoice when it's viewed by a different current_user
+    @invoice = Invoice.find(params[:id])
+    fresh_when(@invoice)
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 30
+def etag(&etagger)
+  self.etaggers += [etagger]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ContentSecurityPolicy.html b/src/5.2/classes/ActionController/ContentSecurityPolicy.html new file mode 100644 index 0000000000..e9e11908f6 --- /dev/null +++ b/src/5.2/classes/ActionController/ContentSecurityPolicy.html @@ -0,0 +1,89 @@ +--- +title: ActionController::ContentSecurityPolicy +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ContentSecurityPolicy/ClassMethods.html b/src/5.2/classes/ActionController/ContentSecurityPolicy/ClassMethods.html new file mode 100644 index 0000000000..a0218ec9ff --- /dev/null +++ b/src/5.2/classes/ActionController/ContentSecurityPolicy/ClassMethods.html @@ -0,0 +1,152 @@ +--- +title: ActionController::ContentSecurityPolicy::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + content_security_policy(enabled = true, **options, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/content_security_policy.rb, line 17
+def content_security_policy(enabled = true, **options, &block)
+  before_action(options) do
+    if block_given?
+      policy = current_content_security_policy
+      yield policy
+      request.content_security_policy = policy
+    end
+
+    unless enabled
+      request.content_security_policy = nil
+    end
+  end
+end
+
+
+ +
+ +
+

+ + content_security_policy_report_only(report_only = true, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/content_security_policy.rb, line 31
+def content_security_policy_report_only(report_only = true, **options)
+  before_action(options) do
+    request.content_security_policy_report_only = report_only
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Cookies.html b/src/5.2/classes/ActionController/Cookies.html new file mode 100644 index 0000000000..e327b8ed0f --- /dev/null +++ b/src/5.2/classes/ActionController/Cookies.html @@ -0,0 +1,54 @@ +--- +title: ActionController::Cookies +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/DataStreaming.html b/src/5.2/classes/ActionController/DataStreaming.html new file mode 100644 index 0000000000..408f88ecae --- /dev/null +++ b/src/5.2/classes/ActionController/DataStreaming.html @@ -0,0 +1,232 @@ +--- +title: ActionController::DataStreaming +layout: default +--- +
+ +
+
+ +
+ +

Methods for sending arbitrary data and for streaming files to the browser, instead of rendering.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Private methods

+ +
+

+ + send_data(data, options = {}) + +

+ + +
+

Sends the given binary data to the browser. This method is similar to render plain: data, but also allows you to specify whether the browser should display the response as a file attachment (i.e. in a download dialog) or as inline data. You may also set the content type, the file name, and other things.

+ +

Options:

+
  • +

    :filename - suggests a filename for the browser to use.

    +
  • +

    :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify either a string or a symbol for a registered type with Mime::Type.register, for example :json. If omitted, type will be inferred from the file extension specified in :filename. If no content type is registered for the extension, the default type 'application/octet-stream' will be used.

    +
  • +

    :disposition - specifies whether the file will be shown inline or downloaded. Valid values are 'inline' and 'attachment' (default).

    +
  • +

    :status - specifies the status code to send with the response. Defaults to 200.

    +
+ +

Generic data download:

+ +
send_data buffer
+
+ +

Download a dynamically-generated tarball:

+ +
send_data generate_tgz('dir'), filename: 'dir.tgz'
+
+ +

Display an image Active Record in the browser:

+ +
send_data image.data, type: image.content_type, disposition: 'inline'
+
+ +

See send_file for more information on HTTP Content-* headers and caching.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/data_streaming.rb, line 108
+def send_data(data, options = {}) #:doc:
+  send_file_headers! options
+  render options.slice(:status, :content_type).merge(body: data)
+end
+
+
+ +
+ +
+

+ + send_file(path, options = {}) + +

+ + +
+

Sends the file. This uses a server-appropriate method (such as X-Sendfile) via the Rack::Sendfile middleware. The header to use is set via config.action_dispatch.x_sendfile_header. Your server can also configure this for you by setting the X-Sendfile-Type header.

+ +

Be careful to sanitize the path parameter if it is coming from a web page. send_file(params[:path]) allows a malicious user to download any file on your server.

+ +

Options:

+
  • +

    :filename - suggests a filename for the browser to use. Defaults to File.basename(path).

    +
  • +

    :type - specifies an HTTP content type. You can specify either a string or a symbol for a registered type with Mime::Type.register, for example :json. If omitted, the type will be inferred from the file extension specified in :filename. If no content type is registered for the extension, the default type 'application/octet-stream' will be used.

    +
  • +

    :disposition - specifies whether the file will be shown inline or downloaded. Valid values are 'inline' and 'attachment' (default).

    +
  • +

    :status - specifies the status code to send with the response. Defaults to 200.

    +
  • +

    :url_based_filename - set to true if you want the browser to guess the filename from the URL, which is necessary for i18n filenames on certain browsers (setting :filename overrides this option).

    +
+ +

The default Content-Type and Content-Disposition headers are set to download arbitrary binary files in as many browsers as possible. IE versions 4, 5, 5.5, and 6 are all known to have a variety of quirks (especially when downloading over SSL).

+ +

Simple download:

+ +
send_file '/path/to.zip'
+
+ +

Show a JPEG in the browser:

+ +
send_file '/path/to.jpeg', type: 'image/jpeg', disposition: 'inline'
+
+ +

Show a 404 page in the browser:

+ +
send_file '/path/to/404.html', type: 'text/html; charset=utf-8', status: 404
+
+ +

Read about the other Content-* HTTP headers if you'd like to provide the user with more information (such as Content-Description) in www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.

+ +

Also be aware that the document may be cached by proxies and browsers. The Pragma and Cache-Control headers declare how the file may be cached by intermediaries. They default to require clients to validate with the server before releasing cached responses. See www.mnot.net/cache_docs/ for an overview of web caching and www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 for the Cache-Control header spec.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/data_streaming.rb, line 68
+def send_file(path, options = {}) #:doc:
+  raise MissingFile, "Cannot read file #{path}" unless File.file?(path) && File.readable?(path)
+
+  options[:filename] ||= File.basename(path) unless options[:url_based_filename]
+  send_file_headers! options
+
+  self.status = options[:status] || 200
+  self.content_type = options[:content_type] if options.key?(:content_type)
+  response.send_file path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/EtagWithFlash.html b/src/5.2/classes/ActionController/EtagWithFlash.html new file mode 100644 index 0000000000..5e5620ed80 --- /dev/null +++ b/src/5.2/classes/ActionController/EtagWithFlash.html @@ -0,0 +1,74 @@ +--- +title: ActionController::EtagWithFlash +layout: default +--- +
+ +
+
+ +
+ +

When you're using the flash, it's generally used as a conditional on the view. This means the content of the view depends on the flash. Which in turn means that the ETag for a response should be computed with the content of the flash in mind. This does that by including the content of the flash as a component in the ETag that's generated for a response.

+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/EtagWithTemplateDigest.html b/src/5.2/classes/ActionController/EtagWithTemplateDigest.html new file mode 100644 index 0000000000..d96de611b0 --- /dev/null +++ b/src/5.2/classes/ActionController/EtagWithTemplateDigest.html @@ -0,0 +1,88 @@ +--- +title: ActionController::EtagWithTemplateDigest +layout: default +--- +
+ +
+
+ +
+ +

When our views change, they should bubble up into HTTP cache freshness and bust browser caches. So the template digest for the current action is automatically included in the ETag.

+ +

Enabled by default for apps that use Action View. Disable by setting

+ +
config.action_controller.etag_with_template_digest = false
+
+ +

Override the template to digest by passing :template to fresh_when and stale? calls. For example:

+ +
# We're going to render widgets/show, not posts/show
+fresh_when @post, template: 'widgets/show'
+
+# We're not going to render a template, so omit it from the ETag.
+fresh_when @post, template: false
+
+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Flash.html b/src/5.2/classes/ActionController/Flash.html new file mode 100644 index 0000000000..ded12e46e9 --- /dev/null +++ b/src/5.2/classes/ActionController/Flash.html @@ -0,0 +1,124 @@ +--- +title: ActionController::Flash +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Private methods

+ +
+

+ + redirect_to(options = {}, response_status_and_flash = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/flash.rb, line 47
+def redirect_to(options = {}, response_status_and_flash = {}) #:doc:
+  self.class._flash_types.each do |flash_type|
+    if type = response_status_and_flash.delete(flash_type)
+      flash[flash_type] = type
+    end
+  end
+
+  if other_flashes = response_status_and_flash.delete(:flash)
+    flash.update(other_flashes)
+  end
+
+  super(options, response_status_and_flash)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Flash/ClassMethods.html b/src/5.2/classes/ActionController/Flash/ClassMethods.html new file mode 100644 index 0000000000..1c722217d0 --- /dev/null +++ b/src/5.2/classes/ActionController/Flash/ClassMethods.html @@ -0,0 +1,124 @@ +--- +title: ActionController::Flash::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + add_flash_types(*types) + +

+ + +
+

Creates new flash types. You can pass as many types as you want to create flash types other than the default alert and notice in your controllers and views. For instance:

+ +
# in application_controller.rb
+class ApplicationController < ActionController::Base
+  add_flash_types :warning
+end
+
+# in your controller
+redirect_to user_path(@user), warning: "Incomplete profile"
+
+# in your view
+<%= warning %>
+
+ +

This method will automatically define a new method for each of the given names, and it will be available in your views.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/flash.rb, line 32
+def add_flash_types(*types)
+  types.each do |type|
+    next if _flash_types.include?(type)
+
+    define_method(type) do
+      request.flash[type]
+    end
+    helper_method type
+
+    self._flash_types += [type]
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ForceSSL.html b/src/5.2/classes/ActionController/ForceSSL.html new file mode 100644 index 0000000000..afcd89abd6 --- /dev/null +++ b/src/5.2/classes/ActionController/ForceSSL.html @@ -0,0 +1,200 @@ +--- +title: ActionController::ForceSSL +layout: default +--- +
+ +
+
+ +
+ +

This module provides a method which will redirect the browser to use the secured HTTPS protocol. This will ensure that users' sensitive information will be transferred safely over the internet. You should always force the browser to use HTTPS when you're transferring sensitive information such as user authentication, account information, or credit card information.

+ +

Note that if you are really concerned about your application security, you might consider using config.force_ssl in your config file instead. That will ensure all the data is transferred via HTTPS, and will prevent the user from getting their session hijacked when accessing the site over unsecured HTTP protocol.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ACTION_OPTIONS=[:only, :except, :if, :unless]
 
REDIRECT_OPTIONS=[:status, :flash, :alert, :notice]
 
URL_OPTIONS=[:protocol, :host, :domain, :subdomain, :port, :path]
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + force_ssl_redirect(host_or_options = nil) + +

+ + +
+

Redirect the existing request to use the HTTPS protocol.

+ +

Parameters

+
  • +

    host_or_options - Either a host name or any of the URL and redirect options available to the force_ssl method.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/force_ssl.rb, line 78
+def force_ssl_redirect(host_or_options = nil)
+  unless request.ssl?
+    options = {
+      protocol: "https://",
+      host: request.host,
+      path: request.fullpath,
+      status: :moved_permanently
+    }
+
+    if host_or_options.is_a?(Hash)
+      options.merge!(host_or_options)
+    elsif host_or_options
+      options[:host] = host_or_options
+    end
+
+    secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS))
+    flash.keep if respond_to?(:flash) && request.respond_to?(:flash)
+    redirect_to secure_url, options.slice(*REDIRECT_OPTIONS)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ForceSSL/ClassMethods.html b/src/5.2/classes/ActionController/ForceSSL/ClassMethods.html new file mode 100644 index 0000000000..ee3865ebcb --- /dev/null +++ b/src/5.2/classes/ActionController/ForceSSL/ClassMethods.html @@ -0,0 +1,157 @@ +--- +title: ActionController::ForceSSL::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + force_ssl(options = {}) + +

+ + +
+

Force the request to this particular controller or specified actions to be through the HTTPS protocol.

+ +

If you need to disable this for any reason (e.g. development) then you can use an :if or :unless condition.

+ +
class AccountsController < ApplicationController
+  force_ssl if: :ssl_configured?
+
+  def ssl_configured?
+    !Rails.env.development?
+  end
+end
+
+ +

URL Options

+ +

You can pass any of the following options to affect the redirect URL

+
  • +

    host - Redirect to a different host name

    +
  • +

    subdomain - Redirect to a different subdomain

    +
  • +

    domain - Redirect to a different domain

    +
  • +

    port - Redirect to a non-standard port

    +
  • +

    path - Redirect to a different path

    +
+ +

Redirect Options

+ +

You can pass any of the following options to affect the redirect status and response

+
  • +

    status - Redirect with a custom status (default is 301 Moved Permanently)

    +
  • +

    flash - Set a flash message when redirecting

    +
  • +

    alert - Set an alert message when redirecting

    +
  • +

    notice - Set a notice message when redirecting

    +
+ +

Action Options

+ +

You can pass any of the following options to affect the before_action callback

+
  • +

    only - The callback should be run only for this action

    +
  • +

    except - The callback should be run for all actions except this action

    +
  • +

    if - A symbol naming an instance method or a proc; the callback will be called only when it returns a true value.

    +
  • +

    unless - A symbol naming an instance method or a proc; the callback will be called only when it returns a false value.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/force_ssl.rb, line 64
+def force_ssl(options = {})
+  action_options = options.slice(*ACTION_OPTIONS)
+  redirect_options = options.except(*ACTION_OPTIONS)
+  before_action(action_options) do
+    force_ssl_redirect(redirect_options)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/FormBuilder.html b/src/5.2/classes/ActionController/FormBuilder.html new file mode 100644 index 0000000000..8834eff872 --- /dev/null +++ b/src/5.2/classes/ActionController/FormBuilder.html @@ -0,0 +1,142 @@ +--- +title: ActionController::FormBuilder +layout: default +--- +
+ +
+
+ +
+ +

Override the default form builder for all views rendered by this controller and any of its descendants. Accepts a subclass of ActionView::Helpers::FormBuilder.

+ +

For example, given a form builder:

+ +
class AdminFormBuilder < ActionView::Helpers::FormBuilder
+  def special_field(name)
+  end
+end
+
+ +

The controller specifies a form builder as its default:

+ +
class AdminAreaController < ApplicationController
+  default_form_builder AdminFormBuilder
+end
+
+ +

Then in the view any form using form_for will be an instance of the specified form builder:

+ +
<%= form_for(@instance) do |builder| %>
+  <%= builder.special_field(:name) %>
+<% end %>
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + default_form_builder() + +

+ + +
+

Default form builder for the controller

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/form_builder.rb, line 46
+def default_form_builder
+  self.class._default_form_builder
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/FormBuilder/ClassMethods.html b/src/5.2/classes/ActionController/FormBuilder/ClassMethods.html new file mode 100644 index 0000000000..88772f9b1d --- /dev/null +++ b/src/5.2/classes/ActionController/FormBuilder/ClassMethods.html @@ -0,0 +1,106 @@ +--- +title: ActionController::FormBuilder::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + default_form_builder(builder) + +

+ + +
+

Set the form builder to be used as the default for all forms in the views rendered by this controller and its subclasses.

+ +

Parameters

+
  • +

    builder - Default form builder, an instance of ActionView::Helpers::FormBuilder

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/form_builder.rb, line 40
+def default_form_builder(builder)
+  self._default_form_builder = builder
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Head.html b/src/5.2/classes/ActionController/Head.html new file mode 100644 index 0000000000..9d80561cb4 --- /dev/null +++ b/src/5.2/classes/ActionController/Head.html @@ -0,0 +1,138 @@ +--- +title: ActionController::Head +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + head(status, options = {}) + +

+ + +
+

Returns a response that has no content (merely headers). The options argument is interpreted to be a hash of header names and values. This allows you to easily return a response that consists only of significant headers:

+ +
head :created, location: person_path(@person)
+
+head :created, location: @person
+
+ +

It can also be used to return exceptional conditions:

+ +
return head(:method_not_allowed) unless request.post?
+return head(:bad_request) unless valid_request?
+render
+
+ +

See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list of valid status symbols.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/head.rb, line 21
+def head(status, options = {})
+  if status.is_a?(Hash)
+    raise ArgumentError, "#{status.inspect} is not a valid value for `status`."
+  end
+
+  status ||= :ok
+
+  location = options.delete(:location)
+  content_type = options.delete(:content_type)
+
+  options.each do |key, value|
+    headers[key.to_s.dasherize.split("-").each { |v| v[0] = v[0].chr.upcase }.join("-")] = value.to_s
+  end
+
+  self.status = status
+  self.location = url_for(location) if location
+
+  self.response_body = ""
+
+  if include_content?(response_code)
+    self.content_type = content_type || (Mime[formats.first] if formats)
+    response.charset = false
+  end
+
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Helpers.html b/src/5.2/classes/ActionController/Helpers.html new file mode 100644 index 0000000000..fabe943ec3 --- /dev/null +++ b/src/5.2/classes/ActionController/Helpers.html @@ -0,0 +1,188 @@ +--- +title: ActionController::Helpers +layout: default +--- +
+ +
+
+ +
+ +

The Rails framework provides a large number of helpers for working with assets, dates, forms, numbers and model objects, to name a few. These helpers are available to all templates by default.

+ +

In addition to using the standard template helpers provided, creating custom helpers to extract complicated logic or reusable functionality is strongly encouraged. By default, each controller will include all helpers. These helpers are only accessible on the controller through #helpers

+ +

In previous versions of Rails the controller will include a helper which matches the name of the controller, e.g., MyController will automatically include MyHelper. To return old behavior set config.action_controller.include_all_helpers to false.

+ +

Additional helpers can be specified using the helper class method in ActionController::Base or any controller which inherits from it.

+ +

The to_s method from the Time class can be wrapped in a helper method to display a custom message if a Time object is blank:

+ +
module FormattedTimeHelper
+  def format_time(time, format=:long, blank_message="&nbsp;")
+    time.blank? ? blank_message : time.to_s(format)
+  end
+end
+
+ +

FormattedTimeHelper can now be included in a controller, using the helper class method:

+ +
class EventsController < ActionController::Base
+  helper FormattedTimeHelper
+  def index
+    @events = Event.all
+  end
+end
+
+ +

Then, in any view rendered by EventController, the format_time method can be called:

+ +
<% @events.each do |event| -%>
+  <p>
+    <%= format_time(event.time, :short, "N/A") %> | <%= event.name %>
+  </p>
+<% end -%>
+
+ +

Finally, assuming we have two event instances, one which has a time and one which does not, the output might look like this:

+ +
23 Aug 11:30 | Carolina Railhawks Soccer Match
+N/A | Carolina Railhawks Training Workshop
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + helpers_path
+ + + + + +

Instance Public methods

+ +
+

+ + helpers() + +

+ + +
+

Provides a proxy to access helper methods from outside the view.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/helpers.rb, line 119
+def helpers
+  @_helper_proxy ||= view_context
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Helpers/ClassMethods.html b/src/5.2/classes/ActionController/Helpers/ClassMethods.html new file mode 100644 index 0000000000..2545d52943 --- /dev/null +++ b/src/5.2/classes/ActionController/Helpers/ClassMethods.html @@ -0,0 +1,252 @@ +--- +title: ActionController::Helpers::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + all_helpers_from_path(path) + +

+ + +
+

Returns a list of helper names in a given path.

+ +
ActionController::Base.all_helpers_from_path 'app/helpers'
+# => ["application", "chart", "rubygems"]
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/helpers.rb, line 101
+def all_helpers_from_path(path)
+  helpers = Array(path).flat_map do |_path|
+    extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/
+    names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1'.freeze) }
+    names.sort!
+  end
+  helpers.uniq!
+  helpers
+end
+
+
+ +
+ +
+

+ + helper_attr(*attrs) + +

+ + +
+

Declares helper accessors for controller attributes. For example, the following adds new name and name= instance methods to a controller and makes them available to the view:

+ +
attr_accessor :name
+helper_attr :name
+
+ +

Parameters

+
  • +

    attrs - Names of attributes to be converted into helpers.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/helpers.rb, line 71
+def helper_attr(*attrs)
+  attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
+end
+
+
+ +
+ +
+

+ + helpers() + +

+ + +
+

Provides a proxy to access helper methods from outside the view.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/helpers.rb, line 76
+def helpers
+  @helper_proxy ||= begin
+    proxy = ActionView::Base.new
+    proxy.config = config.inheritable_copy
+    proxy.extend(_helpers)
+  end
+end
+
+
+ +
+ +
+

+ + modules_for_helpers(args) + +

+ + +
+

Overwrite modules_for_helpers to accept :all as argument, which loads all helpers in helpers_path.

+ +

Parameters

+
  • +

    args - A list of helpers

    +
+ +

Returns

+
  • +

    array - A normalized list of modules for the list of helpers provided.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/helpers.rb, line 92
+def modules_for_helpers(args)
+  args += all_application_helpers if args.delete(:all)
+  super(args)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication.html b/src/5.2/classes/ActionController/HttpAuthentication.html new file mode 100644 index 0000000000..0a798d85ef --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication.html @@ -0,0 +1,77 @@ +--- +title: ActionController::HttpAuthentication +layout: default +--- +
+ +
+
+ +
+ +

Makes it dead easy to do HTTP Basic, Digest and Token authentication.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication/Basic.html b/src/5.2/classes/ActionController/HttpAuthentication/Basic.html new file mode 100644 index 0000000000..608cd0239c --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication/Basic.html @@ -0,0 +1,454 @@ +--- +title: ActionController::HttpAuthentication::Basic +layout: default +--- +
+ +
+
+ +
+ +

Makes it dead easy to do HTTP Basic authentication.

+ +

Simple Basic example

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

Advanced Basic example

+ +

Here is a more advanced Basic example where only Atom feeds and the XML API is protected by HTTP authentication, the regular HTML interface is protected by a session approach:

+ +
class ApplicationController < ActionController::Base
+  before_action :set_account, :authenticate
+
+  private
+    def set_account
+      @account = Account.find_by(url_name: request.subdomains.first)
+    end
+
+    def authenticate
+      case request.format
+      when Mime[:xml], Mime[:atom]
+        if user = authenticate_with_http_basic { |u, p| @account.users.authenticate(u, p) }
+          @current_user = user
+        else
+          request_http_basic_authentication
+        end
+      else
+        if session_authenticated?
+          @current_user = @account.users.find(session[:authenticated][:user_id])
+        else
+          redirect_to(login_url) and return false
+        end
+      end
+    end
+end
+
+ +

In your integration tests, you can do something like this:

+ +
def test_access_granted_from_xml
+  @request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
+  get "/notes/1.xml"
+
+  assert_equal 200, status
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + auth_param(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 119
+def auth_param(request)
+  request.authorization.to_s.split(" ", 2).second
+end
+
+
+ +
+ +
+

+ + auth_scheme(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 115
+def auth_scheme(request)
+  request.authorization.to_s.split(" ", 2).first
+end
+
+
+ +
+ +
+

+ + authenticate(request, &login_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 97
+def authenticate(request, &login_procedure)
+  if has_basic_credentials?(request)
+    login_procedure.call(*user_name_and_password(request))
+  end
+end
+
+
+ +
+ +
+

+ + authentication_request(controller, realm, message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 127
+def authentication_request(controller, realm, message)
+  message ||= "HTTP Basic: Access denied.\n"
+  controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.tr('"'.freeze, "".freeze)}")
+  controller.status = 401
+  controller.response_body = message
+end
+
+
+ +
+ +
+

+ + decode_credentials(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 111
+def decode_credentials(request)
+  ::Base64.decode64(auth_param(request) || "")
+end
+
+
+ +
+ +
+

+ + encode_credentials(user_name, password) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 123
+def encode_credentials(user_name, password)
+  "Basic #{::Base64.strict_encode64("#{user_name}:#{password}")}"
+end
+
+
+ +
+ +
+

+ + has_basic_credentials?(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 103
+def has_basic_credentials?(request)
+  request.authorization.present? && (auth_scheme(request).downcase == "basic")
+end
+
+
+ +
+ +
+

+ + user_name_and_password(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 107
+def user_name_and_password(request)
+  decode_credentials(request).split(":", 2)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html b/src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html new file mode 100644 index 0000000000..6a37749989 --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html @@ -0,0 +1,192 @@ +--- +title: ActionController::HttpAuthentication::Basic::ControllerMethods +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + authenticate_or_request_with_http_basic(realm = "Application", message = nil, &login_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 84
+def authenticate_or_request_with_http_basic(realm = "Application", message = nil, &login_procedure)
+  authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm, message)
+end
+
+
+ +
+ +
+

+ + authenticate_with_http_basic(&login_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 88
+def authenticate_with_http_basic(&login_procedure)
+  HttpAuthentication::Basic.authenticate(request, &login_procedure)
+end
+
+
+ +
+ +
+

+ + request_http_basic_authentication(realm = "Application", message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 92
+def request_http_basic_authentication(realm = "Application", message = nil)
+  HttpAuthentication::Basic.authentication_request(self, realm, message)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods/ClassMethods.html b/src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods/ClassMethods.html new file mode 100644 index 0000000000..fb0cd6d244 --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods/ClassMethods.html @@ -0,0 +1,109 @@ +--- +title: ActionController::HttpAuthentication::Basic::ControllerMethods::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + http_basic_authenticate_with(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 71
+def http_basic_authenticate_with(options = {})
+  before_action(options.except(:name, :password, :realm)) do
+    authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
+      # This comparison uses & so that it doesn't short circuit and
+      # uses `secure_compare` so that length information
+      # isn't leaked.
+      ActiveSupport::SecurityUtils.secure_compare(name, options[:name]) &
+        ActiveSupport::SecurityUtils.secure_compare(password, options[:password])
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication/Digest.html b/src/5.2/classes/ActionController/HttpAuthentication/Digest.html new file mode 100644 index 0000000000..299c504b67 --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication/Digest.html @@ -0,0 +1,673 @@ +--- +title: ActionController::HttpAuthentication::Digest +layout: default +--- +
+ +
+
+ +
+ +

Makes it dead easy to do HTTP Digest authentication.

+ +

Simple Digest example

+ +
require 'digest/md5'
+class PostsController < ApplicationController
+  REALM = "SuperSecret"
+  USERS = {"dhh" => "secret", #plain text password
+           "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))}  #ha1 digest password
+
+  before_action :authenticate, except: [:index]
+
+  def index
+    render plain: "Everyone can see me!"
+  end
+
+  def edit
+    render plain: "I'm only accessible if you know the password"
+  end
+
+  private
+    def authenticate
+      authenticate_or_request_with_http_digest(REALM) do |username|
+        USERS[username]
+      end
+    end
+end
+
+ +

Notes

+ +

The authenticate_or_request_with_http_digest block must return the user's password or the ha1 digest hash so the framework can appropriately hash to check the user's credentials. Returning nil will cause authentication to fail.

+ +

Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If the password file or database is compromised, the attacker would be able to use the ha1 hash to authenticate as the user at this realm, but would not have the user's password to try using at other sites.

+ +

In rare instances, web servers or front proxies strip authorization headers before they reach your application. You can debug this situation by logging all environment variables, and check for HTTP_AUTHORIZATION, amongst others.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + authenticate(request, realm, &password_procedure) + +

+ + +
+

Returns false on a valid response, true otherwise

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 197
+def authenticate(request, realm, &password_procedure)
+  request.authorization && validate_digest_response(request, realm, &password_procedure)
+end
+
+
+ +
+ +
+

+ + authentication_header(controller, realm) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 255
+def authentication_header(controller, realm)
+  secret_key = secret_token(controller.request)
+  nonce = self.nonce(secret_key)
+  opaque = opaque(secret_key)
+  controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}")
+end
+
+
+ +
+ +
+

+ + authentication_request(controller, realm, message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 262
+def authentication_request(controller, realm, message = nil)
+  message ||= "HTTP Digest: Access denied.\n"
+  authentication_header(controller, realm)
+  controller.status = 401
+  controller.response_body = message
+end
+
+
+ +
+ +
+

+ + decode_credentials(header) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 248
+def decode_credentials(header)
+  ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, "").split(",").map do |pair|
+    key, value = pair.split("=", 2)
+    [key.strip, value.to_s.gsub(/^"|"$/, "").delete("'")]
+  end]
+end
+
+
+ +
+ +
+

+ + decode_credentials_header(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 244
+def decode_credentials_header(request)
+  decode_credentials(request.authorization)
+end
+
+
+ +
+ +
+

+ + encode_credentials(http_method, credentials, password, password_is_ha1) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 239
+def encode_credentials(http_method, credentials, password, password_is_ha1)
+  credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password, password_is_ha1)
+  "Digest " + credentials.sort_by { |x| x[0].to_s }.map { |v| "#{v[0]}='#{v[1]}'" }.join(", ")
+end
+
+
+ +
+ +
+

+ + expected_response(http_method, uri, credentials, password, password_is_ha1 = true) + +

+ + +
+

Returns the expected response for a request of http_method to uri with the decoded credentials and the expected password Optional parameter password_is_ha1 is set to true by default, since best practice is to store ha1 digest instead of a plain-text password.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 229
+def expected_response(http_method, uri, credentials, password, password_is_ha1 = true)
+  ha1 = password_is_ha1 ? password : ha1(credentials, password)
+  ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":"))
+  ::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":"))
+end
+
+
+ +
+ +
+

+ + ha1(credentials, password) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 235
+def ha1(credentials, password)
+  ::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(":"))
+end
+
+
+ +
+ +
+

+ + nonce(secret_key, time = Time.now) + +

+ + +
+

Uses an MD5 digest based on time to generate a value to be used only once.

+ +

A server-specified data string which should be uniquely generated each time a 401 response is made. It is recommended that this string be base64 or hexadecimal data. Specifically, since the string is passed in the header lines as a quoted string, the double-quote character is not allowed.

+ +

The contents of the nonce are implementation dependent. The quality of the implementation depends on a good choice. A nonce might, for example, be constructed as the base 64 encoding of

+ +
time-stamp H(time-stamp ":" ETag ":" private-key)
+
+ +

where time-stamp is a server-generated time or other non-repeating value, ETag is the value of the HTTP ETag header associated with the requested entity, and private-key is data known only to the server. With a nonce of this form a server would recalculate the hash portion after receiving the client authentication header and reject the request if it did not match the nonce from that header or if the time-stamp value is not recent enough. In this way the server can limit the time of the nonce's validity. The inclusion of the ETag prevents a replay request for an updated version of the resource. (Note: including the IP address of the client in the nonce would appear to offer the server the ability to limit the reuse of the nonce to the same client that originally got it. However, that would break proxy farms, where requests from a single user often go through different proxies in the farm. Also, IP address spoofing is not that hard.)

+ +

An implementation might choose not to accept a previously used nonce or a previously used digest, in order to protect against a replay attack. Or, an implementation might choose to use one-time nonces or digests for POST, PUT, or PATCH requests and a time-stamp for GET requests. For more details on the issues involved see Section 4 of this document.

+ +

The nonce is opaque to the client. Composed of Time, and hash of Time with secret key from the Rails session secret generated upon creation of project. Ensures the time cannot be modified by client.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 307
+def nonce(secret_key, time = Time.now)
+  t = time.to_i
+  hashed = [t, secret_key]
+  digest = ::Digest::MD5.hexdigest(hashed.join(":"))
+  ::Base64.strict_encode64("#{t}:#{digest}")
+end
+
+
+ +
+ +
+

+ + opaque(secret_key) + +

+ + +
+

Opaque based on digest of secret key

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 326
+def opaque(secret_key)
+  ::Digest::MD5.hexdigest(secret_key)
+end
+
+
+ +
+ +
+

+ + secret_token(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 269
+def secret_token(request)
+  key_generator  = request.key_generator
+  http_auth_salt = request.http_auth_salt
+  key_generator.generate_key(http_auth_salt)
+end
+
+
+ +
+ +
+

+ + validate_digest_response(request, realm, &password_procedure) + +

+ + +
+

Returns false unless the request credentials response value matches the expected value. First try the password as a ha1 digest password. If this fails, then try it as a plain text password.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 204
+def validate_digest_response(request, realm, &password_procedure)
+  secret_key  = secret_token(request)
+  credentials = decode_credentials_header(request)
+  valid_nonce = validate_nonce(secret_key, request, credentials[:nonce])
+
+  if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque]
+    password = password_procedure.call(credentials[:username])
+    return false unless password
+
+    method = request.get_header("rack.methodoverride.original_method") || request.get_header("REQUEST_METHOD")
+    uri    = credentials[:uri]
+
+    [true, false].any? do |trailing_question_mark|
+      [true, false].any? do |password_is_ha1|
+        _uri = trailing_question_mark ? uri + "?" : uri
+        expected = expected_response(method, _uri, credentials, password, password_is_ha1)
+        expected == credentials[:response]
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + validate_nonce(secret_key, request, value, seconds_to_timeout = 5 * 60) + +

+ + +
+

Might want a shorter timeout depending on whether the request is a PATCH, PUT, or POST, and if the client is a browser or web service. Can be much shorter if the Stale directive is implemented. This would allow a user to use new nonce without prompting the user again for their username and password.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 319
+def validate_nonce(secret_key, request, value, seconds_to_timeout = 5 * 60)
+  return false if value.nil?
+  t = ::Base64.decode64(value).split(":").first.to_i
+  nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication/Digest/ControllerMethods.html b/src/5.2/classes/ActionController/HttpAuthentication/Digest/ControllerMethods.html new file mode 100644 index 0000000000..6f6978dab9 --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication/Digest/ControllerMethods.html @@ -0,0 +1,179 @@ +--- +title: ActionController::HttpAuthentication::Digest::ControllerMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + authenticate_or_request_with_http_digest(realm = "Application", message = nil, &password_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 181
+def authenticate_or_request_with_http_digest(realm = "Application", message = nil, &password_procedure)
+  authenticate_with_http_digest(realm, &password_procedure) || request_http_digest_authentication(realm, message)
+end
+
+
+ +
+ +
+

+ + authenticate_with_http_digest(realm = "Application", &password_procedure) + +

+ + +
+

Authenticate with HTTP Digest, returns true or false

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 186
+def authenticate_with_http_digest(realm = "Application", &password_procedure)
+  HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
+end
+
+
+ +
+ +
+

+ + request_http_digest_authentication(realm = "Application", message = nil) + +

+ + +
+

Render output including the HTTP Digest authentication header

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 191
+def request_http_digest_authentication(realm = "Application", message = nil)
+  HttpAuthentication::Digest.authentication_request(self, realm, message)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication/Token.html b/src/5.2/classes/ActionController/HttpAuthentication/Token.html new file mode 100644 index 0000000000..eb39468512 --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication/Token.html @@ -0,0 +1,554 @@ +--- +title: ActionController::HttpAuthentication::Token +layout: default +--- +
+ +
+
+ +
+ +

Makes it dead easy to do HTTP Token authentication.

+ +

Simple Token example:

+ +
class PostsController < ApplicationController
+  TOKEN = "secret"
+
+  before_action :authenticate, except: [ :index ]
+
+  def index
+    render plain: "Everyone can see me!"
+  end
+
+  def edit
+    render plain: "I'm only accessible if you know the password"
+  end
+
+  private
+    def authenticate
+      authenticate_or_request_with_http_token do |token, options|
+        # Compare the tokens in a time-constant manner, to mitigate
+        # timing attacks.
+        ActiveSupport::SecurityUtils.secure_compare(token, TOKEN)
+      end
+    end
+end
+
+ +

Here is a more advanced Token example where only Atom feeds and the XML API is protected by HTTP token authentication, the regular HTML interface is protected by a session approach:

+ +
class ApplicationController < ActionController::Base
+  before_action :set_account, :authenticate
+
+  private
+    def set_account
+      @account = Account.find_by(url_name: request.subdomains.first)
+    end
+
+    def authenticate
+      case request.format
+      when Mime[:xml], Mime[:atom]
+        if user = authenticate_with_http_token { |t, o| @account.users.authenticate(t, o) }
+          @current_user = user
+        else
+          request_http_token_authentication
+        end
+      else
+        if session_authenticated?
+          @current_user = @account.users.find(session[:authenticated][:user_id])
+        else
+          redirect_to(login_url) and return false
+        end
+      end
+    end
+end
+
+ +

In your integration tests, you can do something like this:

+ +
def test_access_granted_from_xml
+  get(
+    "/notes/1.xml", nil,
+    'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Token.encode_credentials(users(:dhh).token)
+  )
+
+  assert_equal 200, status
+end
+
+ +

On shared hosts, Apache sometimes doesn't pass authentication headers to FCGI instances. If your environment matches this description and you cannot authenticate, try this rule in your Apache setup:

+ +
RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AUTHN_PAIR_DELIMITERS=/(?:,|;|\t+)/
 
TOKEN_KEY="token="
 
TOKEN_REGEX=/^(Token|Bearer)\s+/
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + authenticate(controller, &login_procedure) + +

+ + +
+

If token Authorization header is present, call the login procedure with the present token and options.

+
controller +
+

ActionController::Base instance for the current request.

+
login_procedure +
+

Proc to call if a token is present. The Proc should take two arguments:

+ +
authenticate(controller) { |token, options| ... }
+
+
+ +

Returns the return value of login_procedure if a token is found. Returns nil if no token is found.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 440
+def authenticate(controller, &login_procedure)
+  token, options = token_and_options(controller.request)
+  unless token.blank?
+    login_procedure.call(token, options)
+  end
+end
+
+
+ +
+ +
+

+ + authentication_request(controller, realm, message = nil) + +

+ + +
+

Sets a WWW-Authenticate header to let the client know a token is desired.

+ +

controller - ActionController::Base instance for the outgoing response. realm - String realm to use in the header.

+ +

Returns nothing.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 512
+def authentication_request(controller, realm, message = nil)
+  message ||= "HTTP Token: Access denied.\n"
+  controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.tr('"'.freeze, "".freeze)}")
+  controller.__send__ :render, plain: message, status: :unauthorized
+end
+
+
+ +
+ +
+

+ + encode_credentials(token, options = {}) + +

+ + +
+

Encodes the given token and options into an Authorization header value.

+ +

token - String token. options - optional Hash of the options.

+ +

Returns String.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 499
+def encode_credentials(token, options = {})
+  values = ["#{TOKEN_KEY}#{token.to_s.inspect}"] + options.map do |key, value|
+    "#{key}=#{value.to_s.inspect}"
+  end
+  "Token #{values * ", "}"
+end
+
+
+ +
+ +
+

+ + params_array_from(raw_params) + +

+ + +
+

Takes raw_params and turns it into an array of parameters

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 471
+def params_array_from(raw_params)
+  raw_params.map { |param| param.split %r/=(.+)?/ }
+end
+
+
+ +
+ +
+

+ + raw_params(auth) + +

+ + +
+

This method takes an authorization body and splits up the key-value pairs by the standardized :, ;, or \t delimiters defined in AUTHN_PAIR_DELIMITERS.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 483
+def raw_params(auth)
+  _raw_params = auth.sub(TOKEN_REGEX, "").split(/\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
+
+  if !(_raw_params.first =~ %r{\A#{TOKEN_KEY}})
+    _raw_params[0] = "#{TOKEN_KEY}#{_raw_params.first}"
+  end
+
+  _raw_params
+end
+
+
+ +
+ +
+

+ + rewrite_param_values(array_params) + +

+ + +
+

This removes the " characters wrapping the value.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 476
+def rewrite_param_values(array_params)
+  array_params.each { |param| (param[1] || "".dup).gsub! %r/^"|"$/, "" }
+end
+
+
+ +
+ +
+

+ + token_and_options(request) + +

+ + +
+

Parses the token and options out of the token Authorization header. The value for the Authorization header is expected to have the prefix "Token" or "Bearer". If the header looks like this:

+ +
Authorization: Token token="abc", nonce="def"
+
+ +

Then the returned token is "abc", and the options are {nonce: "def"}

+ +

request - ActionDispatch::Request instance with the current headers.

+ +

Returns an Array of [String, Hash] if a token is present. Returns nil if no token is found.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 458
+def token_and_options(request)
+  authorization_request = request.authorization.to_s
+  if authorization_request[TOKEN_REGEX]
+    params = token_params_from authorization_request
+    [params.shift[1], Hash[params].with_indifferent_access]
+  end
+end
+
+
+ +
+ +
+

+ + token_params_from(auth) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 466
+def token_params_from(auth)
+  rewrite_param_values params_array_from raw_params auth
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html b/src/5.2/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html new file mode 100644 index 0000000000..c3ae1f25db --- /dev/null +++ b/src/5.2/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html @@ -0,0 +1,179 @@ +--- +title: ActionController::HttpAuthentication::Token::ControllerMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + authenticate_or_request_with_http_token(realm = "Application", message = nil, &login_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 413
+def authenticate_or_request_with_http_token(realm = "Application", message = nil, &login_procedure)
+  authenticate_with_http_token(&login_procedure) || request_http_token_authentication(realm, message)
+end
+
+
+ +
+ +
+

+ + authenticate_with_http_token(&login_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 417
+def authenticate_with_http_token(&login_procedure)
+  Token.authenticate(self, &login_procedure)
+end
+
+
+ +
+ +
+

+ + request_http_token_authentication(realm = "Application", message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 421
+def request_http_token_authentication(realm = "Application", message = nil)
+  Token.authentication_request(self, realm, message)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ImplicitRender.html b/src/5.2/classes/ActionController/ImplicitRender.html new file mode 100644 index 0000000000..1adf02f783 --- /dev/null +++ b/src/5.2/classes/ActionController/ImplicitRender.html @@ -0,0 +1,72 @@ +--- +title: ActionController::ImplicitRender +layout: default +--- +
+ +
+
+ +
+ +

Handles implicit rendering for a controller action that does not explicitly respond with render, respond_to, redirect, or head.

+ +

For API controllers, the implicit response is always 204 No Content.

+ +

For all other controllers, we use these heuristics to decide whether to render a template, raise an error for a missing template, or respond with 204 No Content:

+ +

First, if we DO find a template, it's rendered. Template lookup accounts for the action name, locales, format, variant, template handlers, and more (see render for details).

+ +

Second, if we DON'T find a template but the controller action does have templates for other formats, variants, etc., then we trust that you meant to provide a template for this response, too, and we raise ActionController::UnknownFormat with an explanation.

+ +

Third, if we DON'T find a template AND the request is a page load in a web browser (technically, a non-XHR GET request for an HTML response) where you reasonably expect to have rendered a template, then we raise ActionView::UnknownFormat with an explanation.

+ +

Finally, if we DON'T find a template AND the request isn't a browser page load, then we implicitly respond with 204 No Content.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Instrumentation.html b/src/5.2/classes/ActionController/Instrumentation.html new file mode 100644 index 0000000000..7d7a2790b8 --- /dev/null +++ b/src/5.2/classes/ActionController/Instrumentation.html @@ -0,0 +1,398 @@ +--- +title: ActionController::Instrumentation +layout: default +--- +
+ +
+
+ +
+ +

Adds instrumentation to several ends in ActionController::Base. It also provides some hooks related with process_action. This allows an ORM like Active Record and/or DataMapper to plug in ActionController and show related information.

+ +

Check ActiveRecord::Railties::ControllerRuntime for an example.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + process_action(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 19
+def process_action(*args)
+  raw_payload = {
+    controller: self.class.name,
+    action: action_name,
+    params: request.filtered_parameters,
+    headers: request.headers,
+    format: request.format.ref,
+    method: request.request_method,
+    path: request.fullpath
+  }
+
+  ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
+
+  ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
+    begin
+      result = super
+      payload[:status] = response.status
+      result
+    ensure
+      append_info_to_payload(payload)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + redirect_to(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 64
+def redirect_to(*args)
+  ActiveSupport::Notifications.instrument("redirect_to.action_controller") do |payload|
+    result = super
+    payload[:status]   = response.status
+    payload[:location] = response.filtered_location
+    result
+  end
+end
+
+
+ +
+ +
+

+ + render(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 43
+def render(*args)
+  render_output = nil
+  self.view_runtime = cleanup_view_runtime do
+    Benchmark.ms { render_output = super }
+  end
+  render_output
+end
+
+
+ +
+ +
+

+ + send_data(data, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 58
+def send_data(data, options = {})
+  ActiveSupport::Notifications.instrument("send_data.action_controller", options) do
+    super
+  end
+end
+
+
+ +
+ +
+

+ + send_file(path, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 51
+def send_file(path, options = {})
+  ActiveSupport::Notifications.instrument("send_file.action_controller",
+    options.merge(path: path)) do
+    super
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + append_info_to_payload(payload) + +

+ + +
+

Every time after an action is processed, this method is invoked with the payload, so you can add more information.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 92
+def append_info_to_payload(payload) # :doc:
+  payload[:view_runtime] = view_runtime
+end
+
+
+ +
+ +
+

+ + cleanup_view_runtime() + +

+ + +
+

A hook which allows you to clean up any time, wrongly taken into account in views, like database querying time.

+ +
def cleanup_view_runtime
+  super - time_taken_in_something_expensive
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 86
+def cleanup_view_runtime # :doc:
+  yield
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Instrumentation/ClassMethods.html b/src/5.2/classes/ActionController/Instrumentation/ClassMethods.html new file mode 100644 index 0000000000..3b828bead8 --- /dev/null +++ b/src/5.2/classes/ActionController/Instrumentation/ClassMethods.html @@ -0,0 +1,54 @@ +--- +title: ActionController::Instrumentation::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Live.html b/src/5.2/classes/ActionController/Live.html new file mode 100644 index 0000000000..cac9d18e5c --- /dev/null +++ b/src/5.2/classes/ActionController/Live.html @@ -0,0 +1,280 @@ +--- +title: ActionController::Live +layout: default +--- +
+ +
+
+ +
+ +

Mix this module into your controller, and all actions in that controller will be able to stream data to the client as it's written.

+ +
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
+
+ +

There are a few caveats with this module. You cannot write headers after the response has been committed (Response#committed? will return truthy). Calling write or close on the response stream will cause the response object to be committed. Make sure all headers are set before calling write or close on your stream.

+ +

You must call close on your stream when you're finished, otherwise the socket may be left open forever.

+ +

The final caveat is that your actions are executed in a separate thread than the main thread. Make sure your actions are thread safe, and this shouldn't be a problem (don't share state across threads, etc).

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + log_error(exception) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/live.rb, line 295
+def log_error(exception)
+  logger = ActionController::Base.logger
+  return unless logger
+
+  logger.fatal do
+    message = "\n#{exception.class} (#{exception.message}):\n".dup
+    message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
+    message << "  " << exception.backtrace.join("\n  ")
+    "#{message}\n\n"
+  end
+end
+
+
+ +
+ +
+

+ + process(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/live.rb, line 238
+def process(name)
+  t1 = Thread.current
+  locals = t1.keys.map { |key| [key, t1[key]] }
+
+  error = nil
+  # This processes the action in a child thread. It lets us return the
+  # response code and headers back up the Rack stack, and still process
+  # the body in parallel with sending data to the client.
+  new_controller_thread {
+    ActiveSupport::Dependencies.interlock.running do
+      t2 = Thread.current
+
+      # Since we're processing the view in a different thread, copy the
+      # thread locals from the main thread to the child thread. :'(
+      locals.each { |k, v| t2[k] = v }
+
+      begin
+        super(name)
+      rescue => e
+        if @_response.committed?
+          begin
+            @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html
+            @_response.stream.call_on_error
+          rescue => exception
+            log_error(exception)
+          ensure
+            log_error(e)
+            @_response.stream.close
+          end
+        else
+          error = e
+        end
+      ensure
+        @_response.commit!
+      end
+    end
+  }
+
+  ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
+    @_response.await_commit
+  end
+
+  raise error if error
+end
+
+
+ +
+ +
+

+ + response_body=(body) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/live.rb, line 307
+def response_body=(body)
+  super
+  response.close if response
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Live/ClassMethods.html b/src/5.2/classes/ActionController/Live/ClassMethods.html new file mode 100644 index 0000000000..80591fb545 --- /dev/null +++ b/src/5.2/classes/ActionController/Live/ClassMethods.html @@ -0,0 +1,107 @@ +--- +title: ActionController::Live::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + make_response!(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/live.rb, line 41
+def make_response!(request)
+  if request.get_header("HTTP_VERSION") == "HTTP/1.0"
+    super
+  else
+    Live::Response.new.tap do |res|
+      res.request = request
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Live/ClientDisconnected.html b/src/5.2/classes/ActionController/Live/ClientDisconnected.html new file mode 100644 index 0000000000..b306fcebdc --- /dev/null +++ b/src/5.2/classes/ActionController/Live/ClientDisconnected.html @@ -0,0 +1,60 @@ +--- +title: ActionController::Live::ClientDisconnected +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Live/SSE.html b/src/5.2/classes/ActionController/Live/SSE.html new file mode 100644 index 0000000000..399e67a57a --- /dev/null +++ b/src/5.2/classes/ActionController/Live/SSE.html @@ -0,0 +1,250 @@ +--- +title: ActionController::Live::SSE +layout: default +--- +
+ +
+
+ +
+ +

This class provides the ability to write an SSE (Server Sent Event) to an IO stream. The class is initialized with a stream and can be used to either write a JSON string or an object which can be converted to JSON.

+ +

Writing an object will convert it into standard SSE format with whatever options you have configured. You may choose to set the following options:

+ +
1) Event. If specified, an event with this name will be dispatched on
+the browser.
+2) Retry. The reconnection time in milliseconds used when attempting
+to send the event.
+3) Id. If the connection dies while sending an SSE to the browser, then
+the server will receive a +Last-Event-ID+ header with value equal to +id+.
+
+ +

After setting an option in the constructor of the SSE object, all future SSEs sent across the stream will use those options unless overridden.

+ +

Example Usage:

+ +
class MyController < ActionController::Base
+  include ActionController::Live
+
+  def index
+    response.headers['Content-Type'] = 'text/event-stream'
+    sse = SSE.new(response.stream, retry: 300, event: "event-name")
+    sse.write({ name: 'John'})
+    sse.write({ name: 'John'}, id: 10)
+    sse.write({ name: 'John'}, id: 10, event: "other-event")
+    sse.write({ name: 'John'}, id: 10, event: "other-event", retry: 500)
+  ensure
+    sse.close
+  end
+end
+
+ +

Note: SSEs are not currently supported by IE. However, they are supported by Chrome, Firefox, Opera, and Safari.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
WHITELISTED_OPTIONS=%w( retry event id )
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(stream, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/live.rb, line 91
+def initialize(stream, options = {})
+  @stream = stream
+  @options = options
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/live.rb, line 96
+def close
+  @stream.close
+end
+
+
+ +
+ +
+

+ + write(object, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/live.rb, line 100
+def write(object, options = {})
+  case object
+  when String
+    perform_write(object, options)
+  else
+    perform_write(ActiveSupport::JSON.encode(object), options)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/LiveTestResponse.html b/src/5.2/classes/ActionController/LiveTestResponse.html new file mode 100644 index 0000000000..cc21ad0296 --- /dev/null +++ b/src/5.2/classes/ActionController/LiveTestResponse.html @@ -0,0 +1,60 @@ +--- +title: ActionController::LiveTestResponse +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/LogSubscriber.html b/src/5.2/classes/ActionController/LogSubscriber.html new file mode 100644 index 0000000000..ee751a55aa --- /dev/null +++ b/src/5.2/classes/ActionController/LogSubscriber.html @@ -0,0 +1,423 @@ +--- +title: ActionController::LogSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
INTERNAL_PARAMS=%w(controller action format _method only_path)
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + halted_callback(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 37
+def halted_callback(event)
+  info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" }
+end
+
+
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 72
+def logger
+  ActionController::Base.logger
+end
+
+
+ +
+ +
+

+ + process_action(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 19
+def process_action(event)
+  info do
+    payload   = event.payload
+    additions = ActionController::Base.log_process_action(payload)
+
+    status = payload[:status]
+    if status.nil? && payload[:exception].present?
+      exception_class_name = payload[:exception].first
+      status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
+    end
+    message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms".dup
+    message << " (#{additions.join(" | ".freeze)})" unless additions.empty?
+    message << "\n\n" if defined?(Rails.env) && Rails.env.development?
+
+    message
+  end
+end
+
+
+ +
+ +
+

+ + redirect_to(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 45
+def redirect_to(event)
+  info { "Redirected to #{event.payload[:location]}" }
+end
+
+
+ +
+ +
+

+ + send_data(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 49
+def send_data(event)
+  info { "Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)" }
+end
+
+
+ +
+ +
+

+ + send_file(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 41
+def send_file(event)
+  info { "Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)" }
+end
+
+
+ +
+ +
+

+ + start_processing(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 7
+def start_processing(event)
+  return unless logger.info?
+
+  payload = event.payload
+  params  = payload[:params].except(*INTERNAL_PARAMS)
+  format  = payload[:format]
+  format  = format.to_s.upcase if format.is_a?(Symbol)
+
+  info "Processing by #{payload[:controller]}##{payload[:action]} as #{format}"
+  info "  Parameters: #{params.inspect}" unless params.empty?
+end
+
+
+ +
+ +
+

+ + unpermitted_parameters(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/log_subscriber.rb, line 53
+def unpermitted_parameters(event)
+  debug do
+    unpermitted_keys = event.payload[:keys]
+    "Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.map { |e| ":#{e}" }.join(", ")}"
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Metal.html b/src/5.2/classes/ActionController/Metal.html new file mode 100644 index 0000000000..6cad6af88b --- /dev/null +++ b/src/5.2/classes/ActionController/Metal.html @@ -0,0 +1,702 @@ +--- +title: ActionController::Metal +layout: default +--- +
+ +
+
+ +
+ +

ActionController::Metal is the simplest possible controller, providing a valid Rack interface without the additional niceties provided by ActionController::Base.

+ +

A sample metal controller might look like this:

+ +
class HelloController < ActionController::Metal
+  def index
+    self.response_body = "Hello World!"
+  end
+end
+
+ +

And then to route requests to your metal controller, you would add something like this to config/routes.rb:

+ +
get 'hello', to: HelloController.action(:index)
+
+ +

The action method returns a valid Rack application for the Rails router to dispatch to.

+ +

Rendering Helpers

+ +

ActionController::Metal by default provides no utilities for rendering views, partials, or other responses aside from explicitly calling of response_body=, content_type=, and status=. To add the render helpers you're used to having in a normal controller, you can do the following:

+ +
class HelloController < ActionController::Metal
+  include AbstractController::Rendering
+  include ActionView::Layouts
+  append_view_path "#{Rails.root}/app/views"
+
+  def index
+    render "hello/index"
+  end
+end
+
+ +

Redirection Helpers

+ +

To add redirection helpers to your metal controller, do the following:

+ +
class HelloController < ActionController::Metal
+  include ActionController::Redirecting
+  include Rails.application.routes.url_helpers
+
+  def index
+    redirect_to root_url
+  end
+end
+
+ +

Other Helpers

+ +

You can refer to the modules included in ActionController::Base to see other features you can bring into your metal controller.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + action(name) + +

+ + +
+

Returns a Rack endpoint for the given action name.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 232
+def self.action(name)
+  app = lambda { |env|
+    req = ActionDispatch::Request.new(env)
+    res = make_response! req
+    new.dispatch(name, req, res)
+  }
+
+  if middleware_stack.any?
+    middleware_stack.build(name, app)
+  else
+    app
+  end
+end
+
+
+ +
+ +
+

+ + controller_name() + +

+ + +
+

Returns the last part of the controller's name, underscored, without the ending Controller. For instance, PostsController returns posts. Namespaces are left out, so Admin::PostsController returns posts as well.

+ +

Returns

+
  • +

    string

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 129
+def self.controller_name
+  @controller_name ||= name.demodulize.sub(/Controller$/, "").underscore
+end
+
+
+ +
+ +
+

+ + dispatch(name, req, res) + +

+ + +
+

Direct dispatch to the controller. Instantiates the controller, then executes the action named name.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 248
+def self.dispatch(name, req, res)
+  if middleware_stack.any?
+    middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env
+  else
+    new.dispatch(name, req, res)
+  end
+end
+
+
+ +
+ +
+

+ + make_response!(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 133
+def self.make_response!(request)
+  ActionDispatch::Response.new.tap do |res|
+    res.request = request
+  end
+end
+
+
+ +
+ +
+

+ + middleware() + +

+ + +
+

Alias for middleware_stack.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 227
+def self.middleware
+  middleware_stack
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 153
+def initialize
+  @_request = nil
+  @_response = nil
+  @_routes = nil
+  super
+end
+
+
+ +
+ +
+

+ + use(*args, &block) + +

+ + +
+

Pushes the given Rack middleware and its arguments to the bottom of the middleware stack.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 222
+def self.use(*args, &block)
+  middleware_stack.use(*args, &block)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + controller_name() + +

+ + +
+

Delegates to the class' controller_name.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 144
+def controller_name
+  self.class.controller_name
+end
+
+
+ +
+ +
+

+ + params() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 160
+def params
+  @_params ||= request.parameters
+end
+
+
+ +
+ +
+

+ + params=(val) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 164
+def params=(val)
+  @_params = val
+end
+
+
+ +
+ +
+

+ + performed?() + +

+ + +
+

Tests if render or redirect has already happened.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 184
+def performed?
+  response_body || response.committed?
+end
+
+
+ +
+ +
+

+ + reset_session() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 209
+def reset_session
+  @_request.reset_session
+end
+
+
+ +
+ +
+

+ + response_body=(body) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 175
+def response_body=(body)
+  body = [body] unless body.nil? || body.respond_to?(:each)
+  response.reset_body!
+  return unless body
+  response.body = body
+  super
+end
+
+
+ +
+ +
+

+ + url_for(string) + +

+ + +
+

Basic url_for that can be overridden for more robust functionality.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal.rb, line 171
+def url_for(string)
+  string
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/MimeResponds.html b/src/5.2/classes/ActionController/MimeResponds.html new file mode 100644 index 0000000000..7853245067 --- /dev/null +++ b/src/5.2/classes/ActionController/MimeResponds.html @@ -0,0 +1,315 @@ +--- +title: ActionController::MimeResponds +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + respond_to(*mimes) + +

+ + +
+

Without web-service support, an action which collects the data for displaying a list of people might look something like this:

+ +
def index
+  @people = Person.all
+end
+
+ +

That action implicitly responds to all formats, but formats can also be whitelisted:

+ +
def index
+  @people = Person.all
+  respond_to :html, :js
+end
+
+ +

Here's the same action, with web-service support baked in:

+ +
def index
+  @people = Person.all
+
+  respond_to do |format|
+    format.html
+    format.js
+    format.xml { render xml: @people }
+  end
+end
+
+ +

What that says is, “if the client wants HTML or JS in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format.” (Rails determines the desired response format from the HTTP Accept header submitted by the client.)

+ +

Supposing you have an action that adds a new person, optionally creating their company (by name) if it does not already exist, without web-services, it might look like this:

+ +
def create
+  @company = Company.find_or_create_by(name: params[:company][:name])
+  @person  = @company.people.create(params[:person])
+
+  redirect_to(person_list_url)
+end
+
+ +

Here's the same action, with web-service support baked in:

+ +
def create
+  company  = params[:person].delete(:company)
+  @company = Company.find_or_create_by(name: company[:name])
+  @person  = @company.people.create(params[:person])
+
+  respond_to do |format|
+    format.html { redirect_to(person_list_url) }
+    format.js
+    format.xml  { render xml: @person.to_xml(include: @company) }
+  end
+end
+
+ +

If the client wants HTML, we just redirect them back to the person list. If they want JavaScript, then it is an Ajax request and we render the JavaScript template associated with this action. Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also include the person's company in the rendered XML, so you get something like this:

+ +
<person>
+  <id>...</id>
+  ...
+  <company>
+    <id>...</id>
+    <name>...</name>
+    ...
+  </company>
+</person>
+
+ +

Note, however, the extra bit at the top of that action:

+ +
company  = params[:person].delete(:company)
+@company = Company.find_or_create_by(name: company[:name])
+
+ +

This is because the incoming XML document (if a web-service request is in process) can only contain a single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):

+ +
person[name]=...&person[company][name]=...&...
+
+ +

And, like this (xml-encoded):

+ +
<person>
+  <name>...</name>
+  <company>
+    <name>...</name>
+  </company>
+</person>
+
+ +

In other words, we make the request so that it operates on a single entity's person. Then, in the action, we extract the company data from the request, find or create the company, and then create the new person with the remaining data.

+ +

Note that you can define your own XML parameter parser which would allow you to describe multiple entities in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow and accept Rails' defaults, life will be much easier.

+ +

If you need to use a MIME type which isn't supported by default, you can register your own handlers in config/initializers/mime_types.rb as follows.

+ +
Mime::Type.register "image/jpg", :jpg
+
+ +

Respond to also allows you to specify a common block for different formats by using any:

+ +
def index
+  @people = Person.all
+
+  respond_to do |format|
+    format.html
+    format.any(:xml, :json) { render request.format.to_sym => @people }
+  end
+end
+
+ +

In the example above, if the format is xml, it will render:

+ +
render xml: @people
+
+ +

Or if the format is json:

+ +
render json: @people
+
+ +

Formats can have different variants.

+ +

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

+ +

We often want to render different html/json/xml templates for phones, tablets, and desktop browsers. Variants make it easy.

+ +

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 |variant|
+    variant.tablet # renders app/views/projects/show.html+tablet.erb
+    variant.phone { extra_setup; render ... }
+    variant.none  { special_setup } # executed only if there is no variant set
+  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
+
+ +

When you're not sharing any code within the format, you can simplify defining variants 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
+
+ +

Variants also support common any/all block that formats have.

+ +

It works for both inline:

+ +
respond_to do |format|
+  format.html.any   { render html: "any"   }
+  format.html.phone { render html: "phone" }
+end
+
+ +

and block syntax:

+ +
respond_to do |format|
+  format.html do |variant|
+    variant.any(:tablet, :phablet){ render html: "any" }
+    variant.phone { render html: "phone" }
+  end
+end
+
+ +

You can also set an array of variants:

+ +
request.variant = [:tablet, :phone]
+
+ +

This will work similarly to formats and MIME types negotiation. If there is no :tablet variant declared, the :phone variant will be used:

+ +
respond_to do |format|
+  format.html.none
+  format.html.phone # this gets rendered
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 193
+def respond_to(*mimes)
+  raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
+
+  collector = Collector.new(mimes, request.variant)
+  yield collector if block_given?
+
+  if format = collector.negotiate_format(request)
+    _process_format(format)
+    _set_rendered_content_type format
+    response = collector.response
+    response.call if response
+  else
+    raise ActionController::UnknownFormat
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/MimeResponds/Collector.html b/src/5.2/classes/ActionController/MimeResponds/Collector.html new file mode 100644 index 0000000000..a70c81396c --- /dev/null +++ b/src/5.2/classes/ActionController/MimeResponds/Collector.html @@ -0,0 +1,365 @@ +--- +title: ActionController::MimeResponds::Collector +layout: default +--- +
+ +
+
+ +
+ +

A container for responses available from the current controller for requests for different mime-types sent to a particular action.

+ +

The public controller methods respond_to may be called with a block that is used to define responses to different mime-types, e.g. for respond_to :

+ +
respond_to do |format|
+  format.html
+  format.xml { render xml: @people }
+end
+
+ +

In this usage, the argument passed to the block (format above) is an instance of the ActionController::MimeResponds::Collector class. This object serves as a container in which available responses can be stored by calling any of the dynamically generated, mime-type-specific methods such as html, xml etc on the Collector. Each response is represented by a corresponding block if present.

+ +

A subsequent call to negotiate_format(request) will enable the Collector to determine which specific mime-type it should respond with for the current request, with this response then being accessible by calling response.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + format
+ + + + +

Class Public methods

+ +
+

+ + new(mimes, variant = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 235
+def initialize(mimes, variant = nil)
+  @responses = {}
+  @variant = variant
+
+  mimes.each { |mime| @responses[Mime[mime]] = nil }
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + all(*args, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: any +
+ + + +
+ +
+

+ + any(*args, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: all +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 242
+def any(*args, &block)
+  if args.any?
+    args.each { |type| send(type, &block) }
+  else
+    custom(Mime::ALL, &block)
+  end
+end
+
+
+ +
+ +
+

+ + custom(mime_type, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 251
+def custom(mime_type, &block)
+  mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
+  @responses[mime_type] ||= if block_given?
+    block
+  else
+    VariantCollector.new(@variant)
+  end
+end
+
+
+ +
+ +
+

+ + negotiate_format(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 273
+def negotiate_format(request)
+  @format = request.negotiate_mime(@responses.keys)
+end
+
+
+ +
+ +
+

+ + response() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 260
+def response
+  response = @responses.fetch(format, @responses[Mime::ALL])
+  if response.is_a?(VariantCollector) # `format.html.phone` - variant inline syntax
+    response.variant
+  elsif response.nil? || response.arity == 0 # `format.html` - just a format, call its block
+    response
+  else # `format.html{ |variant| variant.phone }` - variant block syntax
+    variant_collector = VariantCollector.new(@variant)
+    response.call(variant_collector) # call format block with variants collector
+    variant_collector.variant
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/MissingRenderer.html b/src/5.2/classes/ActionController/MissingRenderer.html new file mode 100644 index 0000000000..30f4cd7af6 --- /dev/null +++ b/src/5.2/classes/ActionController/MissingRenderer.html @@ -0,0 +1,113 @@ +--- +title: ActionController::MissingRenderer +layout: default +--- +
+ +
+
+ +
+ +

See Responder#api_behavior

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(format) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 18
+def initialize(format)
+  super "No renderer defined for format: #{format}"
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ParameterEncoding.html b/src/5.2/classes/ActionController/ParameterEncoding.html new file mode 100644 index 0000000000..afa8f26f67 --- /dev/null +++ b/src/5.2/classes/ActionController/ParameterEncoding.html @@ -0,0 +1,73 @@ +--- +title: ActionController::ParameterEncoding +layout: default +--- +
+ +
+
+ +
+ +

Specify binary encoding for parameters for a given action.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ParameterEncoding/ClassMethods.html b/src/5.2/classes/ActionController/ParameterEncoding/ClassMethods.html new file mode 100644 index 0000000000..879cdec1d5 --- /dev/null +++ b/src/5.2/classes/ActionController/ParameterEncoding/ClassMethods.html @@ -0,0 +1,122 @@ +--- +title: ActionController::ParameterEncoding::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + skip_parameter_encoding(action) + +

+ + +
+

Specify that a given action's parameters should all be encoded as ASCII-8BIT (it “skips” the encoding default of UTF-8).

+ +

For example, a controller would use it like this:

+ +
class RepositoryController < ActionController::Base
+  skip_parameter_encoding :show
+
+  def show
+    @repo = Repository.find_by_filesystem_path params[:file_path]
+
+    # `repo_name` is guaranteed to be UTF-8, but was ASCII-8BIT, so
+    # tag it as such
+    @repo_name = params[:repo_name].force_encoding 'UTF-8'
+  end
+
+  def index
+    @repositories = Repository.all
+  end
+end
+
+ +

The show action in the above controller would have all parameter values encoded as ASCII-8BIT. This is useful in the case where an application must handle data but encoding of the data is unknown, like file system data.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/parameter_encoding.rb, line 46
+def skip_parameter_encoding(action)
+  @_parameter_encodings[action.to_s] = true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ParameterMissing.html b/src/5.2/classes/ActionController/ParameterMissing.html new file mode 100644 index 0000000000..3f1c160c28 --- /dev/null +++ b/src/5.2/classes/ActionController/ParameterMissing.html @@ -0,0 +1,73 @@ +--- +title: ActionController::ParameterMissing +layout: default +--- +
+ +
+
+ +
+ +

Raised when a required parameter is missing.

+ +
params = ActionController::Parameters.new(a: {})
+params.fetch(:b)
+# => ActionController::ParameterMissing: param is missing or the value is empty: b
+params.require(:a)
+# => ActionController::ParameterMissing: param is missing or the value is empty: a
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Parameters.html b/src/5.2/classes/ActionController/Parameters.html new file mode 100644 index 0000000000..92a2c3a29d --- /dev/null +++ b/src/5.2/classes/ActionController/Parameters.html @@ -0,0 +1,2653 @@ +--- +title: ActionController::Parameters +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Parameters

+ +

Allows you to choose which attributes should be whitelisted for mass updating and thus prevent accidentally exposing that which shouldn't be exposed. Provides two methods for this purpose: require and permit. The former is used to mark parameters as required. The latter is used to set the parameter as permitted and limit which attributes should be allowed for mass updating.

+ +
params = ActionController::Parameters.new({
+  person: {
+    name: "Francesco",
+    age:  22,
+    role: "admin"
+  }
+})
+
+permitted = params.require(:person).permit(:name, :age)
+permitted            # => <ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
+permitted.permitted? # => true
+
+Person.first.update!(permitted)
+# => #<Person id: 1, name: "Francesco", age: 22, role: "user">
+
+ +

It provides two options that controls the top-level behavior of new instances:

+
  • +

    permit_all_parameters - If it's true, all the parameters will be permitted by default. The default is false.

    +
  • +

    action_on_unpermitted_parameters - Allow to control the behavior when parameters that are not explicitly permitted are found. The values can be false to just filter them out, :log to additionally write a message on the logger, or :raise to raise ActionController::UnpermittedParameters exception. The default value is :log in test and development environments, false otherwise.

    +
+ +

Examples:

+ +
params = ActionController::Parameters.new
+params.permitted? # => false
+
+ActionController::Parameters.permit_all_parameters = true
+
+params = ActionController::Parameters.new
+params.permitted? # => true
+
+params = ActionController::Parameters.new(a: "123", b: "456")
+params.permit(:c)
+# => <ActionController::Parameters {} permitted: true>
+
+ActionController::Parameters.action_on_unpermitted_parameters = :raise
+
+params = ActionController::Parameters.new(a: "123", b: "456")
+params.permit(:c)
+# => ActionController::UnpermittedParameters: found unpermitted keys: a, b
+
+ +

Please note that these options *are not thread-safe*. In a multi-threaded environment they should only be set once at boot-time and never mutated at runtime.

+ +

You can fetch values of ActionController::Parameters using either :key or "key".

+ +
params = ActionController::Parameters.new(key: "value")
+params[:key]  # => "value"
+params["key"] # => "value"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EMPTY_ARRAY=[]
 
EMPTY_HASH={}
 
PERMITTED_SCALAR_TYPES=[ +String, +Symbol, +NilClass, +Numeric, +TrueClass, +FalseClass, +Date, +Time, +# DateTimes are Dates, we document the type but avoid the redundant check. +StringIO, +IO, +ActionDispatch::Http::UploadedFile, +Rack::Test::UploadedFile, +]
 

This is a white list of permitted scalar types that includes the ones supported in XML and JSON requests.

+ +

This list is in particular used to filter ordinary requests, String goes as first element to quickly short-circuit the common case.

+ +

If you modify this collection please update the API of permit above.

+ + + + +

Attributes

+ + + + + + + + +
+ [R] + parameters
+ + + + +

Class Public methods

+ +
+

+ + new(parameters = {}) + +

+ + +
+

Returns a new instance of ActionController::Parameters. Also, sets the permitted attribute to the default value of ActionController::Parameters.permit_all_parameters.

+ +
class Person < ActiveRecord::Base
+end
+
+params = ActionController::Parameters.new(name: "Francesco")
+params.permitted?  # => false
+Person.new(params) # => ActiveModel::ForbiddenAttributesError
+
+ActionController::Parameters.permit_all_parameters = true
+
+params = ActionController::Parameters.new(name: "Francesco")
+params.permitted?  # => true
+Person.new(params) # => #<Person id: nil, name: "Francesco">
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 235
+def initialize(parameters = {})
+  @parameters = parameters.with_indifferent_access
+  @permitted = self.class.permit_all_parameters
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+

Returns true if another Parameters object contains the same content and permitted flag.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 242
+def ==(other)
+  if other.respond_to?(:permitted?)
+    permitted? == other.permitted? && parameters == other.parameters
+  else
+    @parameters == other
+  end
+end
+
+
+ +
+ +
+

+ + [](key) + +

+ + +
+

Returns a parameter for the given key. If not found, returns nil.

+ +
params = ActionController::Parameters.new(person: { name: "Francesco" })
+params[:person] # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
+params[:none]   # => nil
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 553
+def [](key)
+  convert_hashes_to_parameters(key, @parameters[key])
+end
+
+
+ +
+ +
+

+ + []=(key, value) + +

+ + +
+

Assigns a value to a given key. The given key may still get filtered out when permit is called.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 559
+def []=(key, value)
+  @parameters[key] = value
+end
+
+
+ +
+ +
+

+ + as_json(options=nil) + + +

+ + +
+

Returns a hash that can be used as the JSON representation for the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 129
+    
+
+
+ +
+ +
+

+ + converted_arrays() + +

+ + +
+

Attribute that keeps track of converted arrays, if any, to avoid double looping in the common use case permit + mass-assignment. Defined in a method to instantiate it only if needed.

+ +

Testing membership still loops, but it's going to be faster than our own loop that converts values. Also, we are not going to build a new array object per fetch.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 352
+def converted_arrays
+  @converted_arrays ||= Set.new
+end
+
+
+ +
+ +
+

+ + deep_dup() + +

+ + +
+

Returns duplicate of object including all parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 792
+def deep_dup
+  self.class.new(@parameters.deep_dup).tap do |duplicate|
+    duplicate.permitted = @permitted
+  end
+end
+
+
+ +
+ +
+

+ + delete(key, &block) + +

+ + +
+

Deletes a key-value pair from Parameters and returns the value. If key is not found, returns nil (or, with optional code block, yields key and returns the result). Cf. #extract!, which returns the corresponding ActionController::Parameters object.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 685
+def delete(key, &block)
+  convert_value_to_parameters(@parameters.delete(key, &block))
+end
+
+
+ +
+ +
+

+ + delete_if(&block) + +

+ + +
+ +
+ + + + + +
+ Alias for: reject! +
+ + + +
+ +
+

+ + dig(*keys) + +

+ + +
+

Extracts the nested parameter from the given keys by calling dig at each step. Returns nil if any intermediate step is nil.

+ +
params = ActionController::Parameters.new(foo: { bar: { baz: 1 } })
+params.dig(:foo, :bar, :baz) # => 1
+params.dig(:foo, :zot, :xyz) # => nil
+
+params2 = ActionController::Parameters.new(foo: [10, 11, 12])
+params2.dig(:foo, 1) # => 11
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 598
+def dig(*keys)
+  convert_hashes_to_parameters(keys.first, @parameters[keys.first])
+  @parameters.dig(*keys)
+end
+
+
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + +
+ Alias for: each_pair +
+ + + +
+ +
+

+ + each_pair(&block) + +

+ + +
+

Convert all hashes in values into parameters, then yield each pair in the same way as Hash#each_pair.

+
+ + + +
+ Also aliased as: each +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 336
+def each_pair(&block)
+  @parameters.each_pair do |key, value|
+    yield [key, convert_hashes_to_parameters(key, value)]
+  end
+
+  self
+end
+
+
+ +
+ +
+

+ + empty?() + + +

+ + +
+

Returns true if the parameters have no key/value pairs.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 137
+    
+
+
+ +
+ +
+

+ + except(*keys) + +

+ + +
+

Returns a new ActionController::Parameters instance that filters out the given keys.

+ +
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
+params.except(:a, :b) # => <ActionController::Parameters {"c"=>3} permitted: false>
+params.except(:d)     # => <ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 628
+def except(*keys)
+  new_instance_with_inherited_permitted_status(@parameters.except(*keys))
+end
+
+
+ +
+ +
+

+ + extract!(*keys) + +

+ + +
+

Removes and returns the key/value pairs matching the given keys.

+ +
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
+params.extract!(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
+params                  # => <ActionController::Parameters {"c"=>3} permitted: false>
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 637
+def extract!(*keys)
+  new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
+end
+
+
+ +
+ +
+

+ + fetch(key, *args) + +

+ + +
+

Returns a parameter for the given key. If the key can't be found, there are several options: With no other arguments, it will raise an ActionController::ParameterMissing error; if a second argument is given, then that is returned (converted to an instance of ActionController::Parameters if possible); if a block is given, then that will be run and its result returned.

+ +
params = ActionController::Parameters.new(person: { name: "Francesco" })
+params.fetch(:person)               # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
+params.fetch(:none)                 # => ActionController::ParameterMissing: param is missing or the value is empty: none
+params.fetch(:none, {})             # => <ActionController::Parameters {} permitted: false>
+params.fetch(:none, "Francesco")    # => "Francesco"
+params.fetch(:none) { "Francesco" } # => "Francesco"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 576
+def fetch(key, *args)
+  convert_value_to_parameters(
+    @parameters.fetch(key) {
+      if block_given?
+        yield
+      else
+        args.fetch(0) { raise ActionController::ParameterMissing.new(key) }
+      end
+    }
+  )
+end
+
+
+ +
+ +
+

+ + has_key?(key) + + +

+ + +
+

Returns true if the given key is present in the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 145
+    
+
+
+ +
+ +
+

+ + has_value?(value) + + +

+ + +
+

Returns true if the given value is present for some key in the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 153
+    
+
+
+ +
+ +
+

+ + include?(key) + + +

+ + +
+

Returns true if the given key is present in the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 161
+    
+
+
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 760
+def inspect
+  "<#{self.class} #{@parameters} permitted: #{@permitted}>"
+end
+
+
+ +
+ +
+

+ + keep_if(&block) + +

+ + +
+ +
+ + + + + +
+ Alias for: select! +
+ + + +
+ +
+

+ + key?(key) + + +

+ + +
+

Returns true if the given key is present in the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 169
+    
+
+
+ +
+ +
+

+ + keys() + + +

+ + +
+

Returns a new array of the keys of the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 177
+    
+
+
+ +
+ +
+

+ + merge(other_hash) + +

+ + +
+

Returns a new ActionController::Parameters with all keys from other_hash merged into current hash.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 723
+def merge(other_hash)
+  new_instance_with_inherited_permitted_status(
+    @parameters.merge(other_hash.to_h)
+  )
+end
+
+
+ +
+ +
+

+ + merge!(other_hash) + +

+ + +
+

Returns current ActionController::Parameters instance with other_hash merged into current hash.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 731
+def merge!(other_hash)
+  @parameters.merge!(other_hash.to_h)
+  self
+end
+
+
+ +
+ +
+

+ + permit(*filters) + +

+ + +
+

Returns a new ActionController::Parameters instance that includes only the given filters and sets the permitted attribute for the object to true. This is useful for limiting which attributes should be allowed for mass updating.

+ +
params = ActionController::Parameters.new(user: { name: "Francesco", age: 22, role: "admin" })
+permitted = params.require(:user).permit(:name, :age)
+permitted.permitted?      # => true
+permitted.has_key?(:name) # => true
+permitted.has_key?(:age)  # => true
+permitted.has_key?(:role) # => false
+
+ +

Only permitted scalars pass the filter. For example, given

+ +
params.permit(:name)
+
+ +

:name passes if it is a key of params whose associated value is of type String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile or Rack::Test::UploadedFile. Otherwise, the key :name is filtered out.

+ +

You may declare that the parameter should be an array of permitted scalars by mapping it to an empty array:

+ +
params = ActionController::Parameters.new(tags: ["rails", "parameters"])
+params.permit(tags: [])
+
+ +

Sometimes it is not possible or convenient to declare the valid keys of a hash parameter or its internal structure. Just map to an empty hash:

+ +
params.permit(preferences: {})
+
+ +

Be careful because this opens the door to arbitrary input. In this case, permit ensures values in the returned structure are permitted scalars and filters out anything else.

+ +

You can also use permit on nested parameters, like:

+ +
params = ActionController::Parameters.new({
+  person: {
+    name: "Francesco",
+    age:  22,
+    pets: [{
+      name: "Purplish",
+      category: "dogs"
+    }]
+  }
+})
+
+permitted = params.permit(person: [ :name, { pets: :name } ])
+permitted.permitted?                    # => true
+permitted[:person][:name]               # => "Francesco"
+permitted[:person][:age]                # => nil
+permitted[:person][:pets][0][:name]     # => "Purplish"
+permitted[:person][:pets][0][:category] # => nil
+
+ +

Note that if you use permit in a key that points to a hash, it won't allow all the hash. You also need to specify which attributes inside the hash should be whitelisted.

+ +
params = ActionController::Parameters.new({
+  person: {
+    contact: {
+      email: "none@test.com",
+      phone: "555-1234"
+    }
+  }
+})
+
+params.require(:person).permit(:contact)
+# => <ActionController::Parameters {} permitted: true>
+
+params.require(:person).permit(contact: :phone)
+# => <ActionController::Parameters {"contact"=><ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
+
+params.require(:person).permit(contact: [ :email, :phone ])
+# => <ActionController::Parameters {"contact"=><ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 530
+def permit(*filters)
+  params = self.class.new
+
+  filters.flatten.each do |filter|
+    case filter
+    when Symbol, String
+      permitted_scalar_filter(params, filter)
+    when Hash
+      hash_filter(params, filter)
+    end
+  end
+
+  unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters
+
+  params.permit!
+end
+
+
+ +
+ +
+

+ + permit!() + +

+ + +
+

Sets the permitted attribute to true. This can be used to pass mass assignment. Returns self.

+ +
class Person < ActiveRecord::Base
+end
+
+params = ActionController::Parameters.new(name: "Francesco")
+params.permitted?  # => false
+Person.new(params) # => ActiveModel::ForbiddenAttributesError
+params.permit!
+params.permitted?  # => true
+Person.new(params) # => #<Person id: nil, name: "Francesco">
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 378
+def permit!
+  each_pair do |key, value|
+    Array.wrap(value).flatten.each do |v|
+      v.permit! if v.respond_to? :permit!
+    end
+  end
+
+  @permitted = true
+  self
+end
+
+
+ +
+ +
+

+ + permitted?() + +

+ + +
+

Returns true if the parameter is permitted, false otherwise.

+ +
params = ActionController::Parameters.new
+params.permitted? # => false
+params.permit!
+params.permitted? # => true
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 362
+def permitted?
+  @permitted
+end
+
+
+ +
+ +
+

+ + reject(&block) + +

+ + +
+

Returns a new instance of ActionController::Parameters with items that the block evaluates to true removed.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 704
+def reject(&block)
+  new_instance_with_inherited_permitted_status(@parameters.reject(&block))
+end
+
+
+ +
+ +
+

+ + reject!(&block) + +

+ + +
+

Removes items that the block evaluates to true and returns self.

+
+ + + +
+ Also aliased as: delete_if +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 709
+def reject!(&block)
+  @parameters.reject!(&block)
+  self
+end
+
+
+ +
+ +
+

+ + require(key) + +

+ + +
+

This method accepts both a single key and an array of keys.

+ +

When passed a single key, if it exists and its associated value is either present or the singleton false, returns said value:

+ +
ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
+# => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
+
+ +

Otherwise raises ActionController::ParameterMissing:

+ +
ActionController::Parameters.new.require(:person)
+# ActionController::ParameterMissing: param is missing or the value is empty: person
+
+ActionController::Parameters.new(person: nil).require(:person)
+# ActionController::ParameterMissing: param is missing or the value is empty: person
+
+ActionController::Parameters.new(person: "\t").require(:person)
+# ActionController::ParameterMissing: param is missing or the value is empty: person
+
+ActionController::Parameters.new(person: {}).require(:person)
+# ActionController::ParameterMissing: param is missing or the value is empty: person
+
+ +

When given an array of keys, the method tries to require each one of them in order. If it succeeds, an array with the respective return values is returned:

+ +
params = ActionController::Parameters.new(user: { ... }, profile: { ... })
+user_params, profile_params = params.require([:user, :profile])
+
+ +

Otherwise, the method re-raises the first exception found:

+ +
params = ActionController::Parameters.new(user: {}, profile: {})
+user_params, profile_params = params.require([:user, :profile])
+# ActionController::ParameterMissing: param is missing or the value is empty: user
+
+ +

Technically this method can be used to fetch terminal values:

+ +
# CAREFUL
+params = ActionController::Parameters.new(person: { name: "Finn" })
+name = params.require(:person).require(:name) # CAREFUL
+
+ +

but take into account that at some point those ones have to be permitted:

+ +
def person_params
+  params.require(:person).permit(:name).tap do |person_params|
+    person_params.require(:name) # SAFER
+  end
+end
+
+ +

for example.

+
+ + + +
+ Also aliased as: required +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 439
+def require(key)
+  return key.map { |k| require(k) } if key.is_a?(Array)
+  value = self[key]
+  if value.present? || value == false
+    value
+  else
+    raise ParameterMissing.new(key)
+  end
+end
+
+
+ +
+ +
+

+ + required(key) + +

+ + +
+

Alias of require.

+
+ + + + + +
+ Alias for: require +
+ + + +
+ +
+

+ + reverse_merge(other_hash) + +

+ + +
+

Returns a new ActionController::Parameters with all keys from current hash merged into other_hash.

+
+ + + +
+ Also aliased as: with_defaults +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 738
+def reverse_merge(other_hash)
+  new_instance_with_inherited_permitted_status(
+    other_hash.to_h.merge(@parameters)
+  )
+end
+
+
+ +
+ +
+

+ + reverse_merge!(other_hash) + +

+ + +
+

Returns current ActionController::Parameters instance with current hash merged into other_hash.

+
+ + + +
+ Also aliased as: with_defaults! +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 747
+def reverse_merge!(other_hash)
+  @parameters.merge!(other_hash.to_h) { |key, left, right| left }
+  self
+end
+
+
+ +
+ +
+

+ + select(&block) + +

+ + +
+

Returns a new instance of ActionController::Parameters with only items that the block evaluates to true.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 691
+def select(&block)
+  new_instance_with_inherited_permitted_status(@parameters.select(&block))
+end
+
+
+ +
+ +
+

+ + select!(&block) + +

+ + +
+

Equivalent to Hash#keep_if, but returns nil if no changes were made.

+
+ + + +
+ Also aliased as: keep_if +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 696
+def select!(&block)
+  @parameters.select!(&block)
+  self
+end
+
+
+ +
+ +
+

+ + slice(*keys) + +

+ + +
+

Returns a new ActionController::Parameters instance that includes only the given keys. If the given keys don't exist, returns an empty hash.

+ +
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
+params.slice(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
+params.slice(:d)     # => <ActionController::Parameters {} permitted: false>
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 611
+def slice(*keys)
+  new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
+end
+
+
+ +
+ +
+

+ + slice!(*keys) + +

+ + +
+

Returns current ActionController::Parameters instance which contains only the given keys.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 617
+def slice!(*keys)
+  @parameters.slice!(*keys)
+  self
+end
+
+
+ +
+ +
+

+ + to_h() + +

+ + +
+

Returns a safe ActiveSupport::HashWithIndifferentAccess representation of the parameters with all unpermitted keys removed.

+ +
params = ActionController::Parameters.new({
+  name: "Senjougahara Hitagi",
+  oddity: "Heavy stone crab"
+})
+params.to_h
+# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
+
+safe_params = params.permit(:name)
+safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 262
+def to_h
+  if permitted?
+    convert_parameters_to_hashes(@parameters, :to_h)
+  else
+    raise UnfilteredParameters
+  end
+end
+
+
+ +
+ +
+

+ + to_hash() + +

+ + +
+

Returns a safe Hash representation of the parameters with all unpermitted keys removed.

+ +
params = ActionController::Parameters.new({
+  name: "Senjougahara Hitagi",
+  oddity: "Heavy stone crab"
+})
+params.to_hash
+# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
+
+safe_params = params.permit(:name)
+safe_params.to_hash # => {"name"=>"Senjougahara Hitagi"}
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 282
+def to_hash
+  to_h.to_hash
+end
+
+
+ +
+ +
+

+ + to_param(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_query +
+ + + +
+ +
+

+ + to_query(*args) + +

+ + +
+

Returns a string representation of the receiver suitable for use as a URL query string:

+ +
params = ActionController::Parameters.new({
+  name: "David",
+  nationality: "Danish"
+})
+params.to_query
+# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
+
+safe_params = params.permit(:name, :nationality)
+safe_params.to_query
+# => "name=David&nationality=Danish"
+
+ +

An optional namespace can be passed to enclose key names:

+ +
params = ActionController::Parameters.new({
+  name: "David",
+  nationality: "Danish"
+})
+safe_params = params.permit(:name, :nationality)
+safe_params.to_query("user")
+# => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
+
+ +

The string pairs “key=value” that conform the query string are sorted lexicographically in ascending order.

+ +

This method is also aliased as to_param.

+
+ + + +
+ Also aliased as: to_param +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 314
+def to_query(*args)
+  to_h.to_query(*args)
+end
+
+
+ +
+ +
+

+ + to_s() + + +

+ + +
+

Returns the content of the parameters as a string.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 185
+    
+
+
+ +
+ +
+

+ + to_unsafe_h() + +

+ + +
+

Returns an unsafe, unfiltered ActiveSupport::HashWithIndifferentAccess representation of the parameters.

+ +
params = ActionController::Parameters.new({
+  name: "Senjougahara Hitagi",
+  oddity: "Heavy stone crab"
+})
+params.to_unsafe_h
+# => {"name"=>"Senjougahara Hitagi", "oddity" => "Heavy stone crab"}
+
+
+ + + +
+ Also aliased as: to_unsafe_hash +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 329
+def to_unsafe_h
+  convert_parameters_to_hashes(@parameters, :to_unsafe_h)
+end
+
+
+ +
+ +
+

+ + to_unsafe_hash() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_unsafe_h +
+ + + +
+ +
+

+ + transform_keys(&block) + +

+ + +
+

Returns a new ActionController::Parameters instance with the results of running block once for every key. The values are unchanged.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 664
+def transform_keys(&block)
+  if block
+    new_instance_with_inherited_permitted_status(
+      @parameters.transform_keys(&block)
+    )
+  else
+    @parameters.transform_keys
+  end
+end
+
+
+ +
+ +
+

+ + transform_keys!(&block) + +

+ + +
+

Performs keys transformation and returns the altered ActionController::Parameters instance.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 676
+def transform_keys!(&block)
+  @parameters.transform_keys!(&block)
+  self
+end
+
+
+ +
+ +
+

+ + transform_values() + +

+ + +
+

Returns a new ActionController::Parameters with the results of running block once for every value. The keys are unchanged.

+ +
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
+params.transform_values { |x| x * 2 }
+# => <ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 647
+def transform_values
+  return to_enum(:transform_values) unless block_given?
+  new_instance_with_inherited_permitted_status(
+    @parameters.transform_values { |v| yield convert_value_to_parameters(v) }
+  )
+end
+
+
+ +
+ +
+

+ + transform_values!() + +

+ + +
+

Performs values transformation and returns the altered ActionController::Parameters instance.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 656
+def transform_values!
+  return to_enum(:transform_values!) unless block_given?
+  @parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
+  self
+end
+
+
+ +
+ +
+

+ + value?(value) + + +

+ + +
+

Returns true if the given value is present for some key in the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 193
+    
+
+
+ +
+ +
+

+ + values() + + +

+ + +
+

Returns a new array of the values of the parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 207
+delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?,
+  :as_json, :to_s, to: :@parameters
+
+
+
+ +
+ +
+

+ + values_at(*keys) + +

+ + +
+

Returns values that were assigned to the given keys. Note that all the Hash objects will be converted to ActionController::Parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 717
+def values_at(*keys)
+  convert_value_to_parameters(@parameters.values_at(*keys))
+end
+
+
+ +
+ +
+

+ + with_defaults(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge +
+ + + +
+ +
+

+ + with_defaults!(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge! +
+ + + +
+ + +

Instance Protected methods

+ +
+

+ + fields_for_style?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 805
+def fields_for_style?
+  @parameters.all? { |k, v| k =~ /\A-?\d+\z/ && (v.is_a?(Hash) || v.is_a?(Parameters)) }
+end
+
+
+ +
+ +
+

+ + permitted=(new_permitted) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 801
+def permitted=(new_permitted)
+  @permitted = new_permitted
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ParamsWrapper.html b/src/5.2/classes/ActionController/ParamsWrapper.html new file mode 100644 index 0000000000..ecc3d93466 --- /dev/null +++ b/src/5.2/classes/ActionController/ParamsWrapper.html @@ -0,0 +1,141 @@ +--- +title: ActionController::ParamsWrapper +layout: default +--- +
+ +
+
+ +
+ +

Wraps the parameters hash into a nested hash. This will allow clients to submit requests without having to specify any root elements.

+ +

This functionality is enabled in config/initializers/wrap_parameters.rb and can be customized.

+ +

You could also turn it on per controller by setting the format array to a non-empty array:

+ +
class UsersController < ApplicationController
+  wrap_parameters format: [:json, :xml, :url_encoded_form, :multipart_form]
+end
+
+ +

If you enable ParamsWrapper for :json format, instead of having to send JSON parameters like this:

+ +
{"user": {"name": "Konata"}}
+
+ +

You can send parameters like this:

+ +
{"name": "Konata"}
+
+ +

And it will be wrapped into a nested hash with the key name matching the controller's name. For example, if you're posting to UsersController, your new params hash will look like this:

+ +
{"name" => "Konata", "user" => {"name" => "Konata"}}
+
+ +

You can also specify the key in which the parameters should be wrapped to, and also the list of attributes it should wrap by using either :include or :exclude options like this:

+ +
class UsersController < ApplicationController
+  wrap_parameters :person, include: [:username, :password]
+end
+
+ +

On Active Record models with no :include or :exclude option set, it will only wrap the parameters returned by the class method attribute_names.

+ +

If you're going to pass the parameters to an ActiveModel object (such as User.new(params[:user])), you might consider passing the model class to the method instead. The ParamsWrapper will actually try to determine the list of attribute names from the model and only wrap those attributes:

+ +
class UsersController < ApplicationController
+  wrap_parameters Person
+end
+
+ +

You still could pass :include and :exclude to set the list of attributes you want to wrap.

+ +

By default, if you don't specify the key in which the parameters would be wrapped to, ParamsWrapper will actually try to determine if there's a model related to it or not. This controller, for example:

+ +
class Admin::UsersController < ApplicationController
+end
+
+ +

will try to check if Admin::User or User model exists, and use it to determine the wrapper key respectively. If both models don't exist, it will then fallback to use user as the key.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
EXCLUDE_PARAMETERS=%w(authenticity_token _method utf8)
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ParamsWrapper/Options.html b/src/5.2/classes/ActionController/ParamsWrapper/Options.html new file mode 100644 index 0000000000..2efdc019ec --- /dev/null +++ b/src/5.2/classes/ActionController/ParamsWrapper/Options.html @@ -0,0 +1,73 @@ +--- +title: ActionController::ParamsWrapper::Options +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/ParamsWrapper/Options/ClassMethods.html b/src/5.2/classes/ActionController/ParamsWrapper/Options/ClassMethods.html new file mode 100644 index 0000000000..dcc67d0dc1 --- /dev/null +++ b/src/5.2/classes/ActionController/ParamsWrapper/Options/ClassMethods.html @@ -0,0 +1,229 @@ +--- +title: ActionController::ParamsWrapper::Options::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _set_wrapper_options(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/params_wrapper.rb, line 176
+def _set_wrapper_options(options)
+  self._wrapper_options = Options.from_hash(options)
+end
+
+
+ +
+ +
+

+ + inherited(klass) + +

+ + +
+

Sets the default wrapper key or model which will be used to determine wrapper key and attribute names. Called automatically when the module is inherited.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/params_wrapper.rb, line 231
+def inherited(klass)
+  if klass._wrapper_options.format.any?
+    params = klass._wrapper_options.dup
+    params.klass = klass
+    klass._wrapper_options = params
+  end
+  super
+end
+
+
+ +
+ +
+

+ + wrap_parameters(name_or_model_or_options, options = {}) + +

+ + +
+

Sets the name of the wrapper key, or the model which ParamsWrapper would use to determine the attribute names from.

+ +

Examples

+ +
wrap_parameters format: :xml
+  # enables the parameter wrapper for XML format
+
+wrap_parameters :person
+  # wraps parameters into +params[:person]+ hash
+
+wrap_parameters Person
+  # wraps parameters by determining the wrapper key from Person class
+  (+person+, in this case) and the list of attribute names
+
+wrap_parameters include: [:username, :title]
+  # wraps only +:username+ and +:title+ attributes from parameters.
+
+wrap_parameters false
+  # disables parameters wrapping for this controller altogether.
+
+ +

Options

+
  • +

    :format - The list of formats in which the parameters wrapper will be enabled.

    +
  • +

    :include - The list of attribute names which parameters wrapper will wrap into a nested hash.

    +
  • +

    :exclude - The list of attribute names which parameters wrapper will exclude from a nested hash.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/params_wrapper.rb, line 207
+def wrap_parameters(name_or_model_or_options, options = {})
+  model = nil
+
+  case name_or_model_or_options
+  when Hash
+    options = name_or_model_or_options
+  when false
+    options = options.merge(format: [])
+  when Symbol, String
+    options = options.merge(name: name_or_model_or_options)
+  else
+    model = name_or_model_or_options
+  end
+
+  opts = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options)
+  opts.model = model
+  opts.klass = self
+
+  self._wrapper_options = opts
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Railties.html b/src/5.2/classes/ActionController/Railties.html new file mode 100644 index 0000000000..8410571f7d --- /dev/null +++ b/src/5.2/classes/ActionController/Railties.html @@ -0,0 +1,67 @@ +--- +title: ActionController::Railties +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Railties/Helpers.html b/src/5.2/classes/ActionController/Railties/Helpers.html new file mode 100644 index 0000000000..5f5fd4913c --- /dev/null +++ b/src/5.2/classes/ActionController/Railties/Helpers.html @@ -0,0 +1,114 @@ +--- +title: ActionController::Railties::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + inherited(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/railties/helpers.rb, line 6
+def inherited(klass)
+  super
+  return unless klass.respond_to?(:helpers_path=)
+
+  if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
+    paths = namespace.railtie_helpers_paths
+  else
+    paths = ActionController::Helpers.helpers_path
+  end
+
+  klass.helpers_path = paths
+
+  if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers
+    klass.helper :all
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Redirecting.html b/src/5.2/classes/ActionController/Redirecting.html new file mode 100644 index 0000000000..1a41d1dd4e --- /dev/null +++ b/src/5.2/classes/ActionController/Redirecting.html @@ -0,0 +1,231 @@ +--- +title: ActionController::Redirecting +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + redirect_back(fallback_location:, allow_other_host: true, **args) + +

+ + +
+

Redirects the browser to the page that issued the request (the referrer) if possible, otherwise redirects to the provided default fallback location.

+ +

The referrer information is pulled from the HTTP Referer (sic) header on the request. This is an optional header and its presence on the request is subject to browser security settings and user preferences. If the request is missing this header, the fallback_location will be used.

+ +
redirect_back fallback_location: { action: "show", id: 5 }
+redirect_back fallback_location: @post
+redirect_back fallback_location: "http://www.rubyonrails.org"
+redirect_back fallback_location: "/images/screenshot.jpg"
+redirect_back fallback_location: posts_url
+redirect_back fallback_location: proc { edit_post_url(@post) }
+redirect_back fallback_location: '/', allow_other_host: false
+
+ +

Options

+
  • +

    :fallback_location - The default fallback location that will be used on missing Referer header.

    +
  • +

    :allow_other_host - Allow or disallow redirection to the host that is different to the current host, defaults to true.

    +
+ +

All other options that can be passed to redirect_to are accepted as options and the behavior is identical.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/redirecting.rb, line 90
+def redirect_back(fallback_location:, allow_other_host: true, **args)
+  referer = request.headers["Referer"]
+  redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
+  redirect_to redirect_to_referer ? referer : fallback_location, **args
+end
+
+
+ +
+ +
+

+ + redirect_to(options = {}, response_status = {}) + +

+ + +
+

Redirects the browser to the target specified in options. This parameter can be any one of:

+
  • +

    Hash - The URL will be generated by calling url_for with the options.

    +
  • +

    Record - The URL will be generated by calling url_for with the options, which will reference a named URL for that record.

    +
  • +

    String starting with protocol:// (like http://) or a protocol relative reference (like //) - Is passed straight through as the target for redirection.

    +
  • +

    String not containing a protocol - The current protocol and host is prepended to the string.

    +
  • +

    Proc - A block that will be executed in the controller's context. Should return any option accepted by redirect_to.

    +
+ +

Examples:

+ +
redirect_to action: "show", id: 5
+redirect_to @post
+redirect_to "http://www.rubyonrails.org"
+redirect_to "/images/screenshot.jpg"
+redirect_to posts_url
+redirect_to proc { edit_post_url(@post) }
+
+ +

The redirection happens as a 302 Found header unless otherwise specified using the :status option:

+ +
redirect_to post_url(@post), status: :found
+redirect_to action: 'atom', status: :moved_permanently
+redirect_to post_url(@post), status: 301
+redirect_to action: 'atom', status: 302
+
+ +

The status code can either be a standard HTTP Status code as an integer, or a symbol representing the downcased, underscored and symbolized description. Note that the status code must be a 3xx HTTP code, or redirection will not occur.

+ +

If you are using XHR requests other than GET or POST and redirecting after the request then some browsers will follow the redirect using the original request method. This may lead to undesirable behavior such as a double DELETE. To work around this you can return a 303 See Other status code which will be followed using a GET request.

+ +
redirect_to posts_url, status: :see_other
+redirect_to action: 'index', status: 303
+
+ +

It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names alert and notice as well as a general purpose flash bucket.

+ +
redirect_to post_url(@post), alert: "Watch it, mister!"
+redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
+redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
+redirect_to({ action: 'atom' }, alert: "Something serious happened")
+
+ +

Statements after redirect_to in our controller get executed, so redirect_to doesn't stop the execution of the function. To terminate the execution of the function immediately after the redirect_to, use return.

+ +
redirect_to post_url(@post) and return
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/redirecting.rb, line 58
+def redirect_to(options = {}, response_status = {})
+  raise ActionControllerError.new("Cannot redirect to nil!") unless options
+  raise AbstractController::DoubleRenderError if response_body
+
+  self.status        = _extract_redirect_to_status(options, response_status)
+  self.location      = _compute_redirect_to_location(request, options)
+  self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Renderer.html b/src/5.2/classes/ActionController/Renderer.html new file mode 100644 index 0000000000..6ae6ec884a --- /dev/null +++ b/src/5.2/classes/ActionController/Renderer.html @@ -0,0 +1,406 @@ +--- +title: ActionController::Renderer +layout: default +--- +
+ +
+
+ +
+ +

ActionController::Renderer allows you to render arbitrary templates without requirement of being in controller actions.

+ +

You get a concrete renderer class by invoking ActionController::Base#renderer. For example:

+ +
ApplicationController.renderer
+
+ +

It allows you to call method render directly.

+ +
ApplicationController.renderer.render template: '...'
+
+ +

You can use this shortcut in a controller, instead of the previous example:

+ +
ApplicationController.render template: '...'
+
+ +

render allows you to use the same options that you can use when rendering in a controller. For example:

+ +
FooController.render :action, locals: { ... }, assigns: { ... }
+
+ +

The template will be rendered in a Rack environment which is accessible through ActionController::Renderer#env. You can set it up in two ways:

+
  • +

    by changing renderer defaults, like

    + +
    ApplicationController.renderer.defaults # => hash with default Rack environment
    +
    +
  • +

    by initializing an instance of renderer by passing it a custom environment.

    + +
    ApplicationController.renderer.new(method: 'post', https: true)
    +
    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULTS={ +http_host: "example.org", +https: false, +method: "get", +script_name: "", +input: "" +}.freeze
 
IDENTITY=->(_) { _ }
 
RACK_KEY_TRANSLATION={ +http_host: "HTTP_HOST", +https: "HTTPS", +method: "REQUEST_METHOD", +script_name: "SCRIPT_NAME", +input: "rack.input" +}
 
RACK_VALUE_TRANSLATION={ +https: ->(v) { v ? "on" : "off" }, +method: ->(v) { v.upcase }, +}
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + controller
+ [R] + defaults
+ + + + +

Class Public methods

+ +
+

+ + for(controller, env = {}, defaults = DEFAULTS.dup) + +

+ + +
+

Create a new renderer instance for a specific controller class.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/renderer.rb, line 50
+def self.for(controller, env = {}, defaults = DEFAULTS.dup)
+  new(controller, env, defaults)
+end
+
+
+ +
+ +
+

+ + new(controller, env, defaults) + +

+ + +
+

Accepts a custom Rack environment to render templates in. It will be merged with the default Rack environment defined by ActionController::Renderer::DEFAULTS.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/renderer.rb, line 67
+def initialize(controller, env, defaults)
+  @controller = controller
+  @defaults = defaults
+  @env = normalize_keys defaults.merge(env)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + new(env = {}) + +

+ + +
+

Create a new renderer for the same controller but with a new env.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/renderer.rb, line 55
+def new(env = {})
+  self.class.new controller, env, defaults
+end
+
+
+ +
+ +
+

+ + render(*args) + +

+ + +
+

Render templates with any options from ActionController::Base#render_to_string.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/renderer.rb, line 74
+def render(*args)
+  raise "missing controller" unless controller
+
+  request = ActionDispatch::Request.new @env
+  request.routes = controller._routes
+
+  instance = controller.new
+  instance.set_request! request
+  instance.set_response! controller.make_response!(request)
+  instance.render_to_string(*args)
+end
+
+
+ +
+ +
+

+ + with_defaults(defaults) + +

+ + +
+

Create a new renderer for the same controller but with new defaults.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/renderer.rb, line 60
+def with_defaults(defaults)
+  self.class.new controller, @env, self.defaults.merge(defaults)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Renderers.html b/src/5.2/classes/ActionController/Renderers.html new file mode 100644 index 0000000000..5556378b39 --- /dev/null +++ b/src/5.2/classes/ActionController/Renderers.html @@ -0,0 +1,333 @@ +--- +title: ActionController::Renderers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RENDERERS=Set.new
 

A Set containing renderer names that correspond to available renderer procs. Default values are :json, :js, :xml.

+ + + + + + +

Class Public methods

+ +
+

+ + _render_with_renderer_method_name(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 91
+def self._render_with_renderer_method_name(key)
+  "_render_with_renderer_#{key}"
+end
+
+
+ +
+ +
+

+ + add(key, &block) + +

+ + +
+

Adds a new renderer to call within controller actions. A renderer is invoked by passing its name as an option to AbstractController::Rendering#render. To create a renderer pass it a name and a block. The block takes two arguments, the first is the value paired with its key and the second is the remaining hash of options passed to render.

+ +

Create a csv renderer:

+ +
ActionController::Renderers.add :csv do |obj, options|
+  filename = options[:filename] || 'data'
+  str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
+  send_data str, type: Mime[:csv],
+    disposition: "attachment; filename=#{filename}.csv"
+end
+
+ +

Note that we used Mime for the csv mime type as it comes with Rails. For a custom renderer, you'll need to register a mime type with Mime::Type.register.

+ +

To use the csv renderer in a controller action:

+ +
def show
+  @csvable = Csvable.find(params[:id])
+  respond_to do |format|
+    format.html
+    format.csv { render csv: @csvable, filename: @csvable.name }
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 75
+def self.add(key, &block)
+  define_method(_render_with_renderer_method_name(key), &block)
+  RENDERERS << key.to_sym
+end
+
+
+ +
+ +
+

+ + remove(key) + +

+ + +
+

This method is the opposite of add method.

+ +

To remove a csv renderer:

+ +
ActionController::Renderers.remove(:csv)
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 85
+def self.remove(key)
+  RENDERERS.delete(key.to_sym)
+  method_name = _render_with_renderer_method_name(key)
+  remove_possible_method(method_name)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + _render_to_body_with_renderer(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 145
+def _render_to_body_with_renderer(options)
+  _renderers.each do |name|
+    if options.key?(name)
+      _process_options(options)
+      method_name = Renderers._render_with_renderer_method_name(name)
+      return send(method_name, options.delete(name), options)
+    end
+  end
+  nil
+end
+
+
+ +
+ +
+

+ + render_to_body(options) + +

+ + +
+

Called by render in AbstractController::Rendering which sets the return value as the response_body.

+ +

If no renderer is found, super returns control to ActionView::Rendering.render_to_body, if present.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 141
+def render_to_body(options)
+  _render_to_body_with_renderer(options) || super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Renderers/All.html b/src/5.2/classes/ActionController/Renderers/All.html new file mode 100644 index 0000000000..1d04d007fa --- /dev/null +++ b/src/5.2/classes/ActionController/Renderers/All.html @@ -0,0 +1,74 @@ +--- +title: ActionController::Renderers::All +layout: default +--- +
+ +
+
+ +
+ +

Used in ActionController::Base and ActionController::API to include all renderers by default.

+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Renderers/ClassMethods.html b/src/5.2/classes/ActionController/Renderers/ClassMethods.html new file mode 100644 index 0000000000..7bebe7df13 --- /dev/null +++ b/src/5.2/classes/ActionController/Renderers/ClassMethods.html @@ -0,0 +1,157 @@ +--- +title: ActionController::Renderers::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + use_renderer(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: use_renderers +
+ + + +
+ +
+

+ + use_renderers(*args) + +

+ + +
+

Adds, by name, a renderer or renderers to the _renderers available to call within controller actions.

+ +

It is useful when rendering from an ActionController::Metal controller or otherwise to add an available renderer proc to a specific controller.

+ +

Both ActionController::Base and ActionController::API include ActionController::Renderers::All, making all renderers available in the controller. See Renderers::RENDERERS and Renderers.add.

+ +

Since ActionController::Metal controllers cannot render, the controller must include AbstractController::Rendering, ActionController::Rendering, and ActionController::Renderers, and have at least one renderer.

+ +

Rather than including ActionController::Renderers::All and including all renderers, you may specify which renderers to include by passing the renderer name or names to use_renderers. For example, a controller that includes only the :json renderer (_render_with_renderer_json) might look like:

+ +
class MetalRenderingController < ActionController::Metal
+  include AbstractController::Rendering
+  include ActionController::Rendering
+  include ActionController::Renderers
+
+  use_renderers :json
+
+  def show
+    render json: record
+  end
+end
+
+ +

You must specify a use_renderer, else the controller.renderer and controller._renderers will be nil, and the action will fail.

+
+ + + +
+ Also aliased as: use_renderer +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/renderers.rb, line 129
+def use_renderers(*args)
+  renderers = _renderers + args
+  self._renderers = renderers.freeze
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Rendering.html b/src/5.2/classes/ActionController/Rendering.html new file mode 100644 index 0000000000..b7e514dd4a --- /dev/null +++ b/src/5.2/classes/ActionController/Rendering.html @@ -0,0 +1,178 @@ +--- +title: ActionController::Rendering +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RENDER_FORMATS_IN_PRIORITY=[:body, :plain, :html]
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + render_to_body(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/rendering.rb, line 51
+def render_to_body(options = {})
+  super || _render_in_priorities(options) || " "
+end
+
+
+ +
+ +
+

+ + render_to_string(*) + +

+ + +
+

Overwrite render_to_string because body can now be set to a Rack body.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/rendering.rb, line 40
+def render_to_string(*)
+  result = super
+  if result.respond_to?(:each)
+    string = "".dup
+    result.each { |r| string << r }
+    string
+  else
+    result
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Rendering/ClassMethods.html b/src/5.2/classes/ActionController/Rendering/ClassMethods.html new file mode 100644 index 0000000000..24305d0201 --- /dev/null +++ b/src/5.2/classes/ActionController/Rendering/ClassMethods.html @@ -0,0 +1,116 @@ +--- +title: ActionController::Rendering::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + renderer

Returns a renderer instance (inherited from ActionController::Renderer) for the controller.

+ + + + + +

Instance Public methods

+ +
+

+ + inherited(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/rendering.rb, line 21
+def inherited(klass)
+  klass.setup_renderer!
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/RequestForgeryProtection.html b/src/5.2/classes/ActionController/RequestForgeryProtection.html new file mode 100644 index 0000000000..fe1c854aad --- /dev/null +++ b/src/5.2/classes/ActionController/RequestForgeryProtection.html @@ -0,0 +1,1225 @@ +--- +title: ActionController::RequestForgeryProtection +layout: default +--- +
+ +
+
+ +
+ +

Controller actions are protected from Cross-Site Request Forgery (CSRF) attacks by including a token in the rendered HTML for your application. This token is stored as a random string in the session, to which an attacker does not have access. When a request reaches your application, Rails verifies the received token with the token in the session. All requests are checked except GET requests as these should be idempotent. Keep in mind that all session-oriented requests should be CSRF protected, including JavaScript and HTML requests.

+ +

Since HTML and JavaScript requests are typically made from the browser, we need to ensure to verify request authenticity for the web browser. We can use session-oriented authentication for these types of requests, by using the protect_from_forgery method in our controllers.

+ +

GET requests are not protected since they don't have side effects like writing to the database and don't leak sensitive information. JavaScript requests are an exception: a third-party site can use a <script> tag to reference a JavaScript URL on your site. When your JavaScript response loads on their site, it executes. With carefully crafted JavaScript on their end, sensitive data in your JavaScript response may be extracted. To prevent this, only XmlHttpRequest (known as XHR or Ajax) requests are allowed to make GET requests for JavaScript responses.

+ +

It's important to remember that XML or JSON requests are also affected and if you're building an API you should change forgery protection method in ApplicationController (by default: :exception):

+ +
class ApplicationController < ActionController::Base
+  protect_from_forgery unless: -> { request.format.json? }
+end
+
+ +

CSRF protection is turned on with the protect_from_forgery method. By default protect_from_forgery protects your session with :null_session method, which provides an empty session during request.

+ +

We may want to disable CSRF protection for APIs since they are typically designed to be state-less. That is, the request API client will handle the session for you instead of Rails.

+ +

The token parameter is named authenticity_token by default. The name and value of this token must be added to every layout that renders forms by including csrf_meta_tags in the HTML head.

+ +

Learn more about CSRF attacks and securing your application in the Ruby on Rails Security Guide.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
AUTHENTICITY_TOKEN_LENGTH=32
 
NULL_ORIGIN_MESSAGE=<<-MSG.strip_heredoc
 
+ + + + + + + +

Instance Private methods

+ +
+

+ + any_authenticity_token_valid?() + +

+ + +
+

Checks if any of the authenticity tokens from the request are valid.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 295
+def any_authenticity_token_valid? # :doc:
+  request_authenticity_tokens.any? do |token|
+    valid_authenticity_token?(session, token)
+  end
+end
+
+
+ +
+ +
+

+ + compare_with_global_token(token, session) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 381
+def compare_with_global_token(token, session) # :doc:
+  ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, global_csrf_token(session))
+end
+
+
+ +
+ +
+

+ + compare_with_real_token(token, session) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 377
+def compare_with_real_token(token, session) # :doc:
+  ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, real_csrf_token(session))
+end
+
+
+ +
+ +
+

+ + csrf_token_hmac(session, identifier) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 415
+def csrf_token_hmac(session, identifier) # :doc:
+  OpenSSL::HMAC.digest(
+    OpenSSL::Digest::SHA256.new,
+    real_csrf_token(session),
+    identifier
+  )
+end
+
+
+ +
+ +
+

+ + form_authenticity_param() + +

+ + +
+

The form's authenticity parameter. Override to provide your own.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 430
+def form_authenticity_param # :doc:
+  params[request_forgery_protection_token]
+end
+
+
+ +
+ +
+

+ + global_csrf_token(session) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 411
+def global_csrf_token(session) # :doc:
+  csrf_token_hmac(session, GLOBAL_CSRF_TOKEN_IDENTIFIER)
+end
+
+
+ +
+ +
+

+ + handle_unverified_request() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 242
+def handle_unverified_request # :doc:
+  forgery_protection_strategy.new(self).handle_unverified_request
+end
+
+
+ +
+ +
+

+ + mark_for_same_origin_verification!() + +

+ + +
+

GET requests are checked for cross-origin JavaScript after rendering.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 267
+def mark_for_same_origin_verification! # :doc:
+  @marked_for_same_origin_verification = request.get?
+end
+
+
+ +
+ +
+

+ + marked_for_same_origin_verification?() + +

+ + +
+

If the verify_authenticity_token before_action ran, verify that JavaScript responses are only served to same-origin GET requests.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 273
+def marked_for_same_origin_verification? # :doc:
+  @marked_for_same_origin_verification ||= false
+end
+
+
+ +
+ +
+

+ + mask_token(raw_token) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 370
+def mask_token(raw_token) # :doc:
+  one_time_pad = SecureRandom.random_bytes(AUTHENTICITY_TOKEN_LENGTH)
+  encrypted_csrf_token = xor_byte_strings(one_time_pad, raw_token)
+  masked_token = one_time_pad + encrypted_csrf_token
+  Base64.urlsafe_encode64(masked_token).delete("=")
+end
+
+
+ +
+ +
+

+ + masked_authenticity_token(session, form_options: {}) + +

+ + +
+

Creates a masked version of the authenticity token that varies on each request. The masking is used to mitigate SSL attacks like BREACH.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 314
+def masked_authenticity_token(session, form_options: {}) # :doc:
+  action, method = form_options.values_at(:action, :method)
+
+  raw_token = if per_form_csrf_tokens && action && method
+    action_path = normalize_action_path(action)
+    per_form_csrf_token(session, action_path, method)
+  else
+    global_csrf_token(session)
+  end
+
+  mask_token(raw_token)
+end
+
+
+ +
+ +
+

+ + non_xhr_javascript_response?() + +

+ + +
+

Check for cross-origin JavaScript responses.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 278
+def non_xhr_javascript_response? # :doc:
+  content_type =~ %r(\Atext/javascript) && !request.xhr?
+end
+
+
+ +
+ +
+

+ + normalize_action_path(action_path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 460
+def normalize_action_path(action_path) # :doc:
+  uri = URI.parse(action_path)
+  uri.path.chomp("/")
+end
+
+
+ +
+ +
+

+ + per_form_csrf_token(session, action_path, method) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 404
+def per_form_csrf_token(session, action_path, method) # :doc:
+  csrf_token_hmac(session, [action_path, method.downcase].join("#"))
+end
+
+
+ +
+ +
+

+ + protect_against_forgery?() + +

+ + +
+

Checks if the controller allows forgery protection.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 435
+def protect_against_forgery? # :doc:
+  allow_forgery_protection
+end
+
+
+ +
+ +
+

+ + real_csrf_token(session) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 399
+def real_csrf_token(session) # :doc:
+  session[:_csrf_token] ||= SecureRandom.urlsafe_base64(AUTHENTICITY_TOKEN_LENGTH)
+  Base64.urlsafe_decode64(session[:_csrf_token])
+end
+
+
+ +
+ +
+

+ + request_authenticity_tokens() + +

+ + +
+

Possible authenticity tokens sent in the request.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 302
+def request_authenticity_tokens # :doc:
+  [form_authenticity_param, request.x_csrf_token]
+end
+
+
+ +
+ +
+

+ + unmask_token(masked_token) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 362
+def unmask_token(masked_token) # :doc:
+  # Split the token into the one-time pad and the encrypted
+  # value and decrypt it.
+  one_time_pad = masked_token[0...AUTHENTICITY_TOKEN_LENGTH]
+  encrypted_csrf_token = masked_token[AUTHENTICITY_TOKEN_LENGTH..-1]
+  xor_byte_strings(one_time_pad, encrypted_csrf_token)
+end
+
+
+ +
+ +
+

+ + valid_authenticity_token?(session, encoded_masked_token) + +

+ + +
+

Checks the client's masked token to see if it matches the session token. Essentially the inverse of masked_authenticity_token.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 330
+def valid_authenticity_token?(session, encoded_masked_token) # :doc:
+  if encoded_masked_token.nil? || encoded_masked_token.empty? || !encoded_masked_token.is_a?(String)
+    return false
+  end
+
+  begin
+    masked_token = Base64.urlsafe_decode64(encoded_masked_token)
+  rescue ArgumentError # encoded_masked_token is invalid Base64
+    return false
+  end
+
+  # See if it's actually a masked token or not. In order to
+  # deploy this code, we should be able to handle any unmasked
+  # tokens that we've issued without error.
+
+  if masked_token.length == AUTHENTICITY_TOKEN_LENGTH
+    # This is actually an unmasked token. This is expected if
+    # you have just upgraded to masked tokens, but should stop
+    # happening shortly after installing this gem.
+    compare_with_real_token masked_token, session
+
+  elsif masked_token.length == AUTHENTICITY_TOKEN_LENGTH * 2
+    csrf_token = unmask_token(masked_token)
+
+    compare_with_global_token(csrf_token, session) ||
+      compare_with_real_token(csrf_token, session) ||
+      valid_per_form_csrf_token?(csrf_token, session)
+  else
+    false # Token is malformed.
+  end
+end
+
+
+ +
+ +
+

+ + valid_per_form_csrf_token?(token, session) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 385
+def valid_per_form_csrf_token?(token, session) # :doc:
+  if per_form_csrf_tokens
+    correct_token = per_form_csrf_token(
+      session,
+      normalize_action_path(request.fullpath),
+      request.request_method
+    )
+
+    ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, correct_token)
+  else
+    false
+  end
+end
+
+
+ +
+ +
+

+ + valid_request_origin?() + +

+ + +
+

Checks if the request originated from the same origin by looking at the Origin header.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 450
+def valid_request_origin? # :doc:
+  if forgery_protection_origin_check
+    # We accept blank origin headers because some user agents don't send it.
+    raise InvalidAuthenticityToken, NULL_ORIGIN_MESSAGE if request.origin == "null"
+    request.origin.nil? || request.origin == request.base_url
+  else
+    true
+  end
+end
+
+
+ +
+ +
+

+ + verified_request?() + +

+ + +
+

Returns true or false if a request is verified. Checks:

+
  • +

    Is it a GET or HEAD request? GETs should be safe and idempotent

    +
  • +

    Does the form_authenticity_token match the given token value from the params?

    +
  • +

    Does the X-CSRF-Token header match the form_authenticity_token?

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 289
+def verified_request? # :doc:
+  !protect_against_forgery? || request.get? || request.head? ||
+    (valid_request_origin? && any_authenticity_token_valid?)
+end
+
+
+ +
+ +
+

+ + verify_authenticity_token() + +

+ + +
+

The actual before_action that is used to verify the CSRF token. Don't override this directly. Provide your own forgery protection strategy instead. If you override, you'll disable same-origin <script> verification.

+ +

Lean on the protect_from_forgery declaration to mark which actions are due for same-origin request verification. If protect_from_forgery is enabled on an action, this before_action flags its after_action to verify that JavaScript responses are for XHR requests, ensuring they follow the browser's same-origin policy.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 227
+def verify_authenticity_token # :doc:
+  mark_for_same_origin_verification!
+
+  if !verified_request?
+    if logger && log_warning_on_csrf_failure
+      if valid_request_origin?
+        logger.warn "Can't verify CSRF token authenticity."
+      else
+        logger.warn "HTTP Origin header (#{request.origin}) didn't match request.base_url (#{request.base_url})"
+      end
+    end
+    handle_unverified_request
+  end
+end
+
+
+ +
+ +
+

+ + verify_same_origin_request() + +

+ + +
+

If verify_authenticity_token was run (indicating that we have forgery protection enabled for this request) then also verify that we aren't serving an unauthorized cross-origin response.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 257
+def verify_same_origin_request # :doc:
+  if marked_for_same_origin_verification? && non_xhr_javascript_response?
+    if logger && log_warning_on_csrf_failure
+      logger.warn CROSS_ORIGIN_JAVASCRIPT_WARNING
+    end
+    raise ActionController::InvalidCrossOriginRequest, CROSS_ORIGIN_JAVASCRIPT_WARNING
+  end
+end
+
+
+ +
+ +
+

+ + xor_byte_strings(s1, s2) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 423
+def xor_byte_strings(s1, s2) # :doc:
+  s2_bytes = s2.bytes
+  s1.each_byte.with_index { |c1, i| s2_bytes[i] ^= c1 }
+  s2_bytes.pack("C*")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/RequestForgeryProtection/ClassMethods.html b/src/5.2/classes/ActionController/RequestForgeryProtection/ClassMethods.html new file mode 100644 index 0000000000..83878e444b --- /dev/null +++ b/src/5.2/classes/ActionController/RequestForgeryProtection/ClassMethods.html @@ -0,0 +1,186 @@ +--- +title: ActionController::RequestForgeryProtection::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + protect_from_forgery(options = {}) + +

+ + +
+

Turn on request forgery protection. Bear in mind that GET and HEAD requests are not checked.

+ +
class ApplicationController < ActionController::Base
+  protect_from_forgery
+end
+
+class FooController < ApplicationController
+  protect_from_forgery except: :index
+end
+
+ +

You can disable forgery protection on controller by skipping the verification before_action:

+ +
skip_before_action :verify_authenticity_token
+
+ +

Valid Options:

+
  • +

    :only/:except - Only apply forgery protection to a subset of actions. For example only: [ :create, :create_all ].

    +
  • +

    :if/:unless - Turn off the forgery protection entirely depending on the passed Proc or method reference.

    +
  • +

    :prepend - By default, the verification of the authentication token will be added at the position of the protect_from_forgery call in your application. This means any callbacks added before are run first. This is useful when you want your forgery protection to depend on other callbacks, like authentication methods (Oauth vs Cookie auth).

    + +

    If you need to add verification to the beginning of the callback chain, use prepend: true.

    +
  • +

    :with - Set the method to handle unverified request.

    +
+ +

Valid unverified request handling methods are:

+
  • +

    :exception - Raises ActionController::InvalidAuthenticityToken exception.

    +
  • +

    :reset_session - Resets the session.

    +
  • +

    :null_session - Provides an empty session during request but doesn't reset it completely. Used as default if :with option is not specified.

    +
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 129
+def protect_from_forgery(options = {})
+  options = options.reverse_merge(prepend: false)
+
+  self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session)
+  self.request_forgery_protection_token ||= :authenticity_token
+  before_action :verify_authenticity_token, options
+  append_after_action :verify_same_origin_request
+end
+
+
+ +
+ +
+

+ + skip_forgery_protection(options = {}) + +

+ + +
+

Turn off request forgery protection. This is a wrapper for:

+ +
skip_before_action :verify_authenticity_token
+
+ +

See skip_before_action for allowed options.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 143
+def skip_forgery_protection(options = {})
+  skip_before_action :verify_authenticity_token, options
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods.html b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods.html new file mode 100644 index 0000000000..850a865c19 --- /dev/null +++ b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods.html @@ -0,0 +1,71 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods +layout: default +--- +
+ + +
diff --git a/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/Exception.html b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/Exception.html new file mode 100644 index 0000000000..0c45897a38 --- /dev/null +++ b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/Exception.html @@ -0,0 +1,149 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::Exception +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(controller) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 206
+def initialize(controller)
+  @controller = controller
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + handle_unverified_request() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 210
+def handle_unverified_request
+  raise ActionController::InvalidAuthenticityToken
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html new file mode 100644 index 0000000000..abeb285bc4 --- /dev/null +++ b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html @@ -0,0 +1,153 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::NullSession +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(controller) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 158
+def initialize(controller)
+  @controller = controller
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + handle_unverified_request() + +

+ + +
+

This is the method that defines the application behavior when a request is found to be unverified.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 163
+def handle_unverified_request
+  request = @controller.request
+  request.session = NullSessionHash.new(request)
+  request.flash = nil
+  request.session_options = { skip: true }
+  request.cookie_jar = NullCookieJar.build(request, {})
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/ResetSession.html b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/ResetSession.html new file mode 100644 index 0000000000..f820525e81 --- /dev/null +++ b/src/5.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/ResetSession.html @@ -0,0 +1,149 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::ResetSession +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(controller) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 196
+def initialize(controller)
+  @controller = controller
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + handle_unverified_request() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 200
+def handle_unverified_request
+  @controller.reset_session
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Rescue.html b/src/5.2/classes/ActionController/Rescue.html new file mode 100644 index 0000000000..9e8ddd889d --- /dev/null +++ b/src/5.2/classes/ActionController/Rescue.html @@ -0,0 +1,121 @@ +--- +title: ActionController::Rescue +layout: default +--- +
+ +
+
+ +
+ +

This module is responsible for providing rescue_from helpers to controllers and configuring when detailed exceptions must be shown.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + show_detailed_exceptions?() + +

+ + +
+

Override this method if you want to customize when detailed exceptions must be shown. This method is only called when consider_all_requests_local is false. By default, it returns false, but someone may set it to request.local? so local requests in production still show the detailed exception pages.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/rescue.rb, line 16
+def show_detailed_exceptions?
+  false
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Streaming.html b/src/5.2/classes/ActionController/Streaming.html new file mode 100644 index 0000000000..2c2a6bd1d2 --- /dev/null +++ b/src/5.2/classes/ActionController/Streaming.html @@ -0,0 +1,212 @@ +--- +title: ActionController::Streaming +layout: default +--- +
+ +
+
+ +
+ +

Allows views to be streamed back to the client as they are rendered.

+ +

By default, Rails renders views by first rendering the template and then the layout. The response is sent to the client after the whole template is rendered, all queries are made, and the layout is processed.

+ +

Streaming inverts the rendering flow by rendering the layout first and streaming each part of the layout as they are processed. This allows the header of the HTML (which is usually in the layout) to be streamed back to client very quickly, allowing JavaScripts and stylesheets to be loaded earlier than usual.

+ +

This approach was introduced in Rails 3.1 and is still improving. Several Rack middlewares may not work and you need to be careful when streaming. Those points are going to be addressed soon.

+ +

In order to use streaming, you will need to use a Ruby version that supports fibers (fibers are supported since version 1.9.2 of the main Ruby implementation).

+ +

Streaming can be added to a given template easily, all you need to do is to pass the :stream option.

+ +
class PostsController
+  def index
+    @posts = Post.all
+    render stream: true
+  end
+end
+
+ +

When to use streaming

+ +

Streaming may be considered to be overkill for lightweight actions like new or edit. The real benefit of streaming is on expensive actions that, for example, do a lot of queries on the database.

+ +

In such actions, you want to delay queries execution as much as you can. For example, imagine the following dashboard action:

+ +
def dashboard
+  @posts = Post.all
+  @pages = Page.all
+  @articles = Article.all
+end
+
+ +

Most of the queries here are happening in the controller. In order to benefit from streaming you would want to rewrite it as:

+ +
def dashboard
+  # Allow lazy execution of the queries
+  @posts = Post.all
+  @pages = Page.all
+  @articles = Article.all
+  render stream: true
+end
+
+ +

Notice that :stream only works with templates. Rendering :json or :xml with :stream won't work.

+ +

Communication between layout and template

+ +

When streaming, rendering happens top-down instead of inside-out. Rails starts with the layout, and the template is rendered later, when its yield is reached.

+ +

This means that, if your application currently relies on instance variables set in the template to be used in the layout, they won't work once you move to streaming. The proper way to communicate between layout and template, regardless of whether you use streaming or not, is by using content_for, provide and yield.

+ +

Take a simple example where the layout expects the template to tell which title to use:

+ +
<html>
+  <head><title><%= yield :title %></title></head>
+  <body><%= yield %></body>
+</html>
+
+ +

You would use content_for in your template to specify the title:

+ +
<%= content_for :title, "Main" %>
+Hello
+
+ +

And the final result would be:

+ +
<html>
+  <head><title>Main</title></head>
+  <body>Hello</body>
+</html>
+
+ +

However, if content_for is called several times, the final result would have all calls concatenated. For instance, if we have the following template:

+ +
<%= content_for :title, "Main" %>
+Hello
+<%= content_for :title, " page" %>
+
+ +

The final result would be:

+ +
<html>
+  <head><title>Main page</title></head>
+  <body>Hello</body>
+</html>
+
+ +

This means that, if you have yield :title in your layout and you want to use streaming, you would have to render the whole template (and eventually trigger all queries) before streaming the title and all assets, which kills the purpose of streaming. For this purpose, you can use a helper called provide that does the same as content_for but tells the layout to stop searching for other entries and continue rendering.

+ +

For instance, the template above using provide would be:

+ +
<%= provide :title, "Main" %>
+Hello
+<%= content_for :title, " page" %>
+
+ +

Giving:

+ +
<html>
+  <head><title>Main</title></head>
+  <body>Hello</body>
+</html>
+
+ +

That said, when streaming, you need to properly check your templates and choose when to use provide and content_for.

+ +

Headers, cookies, session and flash

+ +

When streaming, the HTTP headers are sent to the client right before it renders the first line. This means that, modifying headers, cookies, session or flash after the template starts rendering will not propagate to the client.

+ +

Middlewares

+ +

Middlewares that need to manipulate the body won't work with streaming. You should disable those middlewares whenever streaming in development or production. For instance, Rack::Bug won't work when streaming as it needs to inject contents in the HTML body.

+ +

Also Rack::Cache won't work with streaming as it does not support streaming bodies yet. Whenever streaming Cache-Control is automatically set to “no-cache”.

+ +

Errors

+ +

When it comes to streaming, exceptions get a bit more complicated. This happens because part of the template was already rendered and streamed to the client, making it impossible to render a whole exception page.

+ +

Currently, when an exception happens in development or production, Rails will automatically stream to the client:

+ +
"><script>window.location = "/500.html"</script></html>
+
+ +

The first two characters (“>) are required in case the exception happens while rendering attributes for a given tag. You can check the real cause for the exception in your logger.

+ +

Web server support

+ +

Not all web servers support streaming out-of-the-box. You need to check the instructions for each of them.

+ +

Unicorn

+ +

Unicorn supports streaming but it needs to be configured. For this, you need to create a config file as follow:

+ +
# unicorn.config.rb
+listen 3000, tcp_nopush: false
+
+ +

And use it on initialization:

+ +
unicorn_rails --config-file unicorn.config.rb
+
+ +

You may also want to configure other parameters like :tcp_nodelay. Please check its documentation for more information: bogomips.org/unicorn/Unicorn/Configurator.html#method-i-listen

+ +

If you are using Unicorn with NGINX, you may need to tweak NGINX. Streaming should work out of the box on Rainbows.

+ +

Passenger

+ +

To be described.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/StrongParameters.html b/src/5.2/classes/ActionController/StrongParameters.html new file mode 100644 index 0000000000..416c15cf47 --- /dev/null +++ b/src/5.2/classes/ActionController/StrongParameters.html @@ -0,0 +1,221 @@ +--- +title: ActionController::StrongParameters +layout: default +--- +
+ +
+
+ +
+ +

Strong Parameters

+ +

It provides an interface for protecting attributes from end-user assignment. This makes Action Controller parameters forbidden to be used in Active Model mass assignment until they have been whitelisted.

+ +

In addition, parameters can be marked as required and flow through a predefined raise/rescue flow to end up as a 400 Bad Request with no effort.

+ +
class PeopleController < ActionController::Base
+  # Using "Person.create(params[:person])" would raise an
+  # ActiveModel::ForbiddenAttributesError exception because it'd
+  # be using mass assignment without an explicit permit step.
+  # This is the recommended form:
+  def create
+    Person.create(person_params)
+  end
+
+  # This will pass with flying colors as long as there's a person key in the
+  # parameters, otherwise it'll raise an ActionController::ParameterMissing
+  # exception, which will get caught by ActionController::Base and turned
+  # into a 400 Bad Request reply.
+  def update
+    redirect_to current_account.people.find(params[:id]).tap { |person|
+      person.update!(person_params)
+    }
+  end
+
+  private
+    # Using a private method to encapsulate the permissible parameters is
+    # a good pattern since you'll be able to reuse the same permit
+    # list between create and update. Also, you can specialize this method
+    # with per-user checking of permissible attributes.
+    def person_params
+      params.require(:person).permit(:name, :age)
+    end
+end
+
+ +

In order to use accepts_nested_attributes_for with Strong Parameters, you will need to specify which nested attributes should be whitelisted. You might want to allow :id and :_destroy, see ActiveRecord::NestedAttributes for more information.

+ +
class Person
+  has_many :pets
+  accepts_nested_attributes_for :pets
+end
+
+class PeopleController < ActionController::Base
+  def create
+    Person.create(person_params)
+  end
+
+  ...
+
+  private
+
+    def person_params
+      # It's mandatory to specify the nested attributes that should be whitelisted.
+      # If you use `permit` with just the key that points to the nested attributes hash,
+      # it will return an empty hash.
+      params.require(:person).permit(:name, :age, pets_attributes: [ :id, :name, :category ])
+    end
+end
+
+ +

See ActionController::Parameters.require and ActionController::Parameters.permit for more information.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + params() + +

+ + +
+

Returns a new ActionController::Parameters object that has been instantiated with the request.parameters.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1077
+def params
+  @_params ||= Parameters.new(request.parameters)
+end
+
+
+ +
+ +
+

+ + params=(value) + +

+ + +
+

Assigns the given value to the params hash. If value is a Hash, this will create an ActionController::Parameters object that has been instantiated with the given value hash.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1084
+def params=(value)
+  @_params = value.is_a?(Hash) ? Parameters.new(value) : value
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/TemplateAssertions.html b/src/5.2/classes/ActionController/TemplateAssertions.html new file mode 100644 index 0000000000..4bd84719c4 --- /dev/null +++ b/src/5.2/classes/ActionController/TemplateAssertions.html @@ -0,0 +1,103 @@ +--- +title: ActionController::TemplateAssertions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_template(options = {}, message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/template_assertions.rb, line 5
+def assert_template(options = {}, message = nil)
+  raise NoMethodError,
+    "assert_template has been extracted to a gem. To continue using it,
+    add `gem 'rails-controller-testing'` to your Gemfile."
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/TestCase.html b/src/5.2/classes/ActionController/TestCase.html new file mode 100644 index 0000000000..97c0fd8b0b --- /dev/null +++ b/src/5.2/classes/ActionController/TestCase.html @@ -0,0 +1,199 @@ +--- +title: ActionController::TestCase +layout: default +--- +
+ +
+
+ +
+ +

Superclass for ActionController functional tests. Functional tests allow you to test a single controller action per test method.

+ +

Use integration style controller tests over functional style controller tests.

+ +

Rails discourages the use of functional tests in favor of integration tests (use ActionDispatch::IntegrationTest).

+ +

New Rails applications no longer generate functional style controller tests and they should only be used for backward compatibility. Integration style controller tests perform actual requests, whereas functional style controller tests merely simulate a request. Besides, integration tests are as fast as functional tests and provide lot of helpers such as as, parsed_body for effective testing of controller actions including even API endpoints.

+ +

Basic example

+ +

Functional tests are written as follows:

+
  1. +

    First, one uses the get, post, patch, put, delete or head method to simulate an HTTP request.

    +
  2. +

    Then, one asserts whether the current state is as expected. “State” can be anything: the controller's HTTP response, the database contents, etc.

    +
+ +

For example:

+ +
class BooksControllerTest < ActionController::TestCase
+  def test_create
+    # Simulate a POST response with the given HTTP parameters.
+    post(:create, params: { book: { title: "Love Hina" }})
+
+    # Asserts that the controller tried to redirect us to
+    # the created book's URI.
+    assert_response :found
+
+    # Asserts that the controller really put the book in the database.
+    assert_not_nil Book.find_by(title: "Love Hina")
+  end
+end
+
+ +

You can also send a real document in the simulated HTTP request.

+ +
def test_create
+  json = {book: { title: "Love Hina" }}.to_json
+  post :create, body: json
+end
+
+ +

Special instance variables

+ +

ActionController::TestCase will also automatically provide the following instance variables for use in the tests:

+
@controller +
+

The controller instance that will be tested.

+
@request +
+

An ActionController::TestRequest, representing the current HTTP request. You can modify this object before sending the HTTP request. For example, you might want to set some session properties before sending a GET request.

+
@response +
+

An ActionDispatch::TestResponse object, representing the response of the last HTTP response. In the above example, @response becomes valid after calling post. If the various assert methods are not sufficient, then you may use this object to inspect the HTTP response in detail.

+
+ +

(Earlier versions of Rails required each functional test to subclass Test::Unit::TestCase and define @controller, @request, @response in setup.)

+ +

Controller is automatically inferred

+ +

ActionController::TestCase will automatically infer the controller under test from the test class name. If the controller cannot be inferred from the test class name, you can explicitly set it with tests.

+ +
class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
+  tests WidgetController
+end
+
+ +

Testing controller internals

+ +

In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions can be used against. These collections are:

+
  • +

    session: Objects being saved in the session.

    +
  • +

    flash: The flash objects currently in the session.

    +
  • +

    cookies: Cookies being sent to the user on this request.

    +
+ +

These collections can be used just like any other hash:

+ +
assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
+assert flash.empty? # makes sure that there's nothing in the flash
+
+ +

On top of the collections, you have the complete URL that a given action redirected to available in redirect_to_url.

+ +

For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another action call which can then be asserted against.

+ +

Manipulating session and cookie variables

+ +

Sometimes you need to set up the session and cookie variables for a test. To do this just assign a value to the session or cookie collection:

+ +
session[:key] = "value"
+cookies[:key] = "value"
+
+ +

To clear the cookies for a test just clear the cookie collection:

+ +
cookies.clear
+
+ +

Testing named routes

+ +

If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case.

+ +
assert_redirected_to page_url(title: 'foo')
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/TestCase/Behavior.html b/src/5.2/classes/ActionController/TestCase/Behavior.html new file mode 100644 index 0000000000..ef56a538d8 --- /dev/null +++ b/src/5.2/classes/ActionController/TestCase/Behavior.html @@ -0,0 +1,772 @@ +--- +title: ActionController::TestCase::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + request
+ [R] + response
+ + + + + +

Instance Public methods

+ +
+

+ + build_response(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 588
+def build_response(klass)
+  klass.create
+end
+
+
+ +
+ +
+

+ + controller_class_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 548
+def controller_class_name
+  @controller.class.anonymous? ? "anonymous" : @controller.class.controller_path
+end
+
+
+ +
+ +
+

+ + delete(action, **args) + +

+ + +
+

Simulate a DELETE request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 420
+def delete(action, **args)
+  process(action, method: "DELETE", **args)
+end
+
+
+ +
+ +
+

+ + generated_path(generated_extras) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 552
+def generated_path(generated_extras)
+  generated_extras[0]
+end
+
+
+ +
+ +
+

+ + get(action, **args) + +

+ + +
+

Simulate a GET request with the given parameters.

+
  • +

    action: The controller action to call.

    +
  • +

    params: The hash with HTTP parameters that you want to pass. This may be nil.

    +
  • +

    body: The request body with a string that is appropriately encoded (application/x-www-form-urlencoded or multipart/form-data).

    +
  • +

    session: A hash of parameters to store in the session. This may be nil.

    +
  • +

    flash: A hash of parameters to store in the flash. This may be nil.

    +
+ +

You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with post, patch, put, delete, and head. Example sending parameters, session and setting a flash message:

+ +
get :show,
+  params: { id: 7 },
+  session: { user_id: 1 },
+  flash: { notice: 'This is flash message' }
+
+ +

Note that the request method is not verified. The different methods are available to make the tests more expressive.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 394
+def get(action, **args)
+  res = process(action, method: "GET", **args)
+  cookies.update res.cookies
+  res
+end
+
+
+ +
+ +
+

+ + head(action, **args) + +

+ + +
+

Simulate a HEAD request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 426
+def head(action, **args)
+  process(action, method: "HEAD", **args)
+end
+
+
+ +
+ +
+

+ + patch(action, **args) + +

+ + +
+

Simulate a PATCH request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 408
+def patch(action, **args)
+  process(action, method: "PATCH", **args)
+end
+
+
+ +
+ +
+

+ + post(action, **args) + +

+ + +
+

Simulate a POST request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 402
+def post(action, **args)
+  process(action, method: "POST", **args)
+end
+
+
+ +
+ +
+

+ + process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil) + +

+ + +
+

Simulate an HTTP request to action by specifying request method, parameters and set/volley the response.

+
  • +

    action: The controller action to call.

    +
  • +

    method: Request method used to send the HTTP request. Possible values are GET, POST, PATCH, PUT, DELETE, HEAD. Defaults to GET. Can be a symbol.

    +
  • +

    params: The hash with HTTP parameters that you want to pass. This may be nil.

    +
  • +

    body: The request body with a string that is appropriately encoded (application/x-www-form-urlencoded or multipart/form-data).

    +
  • +

    session: A hash of parameters to store in the session. This may be nil.

    +
  • +

    flash: A hash of parameters to store in the flash. This may be nil.

    +
  • +

    format: Request format. Defaults to nil. Can be string or symbol.

    +
  • +

    as: Content type. Defaults to nil. Must be a symbol that corresponds to a mime type.

    +
+ +

Example calling create action and sending two params:

+ +
process :create,
+  method: 'POST',
+  params: {
+    user: { name: 'Gaurish Sharma', email: 'user@example.com' }
+  },
+  session: { user_id: 1 },
+  flash: { notice: 'This is flash message' }
+
+ +

To simulate GET, POST, PATCH, PUT, DELETE and HEAD requests prefer using get, post, patch, put, delete and head methods respectively which will make tests more expressive.

+ +

Note that the request method is not verified.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 460
+def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil)
+  check_required_ivars
+
+  action = action.to_s.dup
+  http_method = method.to_s.upcase
+
+  @html_document = nil
+
+  cookies.update(@request.cookies)
+  cookies.update_cookies_from_jar
+  @request.set_header "HTTP_COOKIE", cookies.to_header
+  @request.delete_header "action_dispatch.cookies"
+
+  @request          = TestRequest.new scrub_env!(@request.env), @request.session, @controller.class
+  @response         = build_response @response_klass
+  @response.request = @request
+  @controller.recycle!
+
+  if body
+    @request.set_header "RAW_POST_DATA", body
+  end
+
+  @request.set_header "REQUEST_METHOD", http_method
+
+  if as
+    @request.content_type = Mime[as].to_s
+    format ||= as
+  end
+
+  parameters = (params || {}).symbolize_keys
+
+  if format
+    parameters[:format] = format
+  end
+
+  generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action))
+  generated_path = generated_path(generated_extras)
+  query_string_keys = query_parameter_names(generated_extras)
+
+  @request.assign_parameters(@routes, controller_class_name, action, parameters, generated_path, query_string_keys)
+
+  @request.session.update(session) if session
+  @request.flash.update(flash || {})
+
+  if xhr
+    @request.set_header "HTTP_X_REQUESTED_WITH", "XMLHttpRequest"
+    @request.fetch_header("HTTP_ACCEPT") do |k|
+      @request.set_header k, [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ")
+    end
+  end
+
+  @request.fetch_header("SCRIPT_NAME") do |k|
+    @request.set_header k, @controller.config.relative_url_root
+  end
+
+  begin
+    @controller.recycle!
+    @controller.dispatch(action, @request, @response)
+  ensure
+    @request = @controller.request
+    @response = @controller.response
+
+    if @request.have_cookie_jar?
+      unless @request.cookie_jar.committed?
+        @request.cookie_jar.write(@response)
+        cookies.update(@request.cookie_jar.instance_variable_get(:@cookies))
+      end
+    end
+    @response.prepare!
+
+    if flash_value = @request.flash.to_session_value
+      @request.session["flash"] = flash_value
+    else
+      @request.session.delete("flash")
+    end
+
+    if xhr
+      @request.delete_header "HTTP_X_REQUESTED_WITH"
+      @request.delete_header "HTTP_ACCEPT"
+    end
+    @request.query_string = ""
+
+    @response.sent!
+  end
+
+  @response
+end
+
+
+ +
+ +
+

+ + put(action, **args) + +

+ + +
+

Simulate a PUT request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 414
+def put(action, **args)
+  process(action, method: "PUT", **args)
+end
+
+
+ +
+ +
+

+ + query_parameter_names(generated_extras) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 556
+def query_parameter_names(generated_extras)
+  generated_extras[1] + [:controller, :action]
+end
+
+
+ +
+ +
+

+ + setup_controller_request_and_response() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 560
+def setup_controller_request_and_response
+  @controller = nil unless defined? @controller
+
+  @response_klass = ActionDispatch::TestResponse
+
+  if klass = self.class.controller_class
+    if klass < ActionController::Live
+      @response_klass = LiveTestResponse
+    end
+    unless @controller
+      begin
+        @controller = klass.new
+      rescue
+        warn "could not construct controller #{klass}" if $VERBOSE
+      end
+    end
+  end
+
+  @request          = TestRequest.create(@controller.class)
+  @response         = build_response @response_klass
+  @response.request = @request
+
+  if @controller
+    @controller.request = @request
+    @controller.params = {}
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/TestCase/Behavior/ClassMethods.html b/src/5.2/classes/ActionController/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..44003e8311 --- /dev/null +++ b/src/5.2/classes/ActionController/TestCase/Behavior/ClassMethods.html @@ -0,0 +1,236 @@ +--- +title: ActionController::TestCase::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + controller_class() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 359
+def controller_class
+  if current_controller_class = _controller_class
+    current_controller_class
+  else
+    self.controller_class = determine_default_controller_class(name)
+  end
+end
+
+
+ +
+ +
+

+ + controller_class=(new_class) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 355
+def controller_class=(new_class)
+  self._controller_class = new_class
+end
+
+
+ +
+ +
+

+ + determine_default_controller_class(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 367
+def determine_default_controller_class(name)
+  determine_constant_from_test_name(name) do |constant|
+    Class === constant && constant < ActionController::Metal
+  end
+end
+
+
+ +
+ +
+

+ + tests(controller_class) + +

+ + +
+

Sets the controller class name. Useful if the name can't be inferred from test class. Normalizes controller_class before using.

+ +
tests WidgetController
+tests :widget
+tests 'widget'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/test_case.rb, line 344
+def tests(controller_class)
+  case controller_class
+  when String, Symbol
+    self.controller_class = "#{controller_class.to_s.camelize}Controller".constantize
+  when Class
+    self.controller_class = controller_class
+  else
+    raise ArgumentError, "controller class must be a String, Symbol, or Class"
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/Testing.html b/src/5.2/classes/ActionController/Testing.html new file mode 100644 index 0000000000..1ce5186c00 --- /dev/null +++ b/src/5.2/classes/ActionController/Testing.html @@ -0,0 +1,54 @@ +--- +title: ActionController::Testing +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/UnfilteredParameters.html b/src/5.2/classes/ActionController/UnfilteredParameters.html new file mode 100644 index 0000000000..246219c0de --- /dev/null +++ b/src/5.2/classes/ActionController/UnfilteredParameters.html @@ -0,0 +1,71 @@ +--- +title: ActionController::UnfilteredParameters +layout: default +--- +
+ +
+
+ +
+ +

Raised when a Parameters instance is not marked as permitted and an operation to transform it to hash is called.

+ +
params = ActionController::Parameters.new(a: "123", b: "456")
+params.to_h
+# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/UnpermittedParameters.html b/src/5.2/classes/ActionController/UnpermittedParameters.html new file mode 100644 index 0000000000..4b6b634e59 --- /dev/null +++ b/src/5.2/classes/ActionController/UnpermittedParameters.html @@ -0,0 +1,71 @@ +--- +title: ActionController::UnpermittedParameters +layout: default +--- +
+ +
+
+ +
+ +

Raised when a supplied parameter is not expected and ActionController::Parameters.action_on_unpermitted_parameters is set to :raise.

+ +
params = ActionController::Parameters.new(a: "123", b: "456")
+params.permit(:c)
+# => ActionController::UnpermittedParameters: found unpermitted parameters: :a, :b
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionController/UrlFor.html b/src/5.2/classes/ActionController/UrlFor.html new file mode 100644 index 0000000000..4031ea5f35 --- /dev/null +++ b/src/5.2/classes/ActionController/UrlFor.html @@ -0,0 +1,160 @@ +--- +title: ActionController::UrlFor +layout: default +--- +
+ +
+
+ +
+ +

Includes url_for into the host class. The class has to provide a RouteSet by implementing the _routes method. Otherwise, an exception will be raised.

+ +

In addition to AbstractController::UrlFor, this module accesses the HTTP layer to define URL options like the host. In order to do so, this module requires the host class to implement env which needs to be Rack-compatible and request which is either an instance of ActionDispatch::Request or an object that responds to the host, optional_port, protocol and symbolized_path_parameter methods.

+ +
class RootUrl
+  include ActionController::UrlFor
+  include Rails.application.routes.url_helpers
+
+  delegate :env, :request, to: :controller
+
+  def initialize(controller)
+    @controller = controller
+    @url        = root_path # named route from the application.
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_controller/metal/url_for.rb, line 30
+def url_options
+  @_url_options ||= {
+    host: request.host,
+    port: request.optional_port,
+    protocol: request.protocol,
+    _recall: request.path_parameters
+  }.merge!(super).freeze
+
+  if (same_origin = _routes.equal?(request.routes)) ||
+     (script_name = request.engine_script_name(_routes)) ||
+     (original_script_name = request.original_script_name)
+
+    options = @_url_options.dup
+    if original_script_name
+      options[:original_script_name] = original_script_name
+    else
+      if same_origin
+        options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup
+      else
+        options[:script_name] = script_name
+      end
+    end
+    options.freeze
+  else
+    @_url_options
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch.html b/src/5.2/classes/ActionDispatch.html new file mode 100644 index 0000000000..5d9098ce49 --- /dev/null +++ b/src/5.2/classes/ActionDispatch.html @@ -0,0 +1,318 @@ +--- +title: ActionDispatch +layout: default +--- +
+ + +
diff --git a/src/5.2/classes/ActionDispatch/AssertionResponse.html b/src/5.2/classes/ActionDispatch/AssertionResponse.html new file mode 100644 index 0000000000..31371a6b5c --- /dev/null +++ b/src/5.2/classes/ActionDispatch/AssertionResponse.html @@ -0,0 +1,186 @@ +--- +title: ActionDispatch::AssertionResponse +layout: default +--- +
+ +
+
+ +
+ +

This is a class that abstracts away an asserted response. It purposely does not inherit from Response because it doesn't need it. That means it does not have headers or a body.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + code
+ [R] + name
+ + + + +

Class Public methods

+ +
+

+ + new(code_or_name) + +

+ + +
+

Accepts a specific response status code as an Integer (404) or String ('404') or a response status range as a Symbol pseudo-code (:success, indicating any 200-299 status code).

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertion_response.rb, line 20
+def initialize(code_or_name)
+  if code_or_name.is_a?(Symbol)
+    @name = code_or_name
+    @code = code_from_name(code_or_name)
+  else
+    @name = name_from_code(code_or_name)
+    @code = code_or_name
+  end
+
+  raise ArgumentError, "Invalid response name: #{name}" if @code.nil?
+  raise ArgumentError, "Invalid response code: #{code}" if @name.nil?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + code_and_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertion_response.rb, line 33
+def code_and_name
+  "#{code}: #{name}"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Assertions.html b/src/5.2/classes/ActionDispatch/Assertions.html new file mode 100644 index 0000000000..a57cbe22bf --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Assertions.html @@ -0,0 +1,152 @@ +--- +title: ActionDispatch::Assertions +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + html_document() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions.rb, line 16
+def html_document
+  @html_document ||= if @response.content_type.to_s.end_with?("xml")
+    Nokogiri::XML::Document.parse(@response.body)
+  else
+    Nokogiri::HTML::Document.parse(@response.body)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Assertions/ResponseAssertions.html b/src/5.2/classes/ActionDispatch/Assertions/ResponseAssertions.html new file mode 100644 index 0000000000..e9a91f7227 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Assertions/ResponseAssertions.html @@ -0,0 +1,190 @@ +--- +title: ActionDispatch::Assertions::ResponseAssertions +layout: default +--- +
+ +
+
+ +
+ +

A small suite of assertions that test responses from Rails applications.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_redirected_to(options = {}, message = nil) + +

+ + +
+

Asserts that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that assert_redirected_to(controller: "weblog") will also match the redirection of redirect_to(controller: "weblog", action: "show") and so on.

+ +
# Asserts that the redirection was to the "index" action on the WeblogController
+assert_redirected_to controller: "weblog", action: "index"
+
+# Asserts that the redirection was to the named route login_url
+assert_redirected_to login_url
+
+# Asserts that the redirection was to the URL for @customer
+assert_redirected_to @customer
+
+# Asserts that the redirection matches the regular expression
+assert_redirected_to %r(\Ahttp://example.org)
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions/response.rb, line 55
+def assert_redirected_to(options = {}, message = nil)
+  assert_response(:redirect, message)
+  return true if options === @response.location
+
+  redirect_is       = normalize_argument_to_redirection(@response.location)
+  redirect_expected = normalize_argument_to_redirection(options)
+
+  message ||= "Expected response to be a redirect to <#{redirect_expected}> but was a redirect to <#{redirect_is}>"
+  assert_operator redirect_expected, :===, redirect_is, message
+end
+
+
+ +
+ +
+

+ + assert_response(type, message = nil) + +

+ + +
+

Asserts that the response is one of the following types:

+
  • +

    :success - Status code was in the 200-299 range

    +
  • +

    :redirect - Status code was in the 300-399 range

    +
  • +

    :missing - Status code was 404

    +
  • +

    :error - Status code was in the 500-599 range

    +
+ +

You can also pass an explicit status number like assert_response(501) or its symbolic equivalent assert_response(:not_implemented). See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.

+ +
# Asserts that the response was a redirection
+assert_response :redirect
+
+# Asserts that the response code was status code 401 (unauthorized)
+assert_response 401
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions/response.rb, line 30
+def assert_response(type, message = nil)
+  message ||= generate_response_message(type)
+
+  if RESPONSE_PREDICATES.keys.include?(type)
+    assert @response.send(RESPONSE_PREDICATES[type]), message
+  else
+    assert_equal AssertionResponse.new(type).code, @response.response_code, message
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Assertions/RoutingAssertions.html b/src/5.2/classes/ActionDispatch/Assertions/RoutingAssertions.html new file mode 100644 index 0000000000..33e1d1fba7 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Assertions/RoutingAssertions.html @@ -0,0 +1,399 @@ +--- +title: ActionDispatch::Assertions::RoutingAssertions +layout: default +--- +
+ +
+
+ +
+ +

Suite of assertions to test routes generated by Rails and the handling of requests made to them.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil) + +

+ + +
+

Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.

+ +

The defaults parameter is unused.

+ +
# Asserts that the default action is generated for a route with no action
+assert_generates "/items", controller: "items", action: "index"
+
+# Tests that the list action is properly routed
+assert_generates "/items/list", controller: "items", action: "list"
+
+# Tests the generation of a route with a parameter
+assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" }
+
+# Asserts that the generated route gives us our custom route
+assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 80
+def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil)
+  if expected_path =~ %r{://}
+    fail_on(URI::InvalidURIError, message) do
+      uri = URI.parse(expected_path)
+      expected_path = uri.path.to_s.empty? ? "/" : uri.path
+    end
+  else
+    expected_path = "/#{expected_path}" unless expected_path.first == "/"
+  end
+  # Load routes.rb if it hasn't been loaded.
+
+  options = options.clone
+  generated_path, query_string_keys = @routes.generate_extras(options, defaults)
+  found_extras = options.reject { |k, _| ! query_string_keys.include? k }
+
+  msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras)
+  assert_equal(extras, found_extras, msg)
+
+  msg = message || sprintf("The generated path <%s> did not match <%s>", generated_path,
+      expected_path)
+  assert_equal(expected_path, generated_path, msg)
+end
+
+
+ +
+ +
+

+ + assert_recognizes(expected_options, path, extras = {}, msg = nil) + +

+ + +
+

Asserts that the routing of the given path was handled correctly and that the parsed options (given in the expected_options hash) match path. Basically, it asserts that Rails recognizes the route given by expected_options.

+ +

Pass a hash in the second argument (path) to specify the request method. This is useful for routes requiring a specific HTTP method. The hash should contain a :path with the incoming request path and a :method containing the required HTTP verb.

+ +
# Asserts that POSTing to /items will call the create action on ItemsController
+assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
+
+ +

You can also pass in extras with a hash containing URL parameters that would normally be in the query string. This can be used to assert that values in the query string will end up in the params hash correctly. To test query strings you must use the extras argument because appending the query string on the path directly will not work. For example:

+ +
# Asserts that a path of '/items/list/1?view=print' returns the correct options
+assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
+
+ +

The message parameter allows you to pass in an error message that is displayed upon failure.

+ +
# Check the default route (i.e., the index action)
+assert_recognizes({controller: 'items', action: 'index'}, 'items')
+
+# Test a specific action
+assert_recognizes({controller: 'items', action: 'list'}, 'items/list')
+
+# Test an action with a parameter
+assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1')
+
+# Test a custom route
+assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1')
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 42
+def assert_recognizes(expected_options, path, extras = {}, msg = nil)
+  if path.is_a?(Hash) && path[:method].to_s == "all"
+    [:get, :post, :put, :delete].each do |method|
+      assert_recognizes(expected_options, path.merge(method: method), extras, msg)
+    end
+  else
+    request = recognized_request_for(path, extras, msg)
+
+    expected_options = expected_options.clone
+
+    expected_options.stringify_keys!
+
+    msg = message(msg, "") {
+      sprintf("The recognized options <%s> did not match <%s>, difference:",
+              request.path_parameters, expected_options)
+    }
+
+    assert_equal(expected_options, request.path_parameters, msg)
+  end
+end
+
+
+ +
+ +
+

+ + assert_routing(path, options, defaults = {}, extras = {}, message = nil) + +

+ + +
+

Asserts that path and options match both ways; in other words, it verifies that path generates options and then that options generates path. This essentially combines assert_recognizes and assert_generates into one step.

+ +

The extras hash allows you to specify options that would normally be provided as a query string to the action. The message parameter allows you to specify a custom error message to display upon failure.

+ +
# Asserts a basic route: a controller with the default action (index)
+assert_routing '/home', controller: 'home', action: 'index'
+
+# Test a route generated with a specific controller, action, and parameter (id)
+assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
+
+# Asserts a basic route (controller + default action), with an error message if it fails
+assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
+
+# Tests a route, providing a defaults hash
+assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"}
+
+# Tests a route with an HTTP method
+assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" })
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 124
+def assert_routing(path, options, defaults = {}, extras = {}, message = nil)
+  assert_recognizes(options, path, extras, message)
+
+  controller, default_controller = options[:controller], defaults[:controller]
+  if controller && controller.include?(?/) && default_controller && default_controller.include?(?/)
+    options[:controller] = "/#{controller}"
+  end
+
+  generate_options = options.dup.delete_if { |k, _| defaults.key?(k) }
+  assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message)
+end
+
+
+ +
+ +
+

+ + method_missing(selector, *args, &block) + +

+ + +
+

ROUTES TODO: These assertions should really work in an integration context

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 172
+def method_missing(selector, *args, &block)
+  if defined?(@controller) && @controller && defined?(@routes) && @routes && @routes.named_routes.route_defined?(selector)
+    @controller.send(selector, *args, &block)
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + with_routing() + +

+ + +
+

A helper to make it easier to test different route configurations. This method temporarily replaces @routes with a new RouteSet instance.

+ +

The new instance is yielded to the passed block. Typically the block will create some routes using set.draw { match ... }:

+ +
with_routing do |set|
+  set.draw do
+    resources :users
+  end
+  assert_equal "/users", users_path
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 149
+def with_routing
+  old_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
+  if defined?(@controller) && @controller
+    old_controller, @controller = @controller, @controller.clone
+    _routes = @routes
+
+    @controller.singleton_class.include(_routes.url_helpers)
+
+    if @controller.respond_to? :view_context_class
+      @controller.view_context_class = Class.new(@controller.view_context_class) do
+        include _routes.url_helpers
+      end
+    end
+  end
+  yield @routes
+ensure
+  @routes = old_routes
+  if defined?(@controller) && @controller
+    @controller = old_controller
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Callbacks.html b/src/5.2/classes/ActionDispatch/Callbacks.html new file mode 100644 index 0000000000..eb2e94d3b8 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Callbacks.html @@ -0,0 +1,255 @@ +--- +title: ActionDispatch::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Provides callbacks to be executed before and after dispatching the request.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + after(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 15
+def after(*args, &block)
+  set_callback(:call, :after, *args, &block)
+end
+
+
+ +
+ +
+

+ + before(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 11
+def before(*args, &block)
+  set_callback(:call, :before, *args, &block)
+end
+
+
+ +
+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 20
+def initialize(app)
+  @app = app
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 24
+def call(env)
+  error = nil
+  result = run_callbacks :call do
+    begin
+      @app.call(env)
+    rescue => error
+    end
+  end
+  raise error if error
+  result
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/ContentSecurityPolicy.html b/src/5.2/classes/ActionDispatch/ContentSecurityPolicy.html new file mode 100644 index 0000000000..389a271664 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/ContentSecurityPolicy.html @@ -0,0 +1,481 @@ +--- +title: ActionDispatch::ContentSecurityPolicy +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + directives
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 141
+def initialize
+  @directives = {}
+  yield self if block_given?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + block_all_mixed_content(enabled = true) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 160
+def block_all_mixed_content(enabled = true)
+  if enabled
+    @directives["block-all-mixed-content"] = true
+  else
+    @directives.delete("block-all-mixed-content")
+  end
+end
+
+
+ +
+ +
+

+ + build(context = nil, nonce = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 206
+def build(context = nil, nonce = nil)
+  build_directives(context, nonce).compact.join("; ")
+end
+
+
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 146
+def initialize_copy(other)
+  @directives = other.directives.deep_dup
+end
+
+
+ +
+ +
+

+ + plugin_types(*types) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 168
+def plugin_types(*types)
+  if types.first
+    @directives["plugin-types"] = types
+  else
+    @directives.delete("plugin-types")
+  end
+end
+
+
+ +
+ +
+

+ + report_uri(uri) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 176
+def report_uri(uri)
+  @directives["report-uri"] = [uri]
+end
+
+
+ +
+ +
+

+ + require_sri_for(*types) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 180
+def require_sri_for(*types)
+  if types.first
+    @directives["require-sri-for"] = types
+  else
+    @directives.delete("require-sri-for")
+  end
+end
+
+
+ +
+ +
+

+ + sandbox(*values) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 188
+def sandbox(*values)
+  if values.empty?
+    @directives["sandbox"] = true
+  elsif values.first
+    @directives["sandbox"] = values
+  else
+    @directives.delete("sandbox")
+  end
+end
+
+
+ +
+ +
+

+ + upgrade_insecure_requests(enabled = true) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 198
+def upgrade_insecure_requests(enabled = true)
+  if enabled
+    @directives["upgrade-insecure-requests"] = true
+  else
+    @directives.delete("upgrade-insecure-requests")
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Middleware.html b/src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Middleware.html new file mode 100644 index 0000000000..4d48a5372a --- /dev/null +++ b/src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Middleware.html @@ -0,0 +1,203 @@ +--- +title: ActionDispatch::ContentSecurityPolicy::Middleware +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CONTENT_TYPE="Content-Type".freeze
 
POLICY="Content-Security-Policy".freeze
 
POLICY_REPORT_ONLY="Content-Security-Policy-Report-Only".freeze
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 12
+def initialize(app)
+  @app = app
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 16
+def call(env)
+  request = ActionDispatch::Request.new env
+  _, headers, _ = response = @app.call(env)
+
+  return response unless html_response?(headers)
+  return response if policy_present?(headers)
+
+  if policy = request.content_security_policy
+    nonce = request.content_security_policy_nonce
+    context = request.controller_instance || request
+    headers[header_name(request)] = policy.build(context, nonce)
+  end
+
+  response
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Request.html b/src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Request.html new file mode 100644 index 0000000000..d9e75e99da --- /dev/null +++ b/src/5.2/classes/ActionDispatch/ContentSecurityPolicy/Request.html @@ -0,0 +1,395 @@ +--- +title: ActionDispatch::ContentSecurityPolicy::Request +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NONCE="action_dispatch.content_security_policy_nonce".freeze
 
NONCE_GENERATOR="action_dispatch.content_security_policy_nonce_generator".freeze
 
POLICY="action_dispatch.content_security_policy".freeze
 
POLICY_REPORT_ONLY="action_dispatch.content_security_policy_report_only".freeze
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + content_security_policy() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 59
+def content_security_policy
+  get_header(POLICY)
+end
+
+
+ +
+ +
+

+ + content_security_policy=(policy) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 63
+def content_security_policy=(policy)
+  set_header(POLICY, policy)
+end
+
+
+ +
+ +
+

+ + content_security_policy_nonce() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 83
+def content_security_policy_nonce
+  if content_security_policy_nonce_generator
+    if nonce = get_header(NONCE)
+      nonce
+    else
+      set_header(NONCE, generate_content_security_policy_nonce)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + content_security_policy_nonce_generator() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 75
+def content_security_policy_nonce_generator
+  get_header(NONCE_GENERATOR)
+end
+
+
+ +
+ +
+

+ + content_security_policy_nonce_generator=(generator) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 79
+def content_security_policy_nonce_generator=(generator)
+  set_header(NONCE_GENERATOR, generator)
+end
+
+
+ +
+ +
+

+ + content_security_policy_report_only() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 67
+def content_security_policy_report_only
+  get_header(POLICY_REPORT_ONLY)
+end
+
+
+ +
+ +
+

+ + content_security_policy_report_only=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 71
+def content_security_policy_report_only=(value)
+  set_header(POLICY_REPORT_ONLY, value)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Cookies.html b/src/5.2/classes/ActionDispatch/Cookies.html new file mode 100644 index 0000000000..ae3b1123b4 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Cookies.html @@ -0,0 +1,466 @@ +--- +title: ActionDispatch::Cookies +layout: default +--- +
+ +
+
+ +
+ +

Cookies are read and written through ActionController#cookies.

+ +

The cookies being read are the ones received along with the request, the cookies being written will be sent out with the response. Reading a cookie does not get the cookie object itself back, just the value it holds.

+ +

Examples of writing:

+ +
# Sets a simple session cookie.
+# This cookie will be deleted when the user's browser is closed.
+cookies[:user_name] = "david"
+
+# Cookie values are String based. Other data types need to be serialized.
+cookies[:lat_lon] = JSON.generate([47.68, -122.37])
+
+# Sets a cookie that expires in 1 hour.
+cookies[:login] = { value: "XJ-122", expires: 1.hour }
+
+# Sets a cookie that expires at a specific time.
+cookies[:login] = { value: "XJ-122", expires: Time.utc(2020, 10, 15, 5) }
+
+# Sets a signed cookie, which prevents users from tampering with its value.
+# It can be read using the signed method `cookies.signed[:name]`
+cookies.signed[:user_id] = current_user.id
+
+# Sets an encrypted cookie value before sending it to the client which
+# prevent users from reading and tampering with its value.
+# It can be read using the encrypted method `cookies.encrypted[:name]`
+cookies.encrypted[:discount] = 45
+
+# Sets a "permanent" cookie (which expires in 20 years from now).
+cookies.permanent[:login] = "XJ-122"
+
+# You can also chain these methods:
+cookies.signed.permanent[:login] = "XJ-122"
+
+ +

Examples of reading:

+ +
cookies[:user_name]           # => "david"
+cookies.size                  # => 2
+JSON.parse(cookies[:lat_lon]) # => [47.68, -122.37]
+cookies.signed[:login]        # => "XJ-122"
+cookies.encrypted[:discount]  # => 45
+
+ +

Example for deleting:

+ +
cookies.delete :user_name
+
+ +

Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:

+ +
cookies[:name] = {
+  value: 'a yummy cookie',
+  expires: 1.year,
+  domain: 'domain.com'
+}
+
+cookies.delete(:name, domain: 'domain.com')
+
+ +

The option symbols for setting cookies are:

+
  • +

    :value - The cookie's value.

    +
  • +

    :path - The path for which this cookie applies. Defaults to the root of the application.

    +
  • +

    :domain - The domain for which this cookie applies so you can restrict to the domain level. If you use a schema like www.example.com and want to share session with user.example.com set :domain to :all. Make sure to specify the :domain option with :all or Array again when deleting cookies.

    + +
    domain: nil  # Does not set cookie domain. (default)
    +domain: :all # Allow the cookie for the top most level
    +             # domain and subdomains.
    +domain: %w(.example.com .example.org) # Allow the cookie
    +                                      # for concrete domain names.
    +
    +
  • +

    :tld_length - When using :domain => :all, this option can be used to explicitly set the TLD length when using a short (<= 3 character) domain that is being interpreted as part of a TLD. For example, to share cookies between user1.lvh.me and user2.lvh.me, set :tld_length to 2.

    +
  • +

    :expires - The time at which this cookie expires, as a Time or ActiveSupport::Duration object.

    +
  • +

    :secure - Whether this cookie is only transmitted to HTTPS servers. Default is false.

    +
  • +

    :httponly - Whether this cookie is accessible via scripting or only HTTP. Defaults to false.

    +
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AUTHENTICATED_ENCRYPTED_COOKIE_SALT="action_dispatch.authenticated_encrypted_cookie_salt".freeze
 
COOKIES_DIGEST="action_dispatch.cookies_digest".freeze
 
COOKIES_ROTATIONS="action_dispatch.cookies_rotations".freeze
 
COOKIES_SERIALIZER="action_dispatch.cookies_serializer".freeze
 
CookieOverflow=Class.new StandardError
 

Raised when storing more than 4K of session data.

ENCRYPTED_COOKIE_CIPHER="action_dispatch.encrypted_cookie_cipher".freeze
 
ENCRYPTED_COOKIE_SALT="action_dispatch.encrypted_cookie_salt".freeze
 
ENCRYPTED_SIGNED_COOKIE_SALT="action_dispatch.encrypted_signed_cookie_salt".freeze
 
GENERATOR_KEY="action_dispatch.key_generator".freeze
 
HTTP_HEADER="Set-Cookie".freeze
 
MAX_COOKIE_SIZE=4096
 

Cookies can typically store 4096 bytes.

SECRET_KEY_BASE="action_dispatch.secret_key_base".freeze
 
SECRET_TOKEN="action_dispatch.secret_token".freeze
 
SIGNED_COOKIE_DIGEST="action_dispatch.signed_cookie_digest".freeze
 
SIGNED_COOKIE_SALT="action_dispatch.signed_cookie_salt".freeze
 
USE_AUTHENTICATED_COOKIE_ENCRYPTION="action_dispatch.use_authenticated_cookie_encryption".freeze
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 663
+def initialize(app)
+  @app = app
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 667
+def call(env)
+  request = ActionDispatch::Request.new env
+
+  status, headers, body = @app.call(env)
+
+  if request.have_cookie_jar?
+    cookie_jar = request.cookie_jar
+    unless cookie_jar.committed?
+      cookie_jar.write(headers)
+      if headers[HTTP_HEADER].respond_to?(:join)
+        headers[HTTP_HEADER] = headers[HTTP_HEADER].join("\n")
+      end
+    end
+  end
+
+  [status, headers, body]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Cookies/ChainedCookieJars.html b/src/5.2/classes/ActionDispatch/Cookies/ChainedCookieJars.html new file mode 100644 index 0000000000..c7ec72efd1 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Cookies/ChainedCookieJars.html @@ -0,0 +1,267 @@ +--- +title: ActionDispatch::Cookies::ChainedCookieJars +layout: default +--- +
+ +
+
+ +
+ +

Include in a cookie jar to allow chaining, e.g. cookies.permanent.signed.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + encrypted() + +

+ + +
+

Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read. If the cookie was tampered with by the user (or a 3rd party), nil will be returned.

+ +

If secret_key_base and secrets.secret_token (deprecated) are both set, legacy cookies signed with the old key generator will be transparently upgraded.

+ +

If config.action_dispatch.encrypted_cookie_salt and config.action_dispatch.encrypted_signed_cookie_salt are both set, legacy cookies encrypted with HMAC AES-256-CBC will be transparently upgraded.

+ +

This jar requires that you set a suitable secret for the verification on your app's secret_key_base.

+ +

Example:

+ +
cookies.encrypted[:discount] = 45
+# => Set-Cookie: discount=DIQ7fw==--K3n//8vvnSbGq9dA--7Xh91HfLpwzbj1czhBiwOg==; path=/
+
+cookies.encrypted[:discount] # => 45
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 245
+def encrypted
+  @encrypted ||= EncryptedKeyRotatingCookieJar.new(self)
+end
+
+
+ +
+ +
+

+ + permanent() + +

+ + +
+

Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example:

+ +
cookies.permanent[:prefers_open_id] = true
+# => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
+
+ +

This jar is only meant for writing. You'll read permanent cookies through the regular accessor.

+ +

This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples:

+ +
cookies.permanent.signed[:remember_me] = current_user.id
+# => Set-Cookie: remember_me=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 205
+def permanent
+  @permanent ||= PermanentCookieJar.new(self)
+end
+
+
+ +
+ +
+

+ + signed() + +

+ + +
+

Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed cookie was tampered with by the user (or a 3rd party), nil will be returned.

+ +

If secret_key_base and secrets.secret_token (deprecated) are both set, legacy cookies signed with the old key generator will be transparently upgraded.

+ +

This jar requires that you set a suitable secret for the verification on your app's secret_key_base.

+ +

Example:

+ +
cookies.signed[:discount] = 45
+# => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/
+
+cookies.signed[:discount] # => 45
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 224
+def signed
+  @signed ||= SignedKeyRotatingCookieJar.new(self)
+end
+
+
+ +
+ +
+

+ + signed_or_encrypted() + +

+ + +
+

Returns the signed or encrypted jar, preferring encrypted if secret_key_base is set. Used by ActionDispatch::Session::CookieStore to avoid the need to introduce new cookie stores.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 251
+def signed_or_encrypted
+  @signed_or_encrypted ||=
+    if request.secret_key_base.present?
+      encrypted
+    else
+      signed
+    end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/DebugExceptions.html b/src/5.2/classes/ActionDispatch/DebugExceptions.html new file mode 100644 index 0000000000..30ebda56c7 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/DebugExceptions.html @@ -0,0 +1,203 @@ +--- +title: ActionDispatch::DebugExceptions +layout: default +--- +
+ +
+
+ +
+ +

This middleware is responsible for logging exceptions and showing a debugging page in case the request is local.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RESCUES_TEMPLATE_PATH=File.expand_path("templates", __dir__)
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(app, routes_app = nil, response_format = :default) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/debug_exceptions.rb, line 53
+def initialize(app, routes_app = nil, response_format = :default)
+  @app             = app
+  @routes_app      = routes_app
+  @response_format = response_format
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/debug_exceptions.rb, line 59
+def call(env)
+  request = ActionDispatch::Request.new env
+  _, headers, body = response = @app.call(env)
+
+  if headers["X-Cascade"] == "pass"
+    body.close if body.respond_to?(:close)
+    raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
+  end
+
+  response
+rescue Exception => exception
+  raise exception unless request.show_exceptions?
+  render_exception(request, exception)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/DebugLocks.html b/src/5.2/classes/ActionDispatch/DebugLocks.html new file mode 100644 index 0000000000..2694edca99 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/DebugLocks.html @@ -0,0 +1,178 @@ +--- +title: ActionDispatch::DebugLocks +layout: default +--- +
+ +
+
+ +
+ +

This middleware can be used to diagnose deadlocks in the autoload interlock.

+ +

To use it, insert it near the top of the middleware stack, using config/application.rb:

+ +
config.middleware.insert_before Rack::Sendfile, ActionDispatch::DebugLocks
+
+ +

After restarting the application and re-triggering the deadlock condition, /rails/locks will show a summary of all threads currently known to the interlock, which lock level they are holding or awaiting, and their current backtrace.

+ +

Generally a deadlock will be caused by the interlock conflicting with some other external lock or blocking I/O call. These cannot be automatically identified, but should be visible in the displayed backtraces.

+ +

NOTE: The formatting and content of this middleware's output is intended for human consumption, and should be expected to change between releases.

+ +

This middleware exposes operational details of the server, with no access control. It should only be enabled when in use, and removed thereafter.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, path = "/rails/locks") + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/debug_locks.rb, line 26
+def initialize(app, path = "/rails/locks")
+  @app = app
+  @path = path
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/debug_locks.rb, line 31
+def call(env)
+  req = ActionDispatch::Request.new env
+
+  if req.get?
+    path = req.path_info.chomp("/".freeze)
+    if path == @path
+      return render_details(req)
+    end
+  end
+
+  @app.call(env)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/ExceptionWrapper.html b/src/5.2/classes/ActionDispatch/ExceptionWrapper.html new file mode 100644 index 0000000000..d6a7a54f69 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/ExceptionWrapper.html @@ -0,0 +1,490 @@ +--- +title: ActionDispatch::ExceptionWrapper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + backtrace_cleaner
+ [R] + exception
+ [R] + file
+ [R] + line_number
+ + + + +

Class Public methods

+ +
+

+ + new(backtrace_cleaner, exception) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 34
+def initialize(backtrace_cleaner, exception)
+  @backtrace_cleaner = backtrace_cleaner
+  @exception = original_exception(exception)
+
+  expand_backtrace if exception.is_a?(SyntaxError) || exception.cause.is_a?(SyntaxError)
+end
+
+
+ +
+ +
+

+ + status_code_for_exception(class_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 85
+def self.status_code_for_exception(class_name)
+  Rack::Utils.status_code(@@rescue_responses[class_name])
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + application_trace() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 49
+def application_trace
+  clean_backtrace(:silent)
+end
+
+
+ +
+ +
+

+ + framework_trace() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 53
+def framework_trace
+  clean_backtrace(:noise)
+end
+
+
+ +
+ +
+

+ + full_trace() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 57
+def full_trace
+  clean_backtrace(:all)
+end
+
+
+ +
+ +
+

+ + rescue_template() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 41
+def rescue_template
+  @@rescue_templates[@exception.class.name]
+end
+
+
+ +
+ +
+

+ + source_extracts() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 89
+def source_extracts
+  backtrace.map do |trace|
+    file, line_number = extract_file_and_line_number(trace)
+
+    {
+      code: source_fragment(file, line_number),
+      line_number: line_number
+    }
+  end
+end
+
+
+ +
+ +
+

+ + status_code() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 45
+def status_code
+  self.class.status_code_for_exception(@exception.class.name)
+end
+
+
+ +
+ +
+

+ + traces() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 61
+def traces
+  application_trace_with_ids = []
+  framework_trace_with_ids = []
+  full_trace_with_ids = []
+
+  full_trace.each_with_index do |trace, idx|
+    trace_with_id = { id: idx, trace: trace }
+
+    if application_trace.include?(trace)
+      application_trace_with_ids << trace_with_id
+    else
+      framework_trace_with_ids << trace_with_id
+    end
+
+    full_trace_with_ids << trace_with_id
+  end
+
+  {
+    "Application Trace" => application_trace_with_ids,
+    "Framework Trace" => framework_trace_with_ids,
+    "Full Trace" => full_trace_with_ids
+  }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Executor.html b/src/5.2/classes/ActionDispatch/Executor.html new file mode 100644 index 0000000000..c7b35ff42c --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Executor.html @@ -0,0 +1,155 @@ +--- +title: ActionDispatch::Executor +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, executor) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/executor.rb, line 7
+def initialize(app, executor)
+  @app, @executor = app, executor
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/executor.rb, line 11
+def call(env)
+  state = @executor.run!
+  begin
+    response = @app.call(env)
+    returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
+  ensure
+    state.complete! unless returned
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/FileHandler.html b/src/5.2/classes/ActionDispatch/FileHandler.html new file mode 100644 index 0000000000..d8d6592422 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/FileHandler.html @@ -0,0 +1,274 @@ +--- +title: ActionDispatch::FileHandler +layout: default +--- +
+ +
+
+ +
+ +

This middleware returns a file's contents from disk in the body response. When initialized, it can accept optional HTTP headers, which will be set when a response containing a file's contents is delivered.

+ +

This middleware will render the file specified in env["PATH_INFO"] where the base path is in the root directory. For example, if the root is set to public/, then a request with env["PATH_INFO"] of assets/application.js will return a response with the contents of a file located at public/assets/application.js if the file exists. If the file does not exist, a 404 “File not Found” response will be returned.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(root, index: "index", headers: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/static.rb, line 18
+def initialize(root, index: "index", headers: {})
+  @root          = root.chomp("/").b
+  @file_server   = ::Rack::File.new(@root, headers)
+  @index         = index
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/static.rb, line 50
+def call(env)
+  serve(Rack::Request.new(env))
+end
+
+
+ +
+ +
+

+ + match?(path) + +

+ + +
+

Takes a path to a file. If the file is found, has valid encoding, and has correct read permissions, the return value is a URI-escaped string representing the filename. Otherwise, false is returned.

+ +

Used by the Static class to check the existence of a valid file in the server's public/ directory (see Static#call).

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/static.rb, line 30
+def match?(path)
+  path = ::Rack::Utils.unescape_path path
+  return false unless ::Rack::Utils.valid_path? path
+  path = ::Rack::Utils.clean_path_info path
+
+  paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"]
+
+  if match = paths.detect { |p|
+    path = File.join(@root, p.b)
+    begin
+      File.file?(path) && File.readable?(path)
+    rescue SystemCallError
+      false
+    end
+
+  }
+    return ::Rack::Utils.escape_path(match).b
+  end
+end
+
+
+ +
+ +
+

+ + serve(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/static.rb, line 54
+def serve(request)
+  path      = request.path_info
+  gzip_path = gzip_file_path(path)
+
+  if gzip_path && gzip_encoding_accepted?(request)
+    request.path_info           = gzip_path
+    status, headers, body       = @file_server.call(request.env)
+    if status == 304
+      return [status, headers, body]
+    end
+    headers["Content-Encoding"] = "gzip"
+    headers["Content-Type"]     = content_type(path)
+  else
+    status, headers, body = @file_server.call(request.env)
+  end
+
+  headers["Vary"] = "Accept-Encoding" if gzip_path
+
+  return [status, headers, body]
+ensure
+  request.path_info = path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Flash.html b/src/5.2/classes/ActionDispatch/Flash.html new file mode 100644 index 0000000000..703cba2f27 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Flash.html @@ -0,0 +1,179 @@ +--- +title: ActionDispatch::Flash +layout: default +--- +
+ +
+
+ +
+ +

The flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create action that sets flash[:notice] = "Post successfully created" before redirecting to a display action that can then expose the flash to its template. Actually, that exposure is automatically done.

+ +
class PostsController < ActionController::Base
+  def create
+    # save post
+    flash[:notice] = "Post successfully created"
+    redirect_to @post
+  end
+
+  def show
+    # doesn't need to assign the flash notice to the template, that's done automatically
+  end
+end
+
+show.html.erb
+  <% if flash[:notice] %>
+    <div class="notice"><%= flash[:notice] %></div>
+  <% end %>
+
+ +

Since the notice and alert keys are a common idiom, convenience accessors are available:

+ +
flash.alert = "You must be logged in"
+flash.notice = "Post successfully created"
+
+ +

This example places a string in the flash. And of course, you can put as many as you like at a time too. If you want to pass non-primitive types, you will have to handle that in your application. Example: To show messages with links, you will have to use sanitize helper.

+ +

Just remember: They'll be gone by the time the next action has been performed.

+ +

See docs on the FlashHash class for more details about the flash.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
KEY="action_dispatch.request.flash_hash".freeze
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 294
+def self.new(app) app; end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Flash/FlashHash.html b/src/5.2/classes/ActionDispatch/Flash/FlashHash.html new file mode 100644 index 0000000000..ea6b20ee51 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Flash/FlashHash.html @@ -0,0 +1,869 @@ +--- +title: ActionDispatch::Flash::FlashHash +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + [](k) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 161
+def [](k)
+  @flashes[k.to_s]
+end
+
+
+ +
+ +
+

+ + []=(k, v) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 155
+def []=(k, v)
+  k = k.to_s
+  @discard.delete k
+  @flashes[k] = v
+end
+
+
+ +
+ +
+

+ + alert() + +

+ + +
+

Convenience accessor for flash[:alert].

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 262
+def alert
+  self[:alert]
+end
+
+
+ +
+ +
+

+ + alert=(message) + +

+ + +
+

Convenience accessor for flash[:alert]=.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 267
+def alert=(message)
+  self[:alert] = message
+end
+
+
+ +
+ +
+

+ + clear() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 194
+def clear
+  @discard.clear
+  @flashes.clear
+end
+
+
+ +
+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 179
+def delete(key)
+  key = key.to_s
+  @discard.delete key
+  @flashes.delete key
+  self
+end
+
+
+ +
+ +
+

+ + discard(k = nil) + +

+ + +
+

Marks the entire flash or a single flash entry to be discarded by the end of the current action:

+ +
flash.discard              # discard the entire flash at the end of the current action
+flash.discard(:warning)    # discard only the "warning" entry at the end of the current action
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 247
+def discard(k = nil)
+  k = k.to_s if k
+  @discard.merge Array(k || keys)
+  k ? self[k] : self
+end
+
+
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 199
+def each(&block)
+  @flashes.each(&block)
+end
+
+
+ +
+ +
+

+ + empty?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 190
+def empty?
+  @flashes.empty?
+end
+
+
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 147
+def initialize_copy(other)
+  if other.now_is_loaded?
+    @now = other.now.dup
+    @now.flash = self
+  end
+  super
+end
+
+
+ +
+ +
+

+ + keep(k = nil) + +

+ + +
+

Keeps either the entire current flash or a specific flash entry available for the next action:

+ +
flash.keep            # keeps the entire flash
+flash.keep(:notice)   # keeps only the "notice" entry, the rest of the flash is discarded
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 237
+def keep(k = nil)
+  k = k.to_s if k
+  @discard.subtract Array(k || keys)
+  k ? self[k] : self
+end
+
+
+ +
+ +
+

+ + key?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 175
+def key?(name)
+  @flashes.key? name.to_s
+end
+
+
+ +
+ +
+

+ + keys() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 171
+def keys
+  @flashes.keys
+end
+
+
+ +
+ +
+

+ + notice() + +

+ + +
+

Convenience accessor for flash[:notice].

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 272
+def notice
+  self[:notice]
+end
+
+
+ +
+ +
+

+ + notice=(message) + +

+ + +
+

Convenience accessor for flash[:notice]=.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 277
+def notice=(message)
+  self[:notice] = message
+end
+
+
+ +
+ +
+

+ + now() + +

+ + +
+

Sets a flash that will not be available to the next action, only to the current.

+ +
flash.now[:message] = "Hello current action"
+
+ +

This method enables you to use the flash as a central messaging system in your app. When you need to pass an object to the next action, you use the standard flash assign ([]=). When you need to pass an object to the current action, you use now, and your object will vanish when the current action is done.

+ +

Entries set via now are accessed the same way as standard entries: flash['my-key'].

+ +

Also, brings two convenience accessors:

+ +
flash.now.alert = "Beware now!"
+# Equivalent to flash.now[:alert] = "Beware now!"
+
+flash.now.notice = "Good luck now!"
+# Equivalent to flash.now[:notice] = "Good luck now!"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 229
+def now
+  @now ||= FlashNow.new(self)
+end
+
+
+ +
+ +
+

+ + to_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 186
+def to_hash
+  @flashes.dup
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + now_is_loaded?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 282
+def now_is_loaded?
+  @now
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + stringify_array(array) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 287
+def stringify_array(array) # :doc:
+  array.map do |item|
+    item.kind_of?(Symbol) ? item.to_s : item
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Flash/RequestMethods.html b/src/5.2/classes/ActionDispatch/Flash/RequestMethods.html new file mode 100644 index 0000000000..2ebe0c427d --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Flash/RequestMethods.html @@ -0,0 +1,142 @@ +--- +title: ActionDispatch::Flash::RequestMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + flash() + +

+ + +
+

Access the contents of the flash. Use flash["notice"] to read a notice you put there or flash["notice"] = "hello" to put a new one.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 47
+def flash
+  flash = flash_hash
+  return flash if flash
+  self.flash = Flash::FlashHash.from_session_value(session["flash"])
+end
+
+
+ +
+ +
+

+ + flash=(flash) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 53
+def flash=(flash)
+  set_header Flash::KEY, flash
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http.html b/src/5.2/classes/ActionDispatch/Http.html new file mode 100644 index 0000000000..fc2a3ffc01 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http.html @@ -0,0 +1,116 @@ +--- +title: ActionDispatch::Http +layout: default +--- + diff --git a/src/5.2/classes/ActionDispatch/Http/Cache.html b/src/5.2/classes/ActionDispatch/Http/Cache.html new file mode 100644 index 0000000000..3ba9d09769 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/Cache.html @@ -0,0 +1,69 @@ +--- +title: ActionDispatch::Http::Cache +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/Cache/Request.html b/src/5.2/classes/ActionDispatch/Http/Cache/Request.html new file mode 100644 index 0000000000..ba31143c35 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/Cache/Request.html @@ -0,0 +1,339 @@ +--- +title: ActionDispatch::Http::Cache::Request +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
HTTP_IF_MODIFIED_SINCE="HTTP_IF_MODIFIED_SINCE".freeze
 
HTTP_IF_NONE_MATCH="HTTP_IF_NONE_MATCH".freeze
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + etag_matches?(etag) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 28
+def etag_matches?(etag)
+  if etag
+    validators = if_none_match_etags
+    validators.include?(etag) || validators.include?("*")
+  end
+end
+
+
+ +
+ +
+

+ + fresh?(response) + +

+ + +
+

Check response freshness (Last-Modified and ETag) against request If-Modified-Since and If-None-Match conditions. If both headers are supplied, both must match, or the request is not considered fresh.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 38
+def fresh?(response)
+  last_modified = if_modified_since
+  etag          = if_none_match
+
+  return false unless last_modified || etag
+
+  success = true
+  success &&= not_modified?(response.last_modified) if last_modified
+  success &&= etag_matches?(response.etag) if etag
+  success
+end
+
+
+ +
+ +
+

+ + if_modified_since() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 10
+def if_modified_since
+  if since = get_header(HTTP_IF_MODIFIED_SINCE)
+    Time.rfc2822(since) rescue nil
+  end
+end
+
+
+ +
+ +
+

+ + if_none_match() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 16
+def if_none_match
+  get_header HTTP_IF_NONE_MATCH
+end
+
+
+ +
+ +
+

+ + if_none_match_etags() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 20
+def if_none_match_etags
+  if_none_match ? if_none_match.split(/\s*,\s*/) : []
+end
+
+
+ +
+ +
+

+ + not_modified?(modified_at) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 24
+def not_modified?(modified_at)
+  if_modified_since && modified_at && if_modified_since >= modified_at
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/Cache/Response.html b/src/5.2/classes/ActionDispatch/Http/Cache/Response.html new file mode 100644 index 0000000000..6bd5fda42c --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/Cache/Response.html @@ -0,0 +1,654 @@ +--- +title: ActionDispatch::Http::Cache::Response +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DATE="Date".freeze
 
DEFAULT_CACHE_CONTROL="max-age=0, private, must-revalidate".freeze
 
LAST_MODIFIED="Last-Modified".freeze
 
MUST_REVALIDATE="must-revalidate".freeze
 
NO_CACHE="no-cache".freeze
 
PRIVATE="private".freeze
 
PUBLIC="public".freeze
 
SPECIAL_KEYS=Set.new(%w[extras no-cache max-age public private must-revalidate])
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + cache_control
+ + + + + +

Instance Public methods

+ +
+

+ + date() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 68
+def date
+  if date_header = get_header(DATE)
+    Time.httpdate(date_header)
+  end
+end
+
+
+ +
+ +
+

+ + date=(utc_time) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 78
+def date=(utc_time)
+  set_header DATE, utc_time.httpdate
+end
+
+
+ +
+ +
+

+ + date?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 74
+def date?
+  has_header? DATE
+end
+
+
+ +
+ +
+

+ + etag=(weak_validators) + +

+ + +
+

This method sets a weak ETag validator on the response so browsers and proxies may cache the response, keyed on the ETag. On subsequent requests, the If-None-Match header is set to the cached ETag. If it matches the current ETag, we can return a 304 Not Modified response with no body, letting the browser or proxy know that their cache is current. Big savings in request time and network bandwidth.

+ +

Weak ETags are considered to be semantically equivalent but not byte-for-byte identical. This is perfect for browser caching of HTML pages where we don't care about exact equality, just what the user is viewing.

+ +

Strong ETags are considered byte-for-byte identical. They allow a browser or proxy cache to support Range requests, useful for paging through a PDF file or scrubbing through a video. Some CDNs only support strong ETags and will ignore weak ETags entirely.

+ +

Weak ETags are what we almost always need, so they're the default. Check out strong_etag= to provide a strong ETag validator.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 101
+def etag=(weak_validators)
+  self.weak_etag = weak_validators
+end
+
+
+ +
+ +
+

+ + etag?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 113
+def etag?; etag; end
+
+
+ +
+ +
+

+ + last_modified() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 54
+def last_modified
+  if last = get_header(LAST_MODIFIED)
+    Time.httpdate(last)
+  end
+end
+
+
+ +
+ +
+

+ + last_modified=(utc_time) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 64
+def last_modified=(utc_time)
+  set_header LAST_MODIFIED, utc_time.httpdate
+end
+
+
+ +
+ +
+

+ + last_modified?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 60
+def last_modified?
+  has_header? LAST_MODIFIED
+end
+
+
+ +
+ +
+

+ + strong_etag=(strong_validators) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 109
+def strong_etag=(strong_validators)
+  set_header "ETag", generate_strong_etag(strong_validators)
+end
+
+
+ +
+ +
+

+ + strong_etag?() + +

+ + +
+

True if an ETag is set and it isn't a weak validator (not preceded with W/)

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 121
+def strong_etag?
+  etag? && !weak_etag?
+end
+
+
+ +
+ +
+

+ + weak_etag=(weak_validators) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 105
+def weak_etag=(weak_validators)
+  set_header "ETag", generate_weak_etag(weak_validators)
+end
+
+
+ +
+ +
+

+ + weak_etag?() + +

+ + +
+

True if an ETag is set and it's a weak validator (preceded with W/)

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/cache.rb, line 116
+def weak_etag?
+  etag? && etag.starts_with?('W/"')
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/FilterParameters.html b/src/5.2/classes/ActionDispatch/Http/FilterParameters.html new file mode 100644 index 0000000000..2152a11646 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/FilterParameters.html @@ -0,0 +1,442 @@ +--- +title: ActionDispatch::Http::FilterParameters +layout: default +--- +
+ +
+
+ +
+ +

Allows you to specify sensitive parameters which will be replaced from the request log by looking in the query string of the request and all sub-hashes of the params hash to filter. Filtering only certain sub-keys from a hash is possible by using the dot notation: 'credit_card.number'. If a block is given, each key and value of the params hash and all sub-hashes is passed to it, where the value or the key can be replaced using String#replace or similar method.

+ +
env["action_dispatch.parameter_filter"] = [:password]
+=> replaces the value to all keys matching /password/i with "[FILTERED]"
+
+env["action_dispatch.parameter_filter"] = [:foo, "bar"]
+=> replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
+
+env["action_dispatch.parameter_filter"] = [ "credit_card.code" ]
+=> replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
+change { file: { code: "xxxx"} }
+
+env["action_dispatch.parameter_filter"] = -> (k, v) do
+  v.reverse! if k =~ /secret/i
+end
+=> reverses the value to all keys matching /secret/i
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
KV_RE="[^&;=]+"
 
PAIR_RE=%r{(#{KV_RE})=(#{KV_RE})}
 
+ + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 34
+def initialize
+  super
+  @filtered_parameters = nil
+  @filtered_env        = nil
+  @filtered_path       = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + filtered_env() + +

+ + +
+

Returns a hash of request.env with all sensitive data replaced.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 47
+def filtered_env
+  @filtered_env ||= env_filter.filter(@env)
+end
+
+
+ +
+ +
+

+ + filtered_parameters() + +

+ + +
+

Returns a hash of parameters with all sensitive data replaced.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 42
+def filtered_parameters
+  @filtered_parameters ||= parameter_filter.filter(parameters)
+end
+
+
+ +
+ +
+

+ + filtered_path() + +

+ + +
+

Reconstructs a path with all sensitive GET parameters replaced.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 52
+def filtered_path
+  @filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}"
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + env_filter() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 64
+def env_filter # :doc:
+  user_key = fetch_header("action_dispatch.parameter_filter") {
+    return NULL_ENV_FILTER
+  }
+  parameter_filter_for(Array(user_key) + ENV_MATCH)
+end
+
+
+ +
+ +
+

+ + filtered_query_string() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 77
+def filtered_query_string # :doc:
+  query_string.gsub(PAIR_RE) do |_|
+    parameter_filter.filter($1 => $2).first.join("=")
+  end
+end
+
+
+ +
+ +
+

+ + parameter_filter() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 58
+def parameter_filter # :doc:
+  parameter_filter_for fetch_header("action_dispatch.parameter_filter") {
+    return NULL_PARAM_FILTER
+  }
+end
+
+
+ +
+ +
+

+ + parameter_filter_for(filters) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 71
+def parameter_filter_for(filters) # :doc:
+  ParameterFilter.new(filters)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/FilterRedirect.html b/src/5.2/classes/ActionDispatch/Http/FilterRedirect.html new file mode 100644 index 0000000000..3614e3be78 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/FilterRedirect.html @@ -0,0 +1,54 @@ +--- +title: ActionDispatch::Http::FilterRedirect +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/Headers.html b/src/5.2/classes/ActionDispatch/Http/Headers.html new file mode 100644 index 0000000000..d4e517d530 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/Headers.html @@ -0,0 +1,589 @@ +--- +title: ActionDispatch::Http::Headers +layout: default +--- +
+ +
+
+ +
+ +

Provides access to the request's HTTP headers from the environment.

+ +
env     = { "CONTENT_TYPE" => "text/plain", "HTTP_USER_AGENT" => "curl/7.43.0" }
+headers = ActionDispatch::Http::Headers.from_hash(env)
+headers["Content-Type"] # => "text/plain"
+headers["User-Agent"] # => "curl/7.43.0"
+
+ +

Also note that when headers are mapped to CGI-like variables by the Rack server, both dashes and underscores are converted to underscores. This ambiguity cannot be resolved at this stage anymore. Both underscores and dashes have to be interpreted as if they were originally sent as dashes.

+ +
# GET / HTTP/1.1
+# ...
+# User-Agent: curl/7.43.0
+# X_Custom_Header: token
+
+headers["X_Custom_Header"] # => nil
+headers["X-Custom-Header"] # => "token"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CGI_VARIABLES=Set.new(%W[ +AUTH_TYPE +CONTENT_LENGTH +CONTENT_TYPE +GATEWAY_INTERFACE +HTTPS +PATH_INFO +PATH_TRANSLATED +QUERY_STRING +REMOTE_ADDR +REMOTE_HOST +REMOTE_IDENT +REMOTE_USER +REQUEST_METHOD +SCRIPT_NAME +SERVER_NAME +SERVER_PORT +SERVER_PROTOCOL +SERVER_SOFTWARE +]).freeze
 
HTTP_HEADER=/\A[A-Za-z0-9-]+\z/
 
+ + + + + + +

Class Public methods

+ +
+

+ + from_hash(hash) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 50
+def self.from_hash(hash)
+  new ActionDispatch::Request.new hash
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](key) + +

+ + +
+

Returns the value for the given key mapped to @env.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 59
+def [](key)
+  @req.get_header env_name(key)
+end
+
+
+ +
+ +
+

+ + []=(key, value) + +

+ + +
+

Sets the given value for the key mapped to @env.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 64
+def []=(key, value)
+  @req.set_header env_name(key), value
+end
+
+
+ +
+ +
+

+ + add(key, value) + +

+ + +
+

Add a value to a multivalued header like Vary or Accept-Encoding.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 69
+def add(key, value)
+  @req.add_header env_name(key), value
+end
+
+
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 95
+def each(&block)
+  @req.each_header(&block)
+end
+
+
+ +
+ +
+

+ + env() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 116
+def env; @req.env.dup; end
+
+
+ +
+ +
+

+ + fetch(key, default = DEFAULT) + +

+ + +
+

Returns the value for the given key mapped to @env.

+ +

If the key is not found and an optional code block is not provided, raises a KeyError exception.

+ +

If the code block is provided, then it will be run and its result returned.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 87
+def fetch(key, default = DEFAULT)
+  @req.fetch_header(env_name(key)) do
+    return default unless default == DEFAULT
+    return yield if block_given?
+    raise KeyError, key
+  end
+end
+
+
+ +
+ +
+

+ + include?(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: key? +
+ + + +
+ +
+

+ + key?(key) + +

+ + +
+ +
+ + + +
+ Also aliased as: include? +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 73
+def key?(key)
+  @req.has_header? env_name(key)
+end
+
+
+ +
+ +
+

+ + merge(headers_or_env) + +

+ + +
+

Returns a new Http::Headers instance containing the contents of headers_or_env and the original instance.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 101
+def merge(headers_or_env)
+  headers = @req.dup.headers
+  headers.merge!(headers_or_env)
+  headers
+end
+
+
+ +
+ +
+

+ + merge!(headers_or_env) + +

+ + +
+

Adds the contents of headers_or_env to original instance entries; duplicate keys are overwritten with the values from headers_or_env.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/headers.rb, line 110
+def merge!(headers_or_env)
+  headers_or_env.each do |key, value|
+    @req.set_header env_name(key), value
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/MimeNegotiation.html b/src/5.2/classes/ActionDispatch/Http/MimeNegotiation.html new file mode 100644 index 0000000000..fab0093084 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/MimeNegotiation.html @@ -0,0 +1,682 @@ +--- +title: ActionDispatch::Http::MimeNegotiation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
BROWSER_LIKE_ACCEPTS=/,\s*\*\/\*|\*\/\*\s*,/
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + accepts() + +

+ + +
+

Returns the accepted MIME type for the request.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 35
+def accepts
+  fetch_header("action_dispatch.request.accepts") do |k|
+    header = get_header("HTTP_ACCEPT").to_s.strip
+
+    v = if header.empty?
+      [content_mime_type]
+    else
+      Mime::Type.parse(header)
+    end
+    set_header k, v
+  end
+end
+
+
+ +
+ +
+

+ + content_mime_type() + +

+ + +
+

The MIME type of the HTTP request, such as Mime.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 15
+def content_mime_type
+  fetch_header("action_dispatch.request.content_type") do |k|
+    v = if get_header("CONTENT_TYPE") =~ /^([^,\;]*)/
+      Mime::Type.lookup($1.strip.downcase)
+    else
+      nil
+    end
+    set_header k, v
+  end
+end
+
+
+ +
+ +
+

+ + content_type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 26
+def content_type
+  content_mime_type && content_mime_type.to_s
+end
+
+
+ +
+ +
+

+ + format(view_path = []) + +

+ + +
+

Returns the MIME type for the format used in the request.

+ +
GET /posts/5.xml   | request.format => Mime[:xml]
+GET /posts/5.xhtml | request.format => Mime[:html]
+GET /posts/5       | request.format => Mime[:html] or Mime[:js], or request.accepts.first
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 54
+def format(view_path = [])
+  formats.first || Mime::NullType.instance
+end
+
+
+ +
+ +
+

+ + format=(extension) + +

+ + +
+

Sets the format by string extension, which can be used to force custom formats that are not controlled by the extension.

+ +
class ApplicationController < ActionController::Base
+  before_action :adjust_format_for_iphone
+
+  private
+    def adjust_format_for_iphone
+      request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
+    end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 115
+def format=(extension)
+  parameters[:format] = extension.to_s
+  set_header "action_dispatch.request.formats", [Mime::Type.lookup_by_extension(parameters[:format])]
+end
+
+
+ +
+ +
+

+ + formats() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 58
+def formats
+  fetch_header("action_dispatch.request.formats") do |k|
+    params_readable = begin
+                        parameters[:format]
+                      rescue ActionController::BadRequest
+                        false
+                      end
+
+    v = if params_readable
+      Array(Mime[parameters[:format]])
+    elsif use_accept_header && valid_accept_header
+      accepts
+    elsif extension_format = format_from_path_extension
+      [extension_format]
+    elsif xhr?
+      [Mime[:js]]
+    else
+      [Mime[:html]]
+    end
+
+    v = v.select do |format|
+      format.symbol || format.ref == "*/*"
+    end
+
+    set_header k, v
+  end
+end
+
+
+ +
+ +
+

+ + formats=(extensions) + +

+ + +
+

Sets the formats by string extensions. This differs from format= by allowing you to set multiple, ordered formats, which is useful when you want to have a fallback.

+ +

In this example, the :iphone format will be used if it's available, otherwise it'll fallback to the :html format.

+ +
class ApplicationController < ActionController::Base
+  before_action :adjust_format_for_iphone_with_html_fallback
+
+  private
+    def adjust_format_for_iphone_with_html_fallback
+      request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
+    end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 134
+def formats=(extensions)
+  parameters[:format] = extensions.first.to_s
+  set_header "action_dispatch.request.formats", extensions.collect { |extension|
+    Mime::Type.lookup_by_extension(extension)
+  }
+end
+
+
+ +
+ +
+

+ + negotiate_mime(order) + +

+ + +
+

Returns the first MIME type that matches the provided array of MIME types.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 142
+def negotiate_mime(order)
+  formats.each do |priority|
+    if priority == Mime::ALL
+      return order.first
+    elsif order.include?(priority)
+      return priority
+    end
+  end
+
+  order.include?(Mime::ALL) ? format : nil
+end
+
+
+ +
+ +
+

+ + variant() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 100
+def variant
+  @variant ||= ActiveSupport::ArrayInquirer.new
+end
+
+
+ +
+ +
+

+ + variant=(variant) + +

+ + +
+

Sets the variant for template.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 87
+def variant=(variant)
+  variant = Array(variant)
+
+  if variant.all? { |v| v.is_a?(Symbol) }
+    @variant = ActiveSupport::ArrayInquirer.new(variant)
+  else
+    raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols. " \
+      "For security reasons, never directly set the variant to a user-provided value, " \
+      "like params[:variant].to_sym. Check user-provided value against a whitelist first, " \
+      "then set the variant: request.variant = :tablet if params[:variant] == 'tablet'"
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + format_from_path_extension() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 167
+def format_from_path_extension # :doc:
+  path = get_header("action_dispatch.original_path") || get_header("PATH_INFO")
+  if match = path && path.match(/\.(\w+)\z/)
+    Mime[match.captures.first]
+  end
+end
+
+
+ +
+ +
+

+ + use_accept_header() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 163
+def use_accept_header # :doc:
+  !self.class.ignore_accept_header
+end
+
+
+ +
+ +
+

+ + valid_accept_header() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 158
+def valid_accept_header # :doc:
+  (xhr? && (accept.present? || content_mime_type)) ||
+    (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/ParameterFilter.html b/src/5.2/classes/ActionDispatch/Http/ParameterFilter.html new file mode 100644 index 0000000000..5d5fae4009 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/ParameterFilter.html @@ -0,0 +1,149 @@ +--- +title: ActionDispatch::Http::ParameterFilter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(filters = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/parameter_filter.rb, line 10
+def initialize(filters = [])
+  @filters = filters
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + filter(params) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/parameter_filter.rb, line 14
+def filter(params)
+  compiled_filter.call(params)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/Parameters.html b/src/5.2/classes/ActionDispatch/Http/Parameters.html new file mode 100644 index 0000000000..154118b78f --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/Parameters.html @@ -0,0 +1,255 @@ +--- +title: ActionDispatch::Http::Parameters +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_PARSERS={ +Mime[:json].symbol => -> (raw_post) { +data = ActiveSupport::JSON.decode(raw_post) +data.is_a?(Hash) ? data : { _json: data } +} +}
 
PARAMETERS_KEY="action_dispatch.request.path_parameters"
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + parameter_parsers

Returns the parameter parsers.

+ + + + + +

Instance Public methods

+ +
+

+ + parameters() + +

+ + +
+

Returns both GET and POST parameters in a single hash.

+
+ + + +
+ Also aliased as: params +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/parameters.rb, line 50
+def parameters
+  params = get_header("action_dispatch.request.parameters")
+  return params if params
+
+  params = begin
+             request_parameters.merge(query_parameters)
+           rescue EOFError
+             query_parameters.dup
+           end
+  params.merge!(path_parameters)
+  params = set_binary_encoding(params, params[:controller], params[:action])
+  set_header("action_dispatch.request.parameters", params)
+  params
+end
+
+
+ +
+ +
+

+ + params() + +

+ + +
+ +
+ + + + + +
+ Alias for: parameters +
+ + + +
+ +
+

+ + path_parameters() + +

+ + +
+

Returns a hash with the parameters used to form the path of the request. Returned hash keys are strings:

+ +
{'action' => 'my_action', 'controller' => 'my_controller'}
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/parameters.rb, line 83
+def path_parameters
+  get_header(PARAMETERS_KEY) || set_header(PARAMETERS_KEY, {})
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/Parameters/ClassMethods.html b/src/5.2/classes/ActionDispatch/Http/Parameters/ClassMethods.html new file mode 100644 index 0000000000..0036d406a9 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/Parameters/ClassMethods.html @@ -0,0 +1,109 @@ +--- +title: ActionDispatch::Http::Parameters::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + parameter_parsers=(parsers) + +

+ + +
+

Configure the parameter parser for a given MIME type.

+ +

It accepts a hash where the key is the symbol of the MIME type and the value is a proc.

+ +
original_parsers = ActionDispatch::Request.parameter_parsers
+xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} }
+new_parsers = original_parsers.merge(xml: xml_parser)
+ActionDispatch::Request.parameter_parsers = new_parsers
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/parameters.rb, line 44
+def parameter_parsers=(parsers)
+  @parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/Parameters/ParseError.html b/src/5.2/classes/ActionDispatch/Http/Parameters/ParseError.html new file mode 100644 index 0000000000..cba88fefb4 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/Parameters/ParseError.html @@ -0,0 +1,113 @@ +--- +title: ActionDispatch::Http::Parameters::ParseError +layout: default +--- +
+ +
+
+ +
+ +

Raised when raw data from the request cannot be parsed by the parser defined for request's content MIME type.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/parameters.rb, line 20
+def initialize
+  super($!.message)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/URL.html b/src/5.2/classes/ActionDispatch/Http/URL.html new file mode 100644 index 0000000000..94250b50ba --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/URL.html @@ -0,0 +1,1056 @@ +--- +title: ActionDispatch::Http::URL +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HOST_REGEXP=/(^[^:]+:\/\/)?(\[[^\]]+\]|[^:]+)(?::(\d+$))?/
 
IP_HOST_REGEXP=/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
 
PROTOCOL_REGEXP=/^([^:]+)(:)?(\/\/)?$/
 
+ + + + + + +

Class Public methods

+ +
+

+ + extract_domain(host, tld_length) + +

+ + +
+

Returns the domain part of a host given the domain level.

+ +
# Top-level domain example
+extract_domain('www.example.com', 1) # => "example.com"
+# Second-level domain example
+extract_domain('dev.www.example.co.uk', 2) # => "example.co.uk"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 21
+def extract_domain(host, tld_length)
+  extract_domain_from(host, tld_length) if named_host?(host)
+end
+
+
+ +
+ +
+

+ + extract_subdomain(host, tld_length) + +

+ + +
+

Returns the subdomains of a host as a String given the domain level.

+ +
# Top-level domain example
+extract_subdomain('www.example.com', 1) # => "www"
+# Second-level domain example
+extract_subdomain('dev.www.example.co.uk', 2) # => "dev.www"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 45
+def extract_subdomain(host, tld_length)
+  extract_subdomains(host, tld_length).join(".")
+end
+
+
+ +
+ +
+

+ + extract_subdomains(host, tld_length) + +

+ + +
+

Returns the subdomains of a host as an Array given the domain level.

+ +
# Top-level domain example
+extract_subdomains('www.example.com', 1) # => ["www"]
+# Second-level domain example
+extract_subdomains('dev.www.example.co.uk', 2) # => ["dev", "www"]
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 31
+def extract_subdomains(host, tld_length)
+  if named_host?(host)
+    extract_subdomains_from(host, tld_length)
+  else
+    []
+  end
+end
+
+
+ +
+ +
+

+ + full_url_for(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 57
+def full_url_for(options)
+  host     = options[:host]
+  protocol = options[:protocol]
+  port     = options[:port]
+
+  unless host
+    raise ArgumentError, "Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true"
+  end
+
+  build_host_url(host, port, protocol, options, path_for(options))
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 186
+def initialize
+  super
+  @protocol = nil
+  @port     = nil
+end
+
+
+ +
+ +
+

+ + path_for(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 69
+def path_for(options)
+  path = options[:script_name].to_s.chomp("/".freeze)
+  path << options[:path] if options.key?(:path)
+
+  add_trailing_slash(path) if options[:trailing_slash]
+  add_params(path, options[:params]) if options.key?(:params)
+  add_anchor(path, options[:anchor]) if options.key?(:anchor)
+
+  path
+end
+
+
+ +
+ +
+

+ + url_for(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 49
+def url_for(options)
+  if options[:only_path]
+    path_for options
+  else
+    full_url_for options
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + domain(tld_length = @@tld_length) + +

+ + +
+

Returns the domain part of a host, such as “rubyonrails.org” in “www.rubyonrails.org”. You can specify a different tld_length, such as 2 to catch rubyonrails.co.uk in “www.rubyonrails.co.uk”.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 329
+def domain(tld_length = @@tld_length)
+  ActionDispatch::Http::URL.extract_domain(host, tld_length)
+end
+
+
+ +
+ +
+

+ + host() + +

+ + +
+

Returns the host for this request, such as “example.com”.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.host # => "example.com"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 233
+def host
+  raw_host_with_port.sub(/:\d+$/, "".freeze)
+end
+
+
+ +
+ +
+

+ + host_with_port() + +

+ + +
+

Returns a host:port string for this request, such as “example.com” or “example.com:8080”. Port is only included if it is not a default port (80 or 443)

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
+req.host_with_port # => "example.com"
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
+req.host_with_port # => "example.com"
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.host_with_port # => "example.com:8080"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 249
+def host_with_port
+  "#{host}#{port_string}"
+end
+
+
+ +
+ +
+

+ + optional_port() + +

+ + +
+

Returns a number port suffix like 8080 if the port number of this request is not the default HTTP port 80 or HTTPS port 443.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
+req.optional_port # => nil
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.optional_port # => 8080
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 300
+def optional_port
+  standard_port? ? nil : port
+end
+
+
+ +
+ +
+

+ + port() + +

+ + +
+

Returns the port number of this request as an integer.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
+req.port # => 80
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.port # => 8080
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 260
+def port
+  @port ||= begin
+    if raw_host_with_port =~ /:(\d+)$/
+      $1.to_i
+    else
+      standard_port
+    end
+  end
+end
+
+
+ +
+ +
+

+ + port_string() + +

+ + +
+

Returns a string port suffix, including colon, like “:8080” if the port number of this request is not the default HTTP port 80 or HTTPS port 443.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
+req.port_string # => ""
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.port_string # => ":8080"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 312
+def port_string
+  standard_port? ? "" : ":#{port}"
+end
+
+
+ +
+ +
+

+ + protocol() + +

+ + +
+

Returns 'https://' if this is an SSL request and 'http://' otherwise.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
+req.protocol # => "http://"
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on'
+req.protocol # => "https://"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 207
+def protocol
+  @protocol ||= ssl? ? "https://" : "http://"
+end
+
+
+ +
+ +
+

+ + raw_host_with_port() + +

+ + +
+

Returns the host and port for this request, such as “example.com:8080”.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
+req.raw_host_with_port # => "example.com"
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
+req.raw_host_with_port # => "example.com:80"
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.raw_host_with_port # => "example.com:8080"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 221
+def raw_host_with_port
+  if forwarded = x_forwarded_host.presence
+    forwarded.split(/,\s?/).last
+  else
+    get_header("HTTP_HOST") || "#{server_name || server_addr}:#{get_header('SERVER_PORT')}"
+  end
+end
+
+
+ +
+ +
+

+ + server_port() + +

+ + +
+

Returns the requested port, such as 8080, based on SERVER_PORT

+ +
req = ActionDispatch::Request.new 'SERVER_PORT' => '80'
+req.server_port # => 80
+
+req = ActionDispatch::Request.new 'SERVER_PORT' => '8080'
+req.server_port # => 8080
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 323
+def server_port
+  get_header("SERVER_PORT").to_i
+end
+
+
+ +
+ +
+

+ + standard_port() + +

+ + +
+

Returns the standard port number for this request's protocol.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.standard_port # => 80
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 274
+def standard_port
+  case protocol
+  when "https://" then 443
+  else 80
+  end
+end
+
+
+ +
+ +
+

+ + standard_port?() + +

+ + +
+

Returns whether this request is using the standard port

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
+req.standard_port? # => true
+
+req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.standard_port? # => false
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 288
+def standard_port?
+  port == standard_port
+end
+
+
+ +
+ +
+

+ + subdomain(tld_length = @@tld_length) + +

+ + +
+

Returns all the subdomains as a string, so "dev.www" would be returned for “dev.www.rubyonrails.org”. You can specify a different tld_length, such as 2 to catch "www" instead of "www.rubyonrails" in “www.rubyonrails.co.uk”.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 345
+def subdomain(tld_length = @@tld_length)
+  ActionDispatch::Http::URL.extract_subdomain(host, tld_length)
+end
+
+
+ +
+ +
+

+ + subdomains(tld_length = @@tld_length) + +

+ + +
+

Returns all the subdomains as an array, so ["dev", "www"] would be returned for “dev.www.rubyonrails.org”. You can specify a different tld_length, such as 2 to catch ["www"] instead of ["www", "rubyonrails"] in “www.rubyonrails.co.uk”.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 337
+def subdomains(tld_length = @@tld_length)
+  ActionDispatch::Http::URL.extract_subdomains(host, tld_length)
+end
+
+
+ +
+ +
+

+ + url() + +

+ + +
+

Returns the complete URL used for this request.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
+req.url # => "http://example.com"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/url.rb, line 196
+def url
+  protocol + host_with_port + fullpath
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Http/UploadedFile.html b/src/5.2/classes/ActionDispatch/Http/UploadedFile.html new file mode 100644 index 0000000000..c03f758672 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Http/UploadedFile.html @@ -0,0 +1,397 @@ +--- +title: ActionDispatch::Http::UploadedFile +layout: default +--- +
+ +
+
+ +
+ +

Models uploaded files.

+ +

The actual file is accessible via the tempfile accessor, though some of its interface is available directly for convenience.

+ +

Uploaded files are temporary files whose lifespan is one request. When the object is finalized Ruby unlinks the file, so there is no need to clean them with a separate maintenance task.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + content_type

A string with the MIME type of the file.

+ [RW] + headers

A string with the headers of the multipart request.

+ [RW] + original_filename

The basename of the file in the client.

+ [RW] + tempfile

A Tempfile object with the actual uploaded file. Note that some of its interface is available directly.

+ [RW] + to_io

A Tempfile object with the actual uploaded file. Note that some of its interface is available directly.

+ + + + + +

Instance Public methods

+ +
+

+ + close(unlink_now = false) + +

+ + +
+

Shortcut for tempfile.close.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/upload.rb, line 59
+def close(unlink_now = false)
+  @tempfile.close(unlink_now)
+end
+
+
+ +
+ +
+

+ + eof?() + +

+ + +
+

Shortcut for tempfile.eof?.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/upload.rb, line 79
+def eof?
+  @tempfile.eof?
+end
+
+
+ +
+ +
+

+ + open() + +

+ + +
+

Shortcut for tempfile.open.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/upload.rb, line 54
+def open
+  @tempfile.open
+end
+
+
+ +
+ +
+

+ + path() + +

+ + +
+

Shortcut for tempfile.path.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/upload.rb, line 64
+def path
+  @tempfile.path
+end
+
+
+ +
+ +
+

+ + read(length = nil, buffer = nil) + +

+ + +
+

Shortcut for tempfile.read.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/upload.rb, line 49
+def read(length = nil, buffer = nil)
+  @tempfile.read(length, buffer)
+end
+
+
+ +
+ +
+

+ + rewind() + +

+ + +
+

Shortcut for tempfile.rewind.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/upload.rb, line 69
+def rewind
+  @tempfile.rewind
+end
+
+
+ +
+ +
+

+ + size() + +

+ + +
+

Shortcut for tempfile.size.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/upload.rb, line 74
+def size
+  @tempfile.size
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Integration.html b/src/5.2/classes/ActionDispatch/Integration.html new file mode 100644 index 0000000000..d5bf2cfc56 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Integration.html @@ -0,0 +1,78 @@ +--- +title: ActionDispatch::Integration +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Integration/RequestHelpers.html b/src/5.2/classes/ActionDispatch/Integration/RequestHelpers.html new file mode 100644 index 0000000000..4d61be3f6a --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Integration/RequestHelpers.html @@ -0,0 +1,337 @@ +--- +title: ActionDispatch::Integration::RequestHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + delete(path, **args) + +

+ + +
+

Performs a DELETE request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 41
+def delete(path, **args)
+  process(:delete, path, **args)
+end
+
+
+ +
+ +
+

+ + follow_redirect!() + +

+ + +
+

Follow a single redirect response. If the last response was not a redirect, an exception will be raised. Otherwise, the redirect is performed on the location header.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 54
+def follow_redirect!
+  raise "not a redirect! #{status} #{status_message}" unless redirect?
+  get(response.location)
+  status
+end
+
+
+ +
+ +
+

+ + get(path, **args) + +

+ + +
+

Performs a GET request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 17
+def get(path, **args)
+  process(:get, path, **args)
+end
+
+
+ +
+ +
+

+ + head(path, *args) + +

+ + +
+

Performs a HEAD request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 47
+def head(path, *args)
+  process(:head, path, *args)
+end
+
+
+ +
+ +
+

+ + patch(path, **args) + +

+ + +
+

Performs a PATCH request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 29
+def patch(path, **args)
+  process(:patch, path, **args)
+end
+
+
+ +
+ +
+

+ + post(path, **args) + +

+ + +
+

Performs a POST request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 23
+def post(path, **args)
+  process(:post, path, **args)
+end
+
+
+ +
+ +
+

+ + put(path, **args) + +

+ + +
+

Performs a PUT request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 35
+def put(path, **args)
+  process(:put, path, **args)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Integration/Runner.html b/src/5.2/classes/ActionDispatch/Integration/Runner.html new file mode 100644 index 0000000000..0b41a5c9b1 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Integration/Runner.html @@ -0,0 +1,403 @@ +--- +title: ActionDispatch::Integration::Runner +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
APP_SESSIONS={}
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + app
+ + + + +

Class Public methods

+ +
+

+ + new(*args, &blk) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 307
+def initialize(*args, &blk)
+  super(*args, &blk)
+  @integration_session = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + create_session(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 327
+def create_session(app)
+  klass = APP_SESSIONS[app] ||= Class.new(Integration::Session) {
+    # If the app is a Rails app, make url_helpers available on the session.
+    # This makes app.url_for and app.foo_path available in the console.
+    if app.respond_to?(:routes)
+      include app.routes.url_helpers
+      include app.routes.mounted_helpers
+    end
+  }
+  klass.new(app)
+end
+
+
+ +
+ +
+

+ + default_url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 381
+def default_url_options
+  integration_session.default_url_options
+end
+
+
+ +
+ +
+

+ + default_url_options=(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 385
+def default_url_options=(options)
+  integration_session.default_url_options = options
+end
+
+
+ +
+ +
+

+ + integration_session() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 317
+def integration_session
+  @integration_session ||= create_session(app)
+end
+
+
+ +
+ +
+

+ + open_session() + +

+ + +
+

Open a new session instance. If a block is given, the new session is yielded to the block before being returned.

+ +
session = open_session do |sess|
+  sess.extend(CustomAssertions)
+end
+
+ +

By default, a single session is automatically created for you, but you can use this method to open multiple sessions that ought to be tested simultaneously.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 366
+def open_session
+  dup.tap do |session|
+    session.reset!
+    yield session if block_given?
+  end
+end
+
+
+ +
+ +
+

+ + reset!() + +

+ + +
+

Reset the current session. This is useful for testing multiple sessions in a single test case.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 323
+def reset!
+  @integration_session = create_session(app)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Integration/Session.html b/src/5.2/classes/ActionDispatch/Integration/Session.html new file mode 100644 index 0000000000..eff1a7d0ae --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Integration/Session.html @@ -0,0 +1,628 @@ +--- +title: ActionDispatch::Integration::Session +layout: default +--- +
+ +
+
+ +
+ +

An instance of this class represents a set of requests and responses performed sequentially by a test process. Because you can instantiate multiple sessions and run them side-by-side, you can also mimic (to some limited extent) multiple simultaneous users interacting with your system.

+ +

Typically, you will instantiate a new session using IntegrationTest#open_session, rather than instantiating Integration::Session directly.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_HOST="www.example.com"
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + accept

The Accept header to send.

+ [R] + controller

A reference to the controller instance used by the last request.

+ [W] + host
+ [W] + host!
+ [RW] + remote_addr

The remote_addr used in the last request.

+ [R] + request

A reference to the request instance used by the last request.

+ [RW] + request_count

A running counter of the number of requests processed.

+ [R] + response

A reference to the response instance used by the last request.

+ + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+

Create and initialize a new Session instance.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 116
+def initialize(app)
+  super()
+  @app = app
+
+  reset!
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + cookies() + +

+ + +
+

A map of the cookies returned by the last response, and which will be sent with the next request.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 97
+def cookies
+  _mock_session.cookie_jar
+end
+
+
+ +
+ +
+

+ + host() + +

+ + +
+

The hostname used in the last request.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 84
+def host
+  @host || DEFAULT_HOST
+end
+
+
+ +
+ +
+

+ + https!(flag = true) + +

+ + +
+

Specify whether or not the session should mimic a secure HTTPS request.

+ +
session.https!
+session.https!(false)
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 164
+def https!(flag = true)
+  @https = flag
+end
+
+
+ +
+ +
+

+ + https?() + +

+ + +
+

Returns true if the session is mimicking a secure HTTPS request.

+ +
if session.https?
+  ...
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 173
+def https?
+  @https
+end
+
+
+ +
+ +
+

+ + process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: nil) + +

+ + +
+

Performs the actual request.

+
  • +

    method: The HTTP method (GET, POST, PATCH, PUT, DELETE, HEAD, OPTIONS) as a symbol.

    +
  • +

    path: The URI (as a String) on which you want to perform the request.

    +
  • +

    params: The HTTP parameters that you want to pass. This may be nil, a Hash, or a String that is appropriately encoded (application/x-www-form-urlencoded or multipart/form-data).

    +
  • +

    headers: Additional headers to pass, as a Hash. The headers will be merged into the Rack env hash.

    +
  • +

    env: Additional env to pass, as a Hash. The headers will be merged into the Rack env hash.

    +
+ +

This method is rarely used directly. Use #get, #post, or other standard HTTP methods in integration tests. #process is only required when using a request method that doesn't have a method defined in the integration tests.

+ +

This method returns the response status, after performing the request. Furthermore, if this method was called from an ActionDispatch::IntegrationTest object, then that object's @response instance variable will point to a Response object which one can use to inspect the details of the response.

+ +

Example:

+ +
process :get, '/author', params: { since: 201501011400 }
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 204
+def process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: nil)
+  request_encoder = RequestEncoder.encoder(as)
+  headers ||= {}
+
+  if method == :get && as == :json && params
+    headers["X-Http-Method-Override"] = "GET"
+    method = :post
+  end
+
+  if path =~ %r{://}
+    path = build_expanded_path(path) do |location|
+      https! URI::HTTPS === location if location.scheme
+
+      if url_host = location.host
+        default = Rack::Request::DEFAULT_PORTS[location.scheme]
+        url_host += ":#{location.port}" if default != location.port
+        host! url_host
+      end
+    end
+  end
+
+  hostname, port = host.split(":")
+
+  request_env = {
+    :method => method,
+    :params => request_encoder.encode_params(params),
+
+    "SERVER_NAME"     => hostname,
+    "SERVER_PORT"     => port || (https? ? "443" : "80"),
+    "HTTPS"           => https? ? "on" : "off",
+    "rack.url_scheme" => https? ? "https" : "http",
+
+    "REQUEST_URI"    => path,
+    "HTTP_HOST"      => host,
+    "REMOTE_ADDR"    => remote_addr,
+    "CONTENT_TYPE"   => request_encoder.content_type,
+    "HTTP_ACCEPT"    => request_encoder.accept_header || accept
+  }
+
+  wrapped_headers = Http::Headers.from_hash({})
+  wrapped_headers.merge!(headers) if headers
+
+  if xhr
+    wrapped_headers["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest"
+    wrapped_headers["HTTP_ACCEPT"] ||= [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ")
+  end
+
+  # This modifies the passed request_env directly.
+  if wrapped_headers.present?
+    Http::Headers.from_hash(request_env).merge!(wrapped_headers)
+  end
+  if env.present?
+    Http::Headers.from_hash(request_env).merge!(env)
+  end
+
+  session = Rack::Test::Session.new(_mock_session)
+
+  # NOTE: rack-test v0.5 doesn't build a default uri correctly
+  # Make sure requested path is always a full URI.
+  session.request(build_full_uri(path, request_env), request_env)
+
+  @request_count += 1
+  @request = ActionDispatch::Request.new(session.last_request.env)
+  response = _mock_session.last_response
+  @response = ActionDispatch::TestResponse.from_response(response)
+  @response.request = @request
+  @html_document = nil
+  @url_options = nil
+
+  @controller = @request.controller_instance
+
+  response.status
+end
+
+
+ +
+ +
+

+ + reset!() + +

+ + +
+

Resets the instance. This can be used to reset the state information in an existing session instance, so it can be used from a clean-slate condition.

+ +
session.reset!
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 140
+def reset!
+  @https = false
+  @controller = @request = @response = nil
+  @_mock_session = nil
+  @request_count = 0
+  @url_options = nil
+
+  self.host        = DEFAULT_HOST
+  self.remote_addr = "127.0.0.1"
+  self.accept      = "text/xml,application/xml,application/xhtml+xml," \
+                     "text/html;q=0.9,text/plain;q=0.8,image/png," \
+                     "*/*;q=0.5"
+
+  unless defined? @named_routes_configured
+    # the helpers are made protected by default--we make them public for
+    # easier access during testing and troubleshooting.
+    @named_routes_configured = true
+  end
+end
+
+
+ +
+ +
+

+ + url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 123
+def url_options
+  @url_options ||= default_url_options.dup.tap do |url_options|
+    url_options.reverse_merge!(controller.url_options) if controller
+
+    if @app.respond_to?(:routes)
+      url_options.reverse_merge!(@app.routes.default_url_options)
+    end
+
+    url_options.reverse_merge!(host: host, protocol: https? ? "https" : "http")
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/IntegrationTest.html b/src/5.2/classes/ActionDispatch/IntegrationTest.html new file mode 100644 index 0000000000..260b13b544 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/IntegrationTest.html @@ -0,0 +1,281 @@ +--- +title: ActionDispatch::IntegrationTest +layout: default +--- +
+ +
+
+ +
+ +

An integration test spans multiple controllers and actions, tying them all together to ensure they work together as expected. It tests more completely than either unit or functional tests do, exercising the entire stack, from the dispatcher to the database.

+ +

At its simplest, you simply extend IntegrationTest and write your tests using the get/post methods:

+ +
require "test_helper"
+
+class ExampleTest < ActionDispatch::IntegrationTest
+  fixtures :people
+
+  def test_login
+    # get the login page
+    get "/login"
+    assert_equal 200, status
+
+    # post the login and follow through to the home page
+    post "/login", params: { username: people(:jamis).username,
+      password: people(:jamis).password }
+    follow_redirect!
+    assert_equal 200, status
+    assert_equal "/home", path
+  end
+end
+
+ +

However, you can also have multiple session instances open per test, and even extend those instances with assertions and methods to create a very powerful testing DSL that is specific for your application. You can even reference any named routes you happen to have defined.

+ +
require "test_helper"
+
+class AdvancedTest < ActionDispatch::IntegrationTest
+  fixtures :people, :rooms
+
+  def test_login_and_speak
+    jamis, david = login(:jamis), login(:david)
+    room = rooms(:office)
+
+    jamis.enter(room)
+    jamis.speak(room, "anybody home?")
+
+    david.enter(room)
+    david.speak(room, "hello!")
+  end
+
+  private
+
+    module CustomAssertions
+      def enter(room)
+        # reference a named route, for maximum internal consistency!
+        get(room_url(id: room.id))
+        assert(...)
+        ...
+      end
+
+      def speak(room, message)
+        post "/say/#{room.id}", xhr: true, params: { message: message }
+        assert(...)
+        ...
+      end
+    end
+
+    def login(who)
+      open_session do |sess|
+        sess.extend(CustomAssertions)
+        who = people(who)
+        sess.post "/login", params: { username: who.username,
+          password: who.password }
+        assert(...)
+      end
+    end
+end
+
+ +

Another longer example would be:

+ +

A simple integration test that exercises multiple controllers:

+ +
require 'test_helper'
+
+class UserFlowsTest < ActionDispatch::IntegrationTest
+  test "login and browse site" do
+    # login via https
+    https!
+    get "/login"
+    assert_response :success
+
+    post "/login", params: { username: users(:david).username, password: users(:david).password }
+    follow_redirect!
+    assert_equal '/welcome', path
+    assert_equal 'Welcome david!', flash[:notice]
+
+    https!(false)
+    get "/articles/all"
+    assert_response :success
+    assert_select 'h1', 'Articles'
+  end
+end
+
+ +

As you can see the integration test involves multiple controllers and exercises the entire stack from database to dispatcher. In addition you can have multiple session instances open simultaneously in a test and extend those instances with assertion methods to create a very powerful testing DSL (domain-specific language) just for your application.

+ +

Here's an example of multiple sessions and custom DSL in an integration test

+ +
require 'test_helper'
+
+class UserFlowsTest < ActionDispatch::IntegrationTest
+  test "login and browse site" do
+    # User david logs in
+    david = login(:david)
+    # User guest logs in
+    guest = login(:guest)
+
+    # Both are now available in different sessions
+    assert_equal 'Welcome david!', david.flash[:notice]
+    assert_equal 'Welcome guest!', guest.flash[:notice]
+
+    # User david can browse site
+    david.browses_site
+    # User guest can browse site as well
+    guest.browses_site
+
+    # Continue with other assertions
+  end
+
+  private
+
+    module CustomDsl
+      def browses_site
+        get "/products/all"
+        assert_response :success
+        assert_select 'h1', 'Products'
+      end
+    end
+
+    def login(user)
+      open_session do |sess|
+        sess.extend(CustomDsl)
+        u = users(user)
+        sess.https!
+        sess.post "/login", params: { username: u.username, password: u.password }
+        assert_equal '/welcome', sess.path
+        sess.https!(false)
+      end
+    end
+end
+
+ +

See the request helpers documentation for help on how to use get, etc.

+ +

Changing the request encoding

+ +

You can also test your JSON API easily by setting what the request should be encoded as:

+ +
require "test_helper"
+
+class ApiTest < ActionDispatch::IntegrationTest
+  test "creates articles" do
+    assert_difference -> { Article.count } do
+      post articles_path, params: { article: { title: "Ahoy!" } }, as: :json
+    end
+
+    assert_response :success
+    assert_equal({ id: Article.last.id, title: "Ahoy!" }, response.parsed_body)
+  end
+end
+
+ +

The as option passes an “application/json” Accept header (thereby setting the request format to JSON unless overridden), sets the content type to “application/json” and encodes the parameters as JSON.

+ +

Calling parsed_body on the response parses the response body based on the last response MIME type.

+ +

Out of the box, only :json is supported. But for any custom MIME types you've registered, you can add your own encoders with:

+ +
ActionDispatch::IntegrationTest.register_encoder :wibble,
+  param_encoder: -> params { params.to_wibble },
+  response_parser: -> body { body }
+
+ +

Where param_encoder defines how the params should be encoded and response_parser defines how the response body should be parsed through parsed_body.

+ +

Consult the Rails Testing Guide for more.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/IntegrationTest/Behavior.html b/src/5.2/classes/ActionDispatch/IntegrationTest/Behavior.html new file mode 100644 index 0000000000..3a1d174c97 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/IntegrationTest/Behavior.html @@ -0,0 +1,183 @@ +--- +title: ActionDispatch::IntegrationTest::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 642
+def app
+  super || self.class.app
+end
+
+
+ +
+ +
+

+ + document_root_element() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 646
+def document_root_element
+  html_document.root
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/IntegrationTest/Behavior/ClassMethods.html b/src/5.2/classes/ActionDispatch/IntegrationTest/Behavior/ClassMethods.html new file mode 100644 index 0000000000..15116a8b56 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/IntegrationTest/Behavior/ClassMethods.html @@ -0,0 +1,183 @@ +--- +title: ActionDispatch::IntegrationTest::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 625
+def app
+  if defined?(@@app) && @@app
+    @@app
+  else
+    ActionDispatch.test_app
+  end
+end
+
+
+ +
+ +
+

+ + app=(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 633
+def app=(app)
+  @@app = app
+end
+
+
+ +
+ +
+

+ + register_encoder(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 637
+def register_encoder(*args)
+  RequestEncoder.register_encoder(*args)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/IntegrationTest/UrlOptions.html b/src/5.2/classes/ActionDispatch/IntegrationTest/UrlOptions.html new file mode 100644 index 0000000000..7d6830c05b --- /dev/null +++ b/src/5.2/classes/ActionDispatch/IntegrationTest/UrlOptions.html @@ -0,0 +1,101 @@ +--- +title: ActionDispatch::IntegrationTest::UrlOptions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/integration.rb, line 606
+def url_options
+  integration_session.url_options
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey.html b/src/5.2/classes/ActionDispatch/Journey.html new file mode 100644 index 0000000000..b122958763 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey.html @@ -0,0 +1,111 @@ +--- +title: ActionDispatch::Journey +layout: default +--- + diff --git a/src/5.2/classes/ActionDispatch/Journey/Format.html b/src/5.2/classes/ActionDispatch/Journey/Format.html new file mode 100644 index 0000000000..dd449b0a9e --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Format.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Format +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey/Formatter.html b/src/5.2/classes/ActionDispatch/Journey/Formatter.html new file mode 100644 index 0000000000..97c37ba2b2 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Formatter.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::Journey::Formatter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey/Formatter/RegexCaseComparator.html b/src/5.2/classes/ActionDispatch/Journey/Formatter/RegexCaseComparator.html new file mode 100644 index 0000000000..09879d04ee --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Formatter/RegexCaseComparator.html @@ -0,0 +1,54 @@ +--- +title: ActionDispatch::Journey::Formatter::RegexCaseComparator +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey/Parser.html b/src/5.2/classes/ActionDispatch/Journey/Parser.html new file mode 100644 index 0000000000..d7269a8abd --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Parser.html @@ -0,0 +1,62 @@ +--- +title: ActionDispatch::Journey::Parser +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey/Route.html b/src/5.2/classes/ActionDispatch/Journey/Route.html new file mode 100644 index 0000000000..8534a8ec1f --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Route.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::Journey::Route +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers.html b/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers.html new file mode 100644 index 0000000000..8c7e6f5b62 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers.html @@ -0,0 +1,69 @@ +--- +title: ActionDispatch::Journey::Route::VerbMatchers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/All.html b/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/All.html new file mode 100644 index 0000000000..2cbb76ab7f --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/All.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Route::VerbMatchers::All +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/Unknown.html b/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/Unknown.html new file mode 100644 index 0000000000..9616d2e735 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Journey/Route/VerbMatchers/Unknown.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Route::VerbMatchers::Unknown +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/MiddlewareStack.html b/src/5.2/classes/ActionDispatch/MiddlewareStack.html new file mode 100644 index 0000000000..40c83a516c --- /dev/null +++ b/src/5.2/classes/ActionDispatch/MiddlewareStack.html @@ -0,0 +1,656 @@ +--- +title: ActionDispatch::MiddlewareStack +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + middlewares
+ + + + +

Class Public methods

+ +
+

+ + new(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 45
+def initialize(*args)
+  @middlewares = []
+  yield(self) if block_given?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](i) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 62
+def [](i)
+  middlewares[i]
+end
+
+
+ +
+ +
+

+ + build(app = nil, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 100
+def build(app = nil, &block)
+  middlewares.freeze.reverse.inject(app || block) { |a, e| e.build(a) }
+end
+
+
+ +
+ +
+

+ + delete(target) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 92
+def delete(target)
+  middlewares.delete_if { |m| m.klass == target }
+end
+
+
+ +
+ +
+

+ + each() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 50
+def each
+  @middlewares.each { |x| yield x }
+end
+
+
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 70
+def initialize_copy(other)
+  self.middlewares = other.middlewares.dup
+end
+
+
+ +
+ +
+

+ + insert(index, klass, *args, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: insert_before +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 74
+def insert(index, klass, *args, &block)
+  index = assert_index(index, :before)
+  middlewares.insert(index, build_middleware(klass, args, block))
+end
+
+
+ +
+ +
+

+ + insert_after(index, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 81
+def insert_after(index, *args, &block)
+  index = assert_index(index, :after)
+  insert(index + 1, *args, &block)
+end
+
+
+ +
+ +
+

+ + insert_before(index, klass, *args, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: insert +
+ + + +
+ +
+

+ + last() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 58
+def last
+  middlewares.last
+end
+
+
+ +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 54
+def size
+  middlewares.size
+end
+
+
+ +
+ +
+

+ + swap(target, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 86
+def swap(target, *args, &block)
+  index = assert_index(target, :before)
+  insert(index, *args, &block)
+  middlewares.delete_at(index + 1)
+end
+
+
+ +
+ +
+

+ + unshift(klass, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 66
+def unshift(klass, *args, &block)
+  middlewares.unshift(build_middleware(klass, args, block))
+end
+
+
+ +
+ +
+

+ + use(klass, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 96
+def use(klass, *args, &block)
+  middlewares.push(build_middleware(klass, args, block))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/MiddlewareStack/Middleware.html b/src/5.2/classes/ActionDispatch/MiddlewareStack/Middleware.html new file mode 100644 index 0000000000..464972eff9 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/MiddlewareStack/Middleware.html @@ -0,0 +1,305 @@ +--- +title: ActionDispatch::MiddlewareStack::Middleware +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + args
+ [R] + block
+ [R] + klass
+ + + + +

Class Public methods

+ +
+

+ + new(klass, args, block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 11
+def initialize(klass, args, block)
+  @klass = klass
+  @args  = args
+  @block = block
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(middleware) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 19
+def ==(middleware)
+  case middleware
+  when Middleware
+    klass == middleware.klass
+  when Class
+    klass == middleware
+  end
+end
+
+
+ +
+ +
+

+ + build(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 36
+def build(app)
+  klass.new(app, *args, &block)
+end
+
+
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 28
+def inspect
+  if klass.is_a?(Class)
+    klass.to_s
+  else
+    klass.class.to_s
+  end
+end
+
+
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 17
+def name; klass.name; end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/PublicExceptions.html b/src/5.2/classes/ActionDispatch/PublicExceptions.html new file mode 100644 index 0000000000..d737056926 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/PublicExceptions.html @@ -0,0 +1,176 @@ +--- +title: ActionDispatch::PublicExceptions +layout: default +--- +
+ +
+
+ +
+ +

When called, this middleware renders an error page. By default if an HTML response is expected it will render static error pages from the /public directory. For example when this middleware receives a 500 response it will render the template found in /public/500.html. If an internationalized locale is set, this middleware will attempt to render the template in /public/500.<locale>.html. If an internationalized template is not found it will fall back on /public/500.html.

+ +

When a request with a content type other than HTML is made, this middleware will attempt to convert error information into the appropriate response type.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + public_path
+ + + + +

Class Public methods

+ +
+

+ + new(public_path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/public_exceptions.rb, line 17
+def initialize(public_path)
+  @public_path = public_path
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/public_exceptions.rb, line 21
+def call(env)
+  request      = ActionDispatch::Request.new(env)
+  status       = request.path_info[1..-1].to_i
+  content_type = request.formats.first
+  body         = { status: status, error: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500]) }
+
+  render(status, content_type, body)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsEntityStore.html b/src/5.2/classes/ActionDispatch/RailsEntityStore.html new file mode 100644 index 0000000000..1df6844933 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsEntityStore.html @@ -0,0 +1,322 @@ +--- +title: ActionDispatch::RailsEntityStore +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(store = Rails.cache) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 37
+def initialize(store = Rails.cache)
+  @store = store
+end
+
+
+ +
+ +
+

+ + resolve(uri) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 33
+def self.resolve(uri)
+  new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 41
+def exist?(key)
+  @store.exist?(key)
+end
+
+
+ +
+ +
+

+ + open(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 45
+def open(key)
+  @store.read(key)
+end
+
+
+ +
+ +
+

+ + read(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 49
+def read(key)
+  body = open(key)
+  body.join if body
+end
+
+
+ +
+ +
+

+ + write(body) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 54
+def write(body)
+  buf = []
+  key, size = slurp(body) { |part| buf << part }
+  @store.write(key, buf)
+  [key, size]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack.html b/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack.html new file mode 100644 index 0000000000..4e724ed210 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack.html @@ -0,0 +1,67 @@ +--- +title: ActionDispatch::RailsEntityStore::Rack +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache.html b/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache.html new file mode 100644 index 0000000000..fccc66c0e0 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache.html @@ -0,0 +1,67 @@ +--- +title: ActionDispatch::RailsEntityStore::Rack::Cache +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache/EntityStore.html b/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache/EntityStore.html new file mode 100644 index 0000000000..3e1435c7f9 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsEntityStore/Rack/Cache/EntityStore.html @@ -0,0 +1,72 @@ +--- +title: ActionDispatch::RailsEntityStore::Rack::Cache::EntityStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RAILS=self
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsMetaStore.html b/src/5.2/classes/ActionDispatch/RailsMetaStore.html new file mode 100644 index 0000000000..3a121425b8 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsMetaStore.html @@ -0,0 +1,244 @@ +--- +title: ActionDispatch::RailsMetaStore +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(store = Rails.cache) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 13
+def initialize(store = Rails.cache)
+  @store = store
+end
+
+
+ +
+ +
+

+ + resolve(uri) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 9
+def self.resolve(uri)
+  new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + read(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 17
+def read(key)
+  if data = @store.read(key)
+    Marshal.load(data)
+  else
+    []
+  end
+end
+
+
+ +
+ +
+

+ + write(key, value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/rack_cache.rb, line 25
+def write(key, value)
+  @store.write(key, Marshal.dump(value))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack.html b/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack.html new file mode 100644 index 0000000000..e4be2def1d --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack.html @@ -0,0 +1,67 @@ +--- +title: ActionDispatch::RailsMetaStore::Rack +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache.html b/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache.html new file mode 100644 index 0000000000..425263c962 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache.html @@ -0,0 +1,67 @@ +--- +title: ActionDispatch::RailsMetaStore::Rack::Cache +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache/MetaStore.html b/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache/MetaStore.html new file mode 100644 index 0000000000..abef949caf --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RailsMetaStore/Rack/Cache/MetaStore.html @@ -0,0 +1,72 @@ +--- +title: ActionDispatch::RailsMetaStore::Rack::Cache::MetaStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RAILS=self
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Reloader.html b/src/5.2/classes/ActionDispatch/Reloader.html new file mode 100644 index 0000000000..60db0c4069 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Reloader.html @@ -0,0 +1,68 @@ +--- +title: ActionDispatch::Reloader +layout: default +--- +
+ +
+
+ +
+ +

ActionDispatch::Reloader wraps the request with callbacks provided by ActiveSupport::Reloader callbacks, intended to assist with code reloading during development.

+ +

By default, ActionDispatch::Reloader is included in the middleware stack only in the development environment; specifically, when config.cache_classes is false.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RemoteIp.html b/src/5.2/classes/ActionDispatch/RemoteIp.html new file mode 100644 index 0000000000..b568771f31 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RemoteIp.html @@ -0,0 +1,235 @@ +--- +title: ActionDispatch::RemoteIp +layout: default +--- +
+ +
+
+ +
+ +

This middleware calculates the IP address of the remote client that is making the request. It does this by checking various headers that could contain the address, and then picking the last-set address that is not on the list of trusted IPs. This follows the precedent set by e.g. the Tomcat server, with reasoning explained at length by @gingerlime. A more detailed explanation of the algorithm is given at GetIp#calculate_ip.

+ +

Some Rack servers concatenate repeated headers, like HTTP RFC 2616 requires. Some Rack servers simply drop preceding headers, and only report the value that was given in the last header. If you are behind multiple proxy servers (like NGINX to HAProxy to Unicorn) then you should test your Rack server to make sure your data is good.

+ +

IF YOU DON'T USE A PROXY, THIS MAKES YOU VULNERABLE TO IP SPOOFING. This middleware assumes that there is at least one proxy sitting around and setting headers with the client's remote IP address. If you don't use a proxy, because you are hosted on e.g. Heroku without SSL, any client can claim to have any IP address by setting the X-Forwarded-For header. If you care about that, then you need to explicitly drop or ignore those headers sometime before this middleware runs.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
TRUSTED_PROXIES=[ +"127.0.0.1", # localhost IPv4 +"::1", # localhost IPv6 +"fc00::/7", # private IPv6 range fc00::/7 +"10.0.0.0/8", # private IPv4 range 10.x.x.x +"172.16.0.0/12", # private IPv4 range 172.16.0.0 .. 172.31.255.255 +"192.168.0.0/16", # private IPv4 range 192.168.x.x +].map { |proxy| IPAddr.new(proxy) }
 

The default trusted IPs list simply includes IP addresses that are guaranteed by the IP specification to be private addresses. Those will not be the ultimate client IP in production, and so are discarded. See en.wikipedia.org/wiki/Private_network for details.

+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + check_ip
+ [R] + proxies
+ + + + +

Class Public methods

+ +
+

+ + new(app, ip_spoofing_check = true, custom_proxies = nil) + +

+ + +
+

Create a new RemoteIp middleware instance.

+ +

The ip_spoofing_check option is on by default. When on, an exception is raised if it looks like the client is trying to lie about its own IP address. It makes sense to turn off this check on sites aimed at non-IP clients (like WAP devices), or behind proxies that set headers in an incorrect or confusing way (like AWS ELB).

+ +

The custom_proxies argument can take an Array of string, IPAddr, or Regexp objects which will be used instead of TRUSTED_PROXIES. If a single string, IPAddr, or Regexp object is provided, it will be used in addition to TRUSTED_PROXIES. Any proxy setup will put the value you want in the middle (or at the beginning) of the X-Forwarded-For list, with your proxy servers after it. If your proxies aren't removed, pass them in via the custom_proxies parameter. That way, the middleware will ignore those IP addresses, and return the one that you want.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 62
+def initialize(app, ip_spoofing_check = true, custom_proxies = nil)
+  @app = app
+  @check_ip = ip_spoofing_check
+  @proxies = if custom_proxies.blank?
+    TRUSTED_PROXIES
+  elsif custom_proxies.respond_to?(:any?)
+    custom_proxies
+  else
+    Array(custom_proxies) + TRUSTED_PROXIES
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+

Since the IP address may not be needed, we store the object here without calculating the IP to keep from slowing down the majority of requests. For those requests that do need to know the IP, the GetIp#calculate_ip method will calculate the memoized client IP address.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 78
+def call(env)
+  req = ActionDispatch::Request.new env
+  req.remote_ip = GetIp.new(req, check_ip, proxies)
+  @app.call(req.env)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RemoteIp/GetIp.html b/src/5.2/classes/ActionDispatch/RemoteIp/GetIp.html new file mode 100644 index 0000000000..c398589160 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RemoteIp/GetIp.html @@ -0,0 +1,333 @@ +--- +title: ActionDispatch::RemoteIp::GetIp +layout: default +--- +
+ +
+
+ +
+ +

The GetIp class exists as a way to defer processing of the request data into an actual IP address. If the ActionDispatch::Request#remote_ip method is called, this class will calculate the value and then memoize it.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(req, check_ip, proxies) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 88
+def initialize(req, check_ip, proxies)
+  @req      = req
+  @check_ip = check_ip
+  @proxies  = proxies
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + calculate_ip() + +

+ + +
+

Sort through the various IP address headers, looking for the IP most likely to be the address of the actual remote client making this request.

+ +

REMOTE_ADDR will be correct if the request is made directly against the Ruby process, on e.g. Heroku. When the request is proxied by another server like HAProxy or NGINX, the IP address that made the original request will be put in an X-Forwarded-For header. If there are multiple proxies, that header may contain a list of IPs. Other proxy services set the Client-Ip header instead, so we check that too.

+ +

As discussed in this post about Rails IP Spoofing, while the first IP in the list is likely to be the “originating” IP, it could also have been set by the client maliciously.

+ +

In order to find the first address that is (probably) accurate, we take the list of IPs, remove known and trusted proxies, and then take the last address left, which was presumably set by one of those proxies.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 112
+def calculate_ip
+  # Set by the Rack web server, this is a single value.
+  remote_addr = ips_from(@req.remote_addr).last
+
+  # Could be a CSV list and/or repeated headers that were concatenated.
+  client_ips    = ips_from(@req.client_ip).reverse
+  forwarded_ips = ips_from(@req.x_forwarded_for).reverse
+
+  # +Client-Ip+ and +X-Forwarded-For+ should not, generally, both be set.
+  # If they are both set, it means that either:
+  #
+  # 1) This request passed through two proxies with incompatible IP header
+  #    conventions.
+  # 2) The client passed one of +Client-Ip+ or +X-Forwarded-For+
+  #    (whichever the proxy servers weren't using) themselves.
+  #
+  # Either way, there is no way for us to determine which header is the
+  # right one after the fact. Since we have no idea, if we are concerned
+  # about IP spoofing we need to give up and explode. (If you're not
+  # concerned about IP spoofing you can turn the +ip_spoofing_check+
+  # option off.)
+  should_check_ip = @check_ip && client_ips.last && forwarded_ips.last
+  if should_check_ip && !forwarded_ips.include?(client_ips.last)
+    # We don't know which came from the proxy, and which from the user
+    raise IpSpoofAttackError, "IP spoofing attack?! " \
+      "HTTP_CLIENT_IP=#{@req.client_ip.inspect} " \
+      "HTTP_X_FORWARDED_FOR=#{@req.x_forwarded_for.inspect}"
+  end
+
+  # We assume these things about the IP headers:
+  #
+  #   - X-Forwarded-For will be a list of IPs, one per proxy, or blank
+  #   - Client-Ip is propagated from the outermost proxy, or is blank
+  #   - REMOTE_ADDR will be the IP that made the request to Rack
+  ips = [forwarded_ips, client_ips, remote_addr].flatten.compact
+
+  # If every single IP option is in the trusted list, just return REMOTE_ADDR
+  filter_proxies(ips).first || remote_addr
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+

Memoizes the value returned by calculate_ip and returns it for ActionDispatch::Request to use.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 154
+def to_s
+  @ip ||= calculate_ip
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + filter_proxies(ips) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 176
+def filter_proxies(ips) # :doc:
+  ips.reject do |ip|
+    @proxies.any? { |proxy| proxy === ip }
+  end
+end
+
+
+ +
+ +
+

+ + ips_from(header) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 160
+def ips_from(header) # :doc:
+  return [] unless header
+  # Split the comma-separated list into an array of strings.
+  ips = header.strip.split(/[,\s]+/)
+  ips.select do |ip|
+    begin
+      # Only return IPs that are valid according to the IPAddr#new method.
+      range = IPAddr.new(ip).to_range
+      # We want to make sure nobody is sneaking a netmask in.
+      range.begin == range.end
+    rescue ArgumentError
+      nil
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RemoteIp/IpSpoofAttackError.html b/src/5.2/classes/ActionDispatch/RemoteIp/IpSpoofAttackError.html new file mode 100644 index 0000000000..6cdb4944be --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RemoteIp/IpSpoofAttackError.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::RemoteIp::IpSpoofAttackError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Request.html b/src/5.2/classes/ActionDispatch/Request.html new file mode 100644 index 0000000000..841a0e366f --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Request.html @@ -0,0 +1,1975 @@ +--- +title: ActionDispatch::Request +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ENV_METHODS=%w[ AUTH_TYPE GATEWAY_INTERFACE +PATH_TRANSLATED REMOTE_HOST +REMOTE_IDENT REMOTE_USER REMOTE_ADDR +SERVER_NAME SERVER_PROTOCOL +ORIGINAL_SCRIPT_NAME + +HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING +HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM +HTTP_NEGOTIATE HTTP_PRAGMA HTTP_CLIENT_IP +HTTP_X_FORWARDED_FOR HTTP_ORIGIN HTTP_VERSION +HTTP_X_CSRF_TOKEN HTTP_X_REQUEST_ID HTTP_X_FORWARDED_HOST +SERVER_ADDR +].freeze
 
HTTP_METHODS=RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789
 
HTTP_METHOD_LOOKUP={}
 
LOCALHOST=Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
 
RFC2518=%w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
 
RFC2616=%w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
 

List of HTTP request methods from the following RFCs: Hypertext Transfer Protocol – HTTP/1.1 (www.ietf.org/rfc/rfc2616.txt) HTTP Extensions for Distributed Authoring – WEBDAV (www.ietf.org/rfc/rfc2518.txt) Versioning Extensions to WebDAV (www.ietf.org/rfc/rfc3253.txt) Ordered Collections Protocol (WebDAV) (www.ietf.org/rfc/rfc3648.txt) Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (www.ietf.org/rfc/rfc3744.txt) Web Distributed Authoring and Versioning (WebDAV) SEARCH (www.ietf.org/rfc/rfc5323.txt) Calendar Extensions to WebDAV (www.ietf.org/rfc/rfc4791.txt) PATCH Method for HTTP (www.ietf.org/rfc/rfc5789.txt)

RFC3253=%w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
 
RFC3648=%w(ORDERPATCH)
 
RFC3744=%w(ACL)
 
RFC4791=%w(MKCALENDAR)
 
RFC5323=%w(SEARCH)
 
RFC5789=%w(PATCH)
 
+ + + + + + +

Class Public methods

+ +
+

+ + empty() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 55
+def self.empty
+  new({})
+end
+
+
+ +
+ +
+

+ + new(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 59
+def initialize(env)
+  super
+  @method            = nil
+  @request_method    = nil
+  @remote_ip         = nil
+  @original_fullpath = nil
+  @fullpath          = nil
+  @ip                = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + GET() + +

+ + +
+

Override Rack's GET method to support indifferent access.

+
+ + + +
+ Also aliased as: query_parameters +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 366
+def GET
+  fetch_header("action_dispatch.request.query_parameters") do |k|
+    rack_query_params = super || {}
+    # Check for non UTF-8 parameter values, which would cause errors later
+    Request::Utils.check_param_encoding(rack_query_params)
+    set_header k, Request::Utils.normalize_encode_params(rack_query_params)
+  end
+rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
+  raise ActionController::BadRequest.new("Invalid query parameters: #{e.message}")
+end
+
+
+ +
+ +
+

+ + POST() + +

+ + +
+

Override Rack's POST method to support indifferent access.

+
+ + + +
+ Also aliased as: request_parameters +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 379
+def POST
+  fetch_header("action_dispatch.request.request_parameters") do
+    pr = parse_formatted_parameters(params_parsers) do |params|
+      super || {}
+    end
+    self.request_parameters = Request::Utils.normalize_encode_params(pr)
+  end
+rescue Http::Parameters::ParseError # one of the parse strategies blew up
+  self.request_parameters = Request::Utils.normalize_encode_params(super || {})
+  raise
+rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
+  raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
+end
+
+
+ +
+ +
+

+ + authorization() + +

+ + +
+

Returns the authorization header regardless of whether it was specified directly or through one of the proxy alternatives.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 396
+def authorization
+  get_header("HTTP_AUTHORIZATION")   ||
+  get_header("X-HTTP_AUTHORIZATION") ||
+  get_header("X_HTTP_AUTHORIZATION") ||
+  get_header("REDIRECT_X_HTTP_AUTHORIZATION")
+end
+
+
+ +
+ +
+

+ + body() + +

+ + +
+

The request body is an IO input stream. If the RAW_POST_DATA environment variable is already set, wrap it in a StringIO.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 322
+def body
+  if raw_post = get_header("RAW_POST_DATA")
+    raw_post = raw_post.dup.force_encoding(Encoding::BINARY)
+    StringIO.new(raw_post)
+  else
+    body_stream
+  end
+end
+
+
+ +
+ +
+

+ + commit_flash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 417
+def commit_flash
+end
+
+
+ +
+ +
+

+ + content_length() + +

+ + +
+

Returns the content length of the request as an integer.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 259
+def content_length
+  super.to_i
+end
+
+
+ +
+ +
+

+ + controller_class() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 78
+def controller_class
+  params = path_parameters
+  params[:action] ||= "index"
+  controller_class_for(params[:controller])
+end
+
+
+ +
+ +
+

+ + controller_class_for(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 84
+def controller_class_for(name)
+  if name
+    controller_param = name.underscore
+    const_name = "#{controller_param.camelize}Controller"
+    ActiveSupport::Dependencies.constantize(const_name)
+  else
+    PASS_NOT_FOUND
+  end
+end
+
+
+ +
+ +
+ + + +
+ +
+ + + + + + + + +
+ + + +
+ +
+ +
+

+ + form_data?() + +

+ + +
+

Determine whether the request body contains form-data by checking the request Content-Type for one of the media-types: “application/x-www-form-urlencoded” or “multipart/form-data”. The list of form-data media types can be modified through the FORM_DATA_MEDIA_TYPES array.

+ +

A request body is not assumed to contain form-data when no Content-Type header is provided and the request_method is POST.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 339
+def form_data?
+  FORM_DATA_MEDIA_TYPES.include?(media_type)
+end
+
+
+ +
+ +
+

+ + fullpath() + +

+ + +
+

Returns the String full path including params of the last URL requested.

+ +
# get "/articles"
+request.fullpath # => "/articles"
+
+# get "/articles?page=2"
+request.fullpath # => "/articles?page=2"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 238
+def fullpath
+  @fullpath ||= super
+end
+
+
+ +
+ +
+

+ + headers() + +

+ + +
+

Provides access to the request's HTTP headers, for example:

+ +
request.headers["Content-Type"] # => "text/plain"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 199
+def headers
+  @headers ||= Http::Headers.new(self)
+end
+
+
+ +
+ +
+

+ + http_auth_salt() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 168
+def http_auth_salt
+  get_header "action_dispatch.http_auth_salt"
+end
+
+
+ +
+ +
+

+ + ip() + +

+ + +
+

Returns the IP address of client as a String.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 272
+def ip
+  @ip ||= super
+end
+
+
+ +
+ +
+

+ + key?(key) + +

+ + +
+

Returns true if the request has a header matching the given key parameter.

+ +
request.key? :ip_spoofing_check # => true
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 97
+def key?(key)
+  has_header? key
+end
+
+
+ +
+ +
+

+ + local?() + +

+ + +
+

True if the request came from localhost, 127.0.0.1, or ::1.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 404
+def local?
+  LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
+end
+
+
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 413
+def logger
+  get_header("action_dispatch.logger".freeze)
+end
+
+
+ +
+ +
+

+ + media_type() + +

+ + +
+

The String MIME type of the request.

+ +
# get "/articles"
+request.media_type # => "application/x-www-form-urlencoded"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 254
+def media_type
+  content_mime_type.to_s
+end
+
+
+ +
+ +
+

+ + method() + +

+ + +
+

Returns the original value of the environment's REQUEST_METHOD, even if it was overridden by middleware. See request_method for more information.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 187
+def method
+  @method ||= check_method(get_header("rack.methodoverride.original_method") || get_header("REQUEST_METHOD"))
+end
+
+
+ +
+ +
+

+ + method_symbol() + +

+ + +
+

Returns a symbol form of the method.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 192
+def method_symbol
+  HTTP_METHOD_LOOKUP[method]
+end
+
+
+ +
+ +
+

+ + original_fullpath() + +

+ + +
+

Returns a String with the last requested path including their params.

+ +
# get '/foo'
+request.original_fullpath # => '/foo'
+
+# get '/foo?bar'
+request.original_fullpath # => '/foo?bar'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 227
+def original_fullpath
+  @original_fullpath ||= (get_header("ORIGINAL_FULLPATH") || fullpath)
+end
+
+
+ +
+ +
+

+ + original_url() + +

+ + +
+

Returns the original request URL as a String.

+ +
# get "/articles?page=2"
+request.original_url # => "http://www.example.com/articles?page=2"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 246
+def original_url
+  base_url + original_fullpath
+end
+
+
+ +
+ +
+

+ + query_parameters() + +

+ + +
+ +
+ + + + + +
+ Alias for: GET +
+ + + +
+ +
+

+ + raw_post() + +

+ + +
+

Read the request body. This is useful for web services that need to work with raw requests directly.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 311
+def raw_post
+  unless has_header? "RAW_POST_DATA"
+    raw_post_body = body
+    set_header("RAW_POST_DATA", raw_post_body.read(content_length))
+    raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
+  end
+  get_header "RAW_POST_DATA"
+end
+
+
+ +
+ +
+

+ + remote_ip() + +

+ + +
+

Returns the IP address of client as a String, usually set by the RemoteIp middleware.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 278
+def remote_ip
+  @remote_ip ||= (get_header("action_dispatch.remote_ip") || ip).to_s
+end
+
+
+ +
+ +
+

+ + remote_ip=(remote_ip) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 282
+def remote_ip=(remote_ip)
+  set_header "action_dispatch.remote_ip".freeze, remote_ip
+end
+
+
+ +
+ +
+

+ + request_id() + +

+ + +
+

Returns the unique request id, which is based on either the X-Request-Id header that can be generated by a firewall, load balancer, or web server or by the RequestId middleware (which sets the action_dispatch.request_id environment variable).

+ +

This unique ID is useful for tracing a request from end-to-end as part of logging or debugging. This relies on the Rack variable set by the ActionDispatch::RequestId middleware.

+
+ + + +
+ Also aliased as: uuid +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 294
+def request_id
+  get_header ACTION_DISPATCH_REQUEST_ID
+end
+
+
+ +
+ +
+

+ + request_method() + +

+ + +
+

Returns the HTTP method that the application should see. In the case where the method was overridden by a middleware (for instance, if a HEAD request was converted to a GET, or if a _method parameter was used to determine the method the application should use), this method returns the overridden value, not the original.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 134
+def request_method
+  @request_method ||= check_method(super)
+end
+
+
+ +
+ +
+

+ + request_method_symbol() + +

+ + +
+

Returns a symbol form of the request_method.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 180
+def request_method_symbol
+  HTTP_METHOD_LOOKUP[request_method]
+end
+
+
+ +
+ +
+

+ + request_parameters() + +

+ + +
+ +
+ + + + + +
+ Alias for: POST +
+ + + +
+ +
+

+ + request_parameters=(params) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 408
+def request_parameters=(params)
+  raise if params.nil?
+  set_header("action_dispatch.request.request_parameters".freeze, params)
+end
+
+
+ +
+ +
+

+ + reset_session() + +

+ + +
+

TODO This should be broken apart into AD::Request::Session and probably be included by the session middleware.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 349
+def reset_session
+  if session && session.respond_to?(:destroy)
+    session.destroy
+  else
+    self.session = {}
+  end
+end
+
+
+ +
+ +
+

+ + send_early_hints(links) + +

+ + +
+

Early Hints is an HTTP/2 status code that indicates hints to help a client start making preparations for processing the final response.

+ +

If the env contains rack.early_hints then the server accepts HTTP2 push for Link headers.

+ +

The send_early_hints method accepts a hash of links as follows:

+ +
send_early_hints("Link" => "</style.css>; rel=preload; as=style\n</script.js>; rel=preload")
+
+ +

If you are using javascript_include_tag or stylesheet_link_tag the Early Hints headers are included by default if supported.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 214
+def send_early_hints(links)
+  return unless env["rack.early_hints"]
+
+  env["rack.early_hints"].call(links)
+end
+
+
+ +
+ +
+

+ + server_software() + +

+ + +
+

Returns the lowercase name of the HTTP server software.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 305
+def server_software
+  (get_header("SERVER_SOFTWARE") && /^([a-zA-Z]+)/ =~ get_header("SERVER_SOFTWARE")) ? $1.downcase : nil
+end
+
+
+ +
+ +
+

+ + session_options=(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 361
+def session_options=(options)
+  Session::Options.set self, options
+end
+
+
+ +
+ +
+

+ + ssl?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 420
+def ssl?
+  super || scheme == "wss".freeze
+end
+
+
+ +
+ +
+

+ + uuid() + +

+ + +
+ +
+ + + + + +
+ Alias for: request_id +
+ + + +
+ +
+

+ + xhr?() + +

+ + +
+ +
+ + + + + +
+ Alias for: xml_http_request? +
+ + + +
+ +
+

+ + xml_http_request?() + +

+ + +
+

Returns true if the “X-Requested-With” header contains “XMLHttpRequest” (case-insensitive), which may need to be manually added depending on the choice of JavaScript libraries and frameworks.

+
+ + + +
+ Also aliased as: xhr? +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/request.rb, line 266
+def xml_http_request?
+  get_header("HTTP_X_REQUESTED_WITH") =~ /XMLHttpRequest/i
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RequestEncoder.html b/src/5.2/classes/ActionDispatch/RequestEncoder.html new file mode 100644 index 0000000000..d4bab651e6 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RequestEncoder.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::RequestEncoder +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RequestEncoder/IdentityEncoder.html b/src/5.2/classes/ActionDispatch/RequestEncoder/IdentityEncoder.html new file mode 100644 index 0000000000..d9fdf51a14 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RequestEncoder/IdentityEncoder.html @@ -0,0 +1,216 @@ +--- +title: ActionDispatch::RequestEncoder::IdentityEncoder +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + accept_header() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 7
+def accept_header; end
+
+
+ +
+ +
+

+ + content_type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 6
+def content_type; end
+
+
+ +
+ +
+

+ + encode_params(params) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 8
+def encode_params(params); params; end
+
+
+ +
+ +
+

+ + response_parser() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 9
+def response_parser; -> body { body }; end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/RequestId.html b/src/5.2/classes/ActionDispatch/RequestId.html new file mode 100644 index 0000000000..4ddf7cb4ef --- /dev/null +++ b/src/5.2/classes/ActionDispatch/RequestId.html @@ -0,0 +1,161 @@ +--- +title: ActionDispatch::RequestId +layout: default +--- +
+ +
+
+ +
+ +

Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through ActionDispatch::Request#request_id or the alias ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header.

+ +

The unique request id is either based on the X-Request-Id header in the request, which would typically be generated by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only.

+ +

The unique request id can be used to trace a request end-to-end and would typically end up being part of log files from multiple pieces of the stack.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/request_id.rb, line 20
+def initialize(app)
+  @app = app
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/request_id.rb, line 24
+def call(env)
+  req = ActionDispatch::Request.new env
+  req.request_id = make_request_id(req.x_request_id)
+  @app.call(env).tap { |_status, headers, _body| headers[X_REQUEST_ID] = req.request_id }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Response.html b/src/5.2/classes/ActionDispatch/Response.html new file mode 100644 index 0000000000..d66f2246f4 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Response.html @@ -0,0 +1,1769 @@ +--- +title: ActionDispatch::Response +layout: default +--- +
+ +
+
+ +
+ +

Represents an HTTP response generated by a controller action. Use it to retrieve the current state of the response, or customize the response. It can either represent a real HTTP response (i.e. one that is meant to be sent back to the web browser) or a TestResponse (i.e. one that is generated from integration tests).

+ +

Response is mostly a Ruby on Rails framework implementation detail, and should never be used directly in controllers. Controllers should use the methods defined in ActionController::Base instead. For example, if you want to set the HTTP response's content MIME type, then use ActionControllerBase#headers instead of Response#headers.

+ +

Nevertheless, integration tests may want to inspect controller responses in more detail, and that's when Response can be useful for application developers. Integration test methods such as ActionDispatch::Integration::Session#get and ActionDispatch::Integration::Session#post return objects of type TestResponse (which are of course also of type Response).

+ +

For example, the following demo integration test prints the body of the controller response to the console:

+ +
class DemoControllerTest < ActionDispatch::IntegrationTest
+  def test_print_root_path_to_console
+    get('/')
+    puts response.body
+  end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CONTENT_TYPE="Content-Type".freeze
 
ContentTypeHeader=Struct.new :mime_type, :charset
 
LOCATION="Location".freeze
 
NO_CONTENT_CODES=[100, 101, 102, 204, 205, 304]
 
NullContentTypeHeader=ContentTypeHeader.new nil, nil
 
SET_COOKIE="Set-Cookie".freeze
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + header

Get headers for this response.

+ [R] + headers

Get headers for this response.

+ [RW] + request

The request that the response is responding to.

+ [R] + status

The HTTP status code.

+ [R] + stream

The underlying body, as a streamable object.

+ + + + +

Class Public methods

+ +
+

+ + create(status = 200, header = {}, body = [], default_headers: self.default_headers) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 151
+def self.create(status = 200, header = {}, body = [], default_headers: self.default_headers)
+  header = merge_default_headers(header, default_headers)
+  new status, header, body
+end
+
+
+ +
+ +
+

+ + merge_default_headers(original, default) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 156
+def self.merge_default_headers(original, default)
+  default.respond_to?(:merge) ? default.merge(original) : original
+end
+
+
+ +
+ +
+

+ + new(status = 200, header = {}, body = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 163
+def initialize(status = 200, header = {}, body = [])
+  super()
+
+  @header = Header.new(self, header)
+
+  self.body, self.status = body, status
+
+  @cv           = new_cond
+  @committed    = false
+  @sending      = false
+  @sent         = false
+
+  prepare_cache_control!
+
+  yield self if block_given?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + abort() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 368
+def abort
+  if stream.respond_to?(:abort)
+    stream.abort
+  elsif stream.respond_to?(:close)
+    # `stream.close` should really be reserved for a close from the
+    # other direction, but we must fall back to it for
+    # compatibility.
+    stream.close
+  end
+end
+
+
+ +
+ +
+

+ + await_commit() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 185
+def await_commit
+  synchronize do
+    @cv.wait_until { @committed }
+  end
+end
+
+
+ +
+ +
+

+ + await_sent() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 191
+def await_sent
+  synchronize { @cv.wait_until { @sent } }
+end
+
+
+ +
+ +
+

+ + body() + +

+ + +
+

Returns the content of the response as a string. This contains the contents of any calls to render.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 302
+def body
+  @stream.body
+end
+
+
+ +
+ +
+

+ + body=(body) + +

+ + +
+

Allows you to manually set or override the response body.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 311
+def body=(body)
+  if body.respond_to?(:to_path)
+    @stream = body
+  else
+    synchronize do
+      @stream = build_buffer self, munge_body_object(body)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + body_parts() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 355
+def body_parts
+  parts = []
+  @stream.each { |x| parts << x }
+  parts
+end
+
+
+ +
+ +
+

+ + charset() + +

+ + +
+

The charset of the response. HTML wants to know the encoding of the content you're giving them, so we need to send that along.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 272
+def charset
+  header_info = parsed_content_type_header
+  header_info.charset || self.class.default_charset
+end
+
+
+ +
+ +
+

+ + charset=(charset) + +

+ + +
+

Sets the HTTP character set. In case of nil parameter it sets the charset to default_charset.

+ +
response.charset = 'utf-16' # => 'utf-16'
+response.charset = nil      # => 'utf-8'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 261
+def charset=(charset)
+  content_type = parsed_content_type_header.mime_type
+  if false == charset
+    set_content_type content_type, nil
+  else
+    set_content_type content_type, charset || self.class.default_charset
+  end
+end
+
+
+ +
+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 364
+def close
+  stream.close if stream.respond_to?(:close)
+end
+
+
+ +
+ +
+

+ + code() + +

+ + +
+

Returns a string to ensure compatibility with Net::HTTPResponse.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 283
+def code
+  @status.to_s
+end
+
+
+ +
+ +
+

+ + commit!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 195
+def commit!
+  synchronize do
+    before_committed
+    @committed = true
+    @cv.broadcast
+  end
+end
+
+
+ +
+ +
+

+ + committed?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 219
+def committed?; synchronize { @committed }; end
+
+
+ +
+ +
+

+ + content_type() + +

+ + +
+

Sets the HTTP response's content MIME type. For example, in the controller you could write this:

+ +
response.content_type = "text/plain"
+
+ +

If a character set has been defined for this response (see charset=) then the character set information will also be included in the content type information.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 246
+def content_type
+  parsed_content_type_header.mime_type
+end
+
+
+ +
+ +
+

+ + content_type=(content_type) + +

+ + +
+

Sets the HTTP content type.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 228
+def content_type=(content_type)
+  return unless content_type
+  new_header_info = parse_content_type(content_type.to_s)
+  prev_header_info = parsed_content_type_header
+  charset = new_header_info.charset || prev_header_info.charset
+  charset ||= self.class.default_charset unless prev_header_info.mime_type
+  set_content_type new_header_info.mime_type, charset
+end
+
+
+ +
+ +
+

+ + cookies() + +

+ + +
+

Returns the response cookies, converted to a Hash of (name => value) pairs

+ +
assert_equal 'AuthorOfNewPage', r.cookies['author']
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 392
+def cookies
+  cookies = {}
+  if header = get_header(SET_COOKIE)
+    header = header.split("\n") if header.respond_to?(:to_str)
+    header.each do |cookie|
+      if pair = cookie.split(";").first
+        key, value = pair.split("=").map { |v| Rack::Utils.unescape(v) }
+        cookies[key] = value
+      end
+    end
+  end
+  cookies
+end
+
+
+ +
+ +
+

+ + delete_header(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 183
+def delete_header(key); headers.delete key; end
+
+
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 74
+def each(&block)
+  sending!
+  x = @stream.each(&block)
+  sent!
+  x
+end
+
+
+ +
+ +
+

+ + get_header(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 181
+def get_header(key);    headers[key];       end
+
+
+ +
+ +
+

+ + has_header?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 180
+def has_header?(key);   headers.key? key;   end
+
+
+ +
+ +
+

+ + message() + +

+ + +
+

Returns the corresponding message for the current HTTP status code:

+ +
response.status = 200
+response.message # => "OK"
+
+response.status = 404
+response.message # => "Not Found"
+
+
+ + + +
+ Also aliased as: status_message +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 295
+def message
+  Rack::Utils::HTTP_STATUS_CODES[@status]
+end
+
+
+ +
+ +
+

+ + prepare!() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_a +
+ + + +
+ +
+

+ + reset_body!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 351
+def reset_body!
+  @stream = build_buffer(self, [])
+end
+
+
+ +
+ +
+

+ + response_code() + +

+ + +
+

The response code of the request.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 278
+def response_code
+  @status
+end
+
+
+ +
+ +
+

+ + send_file(path) + +

+ + +
+

Send the file stored at path as the response body.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 346
+def send_file(path)
+  commit!
+  @stream = FileBody.new(path)
+end
+
+
+ +
+ +
+

+ + sending!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 203
+def sending!
+  synchronize do
+    before_sending
+    @sending = true
+    @cv.broadcast
+  end
+end
+
+
+ +
+ +
+

+ + sending?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 218
+def sending?;   synchronize { @sending };   end
+
+
+ +
+ +
+

+ + sending_file=(v) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 250
+def sending_file=(v)
+  if true == v
+    self.charset = false
+  end
+end
+
+
+ +
+ +
+

+ + sent!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 211
+def sent!
+  synchronize do
+    @sent = true
+    @cv.broadcast
+  end
+end
+
+
+ +
+ +
+

+ + sent?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 220
+def sent?;      synchronize { @sent };      end
+
+
+ +
+ +
+

+ + set_header(key, v) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 182
+def set_header(key, v); headers[key] = v;   end
+
+
+ +
+ +
+

+ + status=(status) + +

+ + +
+

Sets the HTTP status code.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 223
+def status=(status)
+  @status = Rack::Utils.status_code(status)
+end
+
+
+ +
+ +
+

+ + status_message() + +

+ + +
+ +
+ + + + + +
+ Alias for: message +
+ + + +
+ +
+

+ + to_a() + +

+ + +
+

Turns the Response into a Rack-compatible array of the status, headers, and body. Allows explicit splatting:

+ +
status, headers, body = *response
+
+
+ + + +
+ Also aliased as: prepare! +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 383
+def to_a
+  commit!
+  rack_response @status, @header.to_hash
+end
+
+
+ +
+ +
+

+ + write(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 306
+def write(string)
+  @stream.write string
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Response/RackBody.html b/src/5.2/classes/ActionDispatch/Response/RackBody.html new file mode 100644 index 0000000000..b14db55513 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Response/RackBody.html @@ -0,0 +1,350 @@ +--- +title: ActionDispatch::Response::RackBody +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(response) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 470
+def initialize(response)
+  @response = response
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + body() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 484
+def body
+  @response.body
+end
+
+
+ +
+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 478
+def close
+  # Rack "close" maps to Response#abort, and *not* Response#close
+  # (which is used when the controller's finished writing)
+  @response.abort
+end
+
+
+ +
+ +
+

+ + each(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 474
+def each(*args, &block)
+  @response.each(*args, &block)
+end
+
+
+ +
+ +
+

+ + respond_to?(method, include_private = false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 488
+def respond_to?(method, include_private = false)
+  if method.to_s == "to_path"
+    @response.stream.respond_to?(method)
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + to_ary() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 500
+def to_ary
+  nil
+end
+
+
+ +
+ +
+

+ + to_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/response.rb, line 496
+def to_path
+  @response.stream.to_path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing.html b/src/5.2/classes/ActionDispatch/Routing.html new file mode 100644 index 0000000000..4ace894660 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing.html @@ -0,0 +1,350 @@ +--- +title: ActionDispatch::Routing +layout: default +--- +
+ +
+
+ +
+ +

The routing module provides URL rewriting in native Ruby. It's a way to redirect incoming requests to controllers and actions. This replaces mod_rewrite rules. Best of all, Rails' Routing works with any web server. Routes are defined in config/routes.rb.

+ +

Think of creating routes as drawing a map for your requests. The map tells them where to go based on some predefined pattern:

+ +
Rails.application.routes.draw do
+  Pattern 1 tells some request to go to one place
+  Pattern 2 tell them to go to another
+  ...
+end
+
+ +

The following symbols are special:

+ +
:controller maps to your controller name
+:action     maps to an action with your controllers
+
+ +

Other names simply map to a parameter as in the case of :id.

+ +

Resources

+ +

Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. Instead of declaring separate routes for your index, show, new, edit, create, update and destroy actions, a resourceful route declares them in a single line of code:

+ +
resources :photos
+
+ +

Sometimes, you have a resource that clients always look up without referencing an ID. A common example, /profile always shows the profile of the currently logged in user. In this case, you can use a singular resource to map /profile (rather than /profile/:id) to the show action.

+ +
resource :profile
+
+ +

It's common to have resources that are logically children of other resources:

+ +
resources :magazines do
+  resources :ads
+end
+
+ +

You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an admin namespace. You would place these controllers under the app/controllers/admin directory, and you can group them together in your router:

+ +
namespace "admin" do
+  resources :posts, :comments
+end
+
+ +

Alternatively, you can add prefixes to your path without using a separate directory by using scope. scope takes additional options which apply to all enclosed routes.

+ +
scope path: "/cpanel", as: 'admin' do
+  resources :posts, :comments
+end
+
+ +

For more, see Routing::Mapper::Resources#resources, Routing::Mapper::Scoping#namespace, and Routing::Mapper::Scoping#scope.

+ +

Non-resourceful routes

+ +

For routes that don't fit the resources mold, you can use the HTTP helper methods get, post, patch, put and delete.

+ +
get 'post/:id' => 'posts#show'
+post 'post/:id' => 'posts#create_comment'
+
+ +

Now, if you POST to /posts/:id, it will route to the create_comment action. A GET on the same URL will route to the show action.

+ +

If your route needs to respond to more than one HTTP method (or all methods) then using the :via option on match is preferable.

+ +
match 'post/:id' => 'posts#show', via: [:get, :post]
+
+ +

Named routes

+ +

Routes can be named by passing an :as option, allowing for easy reference within your source as name_of_route_url for the full URL and name_of_route_path for the URI path.

+ +

Example:

+ +
# In config/routes.rb
+get '/login' => 'accounts#login', as: 'login'
+
+# With render, redirect_to, tests, etc.
+redirect_to login_url
+
+ +

Arguments can be passed as well.

+ +
redirect_to show_item_path(id: 25)
+
+ +

Use root as a shorthand to name a route for the root path “/”.

+ +
# In config/routes.rb
+root to: 'blogs#index'
+
+# would recognize http://www.example.com/ as
+params = { controller: 'blogs', action: 'index' }
+
+# and provide these named routes
+root_url   # => 'http://www.example.com/'
+root_path  # => '/'
+
+ +

Note: when using controller, the route is simply named after the method you call on the block parameter rather than map.

+ +
# In config/routes.rb
+controller :blog do
+  get 'blog/show'     => :list
+  get 'blog/delete'   => :delete
+  get 'blog/edit'     => :edit
+end
+
+# provides named routes for show, delete, and edit
+link_to @article.title, blog_show_path(id: @article.id)
+
+ +

Pretty URLs

+ +

Routes can generate pretty URLs. For example:

+ +
get '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: {
+  year:       /\d{4}/,
+  month:      /\d{1,2}/,
+  day:        /\d{1,2}/
+}
+
+ +

Using the route above, the URL “localhost:3000/articles/2005/11/06” maps to

+ +
params = {year: '2005', month: '11', day: '06'}
+
+ +

Regular Expressions and parameters

+ +

You can specify a regular expression to define a format for a parameter.

+ +
controller 'geocode' do
+  get 'geocode/:postalcode' => :show, constraints: {
+    postalcode: /\d{5}(-\d{4})?/
+  }
+end
+
+ +

Constraints can include the 'ignorecase' and 'extended syntax' regular expression modifiers:

+ +
controller 'geocode' do
+  get 'geocode/:postalcode' => :show, constraints: {
+    postalcode: /hx\d\d\s\d[a-z]{2}/i
+  }
+end
+
+controller 'geocode' do
+  get 'geocode/:postalcode' => :show, constraints: {
+    postalcode: /# Postalcode format
+       \d{5} #Prefix
+       (-\d{4})? #Suffix
+       /x
+  }
+end
+
+ +

Using the multiline modifier will raise an ArgumentError. Encoding regular expression modifiers are silently ignored. The match will always use the default encoding or ASCII.

+ +

External redirects

+ +

You can redirect any path to another path using the redirect helper in your router:

+ +
get "/stories" => redirect("/posts")
+
+ +

Unicode character routes

+ +

You can specify unicode character routes in your router:

+ +
get "こんにちは" => "welcome#index"
+
+ +

Routing to Rack Applications

+ +

Instead of a String, like posts#index, which corresponds to the index action in the PostsController, you can specify any Rack application as the endpoint for a matcher:

+ +
get "/application.js" => Sprockets
+
+ +

Reloading routes

+ +

You can reload routes if you feel you must:

+ +
Rails.application.reload_routes!
+
+ +

This will clear all named routes and reload config/routes.rb if the file has been modified from last load. To absolutely force reloading, use reload!.

+ +

Testing Routes

+ +

The two main methods for testing your routes:

+ +

assert_routing

+ +
def test_movie_route_properly_splits
+ opts = {controller: "plugin", action: "checkout", id: "2"}
+ assert_routing "plugin/checkout/2", opts
+end
+
+ +

assert_routing lets you test whether or not the route properly resolves into options.

+ +

assert_recognizes

+ +
def test_route_has_options
+ opts = {controller: "plugin", action: "show", id: "12"}
+ assert_recognizes opts, "/plugins/show/12"
+end
+
+ +

Note the subtle difference between the two: assert_routing tests that a URL fits options while assert_recognizes tests that a URL breaks into parameters properly.

+ +

In tests you can simply pass the URL or named route to get or post.

+ +
def send_to_jail
+  get '/jail'
+  assert_response :success
+end
+
+def goes_to_login
+  get login_url
+  #...
+end
+
+ +

View a list of all your routes

+ +
rails routes
+
+ +

Target specific controllers by prefixing the command with -c option.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/ConsoleFormatter.html b/src/5.2/classes/ActionDispatch/Routing/ConsoleFormatter.html new file mode 100644 index 0000000000..da07ffa026 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/ConsoleFormatter.html @@ -0,0 +1,315 @@ +--- +title: ActionDispatch::Routing::ConsoleFormatter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 130
+def initialize
+  @buffer = []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + header(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 146
+def header(routes)
+  @buffer << draw_header(routes)
+end
+
+
+ +
+ +
+

+ + no_routes(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 150
+      def no_routes(routes)
+        @buffer <<
+        if routes.none?
+          <<-MESSAGE.strip_heredoc
+          You don't have any routes defined!
+
+          Please add some routes in config/routes.rb.
+          MESSAGE
+        else
+          "No routes were found for this controller"
+        end
+        @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html."
+      end
+
+
+ +
+ +
+

+ + result() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 134
+def result
+  @buffer.join("\n")
+end
+
+
+ +
+ +
+

+ + section(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 142
+def section(routes)
+  @buffer << draw_section(routes)
+end
+
+
+ +
+ +
+

+ + section_title(title) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 138
+def section_title(title)
+  @buffer << "\n#{title}:"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/HtmlTableFormatter.html b/src/5.2/classes/ActionDispatch/Routing/HtmlTableFormatter.html new file mode 100644 index 0000000000..d71e77616b --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/HtmlTableFormatter.html @@ -0,0 +1,316 @@ +--- +title: ActionDispatch::Routing::HtmlTableFormatter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(view) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 188
+def initialize(view)
+  @view = view
+  @buffer = []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + header(routes) + +

+ + +
+

The header is part of the HTML page, so we don't construct it here.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 202
+def header(routes)
+end
+
+
+ +
+ +
+

+ + no_routes(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 205
+      def no_routes(*)
+        @buffer << <<-MESSAGE.strip_heredoc
+          <p>You don't have any routes defined!</p>
+          <ul>
+            <li>Please add some routes in <tt>config/routes.rb</tt>.</li>
+            <li>
+              For more information about routes, please see the Rails guide
+              <a href="http://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>.
+            </li>
+          </ul>
+          MESSAGE
+      end
+
+
+ +
+ +
+

+ + result() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 218
+def result
+  @view.raw @view.render(layout: "routes/table") {
+    @view.raw @buffer.join("\n")
+  }
+end
+
+
+ +
+ +
+

+ + section(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 197
+def section(routes)
+  @buffer << @view.render(partial: "routes/route", collection: routes)
+end
+
+
+ +
+ +
+

+ + section_title(title) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 193
+def section_title(title)
+  @buffer << %(<tr><th colspan="4">#{title}</th></tr>)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Mapper.html b/src/5.2/classes/ActionDispatch/Routing/Mapper.html new file mode 100644 index 0000000000..4cc082eb12 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Mapper.html @@ -0,0 +1,251 @@ +--- +title: ActionDispatch::Routing::Mapper +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
URL_OPTIONS=[:protocol, :subdomain, :domain, :host, :port]
 
+ + + + + + +

Class Public methods

+ +
+

+ + normalize_name(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 397
+def self.normalize_name(name)
+  normalize_path(name)[1..-1].tr("/", "_")
+end
+
+
+ +
+ +
+

+ + normalize_path(path) + +

+ + +
+

Invokes Journey::Router::Utils.normalize_path and ensure that (:locale) becomes (/:locale) instead of /(:locale). Except for root cases, where the latter is the correct one.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 391
+def self.normalize_path(path)
+  path = Journey::Router::Utils.normalize_path(path)
+  path.gsub!(%r{/(\(+)/?}, '\1/') unless path =~ %r{^/(\(+[^)]+\)){1,}$}
+  path
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Mapper/Base.html b/src/5.2/classes/ActionDispatch/Routing/Mapper/Base.html new file mode 100644 index 0000000000..3c2440d91b --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Mapper/Base.html @@ -0,0 +1,505 @@ +--- +title: ActionDispatch::Routing::Mapper::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + default_url_options(options) + +

+ + +
+ +
+ + + + + +
+ Alias for: default_url_options= +
+ + + +
+ +
+

+ + default_url_options=(options) + +

+ + +
+ +
+ + + +
+ Also aliased as: default_url_options +
+ + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 634
+def default_url_options=(options)
+  @set.default_url_options = options
+end
+
+
+ +
+ +
+

+ + has_named_route?(name) + +

+ + +
+

Query if the following named route was already defined.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 646
+def has_named_route?(name)
+  @set.named_routes.key? name
+end
+
+
+ +
+ +
+

+ + match(path, options = nil) + +

+ + +
+

Matches a URL pattern to one or more routes.

+ +

You should not use the match method in your router without specifying an HTTP method.

+ +

If you want to expose your action to both GET and POST, use:

+ +
# sets :controller, :action and :id in params
+match ':controller/:action/:id', via: [:get, :post]
+
+ +

Note that :controller, :action and :id are interpreted as URL query parameters and thus available through params in an action.

+ +

If you want to expose your action to GET, use get in the router:

+ +

Instead of:

+ +
match ":controller/:action/:id"
+
+ +

Do:

+ +
get ":controller/:action/:id"
+
+ +

Two of these symbols are special, :controller maps to the controller and :action to the controller's action. A pattern can also map wildcard segments (globs) to params:

+ +
get 'songs/*category/:title', to: 'songs#show'
+
+# 'songs/rock/classic/stairway-to-heaven' sets
+#  params[:category] = 'rock/classic'
+#  params[:title] = 'stairway-to-heaven'
+
+ +

To match a wildcard parameter, it must have a name assigned to it. Without a variable name to attach the glob parameter to, the route can't be parsed.

+ +

When a pattern points to an internal route, the route's :action and :controller should be set in options or hash shorthand. Examples:

+ +
match 'photos/:id' => 'photos#show', via: :get
+match 'photos/:id', to: 'photos#show', via: :get
+match 'photos/:id', controller: 'photos', action: 'show', via: :get
+
+ +

A pattern can also point to a Rack endpoint i.e. anything that responds to call:

+ +
match 'photos/:id', to: -> (hash) { [200, {}, ["Coming soon"]] }, via: :get
+match 'photos/:id', to: PhotoRackApp, via: :get
+# Yes, controller actions are just rack endpoints
+match 'photos/:id', to: PhotosController.action(:show), via: :get
+
+ +

Because requesting various HTTP verbs with a single action has security implications, you must either specify the actions in the via options or use one of the HttpHelpers instead match

+ +

Options

+ +

Any options not seen here are passed on as params with the URL.

+
:controller +
+

The route's controller.

+
:action +
+

The route's action.

+
:param +
+

Overrides the default resource identifier :id (name of the dynamic segment used to generate the routes). You can access that segment from your controller using params[<:param>]. In your router:

+ +
resources :users, param: :name
+
+ +

The users resource here will have the following routes generated for it:

+ +
GET       /users(.:format)
+POST      /users(.:format)
+GET       /users/new(.:format)
+GET       /users/:name/edit(.:format)
+GET       /users/:name(.:format)
+PATCH/PUT /users/:name(.:format)
+DELETE    /users/:name(.:format)
+
+ +

You can override ActiveRecord::Base#to_param of a related model to construct a URL:

+ +
class User < ActiveRecord::Base
+  def to_param
+    name
+  end
+end
+
+user = User.find_by(name: 'Phusion')
+user_path(user)  # => "/users/Phusion"
+
+
:path +
+

The path prefix for the routes.

+
:module +
+

The namespace for :controller.

+ +
match 'path', to: 'c#a', module: 'sekret', controller: 'posts', via: :get
+# => Sekret::PostsController
+
+ +

See Scoping#namespace for its scope equivalent.

+
:as +
+

The name used to generate routing helpers.

+
:via +
+

Allowed HTTP verb(s) for route.

+ +
match 'path', to: 'c#a', via: :get
+match 'path', to: 'c#a', via: [:get, :post]
+match 'path', to: 'c#a', via: :all
+
+
:to +
+

Points to a Rack endpoint. Can be an object that responds to call or a string representing a controller's action.

+ +
match 'path', to: 'controller#action', via: :get
+match 'path', to: -> (env) { [200, {}, ["Success!"]] }, via: :get
+match 'path', to: RackApp, via: :get
+
+
:on +
+

Shorthand for wrapping routes in a specific RESTful context. Valid values are :member, :collection, and :new. Only use within resource(s) block. For example:

+ +
resource :bar do
+  match 'foo', to: 'c#a', on: :member, via: [:get, :post]
+end
+
+ +

Is equivalent to:

+ +
resource :bar do
+  member do
+    match 'foo', to: 'c#a', via: [:get, :post]
+  end
+end
+
+
:constraints +
+

Constrains parameters with a hash of regular expressions or an object that responds to matches?. In addition, constraints other than path can also be specified with any object that responds to === (eg. String, Array, Range, etc.).

+ +
match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }, via: :get
+
+match 'json_only', constraints: { format: 'json' }, via: :get
+
+class Whitelist
+  def matches?(request) request.remote_ip == '1.2.3.4' end
+end
+match 'path', to: 'c#a', constraints: Whitelist.new, via: :get
+
+ +

See Scoping#constraints for more examples with its scope equivalent.

+
:defaults +
+

Sets defaults for parameters

+ +
# Sets params[:format] to 'jpg' by default
+match 'path', to: 'c#a', defaults: { format: 'jpg' }, via: :get
+
+ +

See Scoping#defaults for its scope equivalent.

+
:anchor +
+

Boolean to anchor a match pattern. Default is true. When set to false, the pattern matches any request prefixed with the given path.

+ +
# Matches any request starting with 'path'
+match 'path', to: 'c#a', anchor: false, via: :get
+
+
:format +
+

Allows you to specify the default value for optional format segment or disable it by supplying false.

+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 582
+def match(path, options = nil)
+end
+
+
+ +
+ +
+

+ + mount(app, options = nil) + +

+ + +
+

Mount a Rack-based application to be used within the application.

+ +
mount SomeRackApp, at: "some_route"
+
+ +

Alternatively:

+ +
mount(SomeRackApp => "some_route")
+
+ +

For options, see match, as mount uses it internally.

+ +

All mounted applications come with routing helpers to access them. These are named after the class specified, so for the above example the helper is either some_rack_app_path or some_rack_app_url. To customize this helper's name, use the :as option:

+ +
mount(SomeRackApp => "some_route", as: "exciting")
+
+ +

This will generate the exciting_path and exciting_url helpers which can be used to navigate to this mounted app.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 604
+        def mount(app, options = nil)
+          if options
+            path = options.delete(:at)
+          elsif Hash === app
+            options = app
+            app, path = options.find { |k, _| k.respond_to?(:call) }
+            options.delete(app) if app
+          end
+
+          raise ArgumentError, "A rack application must be specified" unless app.respond_to?(:call)
+          raise ArgumentError, <<-MSG.strip_heredoc unless path
+            Must be called with mount point
+
+              mount SomeRackApp, at: "some_route"
+              or
+              mount(SomeRackApp => "some_route")
+          MSG
+
+          rails_app = rails_app? app
+          options[:as] ||= app_name(app, rails_app)
+
+          target_as       = name_for_action(options[:as], path)
+          options[:via] ||= :all
+
+          match(path, options.merge(to: app, anchor: false, format: false))
+
+          define_generate_prefix(app, target_as) if rails_app
+          self
+        end
+
+
+ +
+ +
+

+ + with_default_scope(scope, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 639
+def with_default_scope(scope, &block)
+  scope(scope) do
+    instance_exec(&block)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Mapper/Concerns.html b/src/5.2/classes/ActionDispatch/Routing/Mapper/Concerns.html new file mode 100644 index 0000000000..189ecef501 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Mapper/Concerns.html @@ -0,0 +1,236 @@ +--- +title: ActionDispatch::Routing::Mapper::Concerns +layout: default +--- +
+ +
+
+ +
+ +

Routing Concerns allow you to declare common routes that can be reused inside others resources and routes.

+ +
concern :commentable do
+  resources :comments
+end
+
+concern :image_attachable do
+  resources :images, only: :index
+end
+
+ +

These concerns are used in Resources routing:

+ +
resources :messages, concerns: [:commentable, :image_attachable]
+
+ +

or in a scope or namespace:

+ +
namespace :posts do
+  concerns :commentable
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + concern(name, callable = nil, &block) + +

+ + +
+

Define a routing concern using a name.

+ +

Concerns may be defined inline, using a block, or handled by another object, by passing that object as the second parameter.

+ +

The concern object, if supplied, should respond to call, which will receive two parameters:

+ +
* The current mapper
+* A hash of options which the concern object may use
+
+ +

Options may also be used by concerns defined in a block by accepting a block parameter. So, using a block, you might do something as simple as limit the actions available on certain resources, passing standard resource options through the concern:

+ +
concern :commentable do |options|
+  resources :comments, options
+end
+
+resources :posts, concerns: :commentable
+resources :archived_posts do
+  # Don't allow comments on archived posts
+  concerns :commentable, only: [:index, :show]
+end
+
+ +

Or, using a callable object, you might implement something more specific to your application, which would be out of place in your routes file.

+ +
# purchasable.rb
+class Purchasable
+  def initialize(defaults = {})
+    @defaults = defaults
+  end
+
+  def call(mapper, options = {})
+    options = @defaults.merge(options)
+    mapper.resources :purchases
+    mapper.resources :receipts
+    mapper.resources :returns if options[:returnable]
+  end
+end
+
+# routes.rb
+concern :purchasable, Purchasable.new(returnable: true)
+
+resources :toys, concerns: :purchasable
+resources :electronics, concerns: :purchasable
+resources :pets do
+  concerns :purchasable, returnable: false
+end
+
+ +

Any routing helpers can be used inside a concern. If using a callable, they're accessible from the Mapper that's passed to call.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2021
+def concern(name, callable = nil, &block)
+  callable ||= lambda { |mapper, options| mapper.instance_exec(options, &block) }
+  @concerns[name] = callable
+end
+
+
+ +
+ +
+

+ + concerns(*args) + +

+ + +
+

Use the named concerns

+ +
resources :posts do
+  concerns :commentable
+end
+
+ +

Concerns also work in any routes helper that you want to use:

+ +
namespace :posts do
+  concerns :commentable
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2037
+def concerns(*args)
+  options = args.extract_options!
+  args.flatten.each do |name|
+    if concern = @concerns[name]
+      concern.call(self, options)
+    else
+      raise ArgumentError, "No concern named #{name} was found!"
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Mapper/CustomUrls.html b/src/5.2/classes/ActionDispatch/Routing/Mapper/CustomUrls.html new file mode 100644 index 0000000000..5b324c216f --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Mapper/CustomUrls.html @@ -0,0 +1,234 @@ +--- +title: ActionDispatch::Routing::Mapper::CustomUrls +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + direct(name, options = {}, &block) + +

+ + +
+

Define custom URL helpers that will be added to the application's routes. This allows you to override and/or replace the default behavior of routing helpers, e.g:

+ +
direct :homepage do
+  "http://www.rubyonrails.org"
+end
+
+direct :commentable do |model|
+  [ model, anchor: model.dom_id ]
+end
+
+direct :main do
+  { controller: "pages", action: "index", subdomain: "www" }
+end
+
+ +

The return value from the block passed to direct must be a valid set of arguments for url_for which will actually build the URL string. This can be one of the following:

+
  • +

    A string, which is treated as a generated URL

    +
  • +

    A hash, e.g. { controller: "pages", action: "index" }

    +
  • +

    An array, which is passed to polymorphic_url

    +
  • +

    An Active Model instance

    +
  • +

    An Active Model class

    +
+ +

NOTE: Other URL helpers can be called in the block but be careful not to invoke your custom URL helper again otherwise it will result in a stack overflow error.

+ +

You can also specify default options that will be passed through to your URL helper definition, e.g:

+ +
direct :browse, page: 1, size: 10 do |options|
+  [ :products, options.merge(params.permit(:page, :size).to_h.symbolize_keys) ]
+end
+
+ +

In this instance the params object comes from the context in which the block is executed, e.g. generating a URL inside a controller action or a view. If the block is executed where there isn't a params object such as this:

+ +
Rails.application.routes.url_helpers.browse_path
+
+ +

then it will raise a NameError. Because of this you need to be aware of the context in which you will use your custom URL helper when defining it.

+ +

NOTE: The direct method can't be used inside of a scope block such as namespace or scope and will raise an error if it detects that it is.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2097
+def direct(name, options = {}, &block)
+  unless @scope.root?
+    raise RuntimeError, "The direct method can't be used inside a routes scope block"
+  end
+
+  @set.add_url_helper(name, options, &block)
+end
+
+
+ +
+ +
+

+ + resolve(*args, &block) + +

+ + +
+

Define custom polymorphic mappings of models to URLs. This alters the behavior of polymorphic_url and consequently the behavior of link_to and form_for when passed a model instance, e.g:

+ +
resource :basket
+
+resolve "Basket" do
+  [:basket]
+end
+
+ +

This will now generate “/basket” when a Basket instance is passed to link_to or form_for instead of the standard “/baskets/:id”.

+ +

NOTE: This custom behavior only applies to simple polymorphic URLs where a single model instance is passed and not more complicated forms, e.g:

+ +
# config/routes.rb
+resource :profile
+namespace :admin do
+  resources :users
+end
+
+resolve("User") { [:profile] }
+
+# app/views/application/_menu.html.erb
+link_to "Profile", @current_user
+link_to "Profile", [:admin, @current_user]
+
+ +

The first link_to will generate “/profile” but the second will generate the standard polymorphic URL of “/admin/users/1”.

+ +

You can pass options to a polymorphic mapping - the arity for the block needs to be two as the instance is passed as the first argument, e.g:

+ +
resolve "Basket", anchor: "items" do |basket, options|
+  [:basket, options]
+end
+
+ +

This generates the URL “/basket#items” because when the last item in an array passed to polymorphic_url is a hash then it's treated as options to the URL helper that gets called.

+ +

NOTE: The resolve method can't be used inside of a scope block such as namespace or scope and will raise an error if it detects that it is.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2149
+def resolve(*args, &block)
+  unless @scope.root?
+    raise RuntimeError, "The resolve method can't be used inside a routes scope block"
+  end
+
+  options = args.extract_options!
+  args = args.flatten(1)
+
+  args.each do |klass|
+    @set.add_polymorphic_mapping(klass, options, &block)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html b/src/5.2/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html new file mode 100644 index 0000000000..d940b78b7e --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html @@ -0,0 +1,272 @@ +--- +title: ActionDispatch::Routing::Mapper::HttpHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + delete(*args, &block) + +

+ + +
+

Define a route that only recognizes HTTP DELETE. For supported arguments, see match

+ +
delete 'broccoli', to: 'food#broccoli'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 735
+def delete(*args, &block)
+  map_method(:delete, args, &block)
+end
+
+
+ +
+ +
+

+ + get(*args, &block) + +

+ + +
+

Define a route that only recognizes HTTP GET. For supported arguments, see match

+ +
get 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 703
+def get(*args, &block)
+  map_method(:get, args, &block)
+end
+
+
+ +
+ +
+

+ + patch(*args, &block) + +

+ + +
+

Define a route that only recognizes HTTP PATCH. For supported arguments, see match

+ +
patch 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 719
+def patch(*args, &block)
+  map_method(:patch, args, &block)
+end
+
+
+ +
+ +
+

+ + post(*args, &block) + +

+ + +
+

Define a route that only recognizes HTTP POST. For supported arguments, see match

+ +
post 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 711
+def post(*args, &block)
+  map_method(:post, args, &block)
+end
+
+
+ +
+ +
+

+ + put(*args, &block) + +

+ + +
+

Define a route that only recognizes HTTP PUT. For supported arguments, see match

+ +
put 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 727
+def put(*args, &block)
+  map_method(:put, args, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Mapper/Resources.html b/src/5.2/classes/ActionDispatch/Routing/Mapper/Resources.html new file mode 100644 index 0000000000..d7b36e0eba --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Mapper/Resources.html @@ -0,0 +1,1077 @@ +--- +title: ActionDispatch::Routing::Mapper::Resources +layout: default +--- +
+ +
+
+ +
+ +

Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. Instead of declaring separate routes for your index, show, new, edit, create, update and destroy actions, a resourceful route declares them in a single line of code:

+ +
resources :photos
+
+ +

Sometimes, you have a resource that clients always look up without referencing an ID. A common example, /profile always shows the profile of the currently logged in user. In this case, you can use a singular resource to map /profile (rather than /profile/:id) to the show action.

+ +
resource :profile
+
+ +

It's common to have resources that are logically children of other resources:

+ +
resources :magazines do
+  resources :ads
+end
+
+ +

You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an admin namespace. You would place these controllers under the app/controllers/admin directory, and you can group them together in your router:

+ +
namespace "admin" do
+  resources :posts, :comments
+end
+
+ +

By default the :id parameter doesn't accept dots. If you need to use dots as part of the :id parameter add a constraint which overrides this restriction, e.g:

+ +
resources :articles, id: /[^\/]+/
+
+ +

This allows any character other than a slash as part of your :id.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CANONICAL_ACTIONS=%w(index create new show update destroy)
 
RESOURCE_OPTIONS=[:as, :controller, :path, :only, :except, :param, :concerns]
 
VALID_ON_OPTIONS=[:new, :collection, :member]
 

CANONICAL_ACTIONS holds all actions that does not need a prefix or a path appended since they fit properly in their scope level.

+ + + + + + + +

Instance Public methods

+ +
+

+ + collection() + +

+ + +
+

To add a route to the collection:

+ +
resources :photos do
+  collection do
+    get 'search'
+  end
+end
+
+ +

This will enable Rails to recognize paths such as /photos/search with GET, and route to the search action of PhotosController. It will also create the search_photos_url and search_photos_path route helpers.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1483
+def collection
+  unless resource_scope?
+    raise ArgumentError, "can't use collection outside resource(s) scope"
+  end
+
+  with_scope_level(:collection) do
+    path_scope(parent_resource.collection_scope) do
+      yield
+    end
+  end
+end
+
+
+ +
+ +
+

+ + match(path, *rest, &block) + +

+ + +
+

Matches a URL pattern to one or more routes. For more information, see match.

+ +
match 'path' => 'controller#action', via: :patch
+match 'path', to: 'controller#action', via: :post
+match 'path', 'otherpath', on: :member, via: :get
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1580
+def match(path, *rest, &block)
+  if rest.empty? && Hash === path
+    options  = path
+    path, to = options.find { |name, _value| name.is_a?(String) }
+
+    raise ArgumentError, "Route path not specified" if path.nil?
+
+    case to
+    when Symbol
+      options[:action] = to
+    when String
+      if to =~ /#/
+        options[:to] = to
+      else
+        options[:controller] = to
+      end
+    else
+      options[:to] = to
+    end
+
+    options.delete(path)
+    paths = [path]
+  else
+    options = rest.pop || {}
+    paths = [path] + rest
+  end
+
+  if options.key?(:defaults)
+    defaults(options.delete(:defaults)) { map_match(paths, options, &block) }
+  else
+    map_match(paths, options, &block)
+  end
+end
+
+
+ +
+ +
+

+ + member() + +

+ + +
+

To add a member route, add a member block into the resource block:

+ +
resources :photos do
+  member do
+    get 'preview'
+  end
+end
+
+ +

This will recognize /photos/1/preview with GET, and route to the preview action of PhotosController. It will also create the preview_photo_url and preview_photo_path helpers.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1506
+def member
+  unless resource_scope?
+    raise ArgumentError, "can't use member outside resource(s) scope"
+  end
+
+  with_scope_level(:member) do
+    if shallow?
+      shallow_scope {
+        path_scope(parent_resource.member_scope) { yield }
+      }
+    else
+      path_scope(parent_resource.member_scope) { yield }
+    end
+  end
+end
+
+
+ +
+ +
+

+ + namespace(path, options = {}) + +

+ + + + + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1555
+def namespace(path, options = {})
+  if resource_scope?
+    nested { super }
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + nested() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1534
+def nested
+  unless resource_scope?
+    raise ArgumentError, "can't use nested outside resource(s) scope"
+  end
+
+  with_scope_level(:nested) do
+    if shallow? && shallow_nesting_depth >= 1
+      shallow_scope do
+        path_scope(parent_resource.nested_scope) do
+          scope(nested_options) { yield }
+        end
+      end
+    else
+      path_scope(parent_resource.nested_scope) do
+        scope(nested_options) { yield }
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1522
+def new
+  unless resource_scope?
+    raise ArgumentError, "can't use new outside resource(s) scope"
+  end
+
+  with_scope_level(:new) do
+    path_scope(parent_resource.new_scope(action_path(:new))) do
+      yield
+    end
+  end
+end
+
+
+ +
+ +
+

+ + resource(*resources, &block) + +

+ + +
+

Sometimes, you have a resource that clients always look up without referencing an ID. A common example, /profile always shows the profile of the currently logged in user. In this case, you can use a singular resource to map /profile (rather than /profile/:id) to the show action:

+ +
resource :profile
+
+ +

This creates six different routes in your application, all mapping to the Profiles controller (note that the controller is named after the plural):

+ +
GET       /profile/new
+GET       /profile
+GET       /profile/edit
+PATCH/PUT /profile
+DELETE    /profile
+POST      /profile
+
+ +

Options

+ +

Takes same options as resources

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1280
+def resource(*resources, &block)
+  options = resources.extract_options!.dup
+
+  if apply_common_behavior_for(:resource, resources, options, &block)
+    return self
+  end
+
+  with_scope_level(:resource) do
+    options = apply_action_options options
+    resource_scope(SingletonResource.new(resources.pop, api_only?, @scope[:shallow], options)) do
+      yield if block_given?
+
+      concerns(options[:concerns]) if options[:concerns]
+
+      new do
+        get :new
+      end if parent_resource.actions.include?(:new)
+
+      set_member_mappings_for_resource
+
+      collection do
+        post :create
+      end if parent_resource.actions.include?(:create)
+    end
+  end
+
+  self
+end
+
+
+ +
+ +
+

+ + resources(*resources, &block) + +

+ + +
+

In Rails, a resourceful route provides a mapping between HTTP verbs and URLs and controller actions. By convention, each action also maps to particular CRUD operations in a database. A single entry in the routing file, such as

+ +
resources :photos
+
+ +

creates seven different routes in your application, all mapping to the Photos controller:

+ +
GET       /photos
+GET       /photos/new
+POST      /photos
+GET       /photos/:id
+GET       /photos/:id/edit
+PATCH/PUT /photos/:id
+DELETE    /photos/:id
+
+ +

Resources can also be nested infinitely by using this block syntax:

+ +
resources :photos do
+  resources :comments
+end
+
+ +

This generates the following comments routes:

+ +
GET       /photos/:photo_id/comments
+GET       /photos/:photo_id/comments/new
+POST      /photos/:photo_id/comments
+GET       /photos/:photo_id/comments/:id
+GET       /photos/:photo_id/comments/:id/edit
+PATCH/PUT /photos/:photo_id/comments/:id
+DELETE    /photos/:photo_id/comments/:id
+
+ +

Options

+ +

Takes same options as match as well as:

+
:path_names +
+

Allows you to change the segment component of the edit and new actions. Actions not specified are not changed.

+ +
resources :posts, path_names: { new: "brand_new" }
+
+ +

The above example will now change /posts/new to /posts/brand_new.

+
:path +
+

Allows you to change the path prefix for the resource.

+ +
resources :posts, path: 'postings'
+
+ +

The resource and all segments will now route to /postings instead of /posts.

+
:only +
+

Only generate routes for the given actions.

+ +
resources :cows, only: :show
+resources :cows, only: [:show, :index]
+
+
:except +
+

Generate all routes except for the given actions.

+ +
resources :cows, except: :show
+resources :cows, except: [:show, :index]
+
+
:shallow +
+

Generates shallow routes for nested resource(s). When placed on a parent resource, generates shallow routes for all nested resources.

+ +
resources :posts, shallow: true do
+  resources :comments
+end
+
+ +

Is the same as:

+ +
resources :posts do
+  resources :comments, except: [:show, :edit, :update, :destroy]
+end
+resources :comments, only: [:show, :edit, :update, :destroy]
+
+ +

This allows URLs for resources that otherwise would be deeply nested such as a comment on a blog post like /posts/a-long-permalink/comments/1234 to be shortened to just /comments/1234.

+
:shallow_path +
+

Prefixes nested shallow routes with the specified path.

+ +
scope shallow_path: "sekret" do
+  resources :posts do
+    resources :comments, shallow: true
+  end
+end
+
+ +

The comments resource here will have the following routes generated for it:

+ +
post_comments    GET       /posts/:post_id/comments(.:format)
+post_comments    POST      /posts/:post_id/comments(.:format)
+new_post_comment GET       /posts/:post_id/comments/new(.:format)
+edit_comment     GET       /sekret/comments/:id/edit(.:format)
+comment          GET       /sekret/comments/:id(.:format)
+comment          PATCH/PUT /sekret/comments/:id(.:format)
+comment          DELETE    /sekret/comments/:id(.:format)
+
+
:shallow_prefix +
+

Prefixes nested shallow route names with specified prefix.

+ +
scope shallow_prefix: "sekret" do
+  resources :posts do
+    resources :comments, shallow: true
+  end
+end
+
+ +

The comments resource here will have the following routes generated for it:

+ +
post_comments           GET       /posts/:post_id/comments(.:format)
+post_comments           POST      /posts/:post_id/comments(.:format)
+new_post_comment        GET       /posts/:post_id/comments/new(.:format)
+edit_sekret_comment     GET       /comments/:id/edit(.:format)
+sekret_comment          GET       /comments/:id(.:format)
+sekret_comment          PATCH/PUT /comments/:id(.:format)
+sekret_comment          DELETE    /comments/:id(.:format)
+
+
:format +
+

Allows you to specify the default value for optional format segment or disable it by supplying false.

+
+ +

Examples

+ +
# routes call <tt>Admin::PostsController</tt>
+resources :posts, module: "admin"
+
+# resource actions are at /admin/posts.
+resources :posts, path: "admin/posts"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1441
+def resources(*resources, &block)
+  options = resources.extract_options!.dup
+
+  if apply_common_behavior_for(:resources, resources, options, &block)
+    return self
+  end
+
+  with_scope_level(:resources) do
+    options = apply_action_options options
+    resource_scope(Resource.new(resources.pop, api_only?, @scope[:shallow], options)) do
+      yield if block_given?
+
+      concerns(options[:concerns]) if options[:concerns]
+
+      collection do
+        get  :index if parent_resource.actions.include?(:index)
+        post :create if parent_resource.actions.include?(:create)
+      end
+
+      new do
+        get :new
+      end if parent_resource.actions.include?(:new)
+
+      set_member_mappings_for_resource
+    end
+  end
+
+  self
+end
+
+
+ +
+ +
+

+ + resources_path_names(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1255
+def resources_path_names(options)
+  @scope[:path_names].merge!(options)
+end
+
+
+ +
+ +
+

+ + root(path, options = {}) + +

+ + +
+

You can specify what Rails should route “/” to with the root method:

+ +
root to: 'pages#main'
+
+ +

For options, see match, as root uses it internally.

+ +

You can also pass a string which will expand

+ +
root 'pages#main'
+
+ +

You should put the root route at the top of config/routes.rb, because this means it will be matched first. As this is the most popular route of most Rails applications, this is beneficial.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1627
+def root(path, options = {})
+  if path.is_a?(String)
+    options[:to] = path
+  elsif path.is_a?(Hash) && options.empty?
+    options = path
+  else
+    raise ArgumentError, "must be called with a path and/or options"
+  end
+
+  if @scope.resources?
+    with_scope_level(:root) do
+      path_scope(parent_resource.path) do
+        match_root_route(options)
+      end
+    end
+  else
+    match_root_route(options)
+  end
+end
+
+
+ +
+ +
+

+ + shallow() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1563
+def shallow
+  @scope = @scope.new(shallow: true)
+  yield
+ensure
+  @scope = @scope.parent
+end
+
+
+ +
+ +
+

+ + shallow?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1570
+def shallow?
+  !parent_resource.singleton? && @scope[:shallow]
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + api_only?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1827
+def api_only? # :doc:
+  @set.api_only?
+end
+
+
+ +
+ +
+

+ + set_member_mappings_for_resource() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1815
+def set_member_mappings_for_resource # :doc:
+  member do
+    get :edit if parent_resource.actions.include?(:edit)
+    get :show if parent_resource.actions.include?(:show)
+    if parent_resource.actions.include?(:update)
+      patch :update
+      put   :update
+    end
+    delete :destroy if parent_resource.actions.include?(:destroy)
+  end
+end
+
+
+ +
+ +
+

+ + with_scope_level(kind) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1711
+def with_scope_level(kind) # :doc:
+  @scope = @scope.new_level(kind)
+  yield
+ensure
+  @scope = @scope.parent
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Mapper/Scoping.html b/src/5.2/classes/ActionDispatch/Routing/Mapper/Scoping.html new file mode 100644 index 0000000000..f5c21c6b76 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Mapper/Scoping.html @@ -0,0 +1,514 @@ +--- +title: ActionDispatch::Routing::Mapper::Scoping +layout: default +--- +
+ +
+
+ +
+ +

You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an admin namespace. You would place these controllers under the app/controllers/admin directory, and you can group them together in your router:

+ +
namespace "admin" do
+  resources :posts, :comments
+end
+
+ +

This will create a number of routes for each of the posts and comments controller. For Admin::PostsController, Rails will create:

+ +
GET       /admin/posts
+GET       /admin/posts/new
+POST      /admin/posts
+GET       /admin/posts/1
+GET       /admin/posts/1/edit
+PATCH/PUT /admin/posts/1
+DELETE    /admin/posts/1
+
+ +

If you want to route /posts (without the prefix /admin) to Admin::PostsController, you could use

+ +
scope module: "admin" do
+  resources :posts
+end
+
+ +

or, for a single case

+ +
resources :posts, module: "admin"
+
+ +

If you want to route /admin/posts to PostsController (without the Admin:: module prefix), you could use

+ +
scope "/admin" do
+  resources :posts
+end
+
+ +

or, for a single case

+ +
resources :posts, path: "/admin/posts"
+
+ +

In each of these cases, the named routes remain the same as if you did not use scope. In the last case, the following paths map to PostsController:

+ +
GET       /admin/posts
+GET       /admin/posts/new
+POST      /admin/posts
+GET       /admin/posts/1
+GET       /admin/posts/1/edit
+PATCH/PUT /admin/posts/1
+DELETE    /admin/posts/1
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + constraints(constraints = {}) + +

+ + +
+

Parameter Restriction

+ +

Allows you to constrain the nested routes based on a set of rules. For instance, in order to change the routes to allow for a dot character in the id parameter:

+ +
constraints(id: /\d+\.\d+/) do
+  resources :posts
+end
+
+ +

Now routes such as /posts/1 will no longer be valid, but /posts/1.1 will be. The id parameter must match the constraint passed in for this example.

+ +

You may use this to also restrict other parameters:

+ +
resources :posts do
+  constraints(post_id: /\d+\.\d+/) do
+    resources :comments
+  end
+end
+
+ +

Restricting based on IP

+ +

Routes can also be constrained to an IP or a certain range of IP addresses:

+ +
constraints(ip: /192\.168\.\d+\.\d+/) do
+  resources :posts
+end
+
+ +

Any user connecting from the 192.168.* range will be able to see this resource, where as any user connecting outside of this range will be told there is no such route.

+ +

Dynamic request matching

+ +

Requests to routes can be constrained based on specific criteria:

+ +
constraints(-> (req) { req.env["HTTP_USER_AGENT"] =~ /iPhone/ }) do
+  resources :iphones
+end
+
+ +

You are able to move this logic out into a class if it is too complex for routes. This class must have a matches? method defined on it which either returns true if the user should be given access to that route, or false if the user should not.

+ +
class Iphone
+  def self.matches?(request)
+    request.env["HTTP_USER_AGENT"] =~ /iPhone/
+  end
+end
+
+ +

An expected place for this code would be lib/constraints.

+ +

This class is then used like this:

+ +
constraints(Iphone) do
+  resources :iphones
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1007
+def constraints(constraints = {})
+  scope(constraints: constraints) { yield }
+end
+
+
+ +
+ +
+

+ + controller(controller) + +

+ + +
+

Scopes routes to a specific controller

+ +
controller "food" do
+  match "bacon", action: :bacon, via: :get
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 892
+def controller(controller)
+  @scope = @scope.new(controller: controller)
+  yield
+ensure
+  @scope = @scope.parent
+end
+
+
+ +
+ +
+

+ + defaults(defaults = {}) + +

+ + +
+

Allows you to set default parameters for a route, such as this:

+ +
defaults id: 'home' do
+  match 'scoped_pages/(:id)', to: 'pages#show'
+end
+
+ +

Using this, the :id parameter here will default to 'home'.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1016
+def defaults(defaults = {})
+  @scope = @scope.new(defaults: merge_defaults_scope(@scope[:defaults], defaults))
+  yield
+ensure
+  @scope = @scope.parent
+end
+
+
+ +
+ +
+

+ + namespace(path, options = {}) + +

+ + +
+

Scopes routes to a specific namespace. For example:

+ +
namespace :admin do
+  resources :posts
+end
+
+ +

This generates the following routes:

+ +
    admin_posts GET       /admin/posts(.:format)          admin/posts#index
+    admin_posts POST      /admin/posts(.:format)          admin/posts#create
+ new_admin_post GET       /admin/posts/new(.:format)      admin/posts#new
+edit_admin_post GET       /admin/posts/:id/edit(.:format) admin/posts#edit
+     admin_post GET       /admin/posts/:id(.:format)      admin/posts#show
+     admin_post PATCH/PUT /admin/posts/:id(.:format)      admin/posts#update
+     admin_post DELETE    /admin/posts/:id(.:format)      admin/posts#destroy
+
+ +

Options

+ +

The :path, :as, :module, :shallow_path and :shallow_prefix options all default to the name of the namespace.

+ +

For options, see Base#match. For :shallow_path option, see Resources#resources.

+ +
# accessible through /sekret/posts rather than /admin/posts
+namespace :admin, path: "sekret" do
+  resources :posts
+end
+
+# maps to <tt>Sekret::PostsController</tt> rather than <tt>Admin::PostsController</tt>
+namespace :admin, module: "sekret" do
+  resources :posts
+end
+
+# generates +sekret_posts_path+ rather than +admin_posts_path+
+namespace :admin, as: "sekret" do
+  resources :posts
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 937
+def namespace(path, options = {})
+  path = path.to_s
+
+  defaults = {
+    module:         path,
+    as:             options.fetch(:as, path),
+    shallow_path:   options.fetch(:path, path),
+    shallow_prefix: options.fetch(:as, path)
+  }
+
+  path_scope(options.delete(:path) { path }) do
+    scope(defaults.merge!(options)) { yield }
+  end
+end
+
+
+ +
+ +
+

+ + scope(*args) + +

+ + +
+

Scopes a set of routes to the given default options.

+ +

Take the following route definition as an example:

+ +
scope path: ":account_id", as: "account" do
+  resources :projects
+end
+
+ +

This generates helpers such as account_projects_path, just like resources does. The difference here being that the routes generated are like /:account_id/projects, rather than /accounts/:account_id/projects.

+ +

Options

+ +

Takes same options as Base#match and Resources#resources.

+ +
# route /posts (without the prefix /admin) to <tt>Admin::PostsController</tt>
+scope module: "admin" do
+  resources :posts
+end
+
+# prefix the posts resource's requests with '/admin'
+scope path: "/admin" do
+  resources :posts
+end
+
+# prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+
+scope as: "sekret" do
+  resources :posts
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 833
+def scope(*args)
+  options = args.extract_options!.dup
+  scope = {}
+
+  options[:path] = args.flatten.join("/") if args.any?
+  options[:constraints] ||= {}
+
+  unless nested_scope?
+    options[:shallow_path] ||= options[:path] if options.key?(:path)
+    options[:shallow_prefix] ||= options[:as] if options.key?(:as)
+  end
+
+  if options[:constraints].is_a?(Hash)
+    defaults = options[:constraints].select do |k, v|
+      URL_OPTIONS.include?(k) && (v.is_a?(String) || v.is_a?(Integer))
+    end
+
+    options[:defaults] = defaults.merge(options[:defaults] || {})
+  else
+    block, options[:constraints] = options[:constraints], {}
+  end
+
+  if options.key?(:only) || options.key?(:except)
+    scope[:action_options] = { only: options.delete(:only),
+                               except: options.delete(:except) }
+  end
+
+  if options.key? :anchor
+    raise ArgumentError, "anchor is ignored unless passed to `match`"
+  end
+
+  @scope.options.each do |option|
+    if option == :blocks
+      value = block
+    elsif option == :options
+      value = options
+    else
+      value = options.delete(option) { POISON }
+    end
+
+    unless POISON == value
+      scope[option] = send("merge_#{option}_scope", @scope[option], value)
+    end
+  end
+
+  @scope = @scope.new scope
+  yield
+  self
+ensure
+  @scope = @scope.parent
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/PathRedirect.html b/src/5.2/classes/ActionDispatch/Routing/PathRedirect.html new file mode 100644 index 0000000000..0a62235610 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/PathRedirect.html @@ -0,0 +1,172 @@ +--- +title: ActionDispatch::Routing::PathRedirect +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
URL_PARTS=/\A([^?]+)?(\?[^#]+)?(#.+)?\z/
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/redirection.rb, line 95
+def inspect
+  "redirect(#{status}, #{block})"
+end
+
+
+ +
+ +
+

+ + path(params, request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/redirection.rb, line 83
+def path(params, request)
+  if block.match(URL_PARTS)
+    path     = interpolation_required?($1, params) ? $1 % escape_path(params)     : $1
+    query    = interpolation_required?($2, params) ? $2 % escape(params)          : $2
+    fragment = interpolation_required?($3, params) ? $3 % escape_fragment(params) : $3
+
+    "#{path}#{query}#{fragment}"
+  else
+    interpolation_required?(block, params) ? block % escape(params) : block
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/PolymorphicRoutes.html b/src/5.2/classes/ActionDispatch/Routing/PolymorphicRoutes.html new file mode 100644 index 0000000000..7a150c3bd2 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/PolymorphicRoutes.html @@ -0,0 +1,273 @@ +--- +title: ActionDispatch::Routing::PolymorphicRoutes +layout: default +--- +
+ +
+
+ +
+ +

Polymorphic URL helpers are methods for smart resolution to a named route call when given an Active Record model instance. They are to be used in combination with ActionController::Resources.

+ +

These methods are useful when you want to generate the correct URL or path to a RESTful resource without having to know the exact type of the record in question.

+ +

Nested resources and/or namespaces are also supported, as illustrated in the example:

+ +
polymorphic_url([:admin, @article, @comment])
+
+ +

results in:

+ +
admin_article_comment_url(@article, @comment)
+
+ +

Usage within the framework

+ +

Polymorphic URL helpers are used in a number of places throughout the Rails framework:

+
  • +

    url_for, so you can use it with a record as the argument, e.g. url_for(@article);

    +
  • +

    ActionView::Helpers::FormHelper uses polymorphic_path, so you can write form_for(@article) without having to specify :url parameter for the form action;

    +
  • +

    redirect_to (which, in fact, uses url_for) so you can write redirect_to(post) in your controllers;

    +
  • +

    ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly specify URLs for feed entries.

    +
+ +

Prefixed polymorphic helpers

+ +

In addition to polymorphic_url and polymorphic_path methods, a number of prefixed helpers are available as a shorthand to action: "..." in options. Those are:

+
  • +

    edit_polymorphic_url, edit_polymorphic_path

    +
  • +

    new_polymorphic_url, new_polymorphic_path

    +
+ +

Example usage:

+ +
edit_polymorphic_path(@post)           # => "/posts/1/edit"
+polymorphic_path(@post, format: :pdf)  # => "/posts/1.pdf"
+
+ +

Usage with mounted engines

+ +

If you are using a mounted engine and you need to use a polymorphic_url pointing at the engine's routes, pass in the engine's route proxy as the first argument to the method. For example:

+ +
polymorphic_url([blog, @post])  # calls blog.post_path(@post)
+form_for([blog, @post])         # => "/blog/posts/1"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + polymorphic_path(record_or_hash_or_array, options = {}) + +

+ + +
+

Returns the path component of a URL for the given record. It uses polymorphic_url with routing_type: :path.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/polymorphic_routes.rb, line 125
+def polymorphic_path(record_or_hash_or_array, options = {})
+  if Hash === record_or_hash_or_array
+    options = record_or_hash_or_array.merge(options)
+    record  = options.delete :id
+    return polymorphic_path record, options
+  end
+
+  if mapping = polymorphic_mapping(record_or_hash_or_array)
+    return mapping.call(self, [record_or_hash_or_array, options], true)
+  end
+
+  opts   = options.dup
+  action = opts.delete :action
+  type   = :path
+
+  HelperMethodBuilder.polymorphic_method self,
+                                         record_or_hash_or_array,
+                                         action,
+                                         type,
+                                         opts
+end
+
+
+ +
+ +
+

+ + polymorphic_url(record_or_hash_or_array, options = {}) + +

+ + +
+

Constructs a call to a named RESTful route for the given record and returns the resulting URL string. For example:

+ +
# calls post_url(post)
+polymorphic_url(post) # => "http://example.com/posts/1"
+polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
+polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
+polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
+polymorphic_url(Comment) # => "http://example.com/comments"
+
+ +

Options

+
  • +

    :action - Specifies the action prefix for the named route: :new or :edit. Default is no prefix.

    +
  • +

    :routing_type - Allowed values are :path or :url. Default is :url.

    +
+ +

Also includes all the options from url_for. These include such things as :anchor or :trailing_slash. Example usage is given below:

+ +
polymorphic_url([blog, post], anchor: 'my_anchor')
+  # => "http://example.com/blogs/1/posts/1#my_anchor"
+polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
+  # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
+
+ +

For all of these options, see the documentation for url_for.

+ +

Functionality

+ +
# an Article record
+polymorphic_url(record)  # same as article_url(record)
+
+# a Comment record
+polymorphic_url(record)  # same as comment_url(record)
+
+# it recognizes new records and maps to the collection
+record = Comment.new
+polymorphic_url(record)  # same as comments_url()
+
+# the class of a record will also map to the collection
+polymorphic_url(Comment) # same as comments_url()
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/polymorphic_routes.rb, line 101
+def polymorphic_url(record_or_hash_or_array, options = {})
+  if Hash === record_or_hash_or_array
+    options = record_or_hash_or_array.merge(options)
+    record  = options.delete :id
+    return polymorphic_url record, options
+  end
+
+  if mapping = polymorphic_mapping(record_or_hash_or_array)
+    return mapping.call(self, [record_or_hash_or_array, options], false)
+  end
+
+  opts   = options.dup
+  action = opts.delete :action
+  type   = opts.delete(:routing_type) || :url
+
+  HelperMethodBuilder.polymorphic_method self,
+                                         record_or_hash_or_array,
+                                         action,
+                                         type,
+                                         opts
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/Redirection.html b/src/5.2/classes/ActionDispatch/Routing/Redirection.html new file mode 100644 index 0000000000..0b4dd360b8 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/Redirection.html @@ -0,0 +1,148 @@ +--- +title: ActionDispatch::Routing::Redirection +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + redirect(*args, &block) + +

+ + +
+

Redirect any path to another path:

+ +
get "/stories" => redirect("/posts")
+
+ +

This will redirect the user, while ignoring certain parts of the request, including query string, etc. /stories, /stories?foo=bar, etc all redirect to /posts.

+ +

You can also use interpolation in the supplied redirect argument:

+ +
get 'docs/:article', to: redirect('/wiki/%{article}')
+
+ +

Note that if you return a path without a leading slash then the URL is prefixed with the current SCRIPT_NAME environment variable. This is typically '/' but may be different in a mounted engine or where the application is deployed to a subdirectory of a website.

+ +

Alternatively you can use one of the other syntaxes:

+ +

The block version of redirect allows for the easy encapsulation of any logic associated with the redirect in question. Either the params and request are supplied as arguments, or just params, depending of how many arguments your block accepts. A string is required as a return value.

+ +
get 'jokes/:number', to: redirect { |params, request|
+  path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp")
+  "http://#{request.host_with_port}/#{path}"
+}
+
+ +

Note that the +do end+ syntax for the redirect block wouldn't work, as Ruby would pass the block to get instead of redirect. Use { ... } instead.

+ +

The options version of redirect allows you to supply only the parts of the URL which need to change, it also supports interpolation of the path similar to the first example.

+ +
get 'stores/:name',       to: redirect(subdomain: 'stores', path: '/%{name}')
+get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}')
+get '/stories', to: redirect(path: '/posts')
+
+ +

This will redirect the user, while changing only the specified parts of the request, for example the path option in the last example. /stories, /stories?foo=bar, redirect to /posts and /posts?foo=bar respectively.

+ +

Finally, an object which responds to call can be supplied to redirect, allowing you to reuse common redirect routes. The call method must accept two arguments, params and request, and return a string.

+ +
get 'accounts/:name' => redirect(SubdomainRedirector.new('api'))
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/redirection.rb, line 187
+def redirect(*args, &block)
+  options = args.extract_options!
+  status  = options.delete(:status) || 301
+  path    = args.shift
+
+  return OptionRedirect.new(status, options) if options.any?
+  return PathRedirect.new(status, path) if String === path
+
+  block = path if path.respond_to? :call
+  raise ArgumentError, "redirection argument not supported" unless block
+  Redirect.new status, block
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet.html new file mode 100644 index 0000000000..b0d6925ed8 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet.html @@ -0,0 +1,88 @@ +--- +title: ActionDispatch::Routing::RouteSet +layout: default +--- +
+ + +
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/CustomUrlHelper.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/CustomUrlHelper.html new file mode 100644 index 0000000000..6e79ca1c09 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/CustomUrlHelper.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::CustomUrlHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/Dispatcher.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/Dispatcher.html new file mode 100644 index 0000000000..3733ac5963 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/Dispatcher.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::Dispatcher +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/Generator.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/Generator.html new file mode 100644 index 0000000000..4e93ce1a71 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/Generator.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::Generator +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/MountedHelpers.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/MountedHelpers.html new file mode 100644 index 0000000000..c6824d18fe --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/MountedHelpers.html @@ -0,0 +1,54 @@ +--- +title: ActionDispatch::Routing::RouteSet::MountedHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection.html new file mode 100644 index 0000000000..211e4dc5a9 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::Routing::RouteSet::NamedRouteCollection +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper.html new file mode 100644 index 0000000000..13bc436bab --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::Routing::RouteSet::NamedRouteCollection::UrlHelper +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper/OptimizedUrlHelper.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper/OptimizedUrlHelper.html new file mode 100644 index 0000000000..f61aa5f1a6 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper/OptimizedUrlHelper.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::NamedRouteCollection::UrlHelper::OptimizedUrlHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteSet/StaticDispatcher.html b/src/5.2/classes/ActionDispatch/Routing/RouteSet/StaticDispatcher.html new file mode 100644 index 0000000000..593e76102c --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteSet/StaticDispatcher.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::StaticDispatcher +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/RouteWrapper.html b/src/5.2/classes/ActionDispatch/Routing/RouteWrapper.html new file mode 100644 index 0000000000..5e10c1f666 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/RouteWrapper.html @@ -0,0 +1,462 @@ +--- +title: ActionDispatch::Routing::RouteWrapper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + action() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 41
+def action
+  parts.include?(:action) ? ":action" : requirements[:action]
+end
+
+
+ +
+ +
+

+ + constraints() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 13
+def constraints
+  requirements.except(:controller, :action)
+end
+
+
+ +
+ +
+

+ + controller() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 37
+def controller
+  parts.include?(:controller) ? ":controller" : requirements[:controller]
+end
+
+
+ +
+ +
+

+ + endpoint() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 9
+def endpoint
+  app.dispatcher? ? "#{controller}##{action}" : rack_app.inspect
+end
+
+
+ +
+ +
+

+ + engine?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 49
+def engine?
+  app.engine?
+end
+
+
+ +
+ +
+

+ + internal?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 45
+def internal?
+  internal
+end
+
+
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 25
+def name
+  super.to_s
+end
+
+
+ +
+ +
+

+ + path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 21
+def path
+  super.spec.to_s
+end
+
+
+ +
+ +
+

+ + rack_app() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 17
+def rack_app
+  app.rack_app
+end
+
+
+ +
+ +
+

+ + reqs() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 29
+def reqs
+  @reqs ||= begin
+    reqs = endpoint
+    reqs += " #{constraints}" unless constraints.empty?
+    reqs
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Routing/UrlFor.html b/src/5.2/classes/ActionDispatch/Routing/UrlFor.html new file mode 100644 index 0000000000..1ce9aceec1 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Routing/UrlFor.html @@ -0,0 +1,488 @@ +--- +title: ActionDispatch::Routing::UrlFor +layout: default +--- +
+ +
+
+ +
+ +

In config/routes.rb you define URL-to-controller mappings, but the reverse is also possible: a URL can be generated from one of your routing definitions. URL generation functionality is centralized in this module.

+ +

See ActionDispatch::Routing for general information about routing and routes.rb.

+ +

Tip: If you need to generate URLs from your models or some other place, then ActionController::UrlFor is what you're looking for. Read on for an introduction. In general, this module should not be included on its own, as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).

+ +

URL generation from parameters

+ +

As you may know, some functions, such as ActionController::Base#url_for and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set of parameters. For example, you've probably had the chance to write code like this in one of your views:

+ +
<%= link_to('Click here', controller: 'users',
+        action: 'new', message: 'Welcome!') %>
+# => <a href="/users/new?message=Welcome%21">Click here</a>
+
+ +

link_to, and all other functions that require URL generation functionality, actually use ActionController::UrlFor under the hood. And in particular, they use the ActionController::UrlFor#url_for method. One can generate the same path as the above example by using the following code:

+ +
include UrlFor
+url_for(controller: 'users',
+        action: 'new',
+        message: 'Welcome!',
+        only_path: true)
+# => "/users/new?message=Welcome%21"
+
+ +

Notice the only_path: true part. This is because UrlFor has no information about the website hostname that your Rails app is serving. So if you want to include the hostname as well, then you must also pass the :host argument:

+ +
include UrlFor
+url_for(controller: 'users',
+        action: 'new',
+        message: 'Welcome!',
+        host: 'www.example.com')
+# => "http://www.example.com/users/new?message=Welcome%21"
+
+ +

By default, all controllers and views have access to a special version of url_for, that already knows what the current hostname is. So if you use url_for in your controllers or your views, then you don't need to explicitly pass the :host argument.

+ +

For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for. So within mailers, you only have to type url_for instead of 'ActionController::UrlFor#url_for' in full. However, mailers don't have hostname information, and you still have to provide the :host argument or set the default host that will be used in all mailers using the configuration option config.action_mailer.default_url_options. For more information on url_for in mailers read the ActionMailer#Base documentation.

+ +

URL generation for named routes

+ +

UrlFor also allows one to access methods that have been auto-generated from named routes. For example, suppose that you have a 'users' resource in your config/routes.rb:

+ +
resources :users
+
+ +

This generates, among other things, the method users_path. By default, this method is accessible from your controllers, views and mailers. If you need to access this auto-generated method from other places (such as a model), then you can do that by including Rails.application.routes.url_helpers in your class:

+ +
class User < ActiveRecord::Base
+  include Rails.application.routes.url_helpers
+
+  def base_uri
+    user_path(self)
+  end
+end
+
+User.find(1).base_uri # => "/users/1"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 106
+def initialize(*)
+  @_routes = nil
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + route_for(name, *args) + +

+ + +
+

Allows calling direct or regular named route.

+ +
resources :buckets
+
+direct :recordable do |recording|
+  route_for(:bucket, recording.bucket)
+end
+
+direct :threadable do |threadable|
+  route_for(:recordable, threadable.parent)
+end
+
+ +

This maintains the context of the original caller on whether to return a path or full URL, e.g:

+ +
threadable_path(threadable)  # => "/buckets/1"
+threadable_url(threadable)   # => "http://example.com/buckets/1"
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 212
+def route_for(name, *args)
+  public_send(:"#{name}_url", *args)
+end
+
+
+ +
+ +
+

+ + url_for(options = nil) + +

+ + +
+

Generate a URL based on the options provided, default_url_options and the routes defined in routes.rb. The following options are supported:

+
  • +

    :only_path - If true, the relative URL is returned. Defaults to false.

    +
  • +

    :protocol - The protocol to connect to. Defaults to 'http'.

    +
  • +

    :host - Specifies the host the link should be targeted at. If :only_path is false, this option must be provided either explicitly, or via default_url_options.

    +
  • +

    :subdomain - Specifies the subdomain of the link, using the tld_length to split the subdomain from the host. If false, removes all subdomains from the host part of the link.

    +
  • +

    :domain - Specifies the domain of the link, using the tld_length to split the domain from the host.

    +
  • +

    :tld_length - Number of labels the TLD id composed of, only used if :subdomain or :domain are supplied. Defaults to ActionDispatch::Http::URL.tld_length, which in turn defaults to 1.

    +
  • +

    :port - Optionally specify the port to connect to.

    +
  • +

    :anchor - An anchor name to be appended to the path.

    +
  • +

    :trailing_slash - If true, adds a trailing slash, as in “/archive/2009/”

    +
  • +

    :script_name - Specifies application path relative to domain root. If provided, prepends application path.

    +
+ +

Any other key (:controller, :action, etc.) given to url_for is forwarded to the Routes module.

+ +
url_for controller: 'tasks', action: 'testing', host: 'somehost.org', port: '8080'
+# => 'http://somehost.org:8080/tasks/testing'
+url_for controller: 'tasks', action: 'testing', host: 'somehost.org', anchor: 'ok', only_path: true
+# => '/tasks/testing#ok'
+url_for controller: 'tasks', action: 'testing', trailing_slash: true
+# => 'http://somehost.org/tasks/testing/'
+url_for controller: 'tasks', action: 'testing', host: 'somehost.org', number: '33'
+# => 'http://somehost.org/tasks/testing?number=33'
+url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp"
+# => 'http://somehost.org/myapp/tasks/testing'
+url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true
+# => '/myapp/tasks/testing'
+
+ +

Missing routes keys may be filled in from the current request's parameters (e.g. :controller, :action, :id and any other parameters that are placed in the path). Given that the current action has been reached through GET /users/1:

+ +
url_for(only_path: true)                        # => '/users/1'
+url_for(only_path: true, action: 'edit')        # => '/users/1/edit'
+url_for(only_path: true, action: 'edit', id: 2) # => '/users/2/edit'
+
+ +

Notice that no :id parameter was provided to the first url_for call and the helper used the one from the route's path. Any path parameter implicitly used by url_for can always be overwritten like shown on the last url_for calls.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 168
+def url_for(options = nil)
+  full_url_for(options)
+end
+
+
+ +
+ +
+

+ + url_options() + +

+ + +
+

Hook overridden in controller to add request information with default_url_options. Application logic should not go into url_options.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 114
+def url_options
+  default_url_options
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + optimize_routes_generation?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 218
+def optimize_routes_generation?
+  _routes.optimize_routes_generation? && default_url_options.empty?
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + _routes_context() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 231
+def _routes_context # :doc:
+  self
+end
+
+
+ +
+ +
+

+ + _with_routes(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 224
+def _with_routes(routes) # :doc:
+  old_routes, @_routes = @_routes, routes
+  yield
+ensure
+  @_routes = old_routes
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/SSL.html b/src/5.2/classes/ActionDispatch/SSL.html new file mode 100644 index 0000000000..a48eed9c4a --- /dev/null +++ b/src/5.2/classes/ActionDispatch/SSL.html @@ -0,0 +1,91 @@ +--- +title: ActionDispatch::SSL +layout: default +--- +
+ +
+
+ +
+ +

This middleware is added to the stack when config.force_ssl = true, and is passed the options set in config.ssl_options. It does three jobs to enforce secure HTTP requests:

+
  1. +

    TLS redirect: Permanently redirects http:// requests to https:// with the same URL host, path, etc. Enabled by default. Set config.ssl_options to modify the destination URL (e.g. redirect: { host: "secure.widgets.com", port: 8080 }), or set redirect: false to disable this feature.

    + +

    Requests can opt-out of redirection with exclude:

    + +
    config.ssl_options = { redirect: { exclude: -> request { request.path =~ /healthcheck/ } } }
    +
    + +

    Cookies will not be flagged as secure for excluded requests.

    +
  2. +

    Secure cookies: Sets the secure flag on cookies to tell browsers they must not be sent along with http:// requests. Enabled by default. Set config.ssl_options with secure_cookies: false to disable this feature.

    +
  3. +

    HTTP Strict Transport Security (HSTS): Tells the browser to remember this site as TLS-only and automatically redirect non-TLS requests. Enabled by default. Configure config.ssl_options with hsts: false to disable.

    + +

    Set config.ssl_options with hsts: { ... } to configure HSTS:

    +
    • +

      expires: How long, in seconds, these settings will stick. The minimum required to qualify for browser preload lists is 1 year. Defaults to 1 year (recommended).

      +
    • +

      subdomains: Set to true to tell the browser to apply these settings to all subdomains. This protects your cookies from interception by a vulnerable site on a subdomain. Defaults to true.

      +
    • +

      preload: Advertise that this site may be included in browsers' preloaded HSTS lists. HSTS protects your site on every visit except the first visit since it hasn't seen your HSTS header yet. To close this gap, browser vendors include a baked-in list of HSTS-enabled sites. Go to hstspreload.org to submit your site for inclusion. Defaults to false.

      +
    + +

    To turn off HSTS, omitting the header is not enough. Browsers will remember the original HSTS directive until it expires. Instead, use the header to tell browsers to expire HSTS immediately. Setting hsts: false is a shortcut for hsts: { expires: 0 }.

    +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session.html b/src/5.2/classes/ActionDispatch/Session.html new file mode 100644 index 0000000000..9be7683216 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session.html @@ -0,0 +1,92 @@ +--- +title: ActionDispatch::Session +layout: default +--- + diff --git a/src/5.2/classes/ActionDispatch/Session/AbstractSecureStore.html b/src/5.2/classes/ActionDispatch/Session/AbstractSecureStore.html new file mode 100644 index 0000000000..0cf5e7acf9 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/AbstractSecureStore.html @@ -0,0 +1,129 @@ +--- +title: ActionDispatch::Session::AbstractSecureStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + generate_sid() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 96
+def generate_sid
+  Rack::Session::SessionId.new(super)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session/AbstractStore.html b/src/5.2/classes/ActionDispatch/Session/AbstractStore.html new file mode 100644 index 0000000000..616871b908 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/AbstractStore.html @@ -0,0 +1,82 @@ +--- +title: ActionDispatch::Session::AbstractStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session/CacheStore.html b/src/5.2/classes/ActionDispatch/Session/CacheStore.html new file mode 100644 index 0000000000..40d39d22a8 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/CacheStore.html @@ -0,0 +1,253 @@ +--- +title: ActionDispatch::Session::CacheStore +layout: default +--- +
+ +
+
+ +
+ +

A session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful if you don't store critical data in your sessions and you don't need them to live for extended periods of time.

+ +

Options

+
  • +

    cache - The cache to use. If it is not specified, Rails.cache will be used.

    +
  • +

    expire_after - The length of time a session will be stored before automatically expiring. By default, the :expires_in option of the cache is used.

    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 16
+def initialize(app, options = {})
+  @cache = options[:cache] || Rails.cache
+  options[:expire_after] ||= @cache.options[:expires_in]
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete_session(env, sid, options) + +

+ + +
+

Remove a session from the cache.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 42
+def delete_session(env, sid, options)
+  @cache.delete(cache_key(sid.private_id))
+  @cache.delete(cache_key(sid.public_id))
+  generate_sid
+end
+
+
+ +
+ +
+

+ + find_session(env, sid) + +

+ + +
+

Get a session from the cache.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 23
+def find_session(env, sid)
+  unless sid && (session = get_session_with_fallback(sid))
+    sid, session = generate_sid, {}
+  end
+  [sid, session]
+end
+
+
+ +
+ +
+

+ + write_session(env, sid, session, options) + +

+ + +
+

Set a session in the cache.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 31
+def write_session(env, sid, session, options)
+  key = cache_key(sid.private_id)
+  if session
+    @cache.write(key, session, expires_in: options[:expire_after])
+  else
+    @cache.delete(key)
+  end
+  sid
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session/Compatibility.html b/src/5.2/classes/ActionDispatch/Session/Compatibility.html new file mode 100644 index 0000000000..b3034a9443 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/Compatibility.html @@ -0,0 +1,189 @@ +--- +title: ActionDispatch::Session::Compatibility +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 21
+def initialize(app, options = {})
+  options[:key] ||= "_session_id"
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + generate_sid() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 26
+def generate_sid
+  sid = SecureRandom.hex(16)
+  sid.encode!(Encoding::UTF_8)
+  sid
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + initialize_sid() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 34
+def initialize_sid # :doc:
+  @default_options.delete(:sidbits)
+  @default_options.delete(:secure_random)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session/CookieStore.html b/src/5.2/classes/ActionDispatch/Session/CookieStore.html new file mode 100644 index 0000000000..87ff361ab0 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/CookieStore.html @@ -0,0 +1,240 @@ +--- +title: ActionDispatch::Session::CookieStore +layout: default +--- +
+ +
+
+ +
+ +

This cookie-based session store is the Rails default. It is dramatically faster than the alternatives.

+ +

Sessions typically contain at most a user_id and flash message; both fit within the 4K cookie size limit. A CookieOverflow exception is raised if you attempt to store more than 4K of data.

+ +

The cookie jar used for storage is automatically configured to be the best possible option given your application's configuration.

+ +

If you only have secret_token set, your cookies will be signed, but not encrypted. This means a user cannot alter their user_id without knowing your app's secret key, but can easily read their user_id. This was the default for Rails 3 apps.

+ +

Your cookies will be encrypted using your apps secret_key_base. This goes a step further than signed cookies in that encrypted cookies cannot be altered or read by users. This is the default starting in Rails 4.

+ +

Configure your session store in config/initializers/session_store.rb:

+ +
Rails.application.config.session_store :cookie_store, key: '_your_app_session'
+
+ +

In the development and test environments your application's secret key base is generated by Rails and stored in a temporary file in tmp/development_secret.txt. In all other environments, it is stored encrypted in the config/credentials.yml.enc file.

+ +

If your application was not updated to Rails 5.2 defaults, the secret_key_base will be found in the old config/secrets.yml file.

+ +

Note that changing your secret_key_base will invalidate all existing session. Additionally, you should take care to make sure you are not relying on the ability to decode signed cookies generated by your app in external applications or JavaScript before changing it.

+ +

Because CookieStore extends Rack::Session::Abstract::Persisted, many of the options described there can be used to customize the session cookie that is generated. For example:

+ +
Rails.application.config.session_store :cookie_store, expire_after: 14.days
+
+ +

would set the session cookie to expire automatically 14 days after creation. Other useful options include :key, :secure and :httponly.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 64
+def initialize(app, options = {})
+  super(app, options.merge!(cookie_only: true))
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete_session(req, session_id, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 68
+def delete_session(req, session_id, options)
+  new_sid = generate_sid unless options[:drop]
+  # Reset hash and Assign the new session id
+  req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid.public_id } : {})
+  new_sid
+end
+
+
+ +
+ +
+

+ + load_session(req) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 75
+def load_session(req)
+  stale_session_check! do
+    data = unpacked_cookie_data(req)
+    data = persistent_session_id!(data)
+    [Rack::Session::SessionId.new(data["session_id"]), data]
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session/CookieStore/SessionId.html b/src/5.2/classes/ActionDispatch/Session/CookieStore/SessionId.html new file mode 100644 index 0000000000..593ec534b6 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/CookieStore/SessionId.html @@ -0,0 +1,122 @@ +--- +title: ActionDispatch::Session::CookieStore::SessionId +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + cookie_value
+ + + + +

Class Public methods

+ +
+

+ + new(session_id, cookie_value = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 58
+def initialize(session_id, cookie_value = {})
+  super(session_id)
+  @cookie_value = cookie_value
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session/MemCacheStore.html b/src/5.2/classes/ActionDispatch/Session/MemCacheStore.html new file mode 100644 index 0000000000..550d97e541 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/MemCacheStore.html @@ -0,0 +1,141 @@ +--- +title: ActionDispatch::Session::MemCacheStore +layout: default +--- +
+ +
+
+ +
+ +

A session store that uses MemCache to implement storage.

+ +

Options

+
  • +

    expire_after - The length of time a session will be stored before automatically expiring.

    +
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb, line 22
+def initialize(app, options = {})
+  options[:expire_after] ||= options[:expires]
+  super
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Session/StaleSessionCheck.html b/src/5.2/classes/ActionDispatch/Session/StaleSessionCheck.html new file mode 100644 index 0000000000..5d3fe8bae6 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Session/StaleSessionCheck.html @@ -0,0 +1,191 @@ +--- +title: ActionDispatch::Session::StaleSessionCheck +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + extract_session_id(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 49
+def extract_session_id(env)
+  stale_session_check! { super }
+end
+
+
+ +
+ +
+

+ + load_session(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 45
+def load_session(env)
+  stale_session_check! { super }
+end
+
+
+ +
+ +
+

+ + stale_session_check!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 53
+def stale_session_check!
+  yield
+rescue ArgumentError => argument_error
+  if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
+    begin
+      # Note that the regexp does not allow $1 to end with a ':'.
+      $1.constantize
+    rescue LoadError, NameError
+      raise ActionDispatch::Session::SessionRestoreError
+    end
+    retry
+  else
+    raise
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/ShowExceptions.html b/src/5.2/classes/ActionDispatch/ShowExceptions.html new file mode 100644 index 0000000000..39a4786f87 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/ShowExceptions.html @@ -0,0 +1,189 @@ +--- +title: ActionDispatch::ShowExceptions +layout: default +--- +
+ +
+
+ +
+ +

This middleware rescues any exception returned by the application and calls an exceptions app that will wrap it in a format for the end user.

+ +

The exceptions app should be passed as parameter on initialization of ShowExceptions. Every time there is an exception, ShowExceptions will store the exception in env, rewrite the PATH_INFO to the exception status code and call the Rack app.

+ +

If the application returns a “X-Cascade” pass response, this middleware will send an empty response as result with the correct status code. If any exception happens inside the exceptions app, this middleware catches the exceptions and returns a FAILSAFE_RESPONSE.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
FAILSAFE_RESPONSE=[500, { "Content-Type" => "text/plain" }, +["500 Internal Server Error\n" \ +"If you are the administrator of this website, then please read this web " \ +"application's log file and/or the web server's log file to find out what " \ +"went wrong."]]
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(app, exceptions_app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/show_exceptions.rb, line 26
+def initialize(app, exceptions_app)
+  @app = app
+  @exceptions_app = exceptions_app
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/show_exceptions.rb, line 31
+def call(env)
+  request = ActionDispatch::Request.new env
+  @app.call(env)
+rescue Exception => exception
+  if request.show_exceptions?
+    render_exception(request, exception)
+  else
+    raise exception
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/Static.html b/src/5.2/classes/ActionDispatch/Static.html new file mode 100644 index 0000000000..7440bc3d7d --- /dev/null +++ b/src/5.2/classes/ActionDispatch/Static.html @@ -0,0 +1,168 @@ +--- +title: ActionDispatch::Static +layout: default +--- +
+ +
+
+ +
+ +

This middleware will attempt to return the contents of a file's body from disk in the response. If a file is not found on disk, the request will be delegated to the application stack. This middleware is commonly initialized to serve assets from a server's public/ directory.

+ +

This middleware verifies the path to ensure that only files living in the root directory can be rendered. A request cannot produce a directory traversal using this middleware. Only 'GET' and 'HEAD' requests will result in a file being returned.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, path, index: "index", headers: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/static.rb, line 111
+def initialize(app, path, index: "index", headers: {})
+  @app = app
+  @file_handler = FileHandler.new(path, index: index, headers: headers)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/middleware/static.rb, line 116
+def call(env)
+  req = Rack::Request.new env
+
+  if req.get? || req.head?
+    path = req.path_info.chomp("/".freeze)
+    if match = @file_handler.match?(path)
+      req.path_info = match
+      return @file_handler.serve(req)
+    end
+  end
+
+  @app.call(req.env)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/SystemTestCase.html b/src/5.2/classes/ActionDispatch/SystemTestCase.html new file mode 100644 index 0000000000..b68ef0d45a --- /dev/null +++ b/src/5.2/classes/ActionDispatch/SystemTestCase.html @@ -0,0 +1,214 @@ +--- +title: ActionDispatch::SystemTestCase +layout: default +--- +
+ +
+
+ +
+ +

System Testing

+ +

System tests let you test applications in the browser. Because system tests use a real browser experience, you can test all of your JavaScript easily from your test suite.

+ +

To create a system test in your application, extend your test class from ApplicationSystemTestCase. System tests use Capybara as a base and allow you to configure the settings through your application_system_test_case.rb file that is generated with a new application or scaffold.

+ +

Here is an example system test:

+ +
require 'application_system_test_case'
+
+class Users::CreateTest < ApplicationSystemTestCase
+  test "adding a new user" do
+    visit users_path
+    click_on 'New User'
+
+    fill_in 'Name', with: 'Arya'
+    click_on 'Create User'
+
+    assert_text 'Arya'
+  end
+end
+
+ +

When generating an application or scaffold, an application_system_test_case.rb file will also be generated containing the base class for system testing. This is where you can change the driver, add Capybara settings, and other configuration for your system tests.

+ +
require "test_helper"
+
+class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+  driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
+end
+
+ +

By default, ActionDispatch::SystemTestCase is driven by the Selenium driver, with the Chrome browser, and a browser size of 1400x1400.

+ +

Changing the driver configuration options is easy. Let's say you want to use the Firefox browser instead of Chrome. In your application_system_test_case.rb file add the following:

+ +
require "test_helper"
+
+class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+  driven_by :selenium, using: :firefox
+end
+
+ +

driven_by has a required argument for the driver name. The keyword arguments are :using for the browser and :screen_size to change the size of the browser screen. These two options are not applicable for headless drivers and will be silently ignored if passed.

+ +

Headless browsers such as headless Chrome and headless Firefox are also supported. You can use these browsers by setting the :using argument to :headless_chrome or :headless_firefox.

+ +

To use a headless driver, like Poltergeist, update your Gemfile to use Poltergeist instead of Selenium and then declare the driver name in the application_system_test_case.rb file. In this case, you would leave out the :using option because the driver is headless, but you can still use :screen_size to change the size of the browser screen, also you can use :options to pass options supported by the driver. Please refer to your driver documentation to learn about supported options.

+ +
require "test_helper"
+require "capybara/poltergeist"
+
+class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+  driven_by :poltergeist, screen_size: [1400, 1400], options:
+    { js_errors: true }
+end
+
+ +

Because ActionDispatch::SystemTestCase is a shim between Capybara and Rails, any driver that is supported by Capybara is supported by system tests as long as you include the required gems and files.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}) + +

+ + +
+

System Test configuration options

+ +

The default settings are Selenium, using Chrome, with a screen size of 1400x1400.

+ +

Examples:

+ +
driven_by :poltergeist
+
+driven_by :selenium, screen_size: [800, 800]
+
+driven_by :selenium, using: :chrome
+
+driven_by :selenium, using: :headless_chrome
+
+driven_by :selenium, using: :firefox
+
+driven_by :selenium, using: :headless_firefox
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/system_test_case.rb, line 137
+def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {})
+  self.driver = SystemTesting::Driver.new(driver, using: using, screen_size: screen_size, options: options)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/SystemTesting.html b/src/5.2/classes/ActionDispatch/SystemTesting.html new file mode 100644 index 0000000000..564e2193fb --- /dev/null +++ b/src/5.2/classes/ActionDispatch/SystemTesting.html @@ -0,0 +1,77 @@ +--- +title: ActionDispatch::SystemTesting +layout: default +--- + diff --git a/src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers.html b/src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers.html new file mode 100644 index 0000000000..452d477e7c --- /dev/null +++ b/src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers.html @@ -0,0 +1,71 @@ +--- +title: ActionDispatch::SystemTesting::TestHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers/ScreenshotHelper.html b/src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers/ScreenshotHelper.html new file mode 100644 index 0000000000..1d744abafe --- /dev/null +++ b/src/5.2/classes/ActionDispatch/SystemTesting/TestHelpers/ScreenshotHelper.html @@ -0,0 +1,168 @@ +--- +title: ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper +layout: default +--- +
+ +
+
+ +
+ +

Screenshot helper for system testing.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + take_failed_screenshot() + +

+ + +
+

Takes a screenshot of the current page in the browser if the test failed.

+ +

take_failed_screenshot is included in application_system_test_case.rb that is generated with the application. To take screenshots when a test fails add take_failed_screenshot to the teardown block before clearing sessions.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb, line 36
+def take_failed_screenshot
+  take_screenshot if failed? && supports_screenshot?
+end
+
+
+ +
+ +
+

+ + take_screenshot() + +

+ + +
+

Takes a screenshot of the current page in the browser.

+ +

take_screenshot can be used at any point in your system tests to take a screenshot of the current state. This can be useful for debugging or automating visual testing.

+ +

The screenshot will be displayed in your console, if supported.

+ +

You can set the RAILS_SYSTEM_TESTING_SCREENSHOT environment variable to control the output. Possible values are:

+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb, line 24
+def take_screenshot
+  save_image
+  puts display_image
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/TestProcess.html b/src/5.2/classes/ActionDispatch/TestProcess.html new file mode 100644 index 0000000000..60c34ef865 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/TestProcess.html @@ -0,0 +1,286 @@ +--- +title: ActionDispatch::TestProcess +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assigns(key = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 28
+def assigns(key = nil)
+  raise NoMethodError,
+    "assigns has been extracted to a gem. To continue using it,
+    add `gem 'rails-controller-testing'` to your Gemfile."
+end
+
+
+ +
+ +
+

+ + cookies() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 42
+def cookies
+  @cookie_jar ||= Cookies::CookieJar.build(@request, @request.cookies)
+end
+
+
+ +
+ +
+

+ + flash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 38
+def flash
+  @request.flash
+end
+
+
+ +
+ +
+

+ + redirect_to_url() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 46
+def redirect_to_url
+  @response.redirect_url
+end
+
+
+ +
+ +
+

+ + session() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 34
+def session
+  @request.session
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/TestProcess/FixtureFile.html b/src/5.2/classes/ActionDispatch/TestProcess/FixtureFile.html new file mode 100644 index 0000000000..c0992fc7c0 --- /dev/null +++ b/src/5.2/classes/ActionDispatch/TestProcess/FixtureFile.html @@ -0,0 +1,113 @@ +--- +title: ActionDispatch::TestProcess::FixtureFile +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + fixture_file_upload(path, mime_type = nil, binary = false) + +

+ + +
+

Shortcut for Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.fixture_path, path), type):

+ +
post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png')
+
+ +

To upload binary files on Windows, pass :binary as the last parameter. This will not affect other platforms:

+ +
post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary)
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 17
+def fixture_file_upload(path, mime_type = nil, binary = false)
+  if self.class.respond_to?(:fixture_path) && self.class.fixture_path &&
+      !File.exist?(path)
+    path = File.join(self.class.fixture_path, path)
+  end
+  Rack::Test::UploadedFile.new(path, mime_type, binary)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/TestRequest.html b/src/5.2/classes/ActionDispatch/TestRequest.html new file mode 100644 index 0000000000..06fd5552fb --- /dev/null +++ b/src/5.2/classes/ActionDispatch/TestRequest.html @@ -0,0 +1,564 @@ +--- +title: ActionDispatch::TestRequest +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_ENV=Rack::MockRequest.env_for("/", +"HTTP_HOST" => "test.host", +"REMOTE_ADDR" => "0.0.0.0", +"HTTP_USER_AGENT" => "Rails Testing", +)
 
+ + + + + + +

Class Public methods

+ +
+

+ + create(env = {}) + +

+ + +
+

Create a new test request with default env values.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 15
+def self.create(env = {})
+  env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
+  env["rack.request.cookie_hash"] ||= {}.with_indifferent_access
+  new(default_env.merge(env))
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + accept=(mime_types) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 66
+def accept=(mime_types)
+  delete_header("action_dispatch.request.accepts")
+  set_header("HTTP_ACCEPT", Array(mime_types).collect(&:to_s).join(","))
+end
+
+
+ +
+ +
+

+ + action=(action_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 46
+def action=(action_name)
+  path_parameters[:action] = action_name.to_s
+end
+
+
+ +
+ +
+

+ + host=(host) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 30
+def host=(host)
+  set_header("HTTP_HOST", host)
+end
+
+
+ +
+ +
+

+ + if_modified_since=(last_modified) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 50
+def if_modified_since=(last_modified)
+  set_header("HTTP_IF_MODIFIED_SINCE", last_modified)
+end
+
+
+ +
+ +
+

+ + if_none_match=(etag) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 54
+def if_none_match=(etag)
+  set_header("HTTP_IF_NONE_MATCH", etag)
+end
+
+
+ +
+ +
+

+ + path=(path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 42
+def path=(path)
+  set_header("PATH_INFO", path)
+end
+
+
+ +
+ +
+

+ + port=(number) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 34
+def port=(number)
+  set_header("SERVER_PORT", number.to_i)
+end
+
+
+ +
+ +
+

+ + remote_addr=(addr) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 58
+def remote_addr=(addr)
+  set_header("REMOTE_ADDR", addr)
+end
+
+
+ +
+ +
+

+ + request_method=(method) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 26
+def request_method=(method)
+  super(method.to_s.upcase)
+end
+
+
+ +
+ +
+

+ + request_uri=(uri) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 38
+def request_uri=(uri)
+  set_header("REQUEST_URI", uri)
+end
+
+
+ +
+ +
+

+ + user_agent=(user_agent) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 62
+def user_agent=(user_agent)
+  set_header("HTTP_USER_AGENT", user_agent)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionDispatch/TestResponse.html b/src/5.2/classes/ActionDispatch/TestResponse.html new file mode 100644 index 0000000000..28ed11453b --- /dev/null +++ b/src/5.2/classes/ActionDispatch/TestResponse.html @@ -0,0 +1,286 @@ +--- +title: ActionDispatch::TestResponse +layout: default +--- +
+ +
+
+ +
+ +

Integration test methods such as ActionDispatch::Integration::Session#get and ActionDispatch::Integration::Session#post return objects of class TestResponse, which represent the HTTP response results of the requested controller actions.

+ +

See Response for more information on controller response objects.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + from_response(response) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 13
+def self.from_response(response)
+  new response.status, response.headers, response.body
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + error?() + +

+ + +
+

Was there a server-side error?

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 41
+    def error?
+      ActiveSupport::Deprecation.warn(<<-MSG.squish)
+       The error? predicate is deprecated and will be removed in Rails 6.0.
+       Please use server_error? as provided by Rack::Response::Helpers.
+      MSG
+      server_error?
+    end
+
+
+ +
+ +
+

+ + missing?() + +

+ + +
+

Was the URL not found?

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 32
+    def missing?
+      ActiveSupport::Deprecation.warn(<<-MSG.squish)
+       The missing? predicate is deprecated and will be removed in Rails 6.0.
+       Please use not_found? as provided by Rack::Response::Helpers.
+      MSG
+      not_found?
+    end
+
+
+ +
+ +
+

+ + parsed_body() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 49
+def parsed_body
+  @parsed_body ||= @response_parser.call(body)
+end
+
+
+ +
+ +
+

+ + success?() + +

+ + +
+

Was the response successful?

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 23
+    def success?
+      ActiveSupport::Deprecation.warn(<<-MSG.squish)
+       The success? predicate is deprecated and will be removed in Rails 6.0.
+       Please use successful? as provided by Rack::Response::Helpers.
+      MSG
+      successful?
+    end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer.html b/src/5.2/classes/ActionMailer.html new file mode 100644 index 0000000000..73d985663f --- /dev/null +++ b/src/5.2/classes/ActionMailer.html @@ -0,0 +1,220 @@ +--- +title: ActionMailer +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Action Mailer as a Gem::Version.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded Action Mailer as a Gem::Version.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/version.rb, line 8
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Base.html b/src/5.2/classes/ActionMailer/Base.html new file mode 100644 index 0000000000..02fec71fed --- /dev/null +++ b/src/5.2/classes/ActionMailer/Base.html @@ -0,0 +1,1474 @@ +--- +title: ActionMailer::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer allows you to send email from your application using a mailer model and views.

+ +

Mailer Models

+ +

To use Action Mailer, you need to create a mailer model.

+ +
$ rails generate mailer Notifier
+
+ +

The generated model inherits from ApplicationMailer which in turn inherits from ActionMailer::Base. A mailer model defines methods used to generate an email message. In these methods, you can setup variables to be used in the mailer views, options on the mail itself such as the :from address, and attachments.

+ +
class ApplicationMailer < ActionMailer::Base
+  default from: 'from@example.com'
+  layout 'mailer'
+end
+
+class NotifierMailer < ApplicationMailer
+  default from: 'no-reply@example.com',
+          return_path: 'system@example.com'
+
+  def welcome(recipient)
+    @account = recipient
+    mail(to: recipient.email_address_with_name,
+         bcc: ["bcc@example.com", "Order Watcher <watcher@example.com>"])
+  end
+end
+
+ +

Within the mailer method, you have access to the following methods:

+
  • +

    attachments[]= - Allows you to add attachments to your email in an intuitive manner; attachments['filename.png'] = File.read('path/to/filename.png')

    +
  • +

    attachments.inline[]= - Allows you to add an inline attachment to your email in the same manner as attachments[]=

    +
  • +

    headers[]= - Allows you to specify any header field in your email such as headers['X-No-Spam'] = 'True'. Note that declaring a header multiple times will add many fields of the same name. Read headers doc for more information.

    +
  • +

    headers(hash) - Allows you to specify multiple headers in your email such as headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'})

    +
  • +

    mail - Allows you to specify email to be sent.

    +
+ +

The hash passed to the mail method allows you to specify any header that a Mail::Message will accept (any valid email header including optional fields).

+ +

The mail method, if not passed a block, will inspect your views and send all the views with the same name as the method, so the above action would send the welcome.text.erb view file as well as the welcome.html.erb view file in a multipart/alternative email.

+ +

If you want to explicitly render only certain templates, pass a block:

+ +
mail(to: user.email) do |format|
+  format.text
+  format.html
+end
+
+ +

The block syntax is also useful in providing information specific to a part:

+ +
mail(to: user.email) do |format|
+  format.text(content_transfer_encoding: "base64")
+  format.html
+end
+
+ +

Or even to render a special view:

+ +
mail(to: user.email) do |format|
+  format.text
+  format.html { render "some_other_template" }
+end
+
+ +

Mailer views

+ +

Like Action Controller, each mailer class has a corresponding view directory in which each method of the class looks for a template with its name.

+ +

To define a template to be used with a mailer, create an .erb file with the same name as the method in your mailer model. For example, in the mailer defined above, the template at app/views/notifier_mailer/welcome.text.erb would be used to generate the email.

+ +

Variables defined in the methods of your mailer model are accessible as instance variables in their corresponding view.

+ +

Emails by default are sent in plain text, so a sample view for our model example might look like this:

+ +
Hi <%= @account.name %>,
+Thanks for joining our service! Please check back often.
+
+ +

You can even use Action View helpers in these views. For example:

+ +
You got a new note!
+<%= truncate(@note.body, length: 25) %>
+
+ +

If you need to access the subject, from or the recipients in the view, you can do that through message object:

+ +
You got a new note from <%= message.from %>!
+<%= truncate(@note.body, length: 25) %>
+
+ +

Generating URLs

+ +

URLs can be generated in mailer views using url_for or named routes. Unlike controllers from Action Pack, the mailer instance doesn't have any context about the incoming request, so you'll need to provide all of the details needed to generate a URL.

+ +

When using url_for you'll need to provide the :host, :controller, and :action:

+ +
<%= url_for(host: "example.com", controller: "welcome", action: "greeting") %>
+
+ +

When using named routes you only need to supply the :host:

+ +
<%= users_url(host: "example.com") %>
+
+ +

You should use the named_route_url style (which generates absolute URLs) and avoid using the named_route_path style (which generates relative URLs), since clients reading the mail will have no concept of a current URL from which to determine a relative path.

+ +

It is also possible to set a default host that will be used in all mailers by setting the :host option as a configuration option in config/application.rb:

+ +
config.action_mailer.default_url_options = { host: "example.com" }
+
+ +

You can also define a default_url_options method on individual mailers to override these default settings per-mailer.

+ +

By default when config.force_ssl is true, URLs generated for hosts will use the HTTPS protocol.

+ +

Sending mail

+ +

Once a mailer action and template are defined, you can deliver your message or defer its creation and delivery for later:

+ +
NotifierMailer.welcome(User.first).deliver_now # sends the email
+mail = NotifierMailer.welcome(User.first)      # => an ActionMailer::MessageDelivery object
+mail.deliver_now                               # generates and sends the email now
+
+ +

The ActionMailer::MessageDelivery class is a wrapper around a delegate that will call your method to generate the mail. If you want direct access to the delegator, or Mail::Message, you can call the message method on the ActionMailer::MessageDelivery object.

+ +
NotifierMailer.welcome(User.first).message     # => a Mail::Message object
+
+ +

Action Mailer is nicely integrated with Active Job so you can generate and send emails in the background (example: outside of the request-response cycle, so the user doesn't have to wait on it):

+ +
NotifierMailer.welcome(User.first).deliver_later # enqueue the email sending to Active Job
+
+ +

Note that deliver_later will execute your method from the background job.

+ +

You never instantiate your mailer class. Rather, you just call the method you defined on the class itself. All instance methods are expected to return a message object to be sent.

+ +

Multipart Emails

+ +

Multipart messages can also be used implicitly because Action Mailer will automatically detect and use multipart templates, where each template is named after the name of the action, followed by the content type. Each such detected template will be added to the message, as a separate part.

+ +

For example, if the following templates exist:

+
  • +

    signup_notification.text.erb

    +
  • +

    signup_notification.html.erb

    +
  • +

    signup_notification.xml.builder

    +
  • +

    signup_notification.yml.erb

    +
+ +

Each would be rendered and added as a separate part to the message, with the corresponding content type. The content type for the entire message is automatically set to multipart/alternative, which indicates that the email contains multiple different representations of the same email body. The same instance variables defined in the action are passed to all email templates.

+ +

Implicit template rendering is not performed if any attachments or parts have been added to the email. This means that you'll have to manually add each part to the email and set the content type of the email to multipart/alternative.

+ +

Attachments

+ +

Sending attachment in emails is easy:

+ +
class NotifierMailer < ApplicationMailer
+  def welcome(recipient)
+    attachments['free_book.pdf'] = File.read('path/to/file.pdf')
+    mail(to: recipient, subject: "New account information")
+  end
+end
+
+ +

Which will (if it had both a welcome.text.erb and welcome.html.erb template in the view directory), send a complete multipart/mixed email with two parts, the first part being a multipart/alternative with the text and HTML email parts inside, and the second being a application/pdf with a Base64 encoded copy of the file.pdf book with the filename free_book.pdf.

+ +

If you need to send attachments with no content, you need to create an empty view for it, or add an empty body parameter like this:

+ +
class NotifierMailer < ApplicationMailer
+  def welcome(recipient)
+    attachments['free_book.pdf'] = File.read('path/to/file.pdf')
+    mail(to: recipient, subject: "New account information", body: "")
+  end
+end
+
+ +

You can also send attachments with html template, in this case you need to add body, attachments, and custom content type like this:

+ +
class NotifierMailer < ApplicationMailer
+  def welcome(recipient)
+    attachments["free_book.pdf"] = File.read("path/to/file.pdf")
+    mail(to: recipient,
+         subject: "New account information",
+         content_type: "text/html",
+         body: "<html><body>Hello there</body></html>")
+  end
+end
+
+ +

Inline Attachments

+ +

You can also specify that a file should be displayed inline with other HTML. This is useful if you want to display a corporate logo or a photo.

+ +
class NotifierMailer < ApplicationMailer
+  def welcome(recipient)
+    attachments.inline['photo.png'] = File.read('path/to/photo.png')
+    mail(to: recipient, subject: "Here is what we look like")
+  end
+end
+
+ +

And then to reference the image in the view, you create a welcome.html.erb file and make a call to image_tag passing in the attachment you want to display and then call url on the attachment to get the relative content id path for the image source:

+ +
<h1>Please Don't Cringe</h1>
+
+<%= image_tag attachments['photo.png'].url -%>
+
+ +

As we are using Action View's image_tag method, you can pass in any other options you want:

+ +
<h1>Please Don't Cringe</h1>
+
+<%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>
+
+ +

Observing and Intercepting Mails

+ +

Action Mailer provides hooks into the Mail observer and interceptor methods. These allow you to register classes that are called during the mail delivery life cycle.

+ +

An observer class must implement the :delivered_email(message) method which will be called once for every email sent after the email has been sent.

+ +

An interceptor class must implement the :delivering_email(message) method which will be called before the email is sent, allowing you to make modifications to the email before it hits the delivery agents. Your class should make any needed modifications directly to the passed in Mail::Message instance.

+ +

Default Hash

+ +

Action Mailer provides some intelligent defaults for your emails, these are usually specified in a default method inside the class definition:

+ +
class NotifierMailer < ApplicationMailer
+  default sender: 'system@example.com'
+end
+
+ +

You can pass in any header value that a Mail::Message accepts. Out of the box, ActionMailer::Base sets the following:

+
  • +

    mime_version: "1.0"

    +
  • +

    charset: "UTF-8"

    +
  • +

    content_type: "text/plain"

    +
  • +

    parts_order: [ "text/plain", "text/enriched", "text/html" ]

    +
+ +

parts_order and charset are not actually valid Mail::Message header fields, but Action Mailer translates them appropriately and sets the correct values.

+ +

As you can pass in any header, you need to either quote the header as a string, or pass it in as an underscored symbol, so the following will work:

+ +
class NotifierMailer < ApplicationMailer
+  default 'Content-Transfer-Encoding' => '7bit',
+          content_description: 'This is a description'
+end
+
+ +

Finally, Action Mailer also supports passing Proc and Lambda objects into the default hash, so you can define methods that evaluate as the message is being generated:

+ +
class NotifierMailer < ApplicationMailer
+  default 'X-Special-Header' => Proc.new { my_method }, to: -> { @inviter.email_address }
+
+  private
+    def my_method
+      'some complex call'
+    end
+end
+
+ +

Note that the proc/lambda is evaluated right at the start of the mail message generation, so if you set something in the default hash using a proc, and then set the same thing inside of your mailer method, it will get overwritten by the mailer method.

+ +

It is also possible to set these default options that will be used in all mailers through the default_options= configuration in config/application.rb:

+ +
config.action_mailer.default_options = { from: "no-reply@example.org" }
+
+ +

Callbacks

+ +

You can specify callbacks using before_action and after_action for configuring your messages. This may be useful, for example, when you want to add default inline attachments for all messages sent out by a certain mailer class:

+ +
class NotifierMailer < ApplicationMailer
+  before_action :add_inline_attachment!
+
+  def welcome
+    mail
+  end
+
+  private
+    def add_inline_attachment!
+      attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
+    end
+end
+
+ +

Callbacks in Action Mailer are implemented using AbstractController::Callbacks, so you can define and configure callbacks in the same manner that you would use callbacks in classes that inherit from ActionController::Base.

+ +

Note that unless you have a specific reason to do so, you should prefer using before_action rather than after_action in your Action Mailer classes so that headers are parsed properly.

+ +

Previewing emails

+ +

You can preview your email templates visually by adding a mailer preview file to the ActionMailer::Base.preview_path. Since most emails do something interesting with database data, you'll need to write some scenarios to load messages with fake data:

+ +
class NotifierMailerPreview < ActionMailer::Preview
+  def welcome
+    NotifierMailer.welcome(User.first)
+  end
+end
+
+ +

Methods must return a Mail::Message object which can be generated by calling the mailer method without the additional deliver_now / deliver_later. The location of the mailer previews directory can be configured using the preview_path option which has a default of test/mailers/previews:

+ +
config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
+
+ +

An overview of all previews is accessible at http://localhost:3000/rails/mailers on a running development server instance.

+ +

Previews can also be intercepted in a similar manner as deliveries can be by registering a preview interceptor that has a previewing_email method:

+ +
class CssInlineStyler
+  def self.previewing_email(message)
+    # inline CSS styles
+  end
+end
+
+config.action_mailer.preview_interceptors :css_inline_styler
+
+ +

Note that interceptors need to be registered both with register_interceptor and register_preview_interceptor if they should operate on both sending and previewing emails.

+ +

Configuration options

+ +

These options are specified on the class level, like ActionMailer::Base.raise_delivery_errors = true

+
  • +

    default_options - You can pass this in at a class level as well as within the class itself as per the above section.

    +
  • +

    logger - the logger is used for generating information on the mailing run if available. Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.

    +
  • +

    smtp_settings - Allows detailed configuration for :smtp delivery method:

    +
    • +

      :address - Allows you to use a remote mail server. Just change it from its default “localhost” setting.

      +
    • +

      :port - On the off chance that your mail server doesn't run on port 25, you can change it.

      +
    • +

      :domain - If you need to specify a HELO domain, you can do it here.

      +
    • +

      :user_name - If your mail server requires authentication, set the username in this setting.

      +
    • +

      :password - If your mail server requires authentication, set the password in this setting.

      +
    • +

      :authentication - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of :plain (will send the password Base64 encoded), :login (will send the password Base64 encoded) or :cram_md5 (combines a Challenge/Response mechanism to exchange information and a cryptographic Message Digest 5 algorithm to hash important information)

      +
    • +

      :enable_starttls_auto - Detects if STARTTLS is enabled in your SMTP server and starts to use it. Defaults to true.

      +
    • +

      :openssl_verify_mode - When using TLS, you can set how OpenSSL checks the certificate. This is really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name of an OpenSSL verify constant ('none' or 'peer') or directly the constant (OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER). :ssl/:tls Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection)

      +
    +
  • +

    sendmail_settings - Allows you to override options for the :sendmail delivery method.

    +
    • +

      :location - The location of the sendmail executable. Defaults to /usr/sbin/sendmail.

      +
    • +

      :arguments - The command line arguments. Defaults to -i with -f sender@address added automatically before the message is sent.

      +
    +
  • +

    file_settings - Allows you to override options for the :file delivery method.

    +
    • +

      :location - The directory into which emails will be written. Defaults to the application tmp/mails.

      +
    +
  • +

    raise_delivery_errors - Whether or not errors should be raised if the email fails to be delivered.

    +
  • +

    delivery_method - Defines a delivery method. Possible values are :smtp (default), :sendmail, :test, and :file. Or you may provide a custom delivery method object e.g. MyOwnDeliveryMethodClass. See the Mail gem documentation on the interface you need to implement for a custom delivery agent.

    +
  • +

    perform_deliveries - Determines whether emails are actually sent from Action Mailer when you call .deliver on an email message or on an Action Mailer method. This is on by default but can be turned off to aid in functional testing.

    +
  • +

    deliveries - Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.

    +
  • +

    deliver_later_queue_name - The name of the queue used with deliver_later. Defaults to mailers.

    +
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
PROTECTED_IVARS=AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout]
 
+ + + + +

Attributes

+ + + + + + + + +
+ [W] + mailer_name

Allows to set the name of current mailer.

+ + + + +

Class Public methods

+ +
+

+ + controller_path() + +

+ + +
+ +
+ + + + + +
+ Alias for: mailer_name +
+ + + +
+ +
+

+ + default(value = nil) + +

+ + +
+

Sets the defaults through app configuration:

+ +
config.action_mailer.default(from: "no-reply@example.org")
+
+ +

Aliased by ::default_options=

+
+ + + +
+ Also aliased as: default_options= +
+ + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 521
+def default(value = nil)
+  self.default_params = default_params.merge(value).freeze if value
+  default_params
+end
+
+
+ +
+ +
+

+ + default_options=(value = nil) + +

+ + +
+

Allows to set defaults through app configuration:

+ +
config.action_mailer.default_options = { from: "no-reply@example.org" }
+
+
+ + + + + +
+ Alias for: default +
+ + + +
+ +
+

+ + mailer_name() + +

+ + +
+

Returns the name of the current mailer. This method is also being used as a path for a view lookup. If this is an anonymous mailer, this method will return anonymous instead.

+
+ + + +
+ Also aliased as: controller_path +
+ + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 509
+def mailer_name
+  @mailer_name ||= anonymous? ? "anonymous" : name.underscore
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 593
+def initialize
+  super()
+  @_mail_was_called = false
+  @_message = Mail.new
+end
+
+
+ +
+ +
+

+ + receive(raw_mail) + +

+ + +
+

Receives a raw email, parses it into an email object, decodes it, instantiates a new mailer, and passes the email object to the mailer object's receive method.

+ +

If you want your mailer to be able to process incoming messages, you'll need to implement a receive method that accepts the raw email string as a parameter:

+ +
class MyMailer < ActionMailer::Base
+  def receive(mail)
+    # ...
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 543
+def receive(raw_mail)
+  ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
+    mail = Mail.new(raw_mail)
+    set_payload_for_mail(payload, mail)
+    new.receive(mail)
+  end
+end
+
+
+ +
+ +
+

+ + register_interceptor(interceptor) + +

+ + +
+

Register an Interceptor which will be called before mail is sent. Either a class, string or symbol can be passed in as the Interceptor. If a string or symbol is passed in it will be camelized and constantized.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 493
+def register_interceptor(interceptor)
+  Mail.register_interceptor(observer_class_for(interceptor))
+end
+
+
+ +
+ +
+

+ + register_interceptors(*interceptors) + +

+ + +
+

Register one or more Interceptors which will be called before mail is sent.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 479
+def register_interceptors(*interceptors)
+  interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
+end
+
+
+ +
+ +
+

+ + register_observer(observer) + +

+ + +
+

Register an Observer which will be notified when mail is delivered. Either a class, string or symbol can be passed in as the Observer. If a string or symbol is passed in it will be camelized and constantized.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 486
+def register_observer(observer)
+  Mail.register_observer(observer_class_for(observer))
+end
+
+
+ +
+ +
+

+ + register_observers(*observers) + +

+ + +
+

Register one or more Observers which will be notified when mail is delivered.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 474
+def register_observers(*observers)
+  observers.flatten.compact.each { |observer| register_observer(observer) }
+end
+
+
+ +
+ + +

Class Private methods

+ +
+

+ + supports_path?() + +

+ + +
+

Emails do not support relative path links.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 884
+def self.supports_path? # :doc:
+  false
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + attachments() + +

+ + +
+

Allows you to add attachments to an email, like so:

+ +
mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
+
+ +

If you do this, then Mail will take the file name and work out the mime type. It will also set the Content-Type, Content-Disposition, Content-Transfer-Encoding and encode the contents of the attachment in Base64.

+ +

You can also specify overrides if you want by passing a hash instead of a string:

+ +
mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
+                                    content: File.read('/path/to/filename.jpg')}
+
+ +

If you want to use encoding other than Base64 then you will need to pass encoding type along with the pre-encoded content as Mail doesn't know how to decode the data:

+ +
file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
+mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
+                                    encoding: 'SpecialEncoding',
+                                    content: file_content }
+
+ +

You can also search for specific attachments:

+ +
# By Filename
+mail.attachments['filename.jpg']   # => Mail::Part object or nil
+
+# or by index
+mail.attachments[0]                # => Mail::Part (first attachment)
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 702
+def attachments
+  if @_mail_was_called
+    LateAttachmentsProxy.new(@_message.attachments)
+  else
+    @_message.attachments
+  end
+end
+
+
+ +
+ +
+

+ + headers(args = nil) + +

+ + +
+

Allows you to pass random and unusual headers to the new Mail::Message object which will add them to itself.

+ +
headers['X-Special-Domain-Specific-Header'] = "SecretValue"
+
+ +

You can also pass a hash into headers of header field names and values, which will then be set on the Mail::Message object:

+ +
headers 'X-Special-Domain-Specific-Header' => "SecretValue",
+        'In-Reply-To' => incoming.message_id
+
+ +

The resulting Mail::Message will have the following in its header:

+ +
X-Special-Domain-Specific-Header: SecretValue
+
+ +

Note about replacing already defined headers:

+
  • +

    subject

    +
  • +

    sender

    +
  • +

    from

    +
  • +

    to

    +
  • +

    cc

    +
  • +

    bcc

    +
  • +

    reply-to

    +
  • +

    orig-date

    +
  • +

    message-id

    +
  • +

    references

    +
+ +

Fields can only appear once in email headers while other fields such as X-Anything can appear multiple times.

+ +

If you want to replace any header which already exists, first set it to nil in order to reset the value otherwise another field will be added for the same header.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 664
+def headers(args = nil)
+  if args
+    @_message.headers(args)
+  else
+    @_message
+  end
+end
+
+
+ +
+ +
+

+ + mail(headers = {}, &block) + +

+ + +
+

The main method that creates the message and renders the email templates. There are two ways to call this method, with a block, or without a block.

+ +

It accepts a headers hash. This hash allows you to specify the most used headers in an email message, these are:

+
  • +

    :subject - The subject of the message, if this is omitted, Action Mailer will ask the Rails I18n class for a translated :subject in the scope of [mailer_scope, action_name] or if this is missing, will translate the humanized version of the action_name

    +
  • +

    :to - Who the message is destined for, can be a string of addresses, or an array of addresses.

    +
  • +

    :from - Who the message is from

    +
  • +

    :cc - Who you would like to Carbon-Copy on this email, can be a string of addresses, or an array of addresses.

    +
  • +

    :bcc - Who you would like to Blind-Carbon-Copy on this email, can be a string of addresses, or an array of addresses.

    +
  • +

    :reply_to - Who to set the Reply-To header of the email to.

    +
  • +

    :date - The date to say the email was sent on.

    +
+ +

You can set default values for any of the above headers (except :date) by using the ::default class method:

+ +
class Notifier < ActionMailer::Base
+  default from: 'no-reply@test.lindsaar.net',
+          bcc: 'email_logger@test.lindsaar.net',
+          reply_to: 'bounces@test.lindsaar.net'
+end
+
+ +

If you need other headers not listed above, you can either pass them in as part of the headers hash or use the headers['name'] = value method.

+ +

When a :return_path is specified as header, that value will be used as the 'envelope from' address for the Mail message. Setting this is useful when you want delivery notifications sent to a different address than the one in :from. Mail will actually use the :return_path in preference to the :sender in preference to the :from field for the 'envelope from' value.

+ +

If you do not pass a block to the mail method, it will find all templates in the view paths using by default the mailer name and the method name that it is being called from, it will then create parts for each of these templates intelligently, making educated guesses on correct content type and sequence, and return a fully prepared Mail::Message ready to call :deliver on to send.

+ +

For example:

+ +
class Notifier < ActionMailer::Base
+  default from: 'no-reply@test.lindsaar.net'
+
+  def welcome
+    mail(to: 'mikel@test.lindsaar.net')
+  end
+end
+
+ +

Will look for all templates at “app/views/notifier” with name “welcome”. If no welcome template exists, it will raise an ActionView::MissingTemplate error.

+ +

However, those can be customized:

+ +
mail(template_path: 'notifications', template_name: 'another')
+
+ +

And now it will look for all templates at “app/views/notifications” with name “another”.

+ +

If you do pass a block, you can render specific templates of your choice:

+ +
mail(to: 'mikel@test.lindsaar.net') do |format|
+  format.text
+  format.html
+end
+
+ +

You can even render plain text directly without using a template:

+ +
mail(to: 'mikel@test.lindsaar.net') do |format|
+  format.text { render plain: "Hello Mikel!" }
+  format.html { render html: "<h1>Hello Mikel!</h1>".html_safe }
+end
+
+ +

Which will render a multipart/alternative email with text/plain and text/html parts.

+ +

The block syntax also allows you to customize the part headers if desired:

+ +
mail(to: 'mikel@test.lindsaar.net') do |format|
+  format.text(content_transfer_encoding: "base64")
+  format.html
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 811
+def mail(headers = {}, &block)
+  return message if @_mail_was_called && headers.blank? && !block
+
+  # At the beginning, do not consider class default for content_type
+  content_type = headers[:content_type]
+
+  headers = apply_defaults(headers)
+
+  # Apply charset at the beginning so all fields are properly quoted
+  message.charset = charset = headers[:charset]
+
+  # Set configure delivery behavior
+  wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options])
+
+  assign_headers_to_message(message, headers)
+
+  # Render the templates and blocks
+  responses = collect_responses(headers, &block)
+  @_mail_was_called = true
+
+  create_parts_from_responses(message, responses)
+
+  # Setup content type, reapply charset and handle parts order
+  message.content_type = set_content_type(message, content_type, headers[:content_type])
+  message.charset      = charset
+
+  if message.multipart?
+    message.body.set_sort_order(headers[:parts_order])
+    message.body.sort_parts!
+  end
+
+  message
+end
+
+
+ +
+ +
+

+ + mailer_name() + +

+ + +
+

Returns the name of the mailer object.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 626
+def mailer_name
+  self.class.mailer_name
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + default_i18n_subject(interpolations = {}) + +

+ + +
+

Translates the subject using Rails I18n class under [mailer_scope, action_name] scope. If it does not find a translation for the subject under the specified scope it will default to a humanized version of the action_name. If the subject has interpolations, you can pass them through the interpolations parameter.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 878
+def default_i18n_subject(interpolations = {}) # :doc:
+  mailer_scope = self.class.mailer_name.tr("/", ".")
+  I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
+end
+
+
+ +
+ +
+

+ + set_content_type(m, user_content_type, class_default) + +

+ + +
+

Used by mail to set the content type of the message.

+ +

It will use the given user_content_type, or multipart if the mail message has any attachments. If the attachments are inline, the content type will be “multipart/related”, otherwise “multipart/mixed”.

+ +

If there is no content type passed in via headers, and there are no attachments, or the message is multipart, then the default content type is used.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 856
+def set_content_type(m, user_content_type, class_default) # :doc:
+  params = m.content_type_parameters || {}
+  case
+  when user_content_type.present?
+    user_content_type
+  when m.has_attachments?
+    if m.attachments.detect(&:inline?)
+      ["multipart", "related", params]
+    else
+      ["multipart", "mixed", params]
+    end
+  when m.multipart?
+    ["multipart", "alternative", params]
+  else
+    m.content_type || class_default
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Base/LateAttachmentsProxy.html b/src/5.2/classes/ActionMailer/Base/LateAttachmentsProxy.html new file mode 100644 index 0000000000..ecf59feb8c --- /dev/null +++ b/src/5.2/classes/ActionMailer/Base/LateAttachmentsProxy.html @@ -0,0 +1,142 @@ +--- +title: ActionMailer::Base::LateAttachmentsProxy +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + []=(_name, _content) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 712
+def []=(_name, _content); _raise_error end
+
+
+ +
+ +
+

+ + inline() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/base.rb, line 711
+def inline; _raise_error end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Collector.html b/src/5.2/classes/ActionMailer/Collector.html new file mode 100644 index 0000000000..7db4442eb5 --- /dev/null +++ b/src/5.2/classes/ActionMailer/Collector.html @@ -0,0 +1,255 @@ +--- +title: ActionMailer::Collector +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + responses
+ + + + +

Class Public methods

+ +
+

+ + new(context, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/collector.rb, line 12
+def initialize(context, &block)
+  @context = context
+  @responses = []
+  @default_render = block
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + all(*args, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: any +
+ + + +
+ +
+

+ + any(*args, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: all +
+ + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/collector.rb, line 18
+def any(*args, &block)
+  options = args.extract_options!
+  raise ArgumentError, "You have to supply at least one format" if args.empty?
+  args.each { |type| send(type, options.dup, &block) }
+end
+
+
+ +
+ +
+

+ + custom(mime, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/collector.rb, line 25
+def custom(mime, options = {})
+  options.reverse_merge!(content_type: mime.to_s)
+  @context.formats = [mime.to_sym]
+  options[:body] = block_given? ? yield : @default_render.call
+  @responses << options
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/DeliveryMethods.html b/src/5.2/classes/ActionMailer/DeliveryMethods.html new file mode 100644 index 0000000000..869b4fdbcc --- /dev/null +++ b/src/5.2/classes/ActionMailer/DeliveryMethods.html @@ -0,0 +1,73 @@ +--- +title: ActionMailer::DeliveryMethods +layout: default +--- +
+ +
+
+ +
+ +

This module handles everything related to mail delivery, from registering new delivery methods to configuring the mail object to be sent.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/DeliveryMethods/ClassMethods.html b/src/5.2/classes/ActionMailer/DeliveryMethods/ClassMethods.html new file mode 100644 index 0000000000..f4ccb30ab8 --- /dev/null +++ b/src/5.2/classes/ActionMailer/DeliveryMethods/ClassMethods.html @@ -0,0 +1,114 @@ +--- +title: ActionMailer::DeliveryMethods::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Helpers for creating and wrapping delivery behavior, used by DeliveryMethods.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + add_delivery_method(symbol, klass, default_options = {}) + +

+ + +
+

Adds a new delivery method through the given class using the given symbol as alias and the default options supplied.

+ +
add_delivery_method :sendmail, Mail::Sendmail,
+  location:  '/usr/sbin/sendmail',
+  arguments: '-i'
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/delivery_methods.rb, line 50
+def add_delivery_method(symbol, klass, default_options = {})
+  class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
+  send(:"#{symbol}_settings=", default_options)
+  self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/InlinePreviewInterceptor.html b/src/5.2/classes/ActionMailer/InlinePreviewInterceptor.html new file mode 100644 index 0000000000..4b1c16a048 --- /dev/null +++ b/src/5.2/classes/ActionMailer/InlinePreviewInterceptor.html @@ -0,0 +1,101 @@ +--- +title: ActionMailer::InlinePreviewInterceptor +layout: default +--- +
+ +
+
+ +
+ +

Implements a mailer preview interceptor that converts image tag src attributes that use inline cid: style URLs to data: style URLs so that they are visible when previewing an HTML email in a web browser.

+ +

This interceptor is enabled by default. To disable it, delete it from the ActionMailer::Base.preview_interceptors array:

+ +
ActionMailer::Base.preview_interceptors.delete(ActionMailer::InlinePreviewInterceptor)
+
+ +
+ + + + + + + + + + + + + + +

Included Modules

+
    + +
  • + + Base64 + +
  • + +
+ + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
PATTERN=/src=(?:"cid:[^"]+"|'cid:[^']+')/i
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/LogSubscriber.html b/src/5.2/classes/ActionMailer/LogSubscriber.html new file mode 100644 index 0000000000..169e255469 --- /dev/null +++ b/src/5.2/classes/ActionMailer/LogSubscriber.html @@ -0,0 +1,240 @@ +--- +title: ActionMailer::LogSubscriber +layout: default +--- +
+ +
+
+ +
+ +

Implements the ActiveSupport::LogSubscriber for logging notifications when email is delivered or received.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + deliver(event) + +

+ + +
+

An email was delivered.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/log_subscriber.rb, line 10
+def deliver(event)
+  info do
+    recipients = Array(event.payload[:to]).join(", ")
+    "Sent mail to #{recipients} (#{event.duration.round(1)}ms)"
+  end
+
+  debug { event.payload[:mail] }
+end
+
+
+ +
+ +
+

+ + logger() + +

+ + +
+

Use the logger configured for ActionMailer::Base.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/log_subscriber.rb, line 35
+def logger
+  ActionMailer::Base.logger
+end
+
+
+ +
+ +
+

+ + process(event) + +

+ + +
+

An email was generated.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/log_subscriber.rb, line 26
+def process(event)
+  debug do
+    mailer = event.payload[:mailer]
+    action = event.payload[:action]
+    "#{mailer}##{action}: processed outbound mail in #{event.duration.round(1)}ms"
+  end
+end
+
+
+ +
+ +
+

+ + receive(event) + +

+ + +
+

An email was received.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/log_subscriber.rb, line 20
+def receive(event)
+  info { "Received mail (#{event.duration.round(1)}ms)" }
+  debug { event.payload[:mail] }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/MailHelper.html b/src/5.2/classes/ActionMailer/MailHelper.html new file mode 100644 index 0000000000..b83990cb3d --- /dev/null +++ b/src/5.2/classes/ActionMailer/MailHelper.html @@ -0,0 +1,301 @@ +--- +title: ActionMailer::MailHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides helper methods for ActionMailer::Base that can be used for easily formatting messages, accessing mailer or message instances, and the attachments list.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attachments() + +

+ + +
+

Access the message attachments list.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/mail_helper.rb, line 43
+def attachments
+  mailer.attachments
+end
+
+
+ +
+ +
+

+ + block_format(text) + +

+ + +
+

Take the text and format it, indented two spaces for each line, and wrapped at 72 columns:

+ +
text = <<-TEXT
+  This is
+  the      paragraph.
+
+  * item1 * item2
+TEXT
+
+block_format text
+# => "  This is the paragraph.\n\n  * item1\n  * item2\n"
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/mail_helper.rb, line 20
+def block_format(text)
+  formatted = text.split(/\n\r?\n/).collect { |paragraph|
+    format_paragraph(paragraph)
+  }.join("\n\n")
+
+  # Make list points stand on their own line
+  formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { "  #{$1} #{$2.strip}\n" }
+  formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { "  #{$1} #{$2.strip}\n" }
+
+  formatted
+end
+
+
+ +
+ +
+

+ + format_paragraph(text, len = 72, indent = 2) + +

+ + +
+

Returns text wrapped at len columns and indented indent spaces. By default column length len equals 72 characters and indent indent equal two spaces.

+ +
my_text = 'Here is a sample text with more than 40 characters'
+
+format_paragraph(my_text, 25, 4)
+# => "    Here is a sample text with\n    more than 40 characters"
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/mail_helper.rb, line 55
+def format_paragraph(text, len = 72, indent = 2)
+  sentences = [[]]
+
+  text.split.each do |word|
+    if sentences.first.present? && (sentences.last + [word]).join(" ").length > len
+      sentences << [word]
+    else
+      sentences.last << word
+    end
+  end
+
+  indentation = " " * indent
+  sentences.map! { |sentence|
+    "#{indentation}#{sentence.join(' ')}"
+  }.join "\n"
+end
+
+
+ +
+ +
+

+ + mailer() + +

+ + +
+

Access the mailer instance.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/mail_helper.rb, line 33
+def mailer
+  @_controller
+end
+
+
+ +
+ +
+

+ + message() + +

+ + +
+

Access the message instance.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/mail_helper.rb, line 38
+def message
+  @_message
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/MessageDelivery.html b/src/5.2/classes/ActionMailer/MessageDelivery.html new file mode 100644 index 0000000000..0125aaa591 --- /dev/null +++ b/src/5.2/classes/ActionMailer/MessageDelivery.html @@ -0,0 +1,366 @@ +--- +title: ActionMailer::MessageDelivery +layout: default +--- +
+ +
+
+ +
+ +

The ActionMailer::MessageDelivery class is used by ActionMailer::Base when creating a new mailer. MessageDelivery is a wrapper (Delegator subclass) around a lazy created Mail::Message. You can get direct access to the Mail::Message, deliver the email or schedule the email to be sent through Active Job.

+ +
Notifier.welcome(User.first)               # an ActionMailer::MessageDelivery object
+Notifier.welcome(User.first).deliver_now   # sends the email
+Notifier.welcome(User.first).deliver_later # enqueue email delivery as a job through Active Job
+Notifier.welcome(User.first).message       # a Mail::Message object
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + deliver_later(options = {}) + +

+ + +
+

Enqueues the email to be delivered through Active Job. When the job runs it will send the email using deliver_now.

+ +
Notifier.welcome(User.first).deliver_later
+Notifier.welcome(User.first).deliver_later(wait: 1.hour)
+Notifier.welcome(User.first).deliver_later(wait_until: 10.hours.from_now)
+
+ +

Options:

+
  • +

    :wait - Enqueue the email to be delivered with a delay.

    +
  • +

    :wait_until - Enqueue the email to be delivered at (after) a specific date / time.

    +
  • +

    :queue - Enqueue the email on the specified queue.

    +
+ +

By default, the email will be enqueued using ActionMailer::DeliveryJob. Each ActionMailer::Base class can specify the job to use by setting the class variable delivery_job.

+ +
class AccountRegistrationMailer < ApplicationMailer
+  self.delivery_job = RegistrationDeliveryJob
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/message_delivery.rb, line 93
+def deliver_later(options = {})
+  enqueue_delivery :deliver_now, options
+end
+
+
+ +
+ +
+

+ + deliver_later!(options = {}) + +

+ + +
+

Enqueues the email to be delivered through Active Job. When the job runs it will send the email using deliver_now!. That means that the message will be sent bypassing checking perform_deliveries and raise_delivery_errors, so use with caution.

+ +
Notifier.welcome(User.first).deliver_later!
+Notifier.welcome(User.first).deliver_later!(wait: 1.hour)
+Notifier.welcome(User.first).deliver_later!(wait_until: 10.hours.from_now)
+
+ +

Options:

+
  • +

    :wait - Enqueue the email to be delivered with a delay

    +
  • +

    :wait_until - Enqueue the email to be delivered at (after) a specific date / time

    +
  • +

    :queue - Enqueue the email on the specified queue

    +
+ +

By default, the email will be enqueued using ActionMailer::DeliveryJob. Each ActionMailer::Base class can specify the job to use by setting the class variable delivery_job.

+ +
class AccountRegistrationMailer < ApplicationMailer
+  self.delivery_job = RegistrationDeliveryJob
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/message_delivery.rb, line 69
+def deliver_later!(options = {})
+  enqueue_delivery :deliver_now!, options
+end
+
+
+ +
+ +
+

+ + deliver_now() + +

+ + +
+

Delivers an email:

+ +
Notifier.welcome(User.first).deliver_now
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/message_delivery.rb, line 112
+def deliver_now
+  processed_mailer.handle_exceptions do
+    message.deliver
+  end
+end
+
+
+ +
+ +
+

+ + deliver_now!() + +

+ + +
+

Delivers an email without checking perform_deliveries and raise_delivery_errors, so use with caution.

+ +
Notifier.welcome(User.first).deliver_now!
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/message_delivery.rb, line 102
+def deliver_now!
+  processed_mailer.handle_exceptions do
+    message.deliver!
+  end
+end
+
+
+ +
+ +
+

+ + message() + +

+ + +
+

Returns the resulting Mail::Message

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/message_delivery.rb, line 38
+def message
+  __getobj__
+end
+
+
+ +
+ +
+

+ + processed?() + +

+ + +
+

Was the delegate loaded, causing the mailer action to be processed?

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/message_delivery.rb, line 43
+def processed?
+  @processed_mailer || @mail_message
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/NonInferrableMailerError.html b/src/5.2/classes/ActionMailer/NonInferrableMailerError.html new file mode 100644 index 0000000000..7466c54a07 --- /dev/null +++ b/src/5.2/classes/ActionMailer/NonInferrableMailerError.html @@ -0,0 +1,109 @@ +--- +title: ActionMailer::NonInferrableMailerError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_case.rb, line 8
+def initialize(name)
+  super "Unable to determine the mailer to test from #{name}. " \
+    "You'll need to specify it using tests YourMailer in your " \
+    "test case definition"
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Parameterized.html b/src/5.2/classes/ActionMailer/Parameterized.html new file mode 100644 index 0000000000..06e30ae425 --- /dev/null +++ b/src/5.2/classes/ActionMailer/Parameterized.html @@ -0,0 +1,158 @@ +--- +title: ActionMailer::Parameterized +layout: default +--- +
+ +
+
+ +
+ +

Provides the option to parameterize mailers in order to share instance variable setup, processing, and common headers.

+ +

Consider this example that does not use parameterization:

+ +
class InvitationsMailer < ApplicationMailer
+  def account_invitation(inviter, invitee)
+    @account = inviter.account
+    @inviter = inviter
+    @invitee = invitee
+
+    subject = "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
+
+    mail \
+      subject:   subject,
+      to:        invitee.email_address,
+      from:      common_address(inviter),
+      reply_to:  inviter.email_address_with_name
+  end
+
+  def project_invitation(project, inviter, invitee)
+    @account = inviter.account
+    @project = project
+    @inviter = inviter
+    @invitee = invitee
+    @summarizer = ProjectInvitationSummarizer.new(@project.bucket)
+
+    subject = "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"
+
+    mail \
+      subject:   subject,
+      to:        invitee.email_address,
+      from:      common_address(inviter),
+      reply_to:  inviter.email_address_with_name
+  end
+
+  def bulk_project_invitation(projects, inviter, invitee)
+    @account  = inviter.account
+    @projects = projects.sort_by(&:name)
+    @inviter  = inviter
+    @invitee  = invitee
+
+    subject = "#{@inviter.name.familiar} added you to some new stuff in Basecamp (#{@account.name})"
+
+    mail \
+      subject:   subject,
+      to:        invitee.email_address,
+      from:      common_address(inviter),
+      reply_to:  inviter.email_address_with_name
+  end
+end
+
+InvitationsMailer.account_invitation(person_a, person_b).deliver_later
+
+ +

Using parameterized mailers, this can be rewritten as:

+ +
class InvitationsMailer < ApplicationMailer
+  before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
+  before_action { @account = params[:inviter].account }
+
+  default to:       -> { @invitee.email_address },
+          from:     -> { common_address(@inviter) },
+          reply_to: -> { @inviter.email_address_with_name }
+
+  def account_invitation
+    mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
+  end
+
+  def project_invitation
+    @project    = params[:project]
+    @summarizer = ProjectInvitationSummarizer.new(@project.bucket)
+
+    mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"
+  end
+
+  def bulk_project_invitation
+    @projects = params[:projects].sort_by(&:name)
+
+    mail subject: "#{@inviter.name.familiar} added you to some new stuff in Basecamp (#{@account.name})"
+  end
+end
+
+InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_later
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Parameterized/ClassMethods.html b/src/5.2/classes/ActionMailer/Parameterized/ClassMethods.html new file mode 100644 index 0000000000..0b7b70614e --- /dev/null +++ b/src/5.2/classes/ActionMailer/Parameterized/ClassMethods.html @@ -0,0 +1,106 @@ +--- +title: ActionMailer::Parameterized::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + with(params) + +

+ + +
+

Provide the parameters to the mailer in order to use them in the instance methods and callbacks.

+ +
InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_later
+
+ +

See Parameterized documentation for full example.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/parameterized.rb, line 100
+def with(params)
+  ActionMailer::Parameterized::Mailer.new(self, params)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Preview.html b/src/5.2/classes/ActionMailer/Preview.html new file mode 100644 index 0000000000..cc06a86063 --- /dev/null +++ b/src/5.2/classes/ActionMailer/Preview.html @@ -0,0 +1,398 @@ +--- +title: ActionMailer::Preview +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + params
+ + + + +

Class Public methods

+ +
+

+ + all() + +

+ + +
+

Returns all mailer preview classes.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 64
+def all
+  load_previews if descendants.empty?
+  descendants
+end
+
+
+ +
+ +
+

+ + call(email, params = {}) + +

+ + +
+

Returns the mail object for the given email name. The registered preview interceptors will be informed so that they can transform the message as they would if the mail was actually being delivered.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 72
+def call(email, params = {})
+  preview = new(params)
+  message = preview.public_send(email)
+  inform_preview_interceptors(message)
+  message
+end
+
+
+ +
+ +
+

+ + email_exists?(email) + +

+ + +
+

Returns true if the email exists.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 85
+def email_exists?(email)
+  emails.include?(email)
+end
+
+
+ +
+ +
+

+ + emails() + +

+ + +
+

Returns all of the available email previews.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 80
+def emails
+  public_instance_methods(false).map(&:to_s).sort
+end
+
+
+ +
+ +
+

+ + exists?(preview) + +

+ + +
+

Returns true if the preview exists.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 90
+def exists?(preview)
+  all.any? { |p| p.preview_name == preview }
+end
+
+
+ +
+ +
+

+ + find(preview) + +

+ + +
+

Find a mailer preview by its underscored class name.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 95
+def find(preview)
+  all.find { |p| p.preview_name == preview }
+end
+
+
+ +
+ +
+

+ + new(params = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 58
+def initialize(params = {})
+  @params = params
+end
+
+
+ +
+ +
+

+ + preview_name() + +

+ + +
+

Returns the underscored name of the mailer preview without the suffix.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 100
+def preview_name
+  name.sub(/Preview$/, "").underscore
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Previews.html b/src/5.2/classes/ActionMailer/Previews.html new file mode 100644 index 0000000000..b4aaf4b0b9 --- /dev/null +++ b/src/5.2/classes/ActionMailer/Previews.html @@ -0,0 +1,67 @@ +--- +title: ActionMailer::Previews +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Previews/ClassMethods.html b/src/5.2/classes/ActionMailer/Previews/ClassMethods.html new file mode 100644 index 0000000000..d88b7371bc --- /dev/null +++ b/src/5.2/classes/ActionMailer/Previews/ClassMethods.html @@ -0,0 +1,150 @@ +--- +title: ActionMailer::Previews::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + register_preview_interceptor(interceptor) + +

+ + +
+

Register an Interceptor which will be called before mail is previewed. Either a class or a string can be passed in as the Interceptor. If a string is passed in it will be constantized.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 37
+def register_preview_interceptor(interceptor)
+  preview_interceptor = \
+    case interceptor
+    when String, Symbol
+      interceptor.to_s.camelize.constantize
+    else
+      interceptor
+    end
+
+  unless preview_interceptors.include?(preview_interceptor)
+    preview_interceptors << preview_interceptor
+  end
+end
+
+
+ +
+ +
+

+ + register_preview_interceptors(*interceptors) + +

+ + +
+

Register one or more Interceptors which will be called before mail is previewed.

+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/preview.rb, line 30
+def register_preview_interceptors(*interceptors)
+  interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/Rescuable.html b/src/5.2/classes/ActionMailer/Rescuable.html new file mode 100644 index 0000000000..a674b2e4d4 --- /dev/null +++ b/src/5.2/classes/ActionMailer/Rescuable.html @@ -0,0 +1,74 @@ +--- +title: ActionMailer::Rescuable +layout: default +--- +
+ +
+
+ +
+ +

Provides rescue_from for mailers. Wraps mailer action processing, mail job processing, and mail delivery.

+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/TestCase.html b/src/5.2/classes/ActionMailer/TestCase.html new file mode 100644 index 0000000000..f40c13232c --- /dev/null +++ b/src/5.2/classes/ActionMailer/TestCase.html @@ -0,0 +1,89 @@ +--- +title: ActionMailer::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/TestCase/Behavior.html b/src/5.2/classes/ActionMailer/TestCase/Behavior.html new file mode 100644 index 0000000000..d2279598ce --- /dev/null +++ b/src/5.2/classes/ActionMailer/TestCase/Behavior.html @@ -0,0 +1,101 @@ +--- +title: ActionMailer::TestCase::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/TestCase/Behavior/ClassMethods.html b/src/5.2/classes/ActionMailer/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..c3f7032eb1 --- /dev/null +++ b/src/5.2/classes/ActionMailer/TestCase/Behavior/ClassMethods.html @@ -0,0 +1,194 @@ +--- +title: ActionMailer::TestCase::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + determine_default_mailer(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_case.rb, line 69
+def determine_default_mailer(name)
+  mailer = determine_constant_from_test_name(name) do |constant|
+    Class === constant && constant < ActionMailer::Base
+  end
+  raise NonInferrableMailerError.new(name) if mailer.nil?
+  mailer
+end
+
+
+ +
+ +
+

+ + mailer_class() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_case.rb, line 61
+def mailer_class
+  if mailer = _mailer_class
+    mailer
+  else
+    tests determine_default_mailer(name)
+  end
+end
+
+
+ +
+ +
+

+ + tests(mailer) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_case.rb, line 50
+def tests(mailer)
+  case mailer
+  when String, Symbol
+    self._mailer_class = mailer.to_s.camelize.constantize
+  when Module
+    self._mailer_class = mailer
+  else
+    raise NonInferrableMailerError.new(mailer)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/TestCase/ClearTestDeliveries.html b/src/5.2/classes/ActionMailer/TestCase/ClearTestDeliveries.html new file mode 100644 index 0000000000..125d041c7a --- /dev/null +++ b/src/5.2/classes/ActionMailer/TestCase/ClearTestDeliveries.html @@ -0,0 +1,54 @@ +--- +title: ActionMailer::TestCase::ClearTestDeliveries +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/TestHelper.html b/src/5.2/classes/ActionMailer/TestHelper.html new file mode 100644 index 0000000000..9cf30a80d2 --- /dev/null +++ b/src/5.2/classes/ActionMailer/TestHelper.html @@ -0,0 +1,392 @@ +--- +title: ActionMailer::TestHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides helper methods for testing Action Mailer, including assert_emails and assert_no_emails.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_emails(number) + +

+ + +
+

Asserts that the number of emails sent matches the given number.

+ +
def test_emails
+  assert_emails 0
+  ContactMailer.welcome.deliver_now
+  assert_emails 1
+  ContactMailer.welcome.deliver_now
+  assert_emails 2
+end
+
+ +

If a block is passed, that block should cause the specified number of emails to be sent.

+ +
def test_emails_again
+  assert_emails 1 do
+    ContactMailer.welcome.deliver_now
+  end
+
+  assert_emails 2 do
+    ContactMailer.welcome.deliver_now
+    ContactMailer.welcome.deliver_now
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_helper.rb, line 34
+def assert_emails(number)
+  if block_given?
+    original_count = ActionMailer::Base.deliveries.size
+    yield
+    new_count = ActionMailer::Base.deliveries.size
+    assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent"
+  else
+    assert_equal number, ActionMailer::Base.deliveries.size
+  end
+end
+
+
+ +
+ +
+

+ + assert_enqueued_email_with(mailer, method, args: nil, queue: "mailers", &block) + +

+ + +
+

Asserts that block should cause the specified email to be enqueued.

+ +
def test_email_in_block
+  assert_enqueued_email_with ContactMailer, :welcome do
+    ContactMailer.welcome.deliver_later
+  end
+end
+
+ +

If args is provided as a Hash, a parameterized email is matched.

+ +
def test_parameterized_email
+  assert_enqueued_email_with ContactMailer, :welcome,
+    args: {email: 'user@example.com} do
+    ContactMailer.with(email: 'user@example.com').welcome.deliver_later
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_helper.rb, line 113
+def assert_enqueued_email_with(mailer, method, args: nil, queue: "mailers", &block)
+  if args.is_a? Hash
+    job = ActionMailer::Parameterized::DeliveryJob
+    args = [mailer.to_s, method.to_s, "deliver_now", args]
+  else
+    job = ActionMailer::DeliveryJob
+    args = [mailer.to_s, method.to_s, "deliver_now", *args]
+  end
+
+  assert_enqueued_with(job: job, args: args, queue: queue, &block)
+end
+
+
+ +
+ +
+

+ + assert_enqueued_emails(number, &block) + +

+ + +
+

Asserts that the number of emails enqueued for later delivery matches the given number.

+ +
def test_emails
+  assert_enqueued_emails 0
+  ContactMailer.welcome.deliver_later
+  assert_enqueued_emails 1
+  ContactMailer.welcome.deliver_later
+  assert_enqueued_emails 2
+end
+
+ +

If a block is passed, that block should cause the specified number of emails to be enqueued.

+ +
def test_emails_again
+  assert_enqueued_emails 1 do
+    ContactMailer.welcome.deliver_later
+  end
+
+  assert_enqueued_emails 2 do
+    ContactMailer.welcome.deliver_later
+    ContactMailer.welcome.deliver_later
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_helper.rb, line 92
+def assert_enqueued_emails(number, &block)
+  assert_enqueued_jobs number, only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block
+end
+
+
+ +
+ +
+

+ + assert_no_emails(&block) + +

+ + +
+

Asserts that no emails have been sent.

+ +
def test_emails
+  assert_no_emails
+  ContactMailer.welcome.deliver_now
+  assert_emails 1
+end
+
+ +

If a block is passed, that block should not cause any emails to be sent.

+ +
def test_emails_again
+  assert_no_emails do
+    # No emails should be sent from this block
+  end
+end
+
+ +

Note: This assertion is simply a shortcut for:

+ +
assert_emails 0, &block
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_helper.rb, line 64
+def assert_no_emails(&block)
+  assert_emails 0, &block
+end
+
+
+ +
+ +
+

+ + assert_no_enqueued_emails(&block) + +

+ + +
+

Asserts that no emails are enqueued for later delivery.

+ +
def test_no_emails
+  assert_no_enqueued_emails
+  ContactMailer.welcome.deliver_later
+  assert_enqueued_emails 1
+end
+
+ +

If a block is provided, it should not cause any emails to be enqueued.

+ +
def test_no_emails
+  assert_no_enqueued_emails do
+    # No emails should be enqueued from this block
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionmailer/lib/action_mailer/test_helper.rb, line 140
+def assert_no_enqueued_emails(&block)
+  assert_no_enqueued_jobs only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionMailer/VERSION.html b/src/5.2/classes/ActionMailer/VERSION.html new file mode 100644 index 0000000000..8e3cf68627 --- /dev/null +++ b/src/5.2/classes/ActionMailer/VERSION.html @@ -0,0 +1,120 @@ +--- +title: ActionMailer::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView.html b/src/5.2/classes/ActionView.html new file mode 100644 index 0000000000..eb9436fd49 --- /dev/null +++ b/src/5.2/classes/ActionView.html @@ -0,0 +1,412 @@ +--- +title: ActionView +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
TemplateError=Template::Error
 
+ + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Action View as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded ActionView as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/version.rb, line 7
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Base.html b/src/5.2/classes/ActionView/Base.html new file mode 100644 index 0000000000..f9ad893331 --- /dev/null +++ b/src/5.2/classes/ActionView/Base.html @@ -0,0 +1,290 @@ +--- +title: ActionView::Base +layout: default +--- +
+ +
+
+ +
+ +

Action View Base

+ +

Action View templates can be written in several ways. If the template file has a .erb extension, then it uses the erubi template system which can embed Ruby into an HTML document. If the template file has a .builder extension, then Jim Weirich's Builder::XmlMarkup library is used.

+ +

ERB

+ +

You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the following loop for names:

+ +
<b>Names of all the people</b>
+<% @people.each do |person| %>
+  Name: <%= person.name %><br/>
+<% end %>
+
+ +

The loop is setup in regular embedding tags <% %>, and the name is written using the output embedding tag <%= %>. Note that this is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong:

+ +
<%# WRONG %>
+Hi, Mr. <% puts "Frodo" %>
+
+ +

If you absolutely must write from within a function use concat.

+ +

When on a line that only contains whitespaces except for the tag, <% %> suppresses leading and trailing whitespace, including the trailing newline. <% %> and <%- -%> are the same. Note however that <%= %> and <%= -%> are different: only the latter removes trailing whitespaces.

+ +

Using sub templates

+ +

Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts):

+ +
<%= render "shared/header" %>
+Something really specific and terrific
+<%= render "shared/footer" %>
+
+ +

As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the result of the rendering. The output embedding writes it to the current template.

+ +

But you don't have to restrict yourself to static includes. Templates can share variables amongst themselves by using instance variables defined using the regular embedding tags. Like this:

+ +
<% @page_title = "A Wonderful Hello" %>
+<%= render "shared/header" %>
+
+ +

Now the header can pick up on the @page_title variable and use it for outputting a title tag:

+ +
<title><%= @page_title %></title>
+
+ +

Passing local variables to sub templates

+ +

You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:

+ +
<%= render "shared/header", { headline: "Welcome", person: person } %>
+
+ +

These can now be accessed in shared/header with:

+ +
Headline: <%= headline %>
+First name: <%= person.first_name %>
+
+ +

The local variables passed to sub templates can be accessed as a hash using the local_assigns hash. This lets you access the variables as:

+ +
Headline: <%= local_assigns[:headline] %>
+
+ +

This is useful in cases where you aren't sure if the local variable has been assigned. Alternatively, you could also use defined? headline to first check if the variable has been assigned before using it.

+ +

Template caching

+ +

By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file's modification time and recompile it in development mode.

+ +

Builder

+ +

Builder templates are a more programmatic alternative to ERB. They are especially useful for generating XML content. An XmlMarkup object named xml is automatically made available to templates with a .builder extension.

+ +

Here are some basic examples:

+ +
xml.em("emphasized")                                 # => <em>emphasized</em>
+xml.em { xml.b("emph & bold") }                      # => <em><b>emph &amp; bold</b></em>
+xml.a("A Link", "href" => "http://onestepback.org")  # => <a href="http://onestepback.org">A Link</a>
+xml.target("name" => "compile", "option" => "fast")  # => <target option="fast" name="compile"\>
+                                                     # NOTE: order of attributes is not specified.
+
+ +

Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:

+ +
xml.div do
+  xml.h1(@person.name)
+  xml.p(@person.bio)
+end
+
+ +

would produce something like:

+ +
<div>
+  <h1>David Heinemeier Hansson</h1>
+  <p>A product of Danish Design during the Winter of '79...</p>
+</div>
+
+ +

Here is a full-length RSS example actually used on Basecamp:

+ +
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"
+
+    @recent_items.each do |item|
+      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(item))
+        xml.link(@person.firm.account.url + @recent_items.url(item))
+
+        xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
+      end
+    end
+  end
+end
+
+ +

For more information on Builder please consult the source code.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + view_renderer
+ + + + +

Class Public methods

+ +
+

+ + cache_template_loading() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/base.rb, line 171
+def cache_template_loading
+  ActionView::Resolver.caching?
+end
+
+
+ +
+ +
+

+ + cache_template_loading=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/base.rb, line 175
+def cache_template_loading=(value)
+  ActionView::Resolver.caching = value
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Context.html b/src/5.2/classes/ActionView/Context.html new file mode 100644 index 0000000000..50f96fab4e --- /dev/null +++ b/src/5.2/classes/ActionView/Context.html @@ -0,0 +1,175 @@ +--- +title: ActionView::Context +layout: default +--- +
+ +
+
+ +
+ +

Action View Context

+ +

Action View contexts are supplied to Action Controller to render a template. The default Action View context is ActionView::Base.

+ +

In order to work with ActionController, a Context must just include this module. The initialization of the variables used by the context (@output_buffer, @view_flow, and @virtual_path) is responsibility of the object that includes this module (although you can call _prepare_context defined below).

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + output_buffer
+ [RW] + view_flow
+ + + + + +

Instance Public methods

+ +
+

+ + _layout_for(name = nil) + +

+ + +
+

Encapsulates the interaction with the view flow so it returns the correct buffer on yield. This is usually overwritten by helpers to add more behavior.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/context.rb, line 31
+def _layout_for(name = nil)
+  name ||= :layout
+  view_flow.get(name).html_safe
+end
+
+
+ +
+ +
+

+ + _prepare_context() + +

+ + +
+

Prepares the context by setting the appropriate instance variables.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/context.rb, line 22
+def _prepare_context
+  @view_flow     = OutputFlow.new
+  @output_buffer = nil
+  @virtual_path  = nil
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Digestor.html b/src/5.2/classes/ActionView/Digestor.html new file mode 100644 index 0000000000..b3a5ece592 --- /dev/null +++ b/src/5.2/classes/ActionView/Digestor.html @@ -0,0 +1,258 @@ +--- +title: ActionView::Digestor +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + digest(name:, finder:, dependencies: []) + +

+ + +
+

Supported options:

+
  • +

    name - Template name

    +
  • +

    finder - An instance of ActionView::LookupContext

    +
  • +

    dependencies - An array of dependent views

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 23
+def digest(name:, finder:, dependencies: [])
+  dependencies ||= []
+  cache_key = [ name, finder.rendered_format, dependencies ].flatten.compact.join(".")
+
+  # this is a correctly done double-checked locking idiom
+  # (Concurrent::Map's lookups have volatile semantics)
+  finder.digest_cache[cache_key] || @@digest_mutex.synchronize do
+    finder.digest_cache.fetch(cache_key) do # re-check under lock
+      partial = name.include?("/_")
+      root = tree(name, finder, partial)
+      dependencies.each do |injected_dep|
+        root.children << Injected.new(injected_dep, nil, nil)
+      end
+      finder.digest_cache[cache_key] = root.digest(finder)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 41
+def logger
+  ActionView::Base.logger || NullLogger
+end
+
+
+ +
+ +
+

+ + tree(name, finder, partial = false, seen = {}) + +

+ + +
+

Create a dependency tree for template named name.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 46
+def tree(name, finder, partial = false, seen = {})
+  logical_name = name.gsub(%r|/_|, "/")
+
+  if template = find_template(finder, logical_name, [], partial, [])
+    finder.rendered_format ||= template.formats.first
+
+    if node = seen[template.identifier] # handle cycles in the tree
+      node
+    else
+      node = seen[template.identifier] = Node.create(name, logical_name, template, partial)
+
+      deps = DependencyTracker.find_dependencies(name, template, finder.view_paths)
+      deps.uniq { |n| n.gsub(%r|/_|, "/") }.each do |dep_file|
+        node.children << tree(dep_file, finder, true, seen)
+      end
+      node
+    end
+  else
+    unless name.include?("#") # Dynamic template partial names can never be tracked
+      logger.error "  Couldn't find template for digesting: #{name}"
+    end
+
+    seen[name] ||= Missing.new(name, logical_name, nil)
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Digestor/Injected.html b/src/5.2/classes/ActionView/Digestor/Injected.html new file mode 100644 index 0000000000..da2554ff77 --- /dev/null +++ b/src/5.2/classes/ActionView/Digestor/Injected.html @@ -0,0 +1,105 @@ +--- +title: ActionView::Digestor::Injected +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + digest(finder, _ = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 126
+def digest(finder, _ = []) name end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Digestor/Missing.html b/src/5.2/classes/ActionView/Digestor/Missing.html new file mode 100644 index 0000000000..9c8e172756 --- /dev/null +++ b/src/5.2/classes/ActionView/Digestor/Missing.html @@ -0,0 +1,105 @@ +--- +title: ActionView::Digestor::Missing +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + digest(finder, _ = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 122
+def digest(finder, _ = []) "" end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Digestor/Node.html b/src/5.2/classes/ActionView/Digestor/Node.html new file mode 100644 index 0000000000..931a04d63b --- /dev/null +++ b/src/5.2/classes/ActionView/Digestor/Node.html @@ -0,0 +1,317 @@ +--- +title: ActionView::Digestor::Node +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + children
+ [R] + logical_name
+ [R] + name
+ [R] + template
+ + + + +

Class Public methods

+ +
+

+ + create(name, logical_name, template, partial) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 85
+def self.create(name, logical_name, template, partial)
+  klass = partial ? Partial : Node
+  klass.new(name, logical_name, template, [])
+end
+
+
+ +
+ +
+

+ + new(name, logical_name, template, children = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 90
+def initialize(name, logical_name, template, children = [])
+  @name         = name
+  @logical_name = logical_name
+  @template     = template
+  @children     = children
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + dependency_digest(finder, stack) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 101
+def dependency_digest(finder, stack)
+  children.map do |node|
+    if stack.include?(node)
+      false
+    else
+      finder.digest_cache[node.name] ||= begin
+                                           stack.push node
+                                           node.digest(finder, stack).tap { stack.pop }
+                                         end
+    end
+  end.join("-")
+end
+
+
+ +
+ +
+

+ + digest(finder, stack = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 97
+def digest(finder, stack = [])
+  ActiveSupport::Digest.hexdigest("#{template.source}-#{dependency_digest(finder, stack)}")
+end
+
+
+ +
+ +
+

+ + to_dep_map() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 114
+def to_dep_map
+  children.any? ? { name => children.map(&:to_dep_map) } : name
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Digestor/NullLogger.html b/src/5.2/classes/ActionView/Digestor/NullLogger.html new file mode 100644 index 0000000000..42875a860d --- /dev/null +++ b/src/5.2/classes/ActionView/Digestor/NullLogger.html @@ -0,0 +1,142 @@ +--- +title: ActionView::Digestor::NullLogger +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + debug(_) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 130
+def self.debug(_); end
+
+
+ +
+ +
+

+ + error(_) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 131
+def self.error(_); end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Digestor/Partial.html b/src/5.2/classes/ActionView/Digestor/Partial.html new file mode 100644 index 0000000000..2f74dd40aa --- /dev/null +++ b/src/5.2/classes/ActionView/Digestor/Partial.html @@ -0,0 +1,60 @@ +--- +title: ActionView::Digestor::Partial +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Digestor/PerExecutionDigestCacheExpiry.html b/src/5.2/classes/ActionView/Digestor/PerExecutionDigestCacheExpiry.html new file mode 100644 index 0000000000..3992859679 --- /dev/null +++ b/src/5.2/classes/ActionView/Digestor/PerExecutionDigestCacheExpiry.html @@ -0,0 +1,101 @@ +--- +title: ActionView::Digestor::PerExecutionDigestCacheExpiry +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + before(target) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/digestor.rb, line 12
+def self.before(target)
+  ActionView::LookupContext::DetailsKey.clear
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/FileSystemResolver.html b/src/5.2/classes/ActionView/FileSystemResolver.html new file mode 100644 index 0000000000..07f58be961 --- /dev/null +++ b/src/5.2/classes/ActionView/FileSystemResolver.html @@ -0,0 +1,299 @@ +--- +title: ActionView::FileSystemResolver +layout: default +--- +
+ +
+
+ +
+ +

A resolver that loads files from the filesystem. It allows setting your own resolving pattern. Such pattern can be a glob string supported by some variables.

+ +

Examples

+ +

Default pattern, loads views the same way as previous versions of rails, eg. when you're looking for users/new it will produce query glob: users/new{.{en},}{.{html,js},}{.{erb,haml},}

+ +
FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
+
+ +

This one allows you to keep files with different formats in separate subdirectories, eg. users/new.html will be loaded from users/html/new.erb or users/new.html.erb, users/new.js from users/js/new.erb or users/new.js.erb, etc.

+ +
FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
+
+ +

If you don't specify a pattern then the default will be used.

+ +

In order to use any of the customized resolvers above in a Rails application, you just need to configure ActionController::Base.view_paths in an initializer, for example:

+ +
ActionController::Base.view_paths = FileSystemResolver.new(
+  Rails.root.join("app/views"),
+  ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}",
+)
+
+ +

Pattern format and variables

+ +

Pattern has to be a valid glob string, and it allows you to use the following variables:

+
  • +

    :prefix - usually the controller path

    +
  • +

    :action - name of the action

    +
  • +

    :locale - possible locale versions

    +
  • +

    :formats - possible request formats (for example html, json, xml…)

    +
  • +

    :variants - possible request variants (for example phone, tablet…)

    +
  • +

    :handlers - possible handlers (for example erb, haml, builder…)

    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(path, pattern = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 346
+def initialize(path, pattern = nil)
+  raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
+  super(pattern)
+  @path = File.expand_path(path)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(resolver) + +

+ + +
+ +
+ + + + + +
+ Alias for: eql? +
+ + + +
+ +
+

+ + eql?(resolver) + +

+ + +
+ +
+ + + +
+ Also aliased as: == +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 357
+def eql?(resolver)
+  self.class.equal?(resolver.class) && to_path == resolver.to_path
+end
+
+
+ +
+ +
+

+ + to_path() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + +
+ Also aliased as: to_path +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 352
+def to_s
+  @path.to_s
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/FixtureResolver.html b/src/5.2/classes/ActionView/FixtureResolver.html new file mode 100644 index 0000000000..12658578d8 --- /dev/null +++ b/src/5.2/classes/ActionView/FixtureResolver.html @@ -0,0 +1,170 @@ +--- +title: ActionView::FixtureResolver +layout: default +--- +
+ +
+
+ +
+ +

Use FixtureResolver in your tests to simulate the presence of files on the file system. This is used internally by Rails' own test suite, and is useful for testing extensions that have no way of knowing what the file system will look like at runtime.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + hash
+ + + + +

Class Public methods

+ +
+

+ + new(hash = {}, pattern = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/testing/resolvers.rb, line 13
+def initialize(hash = {}, pattern = nil)
+  super(pattern)
+  @hash = hash
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/testing/resolvers.rb, line 18
+def to_s
+  @hash.keys.join(", ")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers.html b/src/5.2/classes/ActionView/Helpers.html new file mode 100644 index 0000000000..22885ce298 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers.html @@ -0,0 +1,242 @@ +--- +title: ActionView::Helpers +layout: default +--- +
+ + +
diff --git a/src/5.2/classes/ActionView/Helpers/ActiveModelHelper.html b/src/5.2/classes/ActionView/Helpers/ActiveModelHelper.html new file mode 100644 index 0000000000..e9e690215a --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/ActiveModelHelper.html @@ -0,0 +1,54 @@ +--- +title: ActionView::Helpers::ActiveModelHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/ActiveModelInstanceTag.html b/src/5.2/classes/ActionView/Helpers/ActiveModelInstanceTag.html new file mode 100644 index 0000000000..b6094002d0 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/ActiveModelInstanceTag.html @@ -0,0 +1,264 @@ +--- +title: ActionView::Helpers::ActiveModelInstanceTag +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + content_tag(type, options, *) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/active_model_helper.rb, line 20
+def content_tag(type, options, *)
+  select_markup_helper?(type) ? super : error_wrapping(super)
+end
+
+
+ +
+ +
+

+ + error_message() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/active_model_helper.rb, line 36
+def error_message
+  object.errors[@method_name]
+end
+
+
+ +
+ +
+

+ + error_wrapping(html_tag) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/active_model_helper.rb, line 28
+def error_wrapping(html_tag)
+  if object_has_errors?
+    Base.field_error_proc.call(html_tag, self)
+  else
+    html_tag
+  end
+end
+
+
+ +
+ +
+

+ + object() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/active_model_helper.rb, line 13
+def object
+  @active_model_object ||= begin
+    object = super
+    object.respond_to?(:to_model) ? object.to_model : object
+  end
+end
+
+
+ +
+ +
+

+ + tag(type, options, *) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/active_model_helper.rb, line 24
+def tag(type, options, *)
+  tag_generate_errors?(options) ? error_wrapping(super) : super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/AssetTagHelper.html b/src/5.2/classes/ActionView/Helpers/AssetTagHelper.html new file mode 100644 index 0000000000..3d3a260ada --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/AssetTagHelper.html @@ -0,0 +1,801 @@ +--- +title: ActionView::Helpers::AssetTagHelper +layout: default +--- +
+ +
+
+ +
+ +

This module provides methods for generating HTML that links views to assets such as images, JavaScripts, stylesheets, and feeds. These methods do not verify the assets exist before linking to them:

+ +
image_tag("rails.png")
+# => <img src="/assets/rails.png" />
+stylesheet_link_tag("application")
+# => <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" />
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + audio_tag(*sources) + +

+ + +
+

Returns an HTML audio tag for the sources. If sources is a string, a single audio tag will be returned. If sources is an array, an audio tag with nested source tags for each source will be returned. The sources can be full paths or files that exist in your public audios directory.

+ +

When the last parameter is a hash you can add HTML attributes using that parameter.

+ +
audio_tag("sound")
+# => <audio src="/audios/sound"></audio>
+audio_tag("sound.wav")
+# => <audio src="/audios/sound.wav"></audio>
+audio_tag("sound.wav", autoplay: true, controls: true)
+# => <audio autoplay="autoplay" controls="controls" src="/audios/sound.wav"></audio>
+audio_tag("sound.wav", "sound.mid")
+# => <audio><source src="/audios/sound.wav" /><source src="/audios/sound.mid" /></audio>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 451
+def audio_tag(*sources)
+  multiple_sources_tag_builder("audio", sources)
+end
+
+
+ +
+ +
+ + + +
+

Returns a link tag that browsers and feed readers can use to auto-detect an RSS, Atom, or JSON feed. The type can be :rss (default), :atom, or :json. Control the link options in url_for format using the url_options. You can modify the LINK tag itself in tag_options.

+ + +
  • +

    :rel - Specify the relation of this link, defaults to “alternate”

    +
  • +

    :type - Override the auto-generated mime type

    +
  • +

    :title - Specify the title of the link, defaults to the type

    +
+ + + +
auto_discovery_link_tag
+# => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" />
+auto_discovery_link_tag(:atom)
+# => <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.currenthost.com/controller/action" />
+auto_discovery_link_tag(:json)
+# => <link rel="alternate" type="application/json" title="JSON" href="http://www.currenthost.com/controller/action" />
+auto_discovery_link_tag(:rss, {action: "feed"})
+# => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/feed" />
+auto_discovery_link_tag(:rss, {action: "feed"}, {title: "My RSS"})
+# => <link rel="alternate" type="application/rss+xml" title="My RSS" href="http://www.currenthost.com/controller/feed" />
+auto_discovery_link_tag(:rss, {controller: "news", action: "feed"})
+# => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/news/feed" />
+auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "Example RSS"})
+# => <link rel="alternate" type="application/rss+xml" title="Example RSS" href="http://www.example.com/feed.rss" />
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+ + + +
+

Returns a link tag for a favicon managed by the asset pipeline.

+ +

If a page has no link like the one generated by this helper, browsers ask for /favicon.ico automatically, and cache the file if the request succeeds. If the favicon changes it is hard to get it updated.

+ +

To have better control applications may let the asset pipeline manage their favicon storing the file under app/assets/images, and using this helper to generate its corresponding link tag.

+ +

The helper gets the name of the favicon file as first argument, which defaults to “favicon.ico”, and also supports :rel and :type options to override their defaults, “shortcut icon” and “image/x-icon” respectively:

+ +
favicon_link_tag
+# => <link href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon" />
+
+favicon_link_tag 'myicon.ico'
+# => <link href="/assets/myicon.ico" rel="shortcut icon" type="image/x-icon" />
+
+ +

Mobile Safari looks for a different link tag, pointing to an image that will be used if you add the page to the home screen of an iOS device. The following call would generate such a tag:

+ +
favicon_link_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
+# => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" />
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+

+ + image_alt(src) + +

+ + +
+

Returns a string suitable for an HTML image tag alt attribute. The src argument is meant to be an image file path. The method removes the basename of the file path and the digest, if any. It also removes hyphens and underscores from file names and replaces them with spaces, returning a space-separated, titleized string.

+ +

Examples

+ +
image_alt('rails.png')
+# => Rails
+
+image_alt('hyphenated-file-name.png')
+# => Hyphenated file name
+
+image_alt('underscored_file_name.png')
+# => Underscored file name
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 375
+def image_alt(src)
+  ActiveSupport::Deprecation.warn("image_alt is deprecated and will be removed from Rails 6.0. You must explicitly set alt text on images.")
+
+  File.basename(src, ".*".freeze).sub(/-[[:xdigit:]]{32,64}\z/, "".freeze).tr("-_".freeze, " ".freeze).capitalize
+end
+
+
+ +
+ +
+

+ + image_tag(source, options = {}) + +

+ + +
+

Returns an HTML image tag for the source. The source can be a full path, a file, or an Active Storage attachment.

+ +

Options

+ +

You can add HTML attributes using the options. The options supports additional keys for convenience and conformance:

+
  • +

    :size - Supplied as “{Width}x{Height}” or “{Number}”, so “30x45” becomes width=“30” and height=“45”, and “50” becomes width=“50” and height=“50”. :size will be ignored if the value is not in the correct format.

    +
  • +

    :srcset - If supplied as a hash or array of [source, descriptor] pairs, each image path will be expanded before the list is formatted as a string.

    +
+ +

Examples

+ +

Assets (images that are part of your app):

+ +
image_tag("icon")
+# => <img src="/assets/icon" />
+image_tag("icon.png")
+# => <img src="/assets/icon.png" />
+image_tag("icon.png", size: "16x10", alt: "Edit Entry")
+# => <img src="/assets/icon.png" width="16" height="10" alt="Edit Entry" />
+image_tag("/icons/icon.gif", size: "16")
+# => <img src="/icons/icon.gif" width="16" height="16" />
+image_tag("/icons/icon.gif", height: '32', width: '32')
+# => <img height="32" src="/icons/icon.gif" width="32" />
+image_tag("/icons/icon.gif", class: "menu_icon")
+# => <img class="menu_icon" src="/icons/icon.gif" />
+image_tag("/icons/icon.gif", data: { title: 'Rails Application' })
+# => <img data-title="Rails Application" src="/icons/icon.gif" />
+image_tag("icon.png", srcset: { "icon_2x.png" => "2x", "icon_4x.png" => "4x" })
+# => <img src="/assets/icon.png" srcset="/assets/icon_2x.png 2x, /assets/icon_4x.png 4x">
+image_tag("pic.jpg", srcset: [["pic_1024.jpg", "1024w"], ["pic_1980.jpg", "1980w"]], sizes: "100vw")
+# => <img src="/assets/pic.jpg" srcset="/assets/pic_1024.jpg 1024w, /assets/pic_1980.jpg 1980w" sizes="100vw">
+
+ +

Active Storage (images that are uploaded by the users of your app):

+ +
image_tag(user.avatar)
+# => <img src="/rails/active_storage/blobs/.../tiger.jpg" />
+image_tag(user.avatar.variant(resize: "100x100"))
+# => <img src="/rails/active_storage/variants/.../tiger.jpg" />
+image_tag(user.avatar.variant(resize: "100x100"), size: '100')
+# => <img width="100" height="100" src="/rails/active_storage/variants/.../tiger.jpg" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 340
+def image_tag(source, options = {})
+  options = options.symbolize_keys
+  check_for_image_tag_errors(options)
+  skip_pipeline = options.delete(:skip_pipeline)
+
+  options[:src] = resolve_image_source(source, skip_pipeline)
+
+  if options[:srcset] && !options[:srcset].is_a?(String)
+    options[:srcset] = options[:srcset].map do |src_path, size|
+      src_path = path_to_image(src_path, skip_pipeline: skip_pipeline)
+      "#{src_path} #{size}"
+    end.join(", ")
+  end
+
+  options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
+  tag("img", options)
+end
+
+
+ +
+ +
+

+ + javascript_include_tag(*sources) + +

+ + +
+

Returns an HTML script tag for each of the sources provided.

+ +

Sources may be paths to JavaScript files. Relative paths are assumed to be relative to assets/javascripts, full paths are assumed to be relative to the document root. Relative paths are idiomatic, use absolute paths only when needed.

+ +

When passing paths, the “.js” extension is optional. If you do not want “.js” appended to the path extname: false can be set on the options.

+ +

You can modify the HTML attributes of the script tag by passing a hash as the last argument.

+ +

When the Asset Pipeline is enabled, you can pass the name of your manifest as source, and include other JavaScript or CoffeeScript files inside the manifest.

+ +

If the server supports Early Hints header links for these assets will be automatically pushed.

+ +

Options

+ +

When the last parameter is a hash you can add HTML attributes using that parameter. The following options are supported:

+
  • +

    :extname - Append an extension to the generated URL unless the extension already exists. This only applies for relative URLs.

    +
  • +

    :protocol - Sets the protocol of the generated URL. This option only applies when a relative URL and host options are provided.

    +
  • +

    :host - When a relative URL is provided the host is added to the that path.

    +
  • +

    :skip_pipeline - This option is used to bypass the asset pipeline when it is set to true.

    +
  • +

    <tt>:nonce<tt> - When set to true, adds an automatic nonce value if you have Content Security Policy enabled.

    +
+ +

Examples

+ +
javascript_include_tag "xmlhr"
+# => <script src="/assets/xmlhr.debug-1284139606.js"></script>
+
+javascript_include_tag "xmlhr", host: "localhost", protocol: "https"
+# => <script src="https://localhost/assets/xmlhr.debug-1284139606.js"></script>
+
+javascript_include_tag "template.jst", extname: false
+# => <script src="/assets/template.debug-1284139606.jst"></script>
+
+javascript_include_tag "xmlhr.js"
+# => <script src="/assets/xmlhr.debug-1284139606.js"></script>
+
+javascript_include_tag "common.javascript", "/elsewhere/cools"
+# => <script src="/assets/common.javascript.debug-1284139606.js"></script>
+#    <script src="/elsewhere/cools.debug-1284139606.js"></script>
+
+javascript_include_tag "http://www.example.com/xmlhr"
+# => <script src="http://www.example.com/xmlhr"></script>
+
+javascript_include_tag "http://www.example.com/xmlhr.js"
+# => <script src="http://www.example.com/xmlhr.js"></script>
+
+javascript_include_tag "http://www.example.com/xmlhr.js", nonce: true
+# => <script src="http://www.example.com/xmlhr.js" nonce="..."></script>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 87
+def javascript_include_tag(*sources)
+  options = sources.extract_options!.stringify_keys
+  path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
+  early_hints_links = []
+
+  sources_tags = sources.uniq.map { |source|
+    href = path_to_javascript(source, path_options)
+    early_hints_links << "<#{href}>; rel=preload; as=script"
+    tag_options = {
+      "src" => href
+    }.merge!(options)
+    if tag_options["nonce"] == true
+      tag_options["nonce"] = content_security_policy_nonce
+    end
+    content_tag("script".freeze, "", tag_options)
+  }.join("\n").html_safe
+
+  request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) && request
+
+  sources_tags
+end
+
+
+ +
+ +
+ + + +
+

Returns a link tag that browsers can use to preload the source. The source can be the path of a resource managed by asset pipeline, a full path, or an URI.

+ + +
  • +

    :type - Override the auto-generated mime type, defaults to the mime type for source extension.

    +
  • +

    :as - Override the auto-generated value for as attribute, calculated using source extension and mime type.

    +
  • +

    :crossorigin - Specify the crossorigin attribute, required to load cross-origin resources.

    +
  • +

    :nopush - Specify if the use of server push is not desired for the resource. Defaults to false.

    +
+ + + +
preload_link_tag("custom_theme.css")
+# => <link rel="preload" href="/assets/custom_theme.css" as="style" type="text/css" />
+
+preload_link_tag("/videos/video.webm")
+# => <link rel="preload" href="/videos/video.mp4" as="video" type="video/webm" />
+
+preload_link_tag(post_path(format: :json), as: "fetch")
+# => <link rel="preload" href="/posts.json" as="fetch" type="application/json" />
+
+preload_link_tag("worker.js", as: "worker")
+# => <link rel="preload" href="/assets/worker.js" as="worker" type="text/javascript" />
+
+preload_link_tag("//example.com/font.woff2")
+# => <link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="anonymous"/>
+
+preload_link_tag("//example.com/font.woff2", crossorigin: "use-credentials")
+# => <link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="use-credentials" />
+
+preload_link_tag("/media/audio.ogg", nopush: true)
+# => <link rel="preload" href="/media/audio.ogg" as="audio" type="audio/ogg" />
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+ + + +
+

Returns a stylesheet link tag for the sources specified as arguments. If you don't specify an extension, .css will be appended automatically. You can modify the link attributes by passing a hash as the last argument. For historical reasons, the 'media' attribute will always be present and defaults to “screen”, so you must explicitly set it to “all” for the stylesheet(s) to apply to all media types.

+ +

If the server supports Early Hints header links for these assets will be automatically pushed.

+ +
stylesheet_link_tag "style"
+# => <link href="/assets/style.css" media="screen" rel="stylesheet" />
+
+stylesheet_link_tag "style.css"
+# => <link href="/assets/style.css" media="screen" rel="stylesheet" />
+
+stylesheet_link_tag "http://www.example.com/style.css"
+# => <link href="http://www.example.com/style.css" media="screen" rel="stylesheet" />
+
+stylesheet_link_tag "style", media: "all"
+# => <link href="/assets/style.css" media="all" rel="stylesheet" />
+
+stylesheet_link_tag "style", media: "print"
+# => <link href="/assets/style.css" media="print" rel="stylesheet" />
+
+stylesheet_link_tag "random.styles", "/css/stylish"
+# => <link href="/assets/random.styles" media="screen" rel="stylesheet" />
+#    <link href="/css/stylish.css" media="screen" rel="stylesheet" />
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+

+ + video_tag(*sources) + +

+ + +
+

Returns an HTML video tag for the sources. If sources is a string, a single video tag will be returned. If sources is an array, a video tag with nested source tags for each source will be returned. The sources can be full paths or files that exist in your public videos directory.

+ +

Options

+ +

When the last parameter is a hash you can add HTML attributes using that parameter. The following options are supported:

+
  • +

    :poster - Set an image (like a screenshot) to be shown before the video loads. The path is calculated like the src of image_tag.

    +
  • +

    :size - Supplied as “{Width}x{Height}” or “{Number}”, so “30x45” becomes width=“30” and height=“45”, and “50” becomes width=“50” and height=“50”. :size will be ignored if the value is not in the correct format.

    +
  • +

    :poster_skip_pipeline will bypass the asset pipeline when using the :poster option instead using an asset in the public folder.

    +
+ +

Examples

+ +
video_tag("trailer")
+# => <video src="/videos/trailer"></video>
+video_tag("trailer.ogg")
+# => <video src="/videos/trailer.ogg"></video>
+video_tag("trailer.ogg", controls: true, preload: 'none')
+# => <video preload="none" controls="controls" src="/videos/trailer.ogg"></video>
+video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png")
+# => <video src="/videos/trailer.m4v" width="16" height="10" poster="/assets/screenshot.png"></video>
+video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png", poster_skip_pipeline: true)
+# => <video src="/videos/trailer.m4v" width="16" height="10" poster="screenshot.png"></video>
+video_tag("/trailers/hd.avi", size: "16x16")
+# => <video src="/trailers/hd.avi" width="16" height="16"></video>
+video_tag("/trailers/hd.avi", size: "16")
+# => <video height="16" src="/trailers/hd.avi" width="16"></video>
+video_tag("/trailers/hd.avi", height: '32', width: '32')
+# => <video height="32" src="/trailers/hd.avi" width="32"></video>
+video_tag("trailer.ogg", "trailer.flv")
+# => <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
+video_tag(["trailer.ogg", "trailer.flv"])
+# => <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
+video_tag(["trailer.ogg", "trailer.flv"], size: "160x120")
+# => <video height="120" width="160"><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 424
+def video_tag(*sources)
+  options = sources.extract_options!.symbolize_keys
+  public_poster_folder = options.delete(:poster_skip_pipeline)
+  sources << options
+  multiple_sources_tag_builder("video", sources) do |tag_options|
+    tag_options[:poster] = path_to_image(tag_options[:poster], skip_pipeline: public_poster_folder) if tag_options[:poster]
+    tag_options[:width], tag_options[:height] = extract_dimensions(tag_options.delete(:size)) if tag_options[:size]
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/AssetUrlHelper.html b/src/5.2/classes/ActionView/Helpers/AssetUrlHelper.html new file mode 100644 index 0000000000..9e9cb1c06e --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/AssetUrlHelper.html @@ -0,0 +1,1536 @@ +--- +title: ActionView::Helpers::AssetUrlHelper +layout: default +--- +
+ +
+
+ +
+ +

This module provides methods for generating asset paths and URLs.

+ +
image_path("rails.png")
+# => "/assets/rails.png"
+
+image_url("rails.png")
+# => "http://www.example.com/assets/rails.png"
+
+ +

Using asset hosts

+ +

By default, Rails links to these assets on the current host in the public folder, but you can direct Rails to link to assets from a dedicated asset server by setting ActionController::Base.asset_host in the application configuration, typically in config/environments/production.rb. For example, you'd define assets.example.com to be your asset host this way, inside the configure block of your environment-specific configuration files or config/application.rb:

+ +
config.action_controller.asset_host = "assets.example.com"
+
+ +

Helpers take that into account:

+ +
image_tag("rails.png")
+# => <img src="http://assets.example.com/assets/rails.png" />
+stylesheet_link_tag("application")
+# => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
+
+ +

Browsers open a limited number of simultaneous connections to a single host. The exact number varies by browser and version. This limit may cause some asset downloads to wait for previous assets to finish before they can begin. You can use the %d wildcard in the asset_host to distribute the requests over four hosts. For example, assets%d.example.com will spread the asset requests over “assets0.example.com”, …, “assets3.example.com”.

+ +
image_tag("rails.png")
+# => <img src="http://assets0.example.com/assets/rails.png" />
+stylesheet_link_tag("application")
+# => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
+
+ +

This may improve the asset loading performance of your application. It is also possible the combination of additional connection overhead (DNS, SSL) and the overall browser connection limits may result in this solution being slower. You should be sure to measure your actual performance across targeted browsers both before and after this change.

+ +

To implement the corresponding hosts you can either setup four actual hosts or use wildcard DNS to CNAME the wildcard to a single asset host. You can read more about setting up your DNS CNAME records from your ISP.

+ +

Note: This is purely a browser performance optimization and is not meant for server load balancing. See www.die.net/musings/page_load_time/ for background and www.browserscope.org/?category=network for connection limit data.

+ +

Alternatively, you can exert more control over the asset host by setting asset_host to a proc like this:

+ +
ActionController::Base.asset_host = Proc.new { |source|
+  "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
+}
+image_tag("rails.png")
+# => <img src="http://assets1.example.com/assets/rails.png" />
+stylesheet_link_tag("application")
+# => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
+
+ +

The example above generates “assets1.example.com” and “assets2.example.com”. This option is useful for example if you need fewer/more than four hosts, custom host names, etc.

+ +

As you see the proc takes a source parameter. That's a string with the absolute path of the asset, for example “/assets/rails.png”.

+ +
 ActionController::Base.asset_host = Proc.new { |source|
+   if source.ends_with?('.css')
+     "http://stylesheets.example.com"
+   else
+     "http://assets.example.com"
+   end
+ }
+image_tag("rails.png")
+# => <img src="http://assets.example.com/assets/rails.png" />
+stylesheet_link_tag("application")
+# => <link href="http://stylesheets.example.com/assets/application.css" media="screen" rel="stylesheet" />
+
+ +

Alternatively you may ask for a second parameter request. That one is particularly useful for serving assets from an SSL-protected page. The example proc below disables asset hosting for HTTPS connections, while still sending assets for plain HTTP requests from asset hosts. If you don't have SSL certificates for each of the asset hosts this technique allows you to avoid warnings in the client about mixed media. Note that the request parameter might not be supplied, e.g. when the assets are precompiled via a Rake task. Make sure to use a Proc instead of a lambda, since a Proc allows missing parameters and sets them to nil.

+ +
config.action_controller.asset_host = Proc.new { |source, request|
+  if request && request.ssl?
+    "#{request.protocol}#{request.host_with_port}"
+  else
+    "#{request.protocol}assets.example.com"
+  end
+}
+
+ +

You can also implement a custom asset host object that responds to call and takes either one or two parameters just like the proc.

+ +
config.action_controller.asset_host = AssetHostingWithMinimumSsl.new(
+  "http://asset%d.example.com", "https://asset1.example.com"
+)
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ASSET_EXTENSIONS={ +javascript: ".js", +stylesheet: ".css" +}
 
ASSET_PUBLIC_DIRECTORIES={ +audio: "/audios", +font: "/fonts", +image: "/images", +javascript: "/javascripts", +stylesheet: "/stylesheets", +video: "/videos" +}
 

Maps asset types to public directory.

URI_REGEXP=%r{^[-a-z]+://|^(?:cid|data):|^//}i
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + asset_path(source, options = {}) + +

+ + +
+

This is the entry point for all assets. When using the asset pipeline (i.e. sprockets and sprockets-rails), the behavior is “enhanced”. You can bypass the asset pipeline by passing in skip_pipeline: true to the options.

+ +

All other asset *_path helpers delegate through this method.

+ +

With the asset pipeline

+ +

All options passed to asset_path will be passed to compute_asset_path which is implemented by sprockets-rails.

+ +
asset_path("application.js") # => "/assets/application-60aa4fdc5cea14baf5400fba1abf4f2a46a5166bad4772b1effe341570f07de9.js"
+
+ +

Without the asset pipeline (skip_pipeline: true)

+ +

Accepts a type option that can specify the asset's extension. No error checking is done to verify the source passed into asset_path is valid and that the file exists on disk.

+ +
asset_path("application.js", skip_pipeline: true)                 # => "application.js"
+asset_path("filedoesnotexist.png", skip_pipeline: true)           # => "filedoesnotexist.png"
+asset_path("application", type: :javascript, skip_pipeline: true) # => "/javascripts/application.js"
+asset_path("application", type: :stylesheet, skip_pipeline: true) # => "/stylesheets/application.css"
+
+ +

Options applying to all assets

+ +

Below lists scenarios that apply to asset_path whether or not you're using the asset pipeline.

+
  • +

    All fully qualified URLs are returned immediately. This bypasses the asset pipeline and all other behavior described.

    + +
    asset_path("http://www.example.com/js/xmlhr.js") # => "http://www.example.com/js/xmlhr.js"
    +
    +
  • +

    All assets that begin with a forward slash are assumed to be full URLs and will not be expanded. This will bypass the asset pipeline.

    + +
    asset_path("/foo.png") # => "/foo.png"
    +
    +
  • +

    All blank strings will be returned immediately. This bypasses the asset pipeline and all other behavior described.

    + +
    asset_path("") # => ""
    +
    +
  • +

    If config.relative_url_root is specified, all assets will have that root prepended.

    + +
    Rails.application.config.relative_url_root = "bar"
    +asset_path("foo.js", skip_pipeline: true) # => "bar/foo.js"
    +
    +
  • +

    A different asset host can be specified via config.action_controller.asset_host this is commonly used in conjunction with a CDN.

    + +
    Rails.application.config.action_controller.asset_host = "assets.example.com"
    +asset_path("foo.js", skip_pipeline: true) # => "http://assets.example.com/foo.js"
    +
    +
  • +

    An extension name can be specified manually with extname.

    + +
    asset_path("foo", skip_pipeline: true, extname: ".js")     # => "/foo.js"
    +asset_path("foo.css", skip_pipeline: true, extname: ".js") # => "/foo.css.js"
    +
    +
+
+ + + +
+ Also aliased as: path_to_asset +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 183
+def asset_path(source, options = {})
+  raise ArgumentError, "nil is not a valid asset source" if source.nil?
+
+  source = source.to_s
+  return "" if source.blank?
+  return source if URI_REGEXP.match?(source)
+
+  tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, "".freeze)
+
+  if extname = compute_asset_extname(source, options)
+    source = "#{source}#{extname}"
+  end
+
+  if source[0] != ?/
+    if options[:skip_pipeline]
+      source = public_compute_asset_path(source, options)
+    else
+      source = compute_asset_path(source, options)
+    end
+  end
+
+  relative_url_root = defined?(config.relative_url_root) && config.relative_url_root
+  if relative_url_root
+    source = File.join(relative_url_root, source) unless source.starts_with?("#{relative_url_root}/")
+  end
+
+  if host = compute_asset_host(source, options)
+    source = File.join(host, source)
+  end
+
+  "#{source}#{tail}"
+end
+
+
+ +
+ +
+

+ + asset_url(source, options = {}) + +

+ + +
+

Computes the full URL to an asset in the public directory. This will use asset_path internally, so most of their behaviors will be the same. If :host options is set, it overwrites global config.action_controller.asset_host setting.

+ +

All other options provided are forwarded to asset_path call.

+ +
asset_url "application.js"                                 # => http://example.com/assets/application.js
+asset_url "application.js", host: "http://cdn.example.com" # => http://cdn.example.com/assets/application.js
+
+
+ + + +
+ Also aliased as: url_to_asset +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 227
+def asset_url(source, options = {})
+  path_to_asset(source, options.merge(protocol: :request))
+end
+
+
+ +
+ +
+

+ + audio_path(source, options = {}) + +

+ + +
+

Computes the path to an audio asset in the public audios directory. Full paths from the document root will be passed through. Used internally by audio_tag to build the audio path.

+ +
audio_path("horse")                                            # => /audios/horse
+audio_path("horse.wav")                                        # => /audios/horse.wav
+audio_path("sounds/horse.wav")                                 # => /audios/sounds/horse.wav
+audio_path("/sounds/horse.wav")                                # => /sounds/horse.wav
+audio_path("http://www.example.com/sounds/horse.wav")          # => http://www.example.com/sounds/horse.wav
+
+
+ + + +
+ Also aliased as: path_to_audio +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 426
+def audio_path(source, options = {})
+  path_to_asset(source, { type: :audio }.merge!(options))
+end
+
+
+ +
+ +
+

+ + audio_url(source, options = {}) + +

+ + +
+

Computes the full URL to an audio asset in the public audios directory. This will use audio_path internally, so most of their behaviors will be the same. Since audio_url is based on asset_url method you can set :host options. If :host options is set, it overwrites global config.action_controller.asset_host setting.

+ +
audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/audios/horse.wav
+
+
+ + + +
+ Also aliased as: url_to_audio +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 438
+def audio_url(source, options = {})
+  url_to_asset(source, { type: :audio }.merge!(options))
+end
+
+
+ +
+ +
+

+ + compute_asset_extname(source, options = {}) + +

+ + +
+

Compute extname to append to asset path. Returns nil if nothing should be added.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 239
+def compute_asset_extname(source, options = {})
+  return if options[:extname] == false
+  extname = options[:extname] || ASSET_EXTENSIONS[options[:type]]
+  if extname && File.extname(source) != extname
+    extname
+  else
+    nil
+  end
+end
+
+
+ +
+ +
+

+ + compute_asset_host(source = "", options = {}) + +

+ + +
+

Pick an asset host for this source. Returns nil if no host is set, the host if no wildcard is set, the host interpolated with the numbers 0-3 if it contains %d (the number is the source hash mod 4), or the value returned from invoking call on an object responding to call (proc or otherwise).

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 273
+def compute_asset_host(source = "", options = {})
+  request = self.request if respond_to?(:request)
+  host = options[:host]
+  host ||= config.asset_host if defined? config.asset_host
+
+  if host
+    if host.respond_to?(:call)
+      arity = host.respond_to?(:arity) ? host.arity : host.method(:call).arity
+      args = [source]
+      args << request if request && (arity > 1 || arity < 0)
+      host = host.call(*args)
+    elsif host.include?("%d")
+      host = host % (Zlib.crc32(source) % 4)
+    end
+  end
+
+  host ||= request.base_url if request && options[:protocol] == :request
+  return unless host
+
+  if URI_REGEXP.match?(host)
+    host
+  else
+    protocol = options[:protocol] || config.default_asset_host_protocol || (request ? :request : :relative)
+    case protocol
+    when :relative
+      "//#{host}"
+    when :request
+      "#{request.protocol}#{host}"
+    else
+      "#{protocol}://#{host}"
+    end
+  end
+end
+
+
+ +
+ +
+

+ + compute_asset_path(source, options = {}) + +

+ + +
+

Computes asset path to public directory. Plugins and extensions can override this method to point to custom assets or generate digested paths or query strings.

+
+ + + +
+ Also aliased as: public_compute_asset_path +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 262
+def compute_asset_path(source, options = {})
+  dir = ASSET_PUBLIC_DIRECTORIES[options[:type]] || ""
+  File.join(dir, source)
+end
+
+
+ +
+ +
+

+ + font_path(source, options = {}) + +

+ + +
+

Computes the path to a font asset. Full paths from the document root will be passed through.

+ +
font_path("font")                                           # => /fonts/font
+font_path("font.ttf")                                       # => /fonts/font.ttf
+font_path("dir/font.ttf")                                   # => /fonts/dir/font.ttf
+font_path("/dir/font.ttf")                                  # => /dir/font.ttf
+font_path("http://www.example.com/dir/font.ttf")            # => http://www.example.com/dir/font.ttf
+
+
+ + + +
+ Also aliased as: path_to_font +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 451
+def font_path(source, options = {})
+  path_to_asset(source, { type: :font }.merge!(options))
+end
+
+
+ +
+ +
+

+ + font_url(source, options = {}) + +

+ + +
+

Computes the full URL to a font asset. This will use font_path internally, so most of their behaviors will be the same. Since font_url is based on asset_url method you can set :host options. If :host options is set, it overwrites global config.action_controller.asset_host setting.

+ +
font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/fonts/font.ttf
+
+
+ + + +
+ Also aliased as: url_to_font +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 463
+def font_url(source, options = {})
+  url_to_asset(source, { type: :font }.merge!(options))
+end
+
+
+ +
+ +
+

+ + image_path(source, options = {}) + +

+ + +
+

Computes the path to an image asset. Full paths from the document root will be passed through. Used internally by image_tag to build the image path:

+ +
image_path("edit")                                         # => "/assets/edit"
+image_path("edit.png")                                     # => "/assets/edit.png"
+image_path("icons/edit.png")                               # => "/assets/icons/edit.png"
+image_path("/icons/edit.png")                              # => "/icons/edit.png"
+image_path("http://www.example.com/img/edit.png")          # => "http://www.example.com/img/edit.png"
+
+ +

If you have images as application resources this method may conflict with their named routes. The alias path_to_image is provided to avoid that. Rails uses the alias internally, and plugin authors are encouraged to do so.

+
+ + + +
+ Also aliased as: path_to_image +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 374
+def image_path(source, options = {})
+  path_to_asset(source, { type: :image }.merge!(options))
+end
+
+
+ +
+ +
+

+ + image_url(source, options = {}) + +

+ + +
+

Computes the full URL to an image asset. This will use image_path internally, so most of their behaviors will be the same. Since image_url is based on asset_url method you can set :host options. If :host options is set, it overwrites global config.action_controller.asset_host setting.

+ +
image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/assets/edit.png
+
+
+ + + +
+ Also aliased as: url_to_image +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 386
+def image_url(source, options = {})
+  url_to_asset(source, { type: :image }.merge!(options))
+end
+
+
+ +
+ +
+

+ + javascript_path(source, options = {}) + +

+ + +
+

Computes the path to a JavaScript asset in the public javascripts directory. If the source filename has no extension, .js will be appended (except for explicit URIs) Full paths from the document root will be passed through. Used internally by javascript_include_tag to build the script path.

+ +
javascript_path "xmlhr"                              # => /assets/xmlhr.js
+javascript_path "dir/xmlhr.js"                       # => /assets/dir/xmlhr.js
+javascript_path "/dir/xmlhr"                         # => /dir/xmlhr.js
+javascript_path "http://www.example.com/js/xmlhr"    # => http://www.example.com/js/xmlhr
+javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
+
+
+ + + +
+ Also aliased as: path_to_javascript +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 317
+def javascript_path(source, options = {})
+  path_to_asset(source, { type: :javascript }.merge!(options))
+end
+
+
+ +
+ +
+

+ + javascript_url(source, options = {}) + +

+ + +
+

Computes the full URL to a JavaScript asset in the public javascripts directory. This will use javascript_path internally, so most of their behaviors will be the same. Since javascript_url is based on asset_url method you can set :host options. If :host options is set, it overwrites global config.action_controller.asset_host setting.

+ +
javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/js/xmlhr.js
+
+
+ + + +
+ Also aliased as: url_to_javascript +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 329
+def javascript_url(source, options = {})
+  url_to_asset(source, { type: :javascript }.merge!(options))
+end
+
+
+ +
+ +
+

+ + path_to_asset(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: asset_path +
+ + + +
+ +
+

+ + path_to_audio(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: audio_path +
+ + + +
+ +
+

+ + path_to_font(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: font_path +
+ + + +
+ +
+

+ + path_to_image(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: image_path +
+ + + +
+ +
+

+ + path_to_javascript(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: javascript_path +
+ + + +
+ +
+

+ + path_to_stylesheet(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: stylesheet_path +
+ + + +
+ +
+

+ + path_to_video(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: video_path +
+ + + +
+ +
+

+ + public_compute_asset_path(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: compute_asset_path +
+ + + +
+ +
+

+ + stylesheet_path(source, options = {}) + +

+ + +
+

Computes the path to a stylesheet asset in the public stylesheets directory. If the source filename has no extension, .css will be appended (except for explicit URIs). Full paths from the document root will be passed through. Used internally by stylesheet_link_tag to build the stylesheet path.

+ +
stylesheet_path "style"                                  # => /assets/style.css
+stylesheet_path "dir/style.css"                          # => /assets/dir/style.css
+stylesheet_path "/dir/style.css"                         # => /dir/style.css
+stylesheet_path "http://www.example.com/css/style"       # => http://www.example.com/css/style
+stylesheet_path "http://www.example.com/css/style.css"   # => http://www.example.com/css/style.css
+
+
+ + + +
+ Also aliased as: path_to_stylesheet +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 344
+def stylesheet_path(source, options = {})
+  path_to_asset(source, { type: :stylesheet }.merge!(options))
+end
+
+
+ +
+ +
+

+ + stylesheet_url(source, options = {}) + +

+ + +
+

Computes the full URL to a stylesheet asset in the public stylesheets directory. This will use stylesheet_path internally, so most of their behaviors will be the same. Since stylesheet_url is based on asset_url method you can set :host options. If :host options is set, it overwrites global config.action_controller.asset_host setting.

+ +
stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/assets/css/style.css
+
+
+ + + +
+ Also aliased as: url_to_stylesheet +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 356
+def stylesheet_url(source, options = {})
+  url_to_asset(source, { type: :stylesheet }.merge!(options))
+end
+
+
+ +
+ +
+

+ + url_to_asset(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: asset_url +
+ + + +
+ +
+

+ + url_to_audio(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: audio_url +
+ + + +
+ +
+

+ + url_to_font(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: font_url +
+ + + +
+ +
+

+ + url_to_image(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: image_url +
+ + + +
+ +
+

+ + url_to_javascript(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: javascript_url +
+ + + +
+ +
+

+ + url_to_stylesheet(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: stylesheet_url +
+ + + +
+ +
+

+ + url_to_video(source, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: video_url +
+ + + +
+ +
+

+ + video_path(source, options = {}) + +

+ + +
+

Computes the path to a video asset in the public videos directory. Full paths from the document root will be passed through. Used internally by video_tag to build the video path.

+ +
video_path("hd")                                            # => /videos/hd
+video_path("hd.avi")                                        # => /videos/hd.avi
+video_path("trailers/hd.avi")                               # => /videos/trailers/hd.avi
+video_path("/trailers/hd.avi")                              # => /trailers/hd.avi
+video_path("http://www.example.com/vid/hd.avi")             # => http://www.example.com/vid/hd.avi
+
+
+ + + +
+ Also aliased as: path_to_video +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 400
+def video_path(source, options = {})
+  path_to_asset(source, { type: :video }.merge!(options))
+end
+
+
+ +
+ +
+

+ + video_url(source, options = {}) + +

+ + +
+

Computes the full URL to a video asset in the public videos directory. This will use video_path internally, so most of their behaviors will be the same. Since video_url is based on asset_url method you can set :host options. If :host options is set, it overwrites global config.action_controller.asset_host setting.

+ +
video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/videos/hd.avi
+
+
+ + + +
+ Also aliased as: url_to_video +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 412
+def video_url(source, options = {})
+  url_to_asset(source, { type: :video }.merge!(options))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/AtomFeedHelper.html b/src/5.2/classes/ActionView/Helpers/AtomFeedHelper.html new file mode 100644 index 0000000000..4429776905 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/AtomFeedHelper.html @@ -0,0 +1,217 @@ +--- +title: ActionView::Helpers::AtomFeedHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + atom_feed(options = {}, &block) + +

+ + +
+

Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other template languages).

+ +

Full usage example:

+ +
config/routes.rb:
+  Rails.application.routes.draw do
+    resources :posts
+    root to: "posts#index"
+  end
+
+app/controllers/posts_controller.rb:
+  class PostsController < ApplicationController
+    # GET /posts.html
+    # GET /posts.atom
+    def index
+      @posts = Post.all
+
+      respond_to do |format|
+        format.html
+        format.atom
+      end
+    end
+  end
+
+app/views/posts/index.atom.builder:
+  atom_feed do |feed|
+    feed.title("My great blog!")
+    feed.updated(@posts[0].created_at) if @posts.length > 0
+
+    @posts.each do |post|
+      feed.entry(post) do |entry|
+        entry.title(post.title)
+        entry.content(post.body, type: 'html')
+
+        entry.author do |author|
+          author.name("DHH")
+        end
+      end
+    end
+  end
+
+ +

The options for atom_feed are:

+
  • +

    :language: Defaults to “en-US”.

    +
  • +

    :root_url: The HTML alternative that this feed is doubling for. Defaults to / on the current host.

    +
  • +

    :url: The URL for this feed. Defaults to the current URL.

    +
  • +

    :id: The id for this feed. Defaults to “tag:localhost,2005:/posts”, in this case.

    +
  • +

    :schema_date: The date at which the tag scheme for the feed was first used. A good default is the year you created the feed. See feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, 2005 is used (as an “I don't care” value).

    +
  • +

    :instruct: Hash of XML processing instructions in the form {target => {attribute => value, }} or {target => [{attribute => value, }, ]}

    +
+ +

Other namespaces can be added to the root element:

+ +
app/views/posts/index.atom.builder:
+  atom_feed({'xmlns:app' => 'http://www.w3.org/2007/app',
+      'xmlns:openSearch' => 'http://a9.com/-/spec/opensearch/1.1/'}) do |feed|
+    feed.title("My great blog!")
+    feed.updated((@posts.first.created_at))
+    feed.tag!('openSearch:totalResults', 10)
+
+    @posts.each do |post|
+      feed.entry(post) do |entry|
+        entry.title(post.title)
+        entry.content(post.body, type: 'html')
+        entry.tag!('app:edited', Time.now)
+
+        entry.author do |author|
+          author.name("DHH")
+        end
+      end
+    end
+  end
+
+ +

The Atom spec defines five elements (content rights title subtitle summary) which may directly contain xhtml content if type: 'xhtml' is specified as an attribute. If so, this helper will take care of the enclosing div and xhtml namespace declaration. Example usage:

+ +
entry.summary type: 'xhtml' do |xhtml|
+  xhtml.p pluralize(order.line_items.count, "line item")
+  xhtml.p "Shipped to #{order.address}"
+  xhtml.p "Paid by #{order.pay_type}"
+end
+
+ +

atom_feed yields an AtomFeedBuilder instance. Nested elements yield an AtomBuilder instance.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/atom_feed_helper.rb, line 98
+def atom_feed(options = {}, &block)
+  if options[:schema_date]
+    options[:schema_date] = options[:schema_date].strftime("%Y-%m-%d") if options[:schema_date].respond_to?(:strftime)
+  else
+    options[:schema_date] = "2005" # The Atom spec copyright date
+  end
+
+  xml = options.delete(:xml) || eval("xml", block.binding)
+  xml.instruct!
+  if options[:instruct]
+    options[:instruct].each do |target, attrs|
+      if attrs.respond_to?(:keys)
+        xml.instruct!(target, attrs)
+      elsif attrs.respond_to?(:each)
+        attrs.each { |attr_group| xml.instruct!(target, attr_group) }
+      end
+    end
+  end
+
+  feed_opts = { "xml:lang" => options[:language] || "en-US", "xmlns" => "http://www.w3.org/2005/Atom" }
+  feed_opts.merge!(options).reject! { |k, v| !k.to_s.match(/^xml/) }
+
+  xml.feed(feed_opts) do
+    xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}")
+    xml.link(rel: "alternate", type: "text/html", href: options[:root_url] || (request.protocol + request.host_with_port))
+    xml.link(rel: "self", type: "application/atom+xml", href: options[:url] || request.url)
+
+    yield AtomFeedBuilder.new(xml, self, options)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/CacheHelper.html b/src/5.2/classes/ActionView/Helpers/CacheHelper.html new file mode 100644 index 0000000000..a3c1fe71cb --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/CacheHelper.html @@ -0,0 +1,384 @@ +--- +title: ActionView::Helpers::CacheHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + cache(name = {}, options = {}, &block) + +

+ + +
+

This helper exposes a method for caching fragments of a view rather than an entire action or page. This technique is useful caching pieces like menus, lists of new topics, static HTML fragments, and so on. This method takes a block that contains the content you wish to cache.

+ +

The best way to use this is by doing recyclable key-based cache expiration on top of a cache store like Memcached or Redis that'll automatically kick out old entries.

+ +

When using this method, you list the cache dependency as the name of the cache, like so:

+ +
<% cache project do %>
+  <b>All the topics on this project</b>
+  <%= render project.topics %>
+<% end %>
+
+ +

This approach will assume that when a new topic is added, you'll touch the project. The cache key generated from this call will be something like:

+ +
views/template/action.html.erb:7a1156131a6928cb0026877f8b749ac9/projects/123
+      ^template path           ^template tree digest            ^class   ^id
+
+ +

This cache key is stable, but it's combined with a cache version derived from the project record. When the project updated_at is touched, the cache_version changes, even if the key stays stable. This means that unlike a traditional key-based cache expiration approach, you won't be generating cache trash, unused keys, simply because the dependent record is updated.

+ +

If your template cache depends on multiple sources (try to avoid this to keep things simple), you can name all these dependencies as part of an array:

+ +
<% cache [ project, current_user ] do %>
+  <b>All the topics on this project</b>
+  <%= render project.topics %>
+<% end %>
+
+ +

This will include both records as part of the cache key and updating either of them will expire the cache.

+ +

Template digest

+ +

The template digest that's added to the cache key is computed by taking an MD5 of the contents of the entire template file. This ensures that your caches will automatically expire when you change the template file.

+ +

Note that the MD5 is taken of the entire template file, not just what's within the cache do/end call. So it's possible that changing something outside of that call will still expire the cache.

+ +

Additionally, the digestor will automatically look through your template file for explicit and implicit dependencies, and include those as part of the digest.

+ +

The digestor can be bypassed by passing skip_digest: true as an option to the cache call:

+ +
<% cache project, skip_digest: true do %>
+  <b>All the topics on this project</b>
+  <%= render project.topics %>
+<% end %>
+
+ +

Implicit dependencies

+ +

Most template dependencies can be derived from calls to render in the template itself. Here are some examples of render calls that Cache Digests knows how to decode:

+ +
render partial: "comments/comment", collection: commentable.comments
+render "comments/comments"
+render 'comments/comments'
+render('comments/comments')
+
+render "header" translates to render("comments/header")
+
+render(@topic)         translates to render("topics/topic")
+render(topics)         translates to render("topics/topic")
+render(message.topics) translates to render("topics/topic")
+
+ +

It's not possible to derive all render calls like that, though. Here are a few examples of things that can't be derived:

+ +
render group_of_attachments
+render @project.documents.where(published: true).order('created_at')
+
+ +

You will have to rewrite those to the explicit form:

+ +
render partial: 'attachments/attachment', collection: group_of_attachments
+render partial: 'documents/document', collection: @project.documents.where(published: true).order('created_at')
+
+ +

Explicit dependencies

+ +

Sometimes you'll have template dependencies that can't be derived at all. This is typically the case when you have template rendering that happens in helpers. Here's an example:

+ +
<%= render_sortable_todolists @project.todolists %>
+
+ +

You'll need to use a special comment format to call those out:

+ +
<%# Template Dependency: todolists/todolist %>
+<%= render_sortable_todolists @project.todolists %>
+
+ +

In some cases, like a single table inheritance setup, you might have a bunch of explicit dependencies. Instead of writing every template out, you can use a wildcard to match any template in a directory:

+ +
<%# Template Dependency: events/* %>
+<%= render_categorizable_events @person.events %>
+
+ +

This marks every template in the directory as a dependency. To find those templates, the wildcard path must be absolutely defined from app/views or paths otherwise added with prepend_view_path or append_view_path. This way the wildcard for app/views/recordings/events would be recordings/events/* etc.

+ +

The pattern used to match explicit dependencies is /# Template Dependency: (\S+)/, so it's important that you type it out just so. You can only declare one template dependency per line.

+ +

External dependencies

+ +

If you use a helper method, for example, inside a cached block and you then update that helper, you'll have to bump the cache as well. It doesn't really matter how you do it, but the MD5 of the template file must change. One recommendation is to simply be explicit in a comment, like:

+ +
<%# Helper Dependency Updated: May 6, 2012 at 6pm %>
+<%= some_helper_method(person) %>
+
+ +

Now all you have to do is change that timestamp when the helper method changes.

+ +

Collection Caching

+ +

When rendering a collection of objects that each use the same partial, a :cached option can be passed.

+ +

For collections rendered such:

+ +
<%= render partial: 'projects/project', collection: @projects, cached: true %>
+
+ +

The cached: true will make Action View's rendering read several templates from cache at once instead of one call per template.

+ +

Templates in the collection not already cached are written to cache.

+ +

Works great alongside individual template fragment caching. For instance if the template the collection renders is cached like:

+ +
# projects/_project.html.erb
+<% cache project do %>
+  <%# ... %>
+<% end %>
+
+ +

Any collection renders will find those cached templates when attempting to read multiple templates at once.

+ +

If your collection cache depends on multiple sources (try to avoid this to keep things simple), you can name all these dependencies as part of a block that returns an array:

+ +
<%= render partial: 'projects/project', collection: @projects, cached: -> project { [ project, current_user ] } %>
+
+ +

This will include both records as part of the cache key and updating either of them will expire the cache.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/cache_helper.rb, line 166
+def cache(name = {}, options = {}, &block)
+  if controller.respond_to?(:perform_caching) && controller.perform_caching
+    name_options = options.slice(:skip_digest, :virtual_path)
+    safe_concat(fragment_for(cache_fragment_name(name, name_options), options, &block))
+  else
+    yield
+  end
+
+  nil
+end
+
+
+ +
+ +
+

+ + cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil) + +

+ + +
+

This helper returns the name of a cache key for a given fragment cache call. By supplying skip_digest: true to cache, the digestion of cache fragments can be manually bypassed. This is useful when cache fragments cannot be manually expired unless you know the exact key which is the case when using memcached.

+ +

The digest will be generated using virtual_path: if it is provided.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/cache_helper.rb, line 211
+def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil)
+  if skip_digest
+    name
+  else
+    fragment_name_with_digest(name, virtual_path)
+  end
+end
+
+
+ +
+ +
+

+ + cache_if(condition, name = {}, options = {}, &block) + +

+ + +
+

Cache fragments of a view if condition is true

+ +
<% cache_if admin?, project do %>
+  <b>All the topics on this project</b>
+  <%= render project.topics %>
+<% end %>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/cache_helper.rb, line 183
+def cache_if(condition, name = {}, options = {}, &block)
+  if condition
+    cache(name, options, &block)
+  else
+    yield
+  end
+
+  nil
+end
+
+
+ +
+ +
+

+ + cache_unless(condition, name = {}, options = {}, &block) + +

+ + +
+

Cache fragments of a view unless condition is true

+ +
<% cache_unless admin?, project do %>
+  <b>All the topics on this project</b>
+  <%= render project.topics %>
+<% end %>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/cache_helper.rb, line 199
+def cache_unless(condition, name = {}, options = {}, &block)
+  cache_if !condition, name, options, &block
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/CaptureHelper.html b/src/5.2/classes/ActionView/Helpers/CaptureHelper.html new file mode 100644 index 0000000000..ef9e6800c7 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/CaptureHelper.html @@ -0,0 +1,390 @@ +--- +title: ActionView::Helpers::CaptureHelper +layout: default +--- +
+ +
+
+ +
+ +

CaptureHelper exposes methods to let you extract generated markup which can be used in other parts of a template or layout file.

+ +

It provides a method to capture blocks into variables through capture and a way to capture a block of markup for use in a layout through content_for.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + capture(*args) + +

+ + +
+

The capture method extracts part of a template as a String object. You can then use this object anywhere in your templates, layout, or helpers.

+ +

The capture method can be used in ERB templates…

+ +
<% @greeting = capture do %>
+  Welcome to my shiny new web page!  The date and time is
+  <%= Time.now %>
+<% end %>
+
+ +

…and Builder (RXML) templates.

+ +
@timestamp = capture do
+  "The current timestamp is #{Time.now}."
+end
+
+ +

You can then use that variable anywhere else. For example:

+ +
<html>
+<head><title><%= @greeting %></title></head>
+<body>
+<b><%= @greeting %></b>
+</body>
+</html>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/capture_helper.rb, line 39
+def capture(*args)
+  value = nil
+  buffer = with_output_buffer { value = yield(*args) }
+  if (string = buffer.presence || value) && string.is_a?(String)
+    ERB::Util.html_escape string
+  end
+end
+
+
+ +
+ +
+

+ + content_for(name, content = nil, options = {}, &block) + +

+ + +
+

Calling content_for stores a block of markup in an identifier for later use. In order to access this stored content in other templates, helper modules or the layout, you would pass the identifier as an argument to content_for.

+ +

Note: yield can still be used to retrieve the stored content, but calling yield doesn't work in helper modules, while content_for does.

+ +
<% content_for :not_authorized do %>
+  alert('You are not authorized to do that!')
+<% end %>
+
+ +

You can then use content_for :not_authorized anywhere in your templates.

+ +
<%= content_for :not_authorized if current_user.nil? %>
+
+ +

This is equivalent to:

+ +
<%= yield :not_authorized if current_user.nil? %>
+
+ +

content_for, however, can also be used in helper modules.

+ +
module StorageHelper
+  def stored_content
+    content_for(:storage) || "Your storage is empty"
+  end
+end
+
+ +

This helper works just like normal helpers.

+ +
<%= stored_content %>
+
+ +

You can also use the yield syntax alongside an existing call to yield in a layout. For example:

+ +
<%# This is the layout %>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>My Website</title>
+  <%= yield :script %>
+</head>
+<body>
+  <%= yield %>
+</body>
+</html>
+
+ +

And now, we'll create a view that has a content_for call that creates the script identifier.

+ +
<%# This is our view %>
+Please login!
+
+<% content_for :script do %>
+  <script>alert('You are not authorized to view this page!')</script>
+<% end %>
+
+ +

Then, in another view, you could to do something like this:

+ +
<%= link_to 'Logout', action: 'logout', remote: true %>
+
+<% content_for :script do %>
+  <%= javascript_include_tag :defaults %>
+<% end %>
+
+ +

That will place script tags for your default set of JavaScript files on the page; this technique is useful if you'll only be using these scripts in a few views.

+ +

Note that content_for concatenates (default) the blocks it is given for a particular identifier in order. For example:

+ +
 <% content_for :navigation do %>
+   <li><%= link_to 'Home', action: 'index' %></li>
+ <% end %>
+
+And in another place:
+
+ <% content_for :navigation do %>
+   <li><%= link_to 'Login', action: 'login' %></li>
+ <% end %>
+
+ +

Then, in another template or layout, this code would render both links in order:

+ +
<ul><%= content_for :navigation %></ul>
+
+ +

If the flush parameter is true content_for replaces the blocks it is given. For example:

+ +
<% content_for :navigation do %>
+  <li><%= link_to 'Home', action: 'index' %></li>
+<% end %>
+
+<%#  Add some other content, or use a different template: %>
+
+<% content_for :navigation, flush: true do %>
+  <li><%= link_to 'Login', action: 'login' %></li>
+<% end %>
+
+ +

Then, in another template or layout, this code would render only the last link:

+ +
<ul><%= content_for :navigation %></ul>
+
+ +

Lastly, simple content can be passed as a parameter:

+ +
<% content_for :script, javascript_include_tag(:defaults) %>
+
+ +

WARNING: content_for is ignored in caches. So you shouldn't use it for elements that will be fragment cached.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/capture_helper.rb, line 151
+def content_for(name, content = nil, options = {}, &block)
+  if content || block_given?
+    if block_given?
+      options = content if content
+      content = capture(&block)
+    end
+    if content
+      options[:flush] ? @view_flow.set(name, content) : @view_flow.append(name, content)
+    end
+    nil
+  else
+    @view_flow.get(name).presence
+  end
+end
+
+
+ +
+ +
+

+ + content_for?(name) + +

+ + +
+

content_for? checks whether any content has been captured yet using content_for. Useful to render parts of your layout differently based on what is in your views.

+ +
<%# This is the layout %>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>My Website</title>
+  <%= yield :script %>
+</head>
+<body class="<%= content_for?(:right_col) ? 'two-column' : 'one-column' %>">
+  <%= yield %>
+  <%= yield :right_col %>
+</body>
+</html>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/capture_helper.rb, line 191
+def content_for?(name)
+  @view_flow.get(name).present?
+end
+
+
+ +
+ +
+

+ + provide(name, content = nil, &block) + +

+ + +
+

The same as content_for but when used with streaming flushes straight back to the layout. In other words, if you want to concatenate several times to the same buffer when rendering a given template, you should use content_for, if not, use provide to tell the layout to stop looking for more contents.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/capture_helper.rb, line 171
+def provide(name, content = nil, &block)
+  content = capture(&block) if block_given?
+  result = @view_flow.append!(name, content) if content
+  result unless content
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/CspHelper.html b/src/5.2/classes/ActionView/Helpers/CspHelper.html new file mode 100644 index 0000000000..612619a5fc --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/CspHelper.html @@ -0,0 +1,110 @@ +--- +title: ActionView::Helpers::CspHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + csp_meta_tag() + +

+ + +
+

Returns a meta tag “csp-nonce” with the per-session nonce value for allowing inline <script> tags.

+ +
<head>
+  <%= csp_meta_tag %>
+</head>
+
+ +

This is used by the Rails UJS helper to create dynamically loaded inline <script> elements.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/csp_helper.rb, line 17
+def csp_meta_tag
+  if content_security_policy?
+    tag("meta", name: "csp-nonce", content: content_security_policy_nonce)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/CsrfHelper.html b/src/5.2/classes/ActionView/Helpers/CsrfHelper.html new file mode 100644 index 0000000000..61de04833d --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/CsrfHelper.html @@ -0,0 +1,149 @@ +--- +title: ActionView::Helpers::CsrfHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + csrf_meta_tag() + +

+ + +
+

For backwards compatibility.

+
+ + + + + +
+ Alias for: csrf_meta_tags +
+ + + +
+ +
+

+ + csrf_meta_tags() + +

+ + +
+

Returns meta tags “csrf-param” and “csrf-token” with the name of the cross-site request forgery protection parameter and token, respectively.

+ +
<head>
+  <%= csrf_meta_tags %>
+</head>
+
+ +

These are used to generate the dynamic forms that implement non-remote links with :method.

+ +

You don't need to use these tags for regular forms as they generate their own hidden fields.

+ +

For AJAX requests other than GETs, extract the “csrf-token” from the meta-tag and send as the “X-CSRF-Token” HTTP header. If you are using rails-ujs this happens automatically.

+
+ + + +
+ Also aliased as: csrf_meta_tag +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/csrf_helper.rb, line 22
+def csrf_meta_tags
+  if protect_against_forgery?
+    [
+      tag("meta", name: "csrf-param", content: request_forgery_protection_token),
+      tag("meta", name: "csrf-token", content: form_authenticity_token)
+    ].join("\n").html_safe
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/DateHelper.html b/src/5.2/classes/ActionView/Helpers/DateHelper.html new file mode 100644 index 0000000000..c189802ab7 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/DateHelper.html @@ -0,0 +1,1289 @@ +--- +title: ActionView::Helpers::DateHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Date Helpers

+ +

The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time elements. All of the select-type methods share a number of common options that are as follows:

+
  • +

    :prefix - overwrites the default prefix of “date” used for the select names. So specifying “birthday” would give birthday[month] instead of date[month] if passed to the select_month method.

    +
  • +

    :include_blank - set to true if it should be possible to set an empty date.

    +
  • +

    :discard_type - set to true if you want to discard the type part of the select name. If set to true, the select_month method would use simply “date” (which can be overwritten using :prefix) instead of date[month].

    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MINUTES_IN_QUARTER_YEAR=131400
 
MINUTES_IN_THREE_QUARTERS_YEAR=394200
 
MINUTES_IN_YEAR=525600
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + date_select(object_name, method, options = {}, html_options = {}) + +

+ + +
+

Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute (identified by method) on an object assigned to the template (identified by object).

+ +

Options

+
  • +

    :use_month_numbers - Set to true if you want to use month numbers rather than month names (e.g. “2” instead of “February”).

    +
  • +

    :use_two_digit_numbers - Set to true if you want to display two digit month and day numbers (e.g. “02” instead of “February” and “08” instead of “8”).

    +
  • +

    :use_short_month - Set to true if you want to use abbreviated month names instead of full month names (e.g. “Feb” instead of “February”).

    +
  • +

    :add_month_numbers - Set to true if you want to use both month numbers and month names (e.g. “2 - February” instead of “February”).

    +
  • +

    :use_month_names - Set to an array with 12 month names if you want to customize month names. Note: You can also use Rails' i18n functionality for this.

    +
  • +

    :month_format_string - Set to a format string. The string gets passed keys :number (integer) and :name (string). A format string would be something like “%{name} (%<number>02d)” for example. See Kernel.sprintf for documentation on format sequences.

    +
  • +

    :date_separator - Specifies a string to separate the date fields. Default is “” (i.e. nothing).

    +
  • +

    :time_separator - Specifies a string to separate the time fields. Default is “” (i.e. nothing).

    +
  • +

    :datetime_separator- Specifies a string to separate the date and time fields. Default is “” (i.e. nothing).

    +
  • +

    :start_year - Set the start year for the year select. Default is Date.today.year - 5 if you are creating new record. While editing existing record, :start_year defaults to the current selected year minus 5.

    +
  • +

    :end_year - Set the end year for the year select. Default is Date.today.year + 5 if you are creating new record. While editing existing record, :end_year defaults to the current selected year plus 5.

    +
  • +

    :discard_day - Set to true if you don't want to show a day select. This includes the day as a hidden field instead of showing a select field. Also note that this implicitly sets the day to be the first of the given month in order to not create invalid dates like 31 February.

    +
  • +

    :discard_month - Set to true if you don't want to show a month select. This includes the month as a hidden field instead of showing a select field. Also note that this implicitly sets :discard_day to true.

    +
  • +

    :discard_year - Set to true if you don't want to show a year select. This includes the year as a hidden field instead of showing a select field.

    +
  • +

    :order - Set to an array containing :day, :month and :year to customize the order in which the select fields are shown. If you leave out any of the symbols, the respective select will not be shown (like when you set discard_xxx: true. Defaults to the order defined in the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails).

    +
  • +

    :include_blank - Include a blank option in every select field so it's possible to set empty dates.

    +
  • +

    :default - Set a default date if the affected date isn't set or is nil.

    +
  • +

    :selected - Set a date that overrides the actual value.

    +
  • +

    :disabled - Set to true if you want show the select fields as disabled.

    +
  • +

    :prompt - Set to true (for a generic prompt), a prompt string or a hash of prompt strings for :year, :month, :day, :hour, :minute and :second. Setting this option prepends a select option with a generic prompt (Day, Month, Year, Hour, Minute, Seconds) or the given prompt string.

    +
  • +

    :with_css_classes - Set to true or a hash of strings. Use true if you want to assign generic styles for select tags. This automatically set classes 'year', 'month', 'day', 'hour', 'minute' and 'second'. A hash of strings for :year, :month, :day, :hour, :minute, :second will extend the select type with the given value. Use html_options to modify every select tag in the set.

    +
  • +

    :use_hidden - Set to true if you only want to generate hidden input tags.

    +
+ +

If anything is passed in the html_options hash it will be applied to every select tag in the set.

+ +

NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.

+ +
# Generates a date select that when POSTed is stored in the article variable, in the written_on attribute.
+date_select("article", "written_on")
+
+# Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
+# with the year in the year drop down box starting at 1995.
+date_select("article", "written_on", start_year: 1995)
+
+# Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
+# with the year in the year drop down box starting at 1995, numbers used for months instead of words,
+# and without a day select box.
+date_select("article", "written_on", start_year: 1995, use_month_numbers: true,
+                                  discard_day: true, include_blank: true)
+
+# Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
+# with two digit numbers used for months and days.
+date_select("article", "written_on", use_two_digit_numbers: true)
+
+# Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
+# with the fields ordered as day, month, year rather than month, day, year.
+date_select("article", "written_on", order: [:day, :month, :year])
+
+# Generates a date select that when POSTed is stored in the user variable, in the birthday attribute
+# lacking a year field.
+date_select("user", "birthday", order: [:month, :day])
+
+# Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
+# which is initially set to the date 3 days from the current date
+date_select("article", "written_on", default: 3.days.from_now)
+
+# Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
+# which is set in the form with today's date, regardless of the value in the Active Record object.
+date_select("article", "written_on", selected: Date.today)
+
+# Generates a date select that when POSTed is stored in the credit_card variable, in the bill_due attribute
+# that will have a default day of 20.
+date_select("credit_card", "bill_due", default: { day: 20 })
+
+# Generates a date select with custom prompts.
+date_select("article", "written_on", prompt: { day: 'Select day', month: 'Select month', year: 'Select year' })
+
+ +

The selects are prepared for multi-parameter assignment to an Active Record object.

+ +

Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month choices are valid.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 282
+def date_select(object_name, method, options = {}, html_options = {})
+  Tags::DateSelect.new(object_name, method, self, options, html_options).render
+end
+
+
+ +
+ +
+

+ + datetime_select(object_name, method, options = {}, html_options = {}) + +

+ + +
+

Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based attribute (identified by method) on an object assigned to the template (identified by object).

+ +

If anything is passed in the html_options hash it will be applied to every select tag in the set.

+ +
# Generates a datetime select that, when POSTed, will be stored in the article variable in the written_on
+# attribute.
+datetime_select("article", "written_on")
+
+# Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the
+# article variable in the written_on attribute.
+datetime_select("article", "written_on", start_year: 1995)
+
+# Generates a datetime select with a default value of 3 days from the current time that, when POSTed, will
+# be stored in the trip variable in the departing attribute.
+datetime_select("trip", "departing", default: 3.days.from_now)
+
+# Generate a datetime select with hours in the AM/PM format
+datetime_select("article", "written_on", ampm: true)
+
+# Generates a datetime select that discards the type that, when POSTed, will be stored in the article variable
+# as the written_on attribute.
+datetime_select("article", "written_on", discard_type: true)
+
+# Generates a datetime select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
+datetime_select("article", "written_on", prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
+datetime_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours
+datetime_select("article", "written_on", prompt: true) # generic prompts for all
+
+ +

The selects are prepared for multi-parameter assignment to an Active Record object.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 354
+def datetime_select(object_name, method, options = {}, html_options = {})
+  Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render
+end
+
+
+ +
+ +
+

+ + distance_of_time_in_words(from_time, to_time = 0, options = {}) + +

+ + +
+

Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds. Pass include_seconds: true if you want more detailed approximations when distance < 1 min, 29 secs. Distances are reported based on the following table:

+ +
0 <-> 29 secs                                                             # => less than a minute
+30 secs <-> 1 min, 29 secs                                                # => 1 minute
+1 min, 30 secs <-> 44 mins, 29 secs                                       # => [2..44] minutes
+44 mins, 30 secs <-> 89 mins, 29 secs                                     # => about 1 hour
+89 mins, 30 secs <-> 23 hrs, 59 mins, 29 secs                             # => about [2..24] hours
+23 hrs, 59 mins, 30 secs <-> 41 hrs, 59 mins, 29 secs                     # => 1 day
+41 hrs, 59 mins, 30 secs  <-> 29 days, 23 hrs, 59 mins, 29 secs           # => [2..29] days
+29 days, 23 hrs, 59 mins, 30 secs <-> 44 days, 23 hrs, 59 mins, 29 secs   # => about 1 month
+44 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs   # => about 2 months
+59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec                    # => [2..12] months
+1 yr <-> 1 yr, 3 months                                                   # => about 1 year
+1 yr, 3 months <-> 1 yr, 9 months                                         # => over 1 year
+1 yr, 9 months <-> 2 yr minus 1 sec                                       # => almost 2 years
+2 yrs <-> max time or date                                                # => (same rules as 1 yr)
+
+ +

With include_seconds: true and the difference < 1 minute 29 seconds:

+ +
0-4   secs      # => less than 5 seconds
+5-9   secs      # => less than 10 seconds
+10-19 secs      # => less than 20 seconds
+20-39 secs      # => half a minute
+40-59 secs      # => less than a minute
+60-89 secs      # => 1 minute
+
+from_time = Time.now
+distance_of_time_in_words(from_time, from_time + 50.minutes)                                # => about 1 hour
+distance_of_time_in_words(from_time, 50.minutes.from_now)                                   # => about 1 hour
+distance_of_time_in_words(from_time, from_time + 15.seconds)                                # => less than a minute
+distance_of_time_in_words(from_time, from_time + 15.seconds, include_seconds: true)         # => less than 20 seconds
+distance_of_time_in_words(from_time, 3.years.from_now)                                      # => about 3 years
+distance_of_time_in_words(from_time, from_time + 60.hours)                                  # => 3 days
+distance_of_time_in_words(from_time, from_time + 45.seconds, include_seconds: true)         # => less than a minute
+distance_of_time_in_words(from_time, from_time - 45.seconds, include_seconds: true)         # => less than a minute
+distance_of_time_in_words(from_time, 76.seconds.from_now)                                   # => 1 minute
+distance_of_time_in_words(from_time, from_time + 1.year + 3.days)                           # => about 1 year
+distance_of_time_in_words(from_time, from_time + 3.years + 6.months)                        # => over 3 years
+distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years
+
+to_time = Time.now + 6.years + 19.days
+distance_of_time_in_words(from_time, to_time, include_seconds: true)                        # => about 6 years
+distance_of_time_in_words(to_time, from_time, include_seconds: true)                        # => about 6 years
+distance_of_time_in_words(Time.now, Time.now)                                               # => less than a minute
+
+ +

With the scope option, you can define a custom scope for Rails to look up the translation.

+ +

For example you can define the following in your locale (e.g. en.yml).

+ +
datetime:
+  distance_in_words:
+    short:
+      about_x_hours:
+        one: 'an hour'
+        other: '%{count} hours'
+
+ +

See github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml for more examples.

+ +

Which will then result in the following:

+ +
from_time = Time.now
+distance_of_time_in_words(from_time, from_time + 50.minutes, scope: 'datetime.distance_in_words.short') # => "an hour"
+distance_of_time_in_words(from_time, from_time + 3.hours, scope: 'datetime.distance_in_words.short')    # => "3 hours"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 95
+def distance_of_time_in_words(from_time, to_time = 0, options = {})
+  options = {
+    scope: :'datetime.distance_in_words'
+  }.merge!(options)
+
+  from_time = normalize_distance_of_time_argument_to_time(from_time)
+  to_time = normalize_distance_of_time_argument_to_time(to_time)
+  from_time, to_time = to_time, from_time if from_time > to_time
+  distance_in_minutes = ((to_time - from_time) / 60.0).round
+  distance_in_seconds = (to_time - from_time).round
+
+  I18n.with_options locale: options[:locale], scope: options[:scope] do |locale|
+    case distance_in_minutes
+    when 0..1
+      return distance_in_minutes == 0 ?
+             locale.t(:less_than_x_minutes, count: 1) :
+             locale.t(:x_minutes, count: distance_in_minutes) unless options[:include_seconds]
+
+      case distance_in_seconds
+      when 0..4   then locale.t :less_than_x_seconds, count: 5
+      when 5..9   then locale.t :less_than_x_seconds, count: 10
+      when 10..19 then locale.t :less_than_x_seconds, count: 20
+      when 20..39 then locale.t :half_a_minute
+      when 40..59 then locale.t :less_than_x_minutes, count: 1
+      else             locale.t :x_minutes,           count: 1
+      end
+
+    when 2...45           then locale.t :x_minutes,      count: distance_in_minutes
+    when 45...90          then locale.t :about_x_hours,  count: 1
+      # 90 mins up to 24 hours
+    when 90...1440        then locale.t :about_x_hours,  count: (distance_in_minutes.to_f / 60.0).round
+      # 24 hours up to 42 hours
+    when 1440...2520      then locale.t :x_days,         count: 1
+      # 42 hours up to 30 days
+    when 2520...43200     then locale.t :x_days,         count: (distance_in_minutes.to_f / 1440.0).round
+      # 30 days up to 60 days
+    when 43200...86400    then locale.t :about_x_months, count: (distance_in_minutes.to_f / 43200.0).round
+      # 60 days up to 365 days
+    when 86400...525600   then locale.t :x_months,       count: (distance_in_minutes.to_f / 43200.0).round
+    else
+      from_year = from_time.year
+      from_year += 1 if from_time.month >= 3
+      to_year = to_time.year
+      to_year -= 1 if to_time.month < 3
+      leap_years = (from_year > to_year) ? 0 : (from_year..to_year).count { |x| Date.leap?(x) }
+      minute_offset_for_leap_year = leap_years * 1440
+      # Discount the leap year days when calculating year distance.
+      # e.g. if there are 20 leap year days between 2 dates having the same day
+      # and month then the based on 365 days calculation
+      # the distance in years will come out to over 80 years when in written
+      # English it would read better as about 80 years.
+      minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
+      remainder                   = (minutes_with_offset % MINUTES_IN_YEAR)
+      distance_in_years           = (minutes_with_offset.div MINUTES_IN_YEAR)
+      if remainder < MINUTES_IN_QUARTER_YEAR
+        locale.t(:about_x_years,  count: distance_in_years)
+      elsif remainder < MINUTES_IN_THREE_QUARTERS_YEAR
+        locale.t(:over_x_years,   count: distance_in_years)
+      else
+        locale.t(:almost_x_years, count: distance_in_years + 1)
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + distance_of_time_in_words_to_now(from_time, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: time_ago_in_words +
+ + + +
+ +
+

+ + select_date(date = Date.current, options = {}, html_options = {}) + +

+ + +
+

Returns a set of HTML select-tags (one for year, month, and day) pre-selected with the date. It's possible to explicitly set the order of the tags using the :order option with an array of symbols :year, :month and :day in the desired order. If the array passed to the :order option does not contain all the three symbols, all tags will be hidden.

+ +

If anything is passed in the html_options hash it will be applied to every select tag in the set.

+ +
my_date = Time.now + 6.days
+
+# Generates a date select that defaults to the date in my_date (six days after today).
+select_date(my_date)
+
+# Generates a date select that defaults to today (no specified date).
+select_date()
+
+# Generates a date select that defaults to the date in my_date (six days after today)
+# with the fields ordered year, month, day rather than month, day, year.
+select_date(my_date, order: [:year, :month, :day])
+
+# Generates a date select that discards the type of the field and defaults to the date in
+# my_date (six days after today).
+select_date(my_date, discard_type: true)
+
+# Generates a date select that defaults to the date in my_date,
+# which has fields separated by '/'.
+select_date(my_date, date_separator: '/')
+
+# Generates a date select that defaults to the datetime in my_date (six days after today)
+# prefixed with 'payday' rather than 'date'.
+select_date(my_date, prefix: 'payday')
+
+# Generates a date select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
+select_date(my_date, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
+select_date(my_date, prompt: {hour: true}) # generic prompt for hours
+select_date(my_date, prompt: true) # generic prompts for all
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 442
+def select_date(date = Date.current, options = {}, html_options = {})
+  DateTimeSelector.new(date, options, html_options).select_date
+end
+
+
+ +
+ +
+

+ + select_datetime(datetime = Time.current, options = {}, html_options = {}) + +

+ + +
+

Returns a set of HTML select-tags (one for year, month, day, hour, minute, and second) pre-selected with the datetime. It's also possible to explicitly set the order of the tags using the :order option with an array of symbols :year, :month and :day in the desired order. If you do not supply a Symbol, it will be appended onto the :order passed in. You can also add :date_separator, :datetime_separator and :time_separator keys to the options to control visual display of the elements.

+ +

If anything is passed in the html_options hash it will be applied to every select tag in the set.

+ +
my_date_time = Time.now + 4.days
+
+# Generates a datetime select that defaults to the datetime in my_date_time (four days after today).
+select_datetime(my_date_time)
+
+# Generates a datetime select that defaults to today (no specified datetime)
+select_datetime()
+
+# Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
+# with the fields ordered year, month, day rather than month, day, year.
+select_datetime(my_date_time, order: [:year, :month, :day])
+
+# Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
+# with a '/' between each date field.
+select_datetime(my_date_time, date_separator: '/')
+
+# Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
+# with a date fields separated by '/', time fields separated by '' and the date and time fields
+# separated by a comma (',').
+select_datetime(my_date_time, date_separator: '/', time_separator: '', datetime_separator: ',')
+
+# Generates a datetime select that discards the type of the field and defaults to the datetime in
+# my_date_time (four days after today)
+select_datetime(my_date_time, discard_type: true)
+
+# Generate a datetime field with hours in the AM/PM format
+select_datetime(my_date_time, ampm: true)
+
+# Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
+# prefixed with 'payday' rather than 'date'
+select_datetime(my_date_time, prefix: 'payday')
+
+# Generates a datetime select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
+select_datetime(my_date_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
+select_datetime(my_date_time, prompt: {hour: true}) # generic prompt for hours
+select_datetime(my_date_time, prompt: true) # generic prompts for all
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 403
+def select_datetime(datetime = Time.current, options = {}, html_options = {})
+  DateTimeSelector.new(datetime, options, html_options).select_datetime
+end
+
+
+ +
+ +
+

+ + select_day(date, options = {}, html_options = {}) + +

+ + +
+

Returns a select tag with options for each of the days 1 through 31 with the current day selected. The date can also be substituted for a day number. If you want to display days with a leading zero set the :use_two_digit_numbers key in options to true. Override the field name using the :field_name option, 'day' by default.

+ +
my_date = Time.now + 2.days
+
+# Generates a select field for days that defaults to the day for the date in my_date.
+select_day(my_date)
+
+# Generates a select field for days that defaults to the number given.
+select_day(5)
+
+# Generates a select field for days that defaults to the number given, but displays it with two digits.
+select_day(5, use_two_digit_numbers: true)
+
+# Generates a select field for days that defaults to the day for the date in my_date
+# that is named 'due' rather than 'day'.
+select_day(my_date, field_name: 'due')
+
+# Generates a select field for days with a custom prompt. Use <tt>prompt: true</tt> for a
+# generic prompt.
+select_day(5, prompt: 'Choose day')
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 585
+def select_day(date, options = {}, html_options = {})
+  DateTimeSelector.new(date, options, html_options).select_day
+end
+
+
+ +
+ +
+

+ + select_hour(datetime, options = {}, html_options = {}) + +

+ + +
+

Returns a select tag with options for each of the hours 0 through 23 with the current hour selected. The datetime can be either a Time or DateTime object or an integer. Override the field name using the :field_name option, 'hour' by default.

+ +
my_time = Time.now + 6.hours
+
+# Generates a select field for hours that defaults to the hour for the time in my_time.
+select_hour(my_time)
+
+# Generates a select field for hours that defaults to the number given.
+select_hour(13)
+
+# Generates a select field for hours that defaults to the hour for the time in my_time
+# that is named 'stride' rather than 'hour'.
+select_hour(my_time, field_name: 'stride')
+
+# Generates a select field for hours with a custom prompt. Use <tt>prompt: true</tt> for a
+# generic prompt.
+select_hour(13, prompt: 'Choose hour')
+
+# Generate a select field for hours in the AM/PM format
+select_hour(my_time, ampm: true)
+
+# Generates a select field that includes options for hours from 2 to 14.
+select_hour(my_time, start_hour: 2, end_hour: 14)
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 558
+def select_hour(datetime, options = {}, html_options = {})
+  DateTimeSelector.new(datetime, options, html_options).select_hour
+end
+
+
+ +
+ +
+

+ + select_minute(datetime, options = {}, html_options = {}) + +

+ + +
+

Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected. Also can return a select tag with options by minute_step from 0 through 59 with the 00 minute selected. The datetime can be either a Time or DateTime object or an integer. Override the field name using the :field_name option, 'minute' by default.

+ +
my_time = Time.now + 10.minutes
+
+# Generates a select field for minutes that defaults to the minutes for the time in my_time.
+select_minute(my_time)
+
+# Generates a select field for minutes that defaults to the number given.
+select_minute(14)
+
+# Generates a select field for minutes that defaults to the minutes for the time in my_time
+# that is named 'moment' rather than 'minute'.
+select_minute(my_time, field_name: 'moment')
+
+# Generates a select field for minutes with a custom prompt. Use <tt>prompt: true</tt> for a
+# generic prompt.
+select_minute(14, prompt: 'Choose minutes')
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 529
+def select_minute(datetime, options = {}, html_options = {})
+  DateTimeSelector.new(datetime, options, html_options).select_minute
+end
+
+
+ +
+ +
+

+ + select_month(date, options = {}, html_options = {}) + +

+ + +
+

Returns a select tag with options for each of the months January through December with the current month selected. The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are used as values (what's submitted to the server). It's also possible to use month numbers for the presentation instead of names – set the :use_month_numbers key in options to true for this to happen. If you want both numbers and names, set the :add_month_numbers key in options to true. If you would prefer to show month names as abbreviations, set the :use_short_month key in options to true. If you want to use your own month names, set the :use_month_names key in options to an array of 12 month names. If you want to display months with a leading zero set the :use_two_digit_numbers key in options to true. Override the field name using the :field_name option, 'month' by default.

+ +
# Generates a select field for months that defaults to the current month that
+# will use keys like "January", "March".
+select_month(Date.today)
+
+# Generates a select field for months that defaults to the current month that
+# is named "start" rather than "month".
+select_month(Date.today, field_name: 'start')
+
+# Generates a select field for months that defaults to the current month that
+# will use keys like "1", "3".
+select_month(Date.today, use_month_numbers: true)
+
+# Generates a select field for months that defaults to the current month that
+# will use keys like "1 - January", "3 - March".
+select_month(Date.today, add_month_numbers: true)
+
+# Generates a select field for months that defaults to the current month that
+# will use keys like "Jan", "Mar".
+select_month(Date.today, use_short_month: true)
+
+# Generates a select field for months that defaults to the current month that
+# will use keys like "Januar", "Marts."
+select_month(Date.today, use_month_names: %w(Januar Februar Marts ...))
+
+# Generates a select field for months that defaults to the current month that
+# will use keys with two digit numbers like "01", "03".
+select_month(Date.today, use_two_digit_numbers: true)
+
+# Generates a select field for months with a custom prompt. Use <tt>prompt: true</tt> for a
+# generic prompt.
+select_month(14, prompt: 'Choose month')
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 630
+def select_month(date, options = {}, html_options = {})
+  DateTimeSelector.new(date, options, html_options).select_month
+end
+
+
+ +
+ +
+

+ + select_second(datetime, options = {}, html_options = {}) + +

+ + +
+

Returns a select tag with options for each of the seconds 0 through 59 with the current second selected. The datetime can be either a Time or DateTime object or an integer. Override the field name using the :field_name option, 'second' by default.

+ +
my_time = Time.now + 16.seconds
+
+# Generates a select field for seconds that defaults to the seconds for the time in my_time.
+select_second(my_time)
+
+# Generates a select field for seconds that defaults to the number given.
+select_second(33)
+
+# Generates a select field for seconds that defaults to the seconds for the time in my_time
+# that is named 'interval' rather than 'second'.
+select_second(my_time, field_name: 'interval')
+
+# Generates a select field for seconds with a custom prompt. Use <tt>prompt: true</tt> for a
+# generic prompt.
+select_second(14, prompt: 'Choose seconds')
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 505
+def select_second(datetime, options = {}, html_options = {})
+  DateTimeSelector.new(datetime, options, html_options).select_second
+end
+
+
+ +
+ +
+

+ + select_time(datetime = Time.current, options = {}, html_options = {}) + +

+ + +
+

Returns a set of HTML select-tags (one for hour and minute). You can set :time_separator key to format the output, and the :include_seconds option to include an input for seconds.

+ +

If anything is passed in the html_options hash it will be applied to every select tag in the set.

+ +
my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds
+
+# Generates a time select that defaults to the time in my_time.
+select_time(my_time)
+
+# Generates a time select that defaults to the current time (no specified time).
+select_time()
+
+# Generates a time select that defaults to the time in my_time,
+# which has fields separated by ':'.
+select_time(my_time, time_separator: ':')
+
+# Generates a time select that defaults to the time in my_time,
+# that also includes an input for seconds.
+select_time(my_time, include_seconds: true)
+
+# Generates a time select that defaults to the time in my_time, that has fields
+# separated by ':' and includes an input for seconds.
+select_time(my_time, time_separator: ':', include_seconds: true)
+
+# Generate a time select field with hours in the AM/PM format
+select_time(my_time, ampm: true)
+
+# Generates a time select field with hours that range from 2 to 14
+select_time(my_time, start_hour: 2, end_hour: 14)
+
+# Generates a time select with a custom prompt. Use <tt>:prompt</tt> to true for generic prompts.
+select_time(my_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
+select_time(my_time, prompt: {hour: true}) # generic prompt for hours
+select_time(my_time, prompt: true) # generic prompts for all
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 482
+def select_time(datetime = Time.current, options = {}, html_options = {})
+  DateTimeSelector.new(datetime, options, html_options).select_time
+end
+
+
+ +
+ +
+

+ + select_year(date, options = {}, html_options = {}) + +

+ + +
+

Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius can be changed using the :start_year and :end_year keys in the options. Both ascending and descending year lists are supported by making :start_year less than or greater than :end_year. The date can also be substituted for a year given as a number. Override the field name using the :field_name option, 'year' by default.

+ +
# Generates a select field for years that defaults to the current year that
+# has ascending year values.
+select_year(Date.today, start_year: 1992, end_year: 2007)
+
+# Generates a select field for years that defaults to the current year that
+# is named 'birth' rather than 'year'.
+select_year(Date.today, field_name: 'birth')
+
+# Generates a select field for years that defaults to the current year that
+# has descending year values.
+select_year(Date.today, start_year: 2005, end_year: 1900)
+
+# Generates a select field for years that defaults to the year 2006 that
+# has ascending year values.
+select_year(2006, start_year: 2000, end_year: 2010)
+
+# Generates a select field for years with a custom prompt. Use <tt>prompt: true</tt> for a
+# generic prompt.
+select_year(14, prompt: 'Choose year')
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 659
+def select_year(date, options = {}, html_options = {})
+  DateTimeSelector.new(date, options, html_options).select_year
+end
+
+
+ +
+ +
+

+ + time_ago_in_words(from_time, options = {}) + +

+ + +
+

Like distance_of_time_in_words, but where to_time is fixed to Time.now.

+ +
time_ago_in_words(3.minutes.from_now)                 # => 3 minutes
+time_ago_in_words(3.minutes.ago)                      # => 3 minutes
+time_ago_in_words(Time.now - 15.hours)                # => about 15 hours
+time_ago_in_words(Time.now)                           # => less than a minute
+time_ago_in_words(Time.now, include_seconds: true) # => less than 5 seconds
+
+from_time = Time.now - 3.days - 14.minutes - 25.seconds
+time_ago_in_words(from_time)      # => 3 days
+
+from_time = (3.days + 14.minutes + 25.seconds).ago
+time_ago_in_words(from_time)      # => 3 days
+
+ +

Note that you cannot pass a Numeric value to time_ago_in_words.

+
+ + + +
+ Also aliased as: distance_of_time_in_words_to_now +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 176
+def time_ago_in_words(from_time, options = {})
+  distance_of_time_in_words(from_time, Time.now, options)
+end
+
+
+ +
+ +
+

+ + time_select(object_name, method, options = {}, html_options = {}) + +

+ + +
+

Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a specified time-based attribute (identified by method) on an object assigned to the template (identified by object). You can include the seconds with :include_seconds. You can get hours in the AM/PM format with :ampm option.

+ +

This method will also generate 3 input hidden tags, for the actual year, month and day unless the option :ignore_date is set to true. If you set the :ignore_date to true, you must have a date_select on the same method within the form otherwise an exception will be raised.

+ +

If anything is passed in the html_options hash it will be applied to every select tag in the set.

+ +
# Creates a time select tag that, when POSTed, will be stored in the article variable in the sunrise attribute.
+time_select("article", "sunrise")
+
+# Creates a time select tag with a seconds field that, when POSTed, will be stored in the article variables in
+# the sunrise attribute.
+time_select("article", "start_time", include_seconds: true)
+
+# You can set the <tt>:minute_step</tt> to 15 which will give you: 00, 15, 30, and 45.
+time_select 'game', 'game_time', {minute_step: 15}
+
+# Creates a time select tag with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
+time_select("article", "written_on", prompt: {hour: 'Choose hour', minute: 'Choose minute', second: 'Choose seconds'})
+time_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours
+time_select("article", "written_on", prompt: true) # generic prompts for all
+
+# You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
+time_select 'game', 'game_time', {ampm: true}
+
+ +

The selects are prepared for multi-parameter assignment to an Active Record object.

+ +

Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month choices are valid.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 319
+def time_select(object_name, method, options = {}, html_options = {})
+  Tags::TimeSelect.new(object_name, method, self, options, html_options).render
+end
+
+
+ +
+ +
+

+ + time_tag(date_or_time, *args, &block) + +

+ + +
+

Returns an HTML time tag for the given date or time.

+ +
time_tag Date.today  # =>
+  <time datetime="2010-11-04">November 04, 2010</time>
+time_tag Time.now  # =>
+  <time datetime="2010-11-04T17:55:45+01:00">November 04, 2010 17:55</time>
+time_tag Date.yesterday, 'Yesterday'  # =>
+  <time datetime="2010-11-03">Yesterday</time>
+time_tag Date.today, pubdate: true  # =>
+  <time datetime="2010-11-04" pubdate="pubdate">November 04, 2010</time>
+time_tag Date.today, datetime: Date.today.strftime('%G-W%V') # =>
+  <time datetime="2010-W44">November 04, 2010</time>
+
+<%= time_tag Time.now do %>
+  <span>Right now</span>
+<% end %>
+# => <time datetime="2010-11-04T17:55:45+01:00"><span>Right now</span></time>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 680
+def time_tag(date_or_time, *args, &block)
+  options  = args.extract_options!
+  format   = options.delete(:format) || :long
+  content  = args.first || I18n.l(date_or_time, format: format)
+  datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.iso8601
+
+  content_tag("time".freeze, content, options.reverse_merge(datetime: datetime), &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/DebugHelper.html b/src/5.2/classes/ActionView/Helpers/DebugHelper.html new file mode 100644 index 0000000000..ae000e50a2 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/DebugHelper.html @@ -0,0 +1,133 @@ +--- +title: ActionView::Helpers::DebugHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + debug(object) + +

+ + +
+

Returns a YAML representation of object wrapped with <pre> and </pre>. If the object cannot be converted to YAML using to_yaml, inspect will be called instead. Useful for inspecting an object at the time of rendering.

+ +
@user = User.new({ username: 'testing', password: 'xyz', age: 42})
+debug(@user)
+# =>
+<pre class='debug_dump'>--- !ruby/object:User
+attributes:
+  updated_at:
+  username: testing
+  age: 42
+  password: xyz
+  created_at:
+</pre>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/debug_helper.rb, line 26
+def debug(object)
+  Marshal.dump(object)
+  object = ERB::Util.html_escape(object.to_yaml)
+  content_tag(:pre, object, class: "debug_dump")
+rescue # errors from Marshal or YAML
+  # Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback
+  content_tag(:code, object.inspect, class: "debug_dump")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/FormBuilder.html b/src/5.2/classes/ActionView/Helpers/FormBuilder.html new file mode 100644 index 0000000000..68251438a7 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/FormBuilder.html @@ -0,0 +1,1653 @@ +--- +title: ActionView::Helpers::FormBuilder +layout: default +--- +
+ +
+
+ +
+ +

A FormBuilder object is associated with a particular model object and allows you to generate fields associated with the model object. The FormBuilder object is yielded when using form_for or fields_for. For example:

+ +
<%= form_for @person do |person_form| %>
+  Name: <%= person_form.text_field :name %>
+  Admin: <%= person_form.check_box :admin %>
+<% end %>
+
+ +

In the above block, a FormBuilder object is yielded as the person_form variable. This allows you to generate the text_field and check_box fields by specifying their eponymous methods, which modify the underlying template and associates the @person model object with the form.

+ +

The FormBuilder object can be thought of as serving as a proxy for the methods in the FormHelper module. This class, however, allows you to call methods with the model object you are building the form for.

+ +

You can create your own custom FormBuilder templates by subclassing this class. For example:

+ +
class MyFormBuilder < ActionView::Helpers::FormBuilder
+  def div_radio_button(method, tag_value, options = {})
+    @template.content_tag(:div,
+      @template.radio_button(
+        @object_name, method, tag_value, objectify_options(options)
+      )
+    )
+  end
+end
+
+ +

The above code creates a new method div_radio_button which wraps a div around the new radio button. Note that when options are passed in, you must call objectify_options in order for the model object to get correctly passed to the method. If objectify_options is not called, then the newly created helper will not be linked back to the model.

+ +

The div_radio_button code from above can now be used as follows:

+ +
<%= form_for @person, :builder => MyFormBuilder do |f| %>
+  I am a child: <%= f.div_radio_button(:admin, "child") %>
+  I am an adult: <%= f.div_radio_button(:admin, "adult") %>
+<% end -%>
+
+ +

The standard set of helper methods for form building are located in the field_helpers class attribute.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + index
+ [R] + multipart
+ [R] + multipart?
+ [RW] + object
+ [RW] + object_name
+ [RW] + options
+ + + + +

Class Public methods

+ +
+

+ + _to_partial_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1645
+def self._to_partial_path
+  @_to_partial_path ||= name.demodulize.underscore.sub!(/_builder$/, "")
+end
+
+
+ +
+ +
+

+ + new(object_name, object, template, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1657
+def initialize(object_name, object, template, options)
+  @nested_child_index = {}
+  @object_name, @object, @template, @options = object_name, object, template, options
+  @default_options = @options ? @options.slice(:index, :namespace, :skip_default_ids, :allow_method_names_outside_object) : {}
+  @default_html_options = @default_options.except(:skip_default_ids, :allow_method_names_outside_object)
+
+  convert_to_legacy_options(@options)
+
+  if @object_name.to_s.match(/\[\]$/)
+    if (object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}")) && object.respond_to?(:to_param)
+      @auto_index = object.to_param
+    else
+      raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
+    end
+  end
+
+  @multipart = nil
+  @index = options[:index] || options[:child_index]
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + button(value = nil, options = {}, &block) + +

+ + +
+

Add the submit button for the given form. When no value is given, it checks if the object is a new resource or not to create the proper label:

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

In the example above, if @post is a new record, it will use “Create Post” as button label; otherwise, it uses “Update Post”.

+ +

Those labels can be customized using I18n under the helpers.submit key (the same as submit helper) and using %{model} for translation interpolation:

+ +
en:
+  helpers:
+    submit:
+      create: "Create a %{model}"
+      update: "Confirm changes to %{model}"
+
+ +

It also searches for a key specific to the given object:

+ +
en:
+  helpers:
+    submit:
+      post:
+        create: "Add %{model}"
+
+ +

Examples

+ +
button("Create post")
+# => <button name='button' type='submit'>Create post</button>
+
+button do
+  content_tag(:strong, 'Ask me!')
+end
+# => <button name='button' type='submit'>
+#      <strong>Ask me!</strong>
+#    </button>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2244
+def button(value = nil, options = {}, &block)
+  value, options = nil, value if value.is_a?(Hash)
+  value ||= submit_default_value
+  @template.button_tag(value, options, &block)
+end
+
+
+ +
+ +
+

+ + check_box(method, options = {}, checked_value = "1", unchecked_value = "0") + +

+ + +
+

Returns a checkbox tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). This object must be an instance object (@object) and not a local object. It's intended that method returns an integer and if that integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a hash with options. The checked_value defaults to 1 while the default unchecked_value is set to 0 which is convenient for boolean values.

+ +

Gotcha

+ +

The HTML specification says unchecked check boxes are not successful, and thus web browsers do not send them. Unfortunately this introduces a gotcha: if an Invoice model has a paid flag, and in the form that edits a paid invoice the user unchecks its check box, no paid parameter is sent. So, any mass-assignment idiom like

+ +
@invoice.update(params[:invoice])
+
+ +

wouldn't update the flag.

+ +

To prevent this the helper generates an auxiliary hidden field before the very check box. The hidden field has the same name and its attributes mimic an unchecked check box.

+ +

This way, the client either sends only the hidden field (representing the check box is unchecked), or both fields. Since the HTML specification says key/value pairs have to be sent in the same order they appear in the form, and parameters extraction gets the last occurrence of any repeated key in the query string, that works for ordinary forms.

+ +

Unfortunately that workaround does not work when the check box goes within an array-like parameter, as in

+ +
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
+  <%= form.check_box :paid %>
+  ...
+<% end %>
+
+ +

because parameter name repetition is precisely what Rails seeks to distinguish the elements of the array. For each item with a checked check box you get an extra ghost item with only that attribute, assigned to “0”.

+ +

In that case it is preferable to either use check_box_tag or to use hashes instead of arrays.

+ +
# Let's say that @post.validated? is 1:
+check_box("validated")
+# => <input name="post[validated]" type="hidden" value="0" />
+#    <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />
+
+# Let's say that @puppy.gooddog is "no":
+check_box("gooddog", {}, "yes", "no")
+# => <input name="puppy[gooddog]" type="hidden" value="no" />
+#    <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
+
+# Let's say that @eula.accepted is "no":
+check_box("accepted", { class: 'eula_check' }, "yes", "no")
+# => <input name="eula[accepted]" type="hidden" value="no" />
+#    <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2086
+def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
+  @template.check_box(@object_name, method, objectify_options(options), checked_value, unchecked_value)
+end
+
+
+ +
+ +
+

+ + collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block) + +

+ + +
+

Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders:

+ +
<%= form_for @post do |f| %>
+  <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 870
+def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
+  @template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
+end
+
+
+ +
+ +
+

+ + collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block) + +

+ + +
+

Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders:

+ +
<%= form_for @post do |f| %>
+  <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 882
+def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
+  @template.collection_radio_buttons(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
+end
+
+
+ +
+ +
+

+ + collection_select(method, collection, value_method, text_method, options = {}, html_options = {}) + +

+ + +
+

Wraps ActionView::Helpers::FormOptionsHelper#collection_select for form builders:

+ +
<%= form_for @post do |f| %>
+  <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 834
+def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
+  @template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options))
+end
+
+
+ +
+ +
+

+ + date_select(method, options = {}, html_options = {}) + +

+ + +
+

Wraps ActionView::Helpers::DateHelper#date_select for form builders:

+ +
<%= form_for @person do |f| %>
+  <%= f.date_select :birth_date %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 1127
+def date_select(method, options = {}, html_options = {})
+  @template.date_select(@object_name, method, objectify_options(options), html_options)
+end
+
+
+ +
+ +
+

+ + datetime_select(method, options = {}, html_options = {}) + +

+ + +
+

Wraps ActionView::Helpers::DateHelper#datetime_select for form builders:

+ +
<%= form_for @person do |f| %>
+  <%= f.datetime_select :last_request_at %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 1151
+def datetime_select(method, options = {}, html_options = {})
+  @template.datetime_select(@object_name, method, objectify_options(options), html_options)
+end
+
+
+ +
+ +
+

+ + emitted_hidden_id?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2250
+def emitted_hidden_id?
+  @emitted_hidden_id ||= nil
+end
+
+
+ +
+ +
+

+ + fields(scope = nil, model: nil, **options, &block) + +

+ + +
+

See the docs for the ActionView::FormHelper.fields helper method.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1968
+def fields(scope = nil, model: nil, **options, &block)
+  options[:allow_method_names_outside_object] = true
+  options[:skip_default_ids] = !FormHelper.form_with_generates_ids
+
+  convert_to_legacy_options(options)
+
+  fields_for(scope || model, model, options, &block)
+end
+
+
+ +
+ +
+

+ + fields_for(record_name, record_object = nil, fields_options = {}, &block) + +

+ + +
+

Creates a scope around a specific model object like form_for, but doesn't create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form.

+ +

Although the usage and purpose of fields_for is similar to form_for's, its method signature is slightly different. Like form_for, it yields a FormBuilder object associated with a particular model object to a block, and within the block allows methods to be called on the builder to generate fields associated with the model object. Fields may reflect a model object in two ways - how they are named (hence how submitted values appear within the params hash in the controller) and what default values are shown when the form the fields appear in is first displayed. In order for both of these features to be specified independently, both an object name (represented by either a symbol or string) and the object itself can be passed to the method separately -

+ +
<%= form_for @person do |person_form| %>
+  First name: <%= person_form.text_field :first_name %>
+  Last name : <%= person_form.text_field :last_name %>
+
+  <%= fields_for :permission, @person.permission do |permission_fields| %>
+    Admin?  : <%= permission_fields.check_box :admin %>
+  <% end %>
+
+  <%= person_form.submit %>
+<% end %>
+
+ +

In this case, the checkbox field will be represented by an HTML input tag with the name attribute permission[admin], and the submitted value will appear in the controller as params[:permission][:admin]. If @person.permission is an existing record with an attribute admin, the initial state of the checkbox when first displayed will reflect the value of @person.permission.admin.

+ +

Often this can be simplified by passing just the name of the model object to fields_for -

+ +
<%= fields_for :permission do |permission_fields| %>
+  Admin?: <%= permission_fields.check_box :admin %>
+<% end %>
+
+ +

…in which case, if :permission also happens to be the name of an instance variable @permission, the initial state of the input field will reflect the value of that variable's attribute @permission.admin.

+ +

Alternatively, you can pass just the model object itself (if the first argument isn't a string or symbol fields_for will realize that the name has been omitted) -

+ +
<%= fields_for @person.permission do |permission_fields| %>
+  Admin?: <%= permission_fields.check_box :admin %>
+<% end %>
+
+ +

and fields_for will derive the required name of the field from the class of the model object, e.g. if @person.permission, is of class Permission, the field will still be named permission[admin].

+ +

Note: This also works for the methods in FormOptionsHelper and DateHelper that are designed to work with an object as base, like FormOptionsHelper#collection_select and DateHelper#datetime_select.

+ +

Nested Attributes Examples

+ +

When the object belonging to the current scope has a nested attribute writer for a certain attribute, fields_for will yield a new scope for that attribute. This allows you to create forms that set or change the attributes of a parent object and its associations in one go.

+ +

Nested attribute writers are normal setter methods named after an association. The most common way of defining these writers is either with accepts_nested_attributes_for in a model definition or by defining a method with the proper name. For example: the attribute writer for the association :address is called address_attributes=.

+ +

Whether a one-to-one or one-to-many style form builder will be yielded depends on whether the normal reader method returns a single object or an array of objects.

+ +

One-to-one

+ +

Consider a Person class which returns a single Address from the address reader method and responds to the address_attributes= writer method:

+ +
class Person
+  def address
+    @address
+  end
+
+  def address_attributes=(attributes)
+    # Process the attributes hash
+  end
+end
+
+ +

This model can now be used with a nested fields_for, like so:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :address do |address_fields| %>
+    Street  : <%= address_fields.text_field :street %>
+    Zip code: <%= address_fields.text_field :zip_code %>
+  <% end %>
+  ...
+<% end %>
+
+ +

When address is already an association on a Person you can use accepts_nested_attributes_for to define the writer method for you:

+ +
class Person < ActiveRecord::Base
+  has_one :address
+  accepts_nested_attributes_for :address
+end
+
+ +

If you want to destroy the associated model through the form, you have to enable it first using the :allow_destroy option for accepts_nested_attributes_for:

+ +
class Person < ActiveRecord::Base
+  has_one :address
+  accepts_nested_attributes_for :address, allow_destroy: true
+end
+
+ +

Now, when you use a form element with the _destroy parameter, with a value that evaluates to true, you will destroy the associated model (eg. 1, '1', true, or 'true'):

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :address do |address_fields| %>
+    ...
+    Delete: <%= address_fields.check_box :_destroy %>
+  <% end %>
+  ...
+<% end %>
+
+ +

One-to-many

+ +

Consider a Person class which returns an array of Project instances from the projects reader method and responds to the projects_attributes= writer method:

+ +
class Person
+  def projects
+    [@project1, @project2]
+  end
+
+  def projects_attributes=(attributes)
+    # Process the attributes hash
+  end
+end
+
+ +

Note that the projects_attributes= writer method is in fact required for fields_for to correctly identify :projects as a collection, and the correct indices to be set in the form markup.

+ +

When projects is already an association on Person you can use accepts_nested_attributes_for to define the writer method for you:

+ +
class Person < ActiveRecord::Base
+  has_many :projects
+  accepts_nested_attributes_for :projects
+end
+
+ +

This model can now be used with a nested fields_for. The block given to the nested fields_for call will be repeated for each instance in the collection:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects do |project_fields| %>
+    <% if project_fields.object.active? %>
+      Name: <%= project_fields.text_field :name %>
+    <% end %>
+  <% end %>
+  ...
+<% end %>
+
+ +

It's also possible to specify the instance to be used:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <% @person.projects.each do |project| %>
+    <% if project.active? %>
+      <%= person_form.fields_for :projects, project do |project_fields| %>
+        Name: <%= project_fields.text_field :name %>
+      <% end %>
+    <% end %>
+  <% end %>
+  ...
+<% end %>
+
+ +

Or a collection to be used:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
+    Name: <%= project_fields.text_field :name %>
+  <% end %>
+  ...
+<% end %>
+
+ +

If you want to destroy any of the associated models through the form, you have to enable it first using the :allow_destroy option for accepts_nested_attributes_for:

+ +
class Person < ActiveRecord::Base
+  has_many :projects
+  accepts_nested_attributes_for :projects, allow_destroy: true
+end
+
+ +

This will allow you to specify which models to destroy in the attributes hash by adding a form element for the _destroy parameter with a value that evaluates to true (eg. 1, '1', true, or 'true'):

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects do |project_fields| %>
+    Delete: <%= project_fields.check_box :_destroy %>
+  <% end %>
+  ...
+<% end %>
+
+ +

When a collection is used you might want to know the index of each object into the array. For this purpose, the index method is available in the FormBuilder object.

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects do |project_fields| %>
+    Project #<%= project_fields.index %>
+    ...
+  <% end %>
+  ...
+<% end %>
+
+ +

Note that fields_for will automatically generate a hidden field to store the ID of the record. There are circumstances where this hidden field is not needed and you can pass include_id: false to prevent fields_for from rendering it automatically.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1930
+def fields_for(record_name, record_object = nil, fields_options = {}, &block)
+  fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
+  fields_options[:builder] ||= options[:builder]
+  fields_options[:namespace] = options[:namespace]
+  fields_options[:parent_builder] = self
+
+  case record_name
+  when String, Symbol
+    if nested_attributes_association?(record_name)
+      return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
+    end
+  else
+    record_object = record_name.is_a?(Array) ? record_name.last : record_name
+    record_name   = model_name_from_record_or_class(record_object).param_key
+  end
+
+  object_name = @object_name
+  index = if options.has_key?(:index)
+    options[:index]
+  elsif defined?(@auto_index)
+    object_name = object_name.to_s.sub(/\[\]$/, "")
+    @auto_index
+  end
+
+  record_name = if index
+    "#{object_name}[#{index}][#{record_name}]"
+  elsif record_name.to_s.end_with?("[]")
+    record_name = record_name.to_s.sub(/(.*)\[\]$/, "[\\1][#{record_object.id}]")
+    "#{object_name}#{record_name}"
+  else
+    "#{object_name}[#{record_name}]"
+  end
+  fields_options[:child_index] = index
+
+  @template.fields_for(record_name, record_object, fields_options, &block)
+end
+
+
+ +
+ +
+

+ + file_field(method, options = {}) + +

+ + +
+

Returns a file upload input tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

+ +

Using this method inside a form_for block will set the enclosing form's encoding to multipart/form-data.

+ +

Options

+
  • +

    Creates standard HTML attributes for the tag.

    +
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    :multiple - If set to true, *in most updated browsers* the user will be allowed to select multiple files.

    +
  • +

    :accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.

    +
+ +

Examples

+ +
# Let's say that @user has avatar:
+file_field(:avatar)
+# => <input type="file" id="user_avatar" name="user[avatar]" />
+
+# Let's say that @post has image:
+file_field(:image, :multiple => true)
+# => <input type="file" id="post_image" name="post[image][]" multiple="multiple" />
+
+# Let's say that @post has attached:
+file_field(:attached, accept: 'text/html')
+# => <input accept="text/html" type="file" id="post_attached" name="post[attached]" />
+
+# Let's say that @post has image:
+file_field(:image, accept: 'image/png,image/gif,image/jpeg')
+# => <input type="file" id="post_image" name="post[image]" accept="image/png,image/gif,image/jpeg" />
+
+# Let's say that @attachment has file:
+file_field(:file, class: 'file_input')
+# => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2168
+def file_field(method, options = {})
+  self.multipart = true
+  @template.file_field(@object_name, method, objectify_options(options))
+end
+
+
+ +
+ +
+

+ + grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) + +

+ + +
+

Wraps ActionView::Helpers::FormOptionsHelper#grouped_collection_select for form builders:

+ +
<%= form_for @city do |f| %>
+  <%= f.grouped_collection_select :country_id, @continents, :countries, :name, :id, :name %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 846
+def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
+  @template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_html_options.merge(html_options))
+end
+
+
+ +
+ +
+

+ + hidden_field(method, options = {}) + +

+ + +
+

Returns a hidden input tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

+ +

Examples

+ +
# Let's say that @signup.pass_confirm returns true:
+hidden_field(:pass_confirm)
+# => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="true" />
+
+# Let's say that @post.tag_list returns "blog, ruby":
+hidden_field(:tag_list)
+# => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="blog, ruby" />
+
+# Let's say that @user.token returns "abcde":
+hidden_field(:token)
+# => <input type="hidden" id="user_token" name="user[token]" value="abcde" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2130
+def hidden_field(method, options = {})
+  @emitted_hidden_id = true if method == :id
+  @template.hidden_field(@object_name, method, objectify_options(options))
+end
+
+
+ +
+ +
+

+ + label(method, text = nil, options = {}, &block) + +

+ + +
+

Returns a label tag tailored for labelling an input field for a specified attribute (identified by method) on an object assigned to the template (identified by object). The text of label will default to the attribute name unless a translation is found in the current I18n locale (through helpers.label.<modelname>.<attribute>) or you specify it explicitly. Additional options on the label tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to target labels for radio_button tags (where the value is used in the ID of the input tag).

+ +

Examples

+ +
label(:title)
+# => <label for="post_title">Title</label>
+
+ +

You can localize your labels based on model and attribute names. For example you can define the following in your locale (e.g. en.yml)

+ +
helpers:
+  label:
+    post:
+      body: "Write your entire text here"
+
+ +

Which then will result in

+ +
label(:body)
+# => <label for="post_body">Write your entire text here</label>
+
+ +

Localization can also be based purely on the translation of the attribute-name (if you are using ActiveRecord):

+ +
activerecord:
+  attributes:
+    post:
+      cost: "Total cost"
+
+label(:cost)
+# => <label for="post_cost">Total cost</label>
+
+label(:title, "A short title")
+# => <label for="post_title">A short title</label>
+
+label(:title, "A short title", class: "title_label")
+# => <label for="post_title" class="title_label">A short title</label>
+
+label(:privacy, "Public Post", value: "public")
+# => <label for="post_privacy_public">Public Post</label>
+
+label(:terms) do
+  raw('Accept <a href="/terms">Terms</a>.')
+end
+# => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2025
+def label(method, text = nil, options = {}, &block)
+  @template.label(@object_name, method, text, objectify_options(options), &block)
+end
+
+
+ +
+ +
+

+ + multipart=(multipart) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1637
+def multipart=(multipart)
+  @multipart = multipart
+
+  if parent_builder = @options[:parent_builder]
+    parent_builder.multipart = multipart
+  end
+end
+
+
+ +
+ +
+

+ + radio_button(method, tag_value, options = {}) + +

+ + +
+

Returns a radio button tag for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). If the current value of method is tag_value the radio button will be checked.

+ +

To force the radio button to be checked pass checked: true in the options hash. You may pass HTML options there as well.

+ +
# Let's say that @post.category returns "rails":
+radio_button("category", "rails")
+radio_button("category", "java")
+# => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
+#    <input type="radio" id="post_category_java" name="post[category]" value="java" />
+
+# Let's say that @user.receive_newsletter returns "no":
+radio_button("receive_newsletter", "yes")
+radio_button("receive_newsletter", "no")
+# => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
+#    <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2108
+def radio_button(method, tag_value, options = {})
+  @template.radio_button(@object_name, method, tag_value, objectify_options(options))
+end
+
+
+ +
+ +
+

+ + select(method, choices = nil, options = {}, html_options = {}, &block) + +

+ + +
+

Wraps ActionView::Helpers::FormOptionsHelper#select for form builders:

+ +
<%= form_for @post do |f| %>
+  <%= f.select :person_id, Person.all.collect { |p| [ p.name, p.id ] }, include_blank: true %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 822
+def select(method, choices = nil, options = {}, html_options = {}, &block)
+  @template.select(@object_name, method, choices, objectify_options(options), @default_html_options.merge(html_options), &block)
+end
+
+
+ +
+ +
+

+ + submit(value = nil, options = {}) + +

+ + +
+

Add the submit button for the given form. When no value is given, it checks if the object is a new resource or not to create the proper label:

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

In the example above, if @post is a new record, it will use “Create Post” as submit button label; otherwise, it uses “Update Post”.

+ +

Those labels can be customized using I18n under the helpers.submit key and using %{model} for translation interpolation:

+ +
en:
+  helpers:
+    submit:
+      create: "Create a %{model}"
+      update: "Confirm changes to %{model}"
+
+ +

It also searches for a key specific to the given object:

+ +
en:
+  helpers:
+    submit:
+      post:
+        create: "Add %{model}"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 2200
+def submit(value = nil, options = {})
+  value, options = nil, value if value.is_a?(Hash)
+  value ||= submit_default_value
+  @template.submit_tag(value, options)
+end
+
+
+ +
+ +
+

+ + time_select(method, options = {}, html_options = {}) + +

+ + +
+

Wraps ActionView::Helpers::DateHelper#time_select for form builders:

+ +
<%= form_for @race do |f| %>
+  <%= f.time_select :average_lap %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/date_helper.rb, line 1139
+def time_select(method, options = {}, html_options = {})
+  @template.time_select(@object_name, method, objectify_options(options), html_options)
+end
+
+
+ +
+ +
+

+ + time_zone_select(method, priority_zones = nil, options = {}, html_options = {}) + +

+ + +
+

Wraps ActionView::Helpers::FormOptionsHelper#time_zone_select for form builders:

+ +
<%= form_for @user do |f| %>
+  <%= f.time_zone_select :time_zone, nil, include_blank: true %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 858
+def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
+  @template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_html_options.merge(html_options))
+end
+
+
+ +
+ +
+

+ + to_model() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1653
+def to_model
+  self
+end
+
+
+ +
+ +
+

+ + to_partial_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1649
+def to_partial_path
+  self.class._to_partial_path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/FormHelper.html b/src/5.2/classes/ActionView/Helpers/FormHelper.html new file mode 100644 index 0000000000..45062b735d --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/FormHelper.html @@ -0,0 +1,2273 @@ +--- +title: ActionView::Helpers::FormHelper +layout: default +--- +
+ +
+
+ +
+ +

Form helpers are designed to make working with resources much easier compared to using vanilla HTML.

+ +

Typically, a form designed to create or update a resource reflects the identity of the resource in several ways: (i) the URL that the form is sent to (the form element's action attribute) should result in a request being routed to the appropriate controller action (with the appropriate :id parameter in the case of an existing resource), (ii) input fields should be named in such a way that in the controller their values appear in the appropriate places within the params hash, and (iii) for an existing record, when the form is initially displayed, input fields corresponding to attributes of the resource should show the current values of those attributes.

+ +

In Rails, this is usually achieved by creating the form using form_for and a number of related helper methods. form_for generates an appropriate form tag and yields a form builder object that knows the model the form is about. Input fields are created by calling methods defined on the form builder, which means they are able to generate the appropriate names and default values corresponding to the model attributes, as well as convenient IDs, etc. Conventions in the generated field names allow controllers to receive form data nicely structured in params with no effort on your side.

+ +

For example, to create a new person you typically set up a new instance of Person in the PeopleController#new action, @person, and in the view template pass that object to form_for:

+ +
<%= form_for @person do |f| %>
+  <%= f.label :first_name %>:
+  <%= f.text_field :first_name %><br />
+
+  <%= f.label :last_name %>:
+  <%= f.text_field :last_name %><br />
+
+  <%= f.submit %>
+<% end %>
+
+ +

The HTML generated for this would be (modulus formatting):

+ +
<form action="/people" class="new_person" id="new_person" method="post">
+  <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
+  <label for="person_first_name">First name</label>:
+  <input id="person_first_name" name="person[first_name]" type="text" /><br />
+
+  <label for="person_last_name">Last name</label>:
+  <input id="person_last_name" name="person[last_name]" type="text" /><br />
+
+  <input name="commit" type="submit" value="Create Person" />
+</form>
+
+ +

As you see, the HTML reflects knowledge about the resource in several spots, like the path the form should be submitted to, or the names of the input fields.

+ +

In particular, thanks to the conventions followed in the generated field names, the controller gets a nested hash params[:person] with the person attributes set in the form. That hash is ready to be passed to Person.new:

+ +
@person = Person.new(params[:person])
+if @person.save
+  # success
+else
+  # error handling
+end
+
+ +

Interestingly, the exact same view code in the previous example can be used to edit a person. If @person is an existing record with name “John Smith” and ID 256, the code above as is would yield instead:

+ +
<form action="/people/256" class="edit_person" id="edit_person_256" method="post">
+  <input name="_method" type="hidden" value="patch" />
+  <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
+  <label for="person_first_name">First name</label>:
+  <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br />
+
+  <label for="person_last_name">Last name</label>:
+  <input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br />
+
+  <input name="commit" type="submit" value="Update Person" />
+</form>
+
+ +

Note that the endpoint, default values, and submit button label are tailored for @person. That works that way because the involved helpers know whether the resource is a new record or not, and generate HTML accordingly.

+ +

The controller would receive the form data again in params[:person], ready to be passed to Person#update:

+ +
if @person.update(params[:person])
+  # success
+else
+  # error handling
+end
+
+ +

That's how you typically work with resources.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") + +

+ + +
+

Returns a checkbox tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). This object must be an instance object (@object) and not a local object. It's intended that method returns an integer and if that integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a hash with options. The checked_value defaults to 1 while the default unchecked_value is set to 0 which is convenient for boolean values.

+ +

Gotcha

+ +

The HTML specification says unchecked check boxes are not successful, and thus web browsers do not send them. Unfortunately this introduces a gotcha: if an Invoice model has a paid flag, and in the form that edits a paid invoice the user unchecks its check box, no paid parameter is sent. So, any mass-assignment idiom like

+ +
@invoice.update(params[:invoice])
+
+ +

wouldn't update the flag.

+ +

To prevent this the helper generates an auxiliary hidden field before the very check box. The hidden field has the same name and its attributes mimic an unchecked check box.

+ +

This way, the client either sends only the hidden field (representing the check box is unchecked), or both fields. Since the HTML specification says key/value pairs have to be sent in the same order they appear in the form, and parameters extraction gets the last occurrence of any repeated key in the query string, that works for ordinary forms.

+ +

Unfortunately that workaround does not work when the check box goes within an array-like parameter, as in

+ +
<%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
+  <%= form.check_box :paid %>
+  ...
+<% end %>
+
+ +

because parameter name repetition is precisely what Rails seeks to distinguish the elements of the array. For each item with a checked check box you get an extra ghost item with only that attribute, assigned to “0”.

+ +

In that case it is preferable to either use check_box_tag or to use hashes instead of arrays.

+ +
# Let's say that @post.validated? is 1:
+check_box("post", "validated")
+# => <input name="post[validated]" type="hidden" value="0" />
+#    <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />
+
+# Let's say that @puppy.gooddog is "no":
+check_box("puppy", "gooddog", {}, "yes", "no")
+# => <input name="puppy[gooddog]" type="hidden" value="no" />
+#    <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
+
+check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no")
+# => <input name="eula[accepted]" type="hidden" value="no" />
+#    <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1294
+def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
+  Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render
+end
+
+
+ +
+ +
+

+ + color_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “color”.

+ +
color_field("car", "color")
+# => <input id="car_color" name="car[color]" type="color" value="#000000" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1324
+def color_field(object_name, method, options = {})
+  Tags::ColorField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + date_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “date”.

+ +
date_field("user", "born_on")
+# => <input id="user_born_on" name="user[born_on]" type="date" />
+
+ +

The default value is generated by trying to call strftime with “%Y-%m-%d” on the object's value, which makes it behave as expected for instances of DateTime and ActiveSupport::TimeWithZone. You can still override that by passing the “value” option explicitly, e.g.

+ +
@user.born_on = Date.new(1984, 1, 27)
+date_field("user", "born_on", value: "1984-05-12")
+# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-05-12" />
+
+ +

You can create values for the “min” and “max” attributes by passing instances of Date or Time to the options hash.

+ +
date_field("user", "born_on", min: Date.today)
+# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
+
+ +

Alternatively, you can pass a String formatted as an ISO8601 date as the values for “min” and “max.”

+ +
date_field("user", "born_on", min: "2014-05-20")
+# => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1388
+def date_field(object_name, method, options = {})
+  Tags::DateField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + datetime_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “datetime-local”.

+ +
datetime_field("user", "born_on")
+# => <input id="user_born_on" name="user[born_on]" type="datetime-local" />
+
+ +

The default value is generated by trying to call strftime with “%Y-%m-%dT%T” on the object's value, which makes it behave as expected for instances of DateTime and ActiveSupport::TimeWithZone.

+ +
@user.born_on = Date.new(1984, 1, 12)
+datetime_field("user", "born_on")
+# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />
+
+ +

You can create values for the “min” and “max” attributes by passing instances of Date or Time to the options hash.

+ +
datetime_field("user", "born_on", min: Date.today)
+# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
+
+ +

Alternatively, you can pass a String formatted as an ISO8601 datetime as the values for “min” and “max.”

+ +
datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
+# => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
+
+
+ + + +
+ Also aliased as: datetime_local_field +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1446
+def datetime_field(object_name, method, options = {})
+  Tags::DatetimeLocalField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + datetime_local_field(object_name, method, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: datetime_field +
+ + + +
+ +
+

+ + email_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “email”.

+ +
email_field("user", "address")
+# => <input id="user_address" name="user[address]" type="email" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1500
+def email_field(object_name, method, options = {})
+  Tags::EmailField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + fields(scope = nil, model: nil, **options, &block) + +

+ + +
+

Scopes input fields with either an explicit scope or model. Like form_with does with :scope or :model, except it doesn't output the form tags.

+ +
# Using a scope prefixes the input field names:
+<%= fields :comment do |fields| %>
+  <%= fields.text_field :body %>
+<% end %>
+# => <input type="text" name="comment[body]">
+
+# Using a model infers the scope and assigns field values:
+<%= fields model: Comment.new(body: "full bodied") do |fields| %>
+  <%= fields.text_field :body %>
+<% end %>
+# => <input type="text" name="comment[body]" value="full bodied">
+
+# Using +fields+ with +form_with+:
+<%= form_with model: @post do |form| %>
+  <%= form.text_field :title %>
+
+  <%= form.fields :comment do |fields| %>
+    <%= fields.text_field :body %>
+  <% end %>
+<% end %>
+
+ +

Much like form_with a FormBuilder instance associated with the scope or model is yielded, so any generated field names are prefixed with either the passed scope or the scope inferred from the :model.

+ +

Mixing with other form helpers

+ +

While form_with uses a FormBuilder object it's possible to mix and match the stand-alone FormHelper methods and methods from FormTagHelper:

+ +
<%= fields model: @comment do |fields| %>
+  <%= fields.text_field :body %>
+
+  <%= text_area :commenter, :biography %>
+  <%= check_box_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %>
+<% end %>
+
+ +

Same goes for the methods in FormOptionsHelper and DateHelper designed to work with an object as a base, like FormOptionsHelper#collection_select and DateHelper#datetime_select.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1054
+def fields(scope = nil, model: nil, **options, &block)
+  options[:allow_method_names_outside_object] = true
+  options[:skip_default_ids] = !form_with_generates_ids
+
+  if model
+    scope ||= model_name_from_record_or_class(model).param_key
+  end
+
+  builder = instantiate_builder(scope, model, options)
+  capture(builder, &block)
+end
+
+
+ +
+ +
+

+ + fields_for(record_name, record_object = nil, options = {}, &block) + +

+ + +
+

Creates a scope around a specific model object like form_for, but doesn't create the form tags themselves. This makes fields_for suitable for specifying additional model objects in the same form.

+ +

Although the usage and purpose of fields_for is similar to form_for's, its method signature is slightly different. Like form_for, it yields a FormBuilder object associated with a particular model object to a block, and within the block allows methods to be called on the builder to generate fields associated with the model object. Fields may reflect a model object in two ways - how they are named (hence how submitted values appear within the params hash in the controller) and what default values are shown when the form the fields appear in is first displayed. In order for both of these features to be specified independently, both an object name (represented by either a symbol or string) and the object itself can be passed to the method separately -

+ +
<%= form_for @person do |person_form| %>
+  First name: <%= person_form.text_field :first_name %>
+  Last name : <%= person_form.text_field :last_name %>
+
+  <%= fields_for :permission, @person.permission do |permission_fields| %>
+    Admin?  : <%= permission_fields.check_box :admin %>
+  <% end %>
+
+  <%= person_form.submit %>
+<% end %>
+
+ +

In this case, the checkbox field will be represented by an HTML input tag with the name attribute permission[admin], and the submitted value will appear in the controller as params[:permission][:admin]. If @person.permission is an existing record with an attribute admin, the initial state of the checkbox when first displayed will reflect the value of @person.permission.admin.

+ +

Often this can be simplified by passing just the name of the model object to fields_for -

+ +
<%= fields_for :permission do |permission_fields| %>
+  Admin?: <%= permission_fields.check_box :admin %>
+<% end %>
+
+ +

…in which case, if :permission also happens to be the name of an instance variable @permission, the initial state of the input field will reflect the value of that variable's attribute @permission.admin.

+ +

Alternatively, you can pass just the model object itself (if the first argument isn't a string or symbol fields_for will realize that the name has been omitted) -

+ +
<%= fields_for @person.permission do |permission_fields| %>
+  Admin?: <%= permission_fields.check_box :admin %>
+<% end %>
+
+ +

and fields_for will derive the required name of the field from the class of the model object, e.g. if @person.permission, is of class Permission, the field will still be named permission[admin].

+ +

Note: This also works for the methods in FormOptionsHelper and DateHelper that are designed to work with an object as base, like FormOptionsHelper#collection_select and DateHelper#datetime_select.

+ +

Nested Attributes Examples

+ +

When the object belonging to the current scope has a nested attribute writer for a certain attribute, fields_for will yield a new scope for that attribute. This allows you to create forms that set or change the attributes of a parent object and its associations in one go.

+ +

Nested attribute writers are normal setter methods named after an association. The most common way of defining these writers is either with accepts_nested_attributes_for in a model definition or by defining a method with the proper name. For example: the attribute writer for the association :address is called address_attributes=.

+ +

Whether a one-to-one or one-to-many style form builder will be yielded depends on whether the normal reader method returns a single object or an array of objects.

+ +

One-to-one

+ +

Consider a Person class which returns a single Address from the address reader method and responds to the address_attributes= writer method:

+ +
class Person
+  def address
+    @address
+  end
+
+  def address_attributes=(attributes)
+    # Process the attributes hash
+  end
+end
+
+ +

This model can now be used with a nested fields_for, like so:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :address do |address_fields| %>
+    Street  : <%= address_fields.text_field :street %>
+    Zip code: <%= address_fields.text_field :zip_code %>
+  <% end %>
+  ...
+<% end %>
+
+ +

When address is already an association on a Person you can use accepts_nested_attributes_for to define the writer method for you:

+ +
class Person < ActiveRecord::Base
+  has_one :address
+  accepts_nested_attributes_for :address
+end
+
+ +

If you want to destroy the associated model through the form, you have to enable it first using the :allow_destroy option for accepts_nested_attributes_for:

+ +
class Person < ActiveRecord::Base
+  has_one :address
+  accepts_nested_attributes_for :address, allow_destroy: true
+end
+
+ +

Now, when you use a form element with the _destroy parameter, with a value that evaluates to true, you will destroy the associated model (eg. 1, '1', true, or 'true'):

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :address do |address_fields| %>
+    ...
+    Delete: <%= address_fields.check_box :_destroy %>
+  <% end %>
+  ...
+<% end %>
+
+ +

One-to-many

+ +

Consider a Person class which returns an array of Project instances from the projects reader method and responds to the projects_attributes= writer method:

+ +
class Person
+  def projects
+    [@project1, @project2]
+  end
+
+  def projects_attributes=(attributes)
+    # Process the attributes hash
+  end
+end
+
+ +

Note that the projects_attributes= writer method is in fact required for fields_for to correctly identify :projects as a collection, and the correct indices to be set in the form markup.

+ +

When projects is already an association on Person you can use accepts_nested_attributes_for to define the writer method for you:

+ +
class Person < ActiveRecord::Base
+  has_many :projects
+  accepts_nested_attributes_for :projects
+end
+
+ +

This model can now be used with a nested fields_for. The block given to the nested fields_for call will be repeated for each instance in the collection:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects do |project_fields| %>
+    <% if project_fields.object.active? %>
+      Name: <%= project_fields.text_field :name %>
+    <% end %>
+  <% end %>
+  ...
+<% end %>
+
+ +

It's also possible to specify the instance to be used:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <% @person.projects.each do |project| %>
+    <% if project.active? %>
+      <%= person_form.fields_for :projects, project do |project_fields| %>
+        Name: <%= project_fields.text_field :name %>
+      <% end %>
+    <% end %>
+  <% end %>
+  ...
+<% end %>
+
+ +

Or a collection to be used:

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
+    Name: <%= project_fields.text_field :name %>
+  <% end %>
+  ...
+<% end %>
+
+ +

If you want to destroy any of the associated models through the form, you have to enable it first using the :allow_destroy option for accepts_nested_attributes_for:

+ +
class Person < ActiveRecord::Base
+  has_many :projects
+  accepts_nested_attributes_for :projects, allow_destroy: true
+end
+
+ +

This will allow you to specify which models to destroy in the attributes hash by adding a form element for the _destroy parameter with a value that evaluates to true (eg. 1, '1', true, or 'true'):

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects do |project_fields| %>
+    Delete: <%= project_fields.check_box :_destroy %>
+  <% end %>
+  ...
+<% end %>
+
+ +

When a collection is used you might want to know the index of each object into the array. For this purpose, the index method is available in the FormBuilder object.

+ +
<%= form_for @person do |person_form| %>
+  ...
+  <%= person_form.fields_for :projects do |project_fields| %>
+    Project #<%= project_fields.index %>
+    ...
+  <% end %>
+  ...
+<% end %>
+
+ +

Note that fields_for will automatically generate a hidden field to store the ID of the record. There are circumstances where this hidden field is not needed and you can pass include_id: false to prevent fields_for from rendering it automatically.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1004
+def fields_for(record_name, record_object = nil, options = {}, &block)
+  builder = instantiate_builder(record_name, record_object, options)
+  capture(builder, &block)
+end
+
+
+ +
+ +
+

+ + file_field(object_name, method, options = {}) + +

+ + +
+

Returns a file upload input tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

+ +

Using this method inside a form_for block will set the enclosing form's encoding to multipart/form-data.

+ +

Options

+
  • +

    Creates standard HTML attributes for the tag.

    +
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    :multiple - If set to true, *in most updated browsers* the user will be allowed to select multiple files.

    +
  • +

    :accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.

    +
+ +

Examples

+ +
file_field(:user, :avatar)
+# => <input type="file" id="user_avatar" name="user[avatar]" />
+
+file_field(:post, :image, multiple: true)
+# => <input type="file" id="post_image" name="post[image][]" multiple="multiple" />
+
+file_field(:post, :attached, accept: 'text/html')
+# => <input accept="text/html" type="file" id="post_attached" name="post[attached]" />
+
+file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg')
+# => <input type="file" id="post_image" name="post[image]" accept="image/png,image/gif,image/jpeg" />
+
+file_field(:attachment, :file, class: 'file_input')
+# => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1206
+def file_field(object_name, method, options = {})
+  Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render
+end
+
+
+ +
+ +
+

+ + form_for(record, options = {}, &block) + +

+ + +
+

Creates a form that allows the user to create or update the attributes of a specific model object.

+ +

The method can be used in several slightly different ways, depending on how much you wish to rely on Rails to infer automatically from the model how the form should be constructed. For a generic model object, a form can be created by passing form_for a string or symbol representing the object we are concerned with:

+ +
<%= form_for :person do |f| %>
+  First name: <%= f.text_field :first_name %><br />
+  Last name : <%= f.text_field :last_name %><br />
+  Biography : <%= f.text_area :biography %><br />
+  Admin?    : <%= f.check_box :admin %><br />
+  <%= f.submit %>
+<% end %>
+
+ +

The variable f yielded to the block is a FormBuilder object that incorporates the knowledge about the model object represented by :person passed to form_for. Methods defined on the FormBuilder are used to generate fields bound to this model. Thus, for example,

+ +
<%= f.text_field :first_name %>
+
+ +

will get expanded to

+ +
<%= text_field :person, :first_name %>
+
+ +

which results in an HTML <input> tag whose name attribute is person[first_name]. This means that when the form is submitted, the value entered by the user will be available in the controller as params[:person][:first_name].

+ +

For fields generated in this way using the FormBuilder, if :person also happens to be the name of an instance variable @person, the default value of the field shown when the form is initially displayed (e.g. in the situation where you are editing an existing record) will be the value of the corresponding attribute of @person.

+ +

The rightmost argument to form_for is an optional hash of options -

+
  • +

    :url - The URL the form is to be submitted to. This may be represented in the same way as values passed to url_for or link_to. So for example you may use a named route directly. When the model is represented by a string or symbol, as in the example above, if the :url option is not specified, by default the form will be sent back to the current URL (We will describe below an alternative resource-oriented usage of form_for in which the URL does not need to be specified explicitly).

    +
  • +

    :namespace - 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.

    +
  • +

    :method - The method to use when submitting the form, usually either “get” or “post”. If “patch”, “put”, “delete”, or another verb is used, a hidden input with name _method is added to simulate the verb over post.

    +
  • +

    :authenticity_token - Authenticity token to use in the form. Use only if you need to pass custom authenticity token string, or to not add authenticity_token field at all (by passing false). Remote forms may omit the embedded authenticity token by setting config.action_view.embed_authenticity_token_in_remote_forms = false. This is helpful when you're fragment-caching the form. Remote forms get the authenticity token from the meta tag, so embedding is unnecessary unless you support browsers without JavaScript.

    +
  • +

    :remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the submit behavior. By default this behavior is an ajax submit.

    +
  • +

    :enforce_utf8 - If set to false, a hidden input with name utf8 is not output.

    +
  • +

    :html - Optional HTML attributes for the form tag.

    +
+ +

Also note that form_for doesn't create an exclusive scope. It's still possible to use both the stand-alone FormHelper methods and methods from FormTagHelper. For example:

+ +
<%= form_for :person do |f| %>
+  First name: <%= f.text_field :first_name %>
+  Last name : <%= f.text_field :last_name %>
+  Biography : <%= text_area :person, :biography %>
+  Admin?    : <%= check_box_tag "person[admin]", "1", @person.company.admin? %>
+  <%= f.submit %>
+<% end %>
+
+ +

This also works for the methods in FormOptionsHelper and DateHelper that are designed to work with an object as base, like FormOptionsHelper#collection_select and DateHelper#datetime_select.

+ +

form_for with a model object

+ +

In the examples above, the object to be created or edited was represented by a symbol passed to form_for, and we noted that a string can also be used equivalently. It is also possible, however, to pass a model object itself to form_for. For example, if @post is an existing record you wish to edit, you can create the form using

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

This behaves in almost the same way as outlined previously, with a couple of small exceptions. First, the prefix used to name the input elements within the form (hence the key that denotes them in the params hash) is actually derived from the object's class, e.g. params[:post] if the object's class is Post. However, this can be overwritten using the :as option, e.g. -

+ +
<%= form_for(@person, as: :client) do |f| %>
+  ...
+<% end %>
+
+ +

would result in params[:client].

+ +

Secondly, the field values shown when the form is initially displayed are taken from the attributes of the object passed to form_for, regardless of whether the object is an instance variable. So, for example, if we had a local variable post representing an existing record,

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

would produce a form with fields whose initial state reflect the current values of the attributes of post.

+ +

Resource-oriented style

+ +

In the examples just shown, although not indicated explicitly, we still need to use the :url option in order to specify where the form is going to be sent. However, further simplification is possible if the record passed to form_for is a resource, i.e. it corresponds to a set of RESTful routes, e.g. defined using the resources method in config/routes.rb. In this case Rails will simply infer the appropriate URL from the record itself. For example,

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

is then equivalent to something like:

+ +
<%= form_for @post, as: :post, url: post_path(@post), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>
+  ...
+<% end %>
+
+ +

And for a new record

+ +
<%= form_for(Post.new) do |f| %>
+  ...
+<% end %>
+
+ +

is equivalent to something like:

+ +
<%= form_for @post, as: :post, url: posts_path, html: { class: "new_post", id: "new_post" } do |f| %>
+  ...
+<% end %>
+
+ +

However you can still overwrite individual conventions, such as:

+ +
<%= form_for(@post, url: super_posts_path) do |f| %>
+  ...
+<% end %>
+
+ +

You can also set the answer format, like this:

+ +
<%= form_for(@post, format: :json) do |f| %>
+  ...
+<% end %>
+
+ +

For namespaced routes, like admin_post_url:

+ +
<%= form_for([:admin, @post]) do |f| %>
+ ...
+<% end %>
+
+ +

If your resource has associations defined, for example, you want to add comments to the document given that the routes are set correctly:

+ +
<%= form_for([@document, @comment]) do |f| %>
+ ...
+<% end %>
+
+ +

Where @document = Document.find(params[:id]) and @comment = Comment.new.

+ +

Setting the method

+ +

You can force the form to use the full array of HTTP verbs by setting

+ +
method: (:get|:post|:patch|:put|:delete)
+
+ +

in the options hash. If the verb is not GET or POST, which are natively supported by HTML forms, the form will be set to POST and a hidden input called _method will carry the intended verb for the server to interpret.

+ +

Unobtrusive JavaScript

+ +

Specifying:

+ +
remote: true
+
+ +

in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor. Even though it's using JavaScript to serialize the form elements, the form submission will work just like a regular submission as viewed by the receiving side (all elements available in params).

+ +

Example:

+ +
<%= form_for(@post, remote: true) do |f| %>
+  ...
+<% end %>
+
+ +

The HTML generated for this would be:

+ +
<form action='http://www.example.com' method='post' data-remote='true'>
+  <input name='_method' type='hidden' value='patch' />
+  ...
+</form>
+
+ +

Setting HTML options

+ +

You can set data attributes directly by passing in a data hash, but all other HTML options must be wrapped in the HTML key. Example:

+ +
<%= form_for(@post, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %>
+  ...
+<% end %>
+
+ +

The HTML generated for this would be:

+ +
<form action='http://www.example.com' method='post' data-behavior='autosave' name='go'>
+  <input name='_method' type='hidden' value='patch' />
+  ...
+</form>
+
+ +

Removing hidden model id's

+ +

The form_for method automatically includes the model id as a hidden field in the form. This is used to maintain the correlation between the form data and its associated model. Some ORM systems do not use IDs on nested models so in this case you want to be able to disable the hidden id.

+ +

In the following example the Post model has many Comments stored within it in a NoSQL database, thus there is no primary key for comments.

+ +

Example:

+ +
<%= form_for(@post) do |f| %>
+  <%= f.fields_for(:comments, include_id: false) do |cf| %>
+    ...
+  <% end %>
+<% end %>
+
+ +

Customized form builders

+ +

You can also build forms using a customized FormBuilder class. Subclass FormBuilder and override or define some more helpers, then use your custom builder. For example, let's say you made a helper to automatically add labels to form inputs.

+ +
<%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %>
+  <%= f.text_field :first_name %>
+  <%= f.text_field :last_name %>
+  <%= f.text_area :biography %>
+  <%= f.check_box :admin %>
+  <%= f.submit %>
+<% end %>
+
+ +

In this case, if you use this:

+ +
<%= render f %>
+
+ +

The rendered template is people/_labelling_form and the local variable referencing the form builder is called labelling_form.

+ +

The custom FormBuilder class is automatically merged with the options of a nested fields_for call, unless it's explicitly set.

+ +

In many cases you will want to wrap the above in another helper, so you could do something like the following:

+ +
def labelled_form_for(record_or_name_or_array, *args, &block)
+  options = args.extract_options!
+  form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block)
+end
+
+ +

If you don't need to attach a form to a model instance, then check out FormTagHelper#form_tag.

+ +

Form to external resources

+ +

When you build forms to external resources sometimes you need to set an authenticity token or just render a form without it, for example when you submit data to a payment gateway number and types of fields could be limited.

+ +

To set an authenticity token you need to pass an :authenticity_token parameter

+ +
<%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %>
+  ...
+<% end %>
+
+ +

If you don't want to an authenticity token field be rendered at all just pass false:

+ +
<%= form_for @invoice, url: external_url, authenticity_token: false do |f| %>
+  ...
+<% end %>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 430
+def form_for(record, options = {}, &block)
+  raise ArgumentError, "Missing block" unless block_given?
+  html_options = options[:html] ||= {}
+
+  case record
+  when String, Symbol
+    object_name = record
+    object      = nil
+  else
+    object      = record.is_a?(Array) ? record.last : record
+    raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
+    object_name = options[:as] || model_name_from_record_or_class(object).param_key
+    apply_form_for_options!(record, object, options)
+  end
+
+  html_options[:data]   = options.delete(:data)   if options.has_key?(:data)
+  html_options[:remote] = options.delete(:remote) if options.has_key?(:remote)
+  html_options[:method] = options.delete(:method) if options.has_key?(:method)
+  html_options[:enforce_utf8] = options.delete(:enforce_utf8) if options.has_key?(:enforce_utf8)
+  html_options[:authenticity_token] = options.delete(:authenticity_token)
+
+  builder = instantiate_builder(object_name, object, options)
+  output  = capture(builder, &block)
+  html_options[:multipart] ||= builder.multipart?
+
+  html_options = html_options_for_form(options[:url] || {}, html_options)
+  form_tag_with_body(html_options, output)
+end
+
+
+ +
+ +
+

+ + form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block) + +

+ + +
+

Creates a form tag based on mixing URLs, scopes, or models.

+ +
# Using just a URL:
+<%= form_with url: posts_path do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/posts" method="post" data-remote="true">
+  <input type="text" name="title">
+</form>
+
+# Adding a scope prefixes the input field names:
+<%= form_with scope: :post, url: posts_path do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/posts" method="post" data-remote="true">
+  <input type="text" name="post[title]">
+</form>
+
+# Using a model infers both the URL and scope:
+<%= form_with model: Post.new do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/posts" method="post" data-remote="true">
+  <input type="text" name="post[title]">
+</form>
+
+# An existing model makes an update form and fills out field values:
+<%= form_with model: Post.first do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/posts/1" method="post" data-remote="true">
+  <input type="hidden" name="_method" value="patch">
+  <input type="text" name="post[title]" value="<the title of the post>">
+</form>
+
+# Though the fields don't have to correspond to model attributes:
+<%= form_with model: Cat.new do |form| %>
+  <%= form.text_field :cats_dont_have_gills %>
+  <%= form.text_field :but_in_forms_they_can %>
+<% end %>
+# =>
+<form action="/cats" method="post" data-remote="true">
+  <input type="text" name="cat[cats_dont_have_gills]">
+  <input type="text" name="cat[but_in_forms_they_can]">
+</form>
+
+ +

The parameters in the forms are accessible in controllers according to their name nesting. So inputs named title and post[title] are accessible as params[:title] and params[:post][:title] respectively.

+ +

By default form_with attaches the data-remote attribute submitting the form via an XMLHTTPRequest in the background if an Unobtrusive JavaScript driver, like rails-ujs, is used. See the :local option for more.

+ +

For ease of comparison the examples above left out the submit button, as well as the auto generated hidden fields that enable UTF-8 support and adds an authenticity token needed for cross site request forgery protection.

+ +

Resource-oriented style

+ +

In many of the examples just shown, the :model passed to form_with is a resource. It corresponds to a set of RESTful routes, most likely defined via resources in config/routes.rb.

+ +

So when passing such a model record, Rails infers the URL and method.

+ +
<%= form_with model: @post do |form| %>
+  ...
+<% end %>
+
+ +

is then equivalent to something like:

+ +
<%= form_with scope: :post, url: post_path(@post), method: :patch do |form| %>
+  ...
+<% end %>
+
+ +

And for a new record

+ +
<%= form_with model: Post.new do |form| %>
+  ...
+<% end %>
+
+ +

is equivalent to something like:

+ +
<%= form_with scope: :post, url: posts_path do |form| %>
+  ...
+<% end %>
+
+ +

form_with options

+
  • +

    :url - The URL the form submits to. Akin to values passed to url_for or link_to. For example, you may use a named route directly. When a :scope is passed without a :url the form just submits to the current URL.

    +
  • +

    :method - The method to use when submitting the form, usually either “get” or “post”. If “patch”, “put”, “delete”, or another verb is used, a hidden input named _method is added to simulate the verb over post.

    +
  • +

    :format - The format of the route the form submits to. Useful when submitting to another resource type, like :json. Skipped if a :url is passed.

    +
  • +

    :scope - The scope to prefix input field names with and thereby how the submitted parameters are grouped in controllers.

    +
  • +

    :model - A model object to infer the :url and :scope by, plus fill out input field values. So if a title attribute is set to “Ahoy!” then a title input field's value would be “Ahoy!”. If the model is a new record a create form is generated, if an existing record, however, an update form is generated. Pass :scope or :url to override the defaults. E.g. turn params[:post] into params[:article].

    +
  • +

    :authenticity_token - Authenticity token to use in the form. Override with a custom authenticity token or pass false to skip the authenticity token field altogether. Useful when submitting to an external resource like a payment gateway that might limit the valid fields. Remote forms may omit the embedded authenticity token by setting config.action_view.embed_authenticity_token_in_remote_forms = false. This is helpful when fragment-caching the form. Remote forms get the authenticity token from the meta tag, so embedding is unnecessary unless you support browsers without JavaScript.

    +
  • +

    :local - By default form submits are remote and unobtrusive XHRs. Disable remote submits with local: true.

    +
  • +

    :skip_enforcing_utf8 - By default a hidden field named utf8 is output to enforce UTF-8 submits. Set to true to skip the field.

    +
  • +

    :builder - Override the object used to build the form.

    +
  • +

    :id - Optional HTML id attribute.

    +
  • +

    :class - Optional HTML class attribute.

    +
  • +

    :data - Optional HTML data attributes.

    +
  • +

    :html - Other optional HTML attributes for the form tag.

    +
+ +

Examples

+ +

When not passing a block, form_with just generates an opening form tag.

+ +
<%= form_with(model: @post, url: super_posts_path) %>
+<%= form_with(model: @post, scope: :article) %>
+<%= form_with(model: @post, format: :json) %>
+<%= form_with(model: @post, authenticity_token: false) %> # Disables the token.
+
+ +

For namespaced routes, like admin_post_url:

+ +
<%= form_with(model: [ :admin, @post ]) do |form| %>
+  ...
+<% end %>
+
+ +

If your resource has associations defined, for example, you want to add comments to the document given that the routes are set correctly:

+ +
<%= form_with(model: [ @document, Comment.new ]) do |form| %>
+  ...
+<% end %>
+
+ +

Where @document = Document.find(params[:id]).

+ +

Mixing with other form helpers

+ +

While form_with uses a FormBuilder object it's possible to mix and match the stand-alone FormHelper methods and methods from FormTagHelper:

+ +
<%= form_with scope: :person do |form| %>
+  <%= form.text_field :first_name %>
+  <%= form.text_field :last_name %>
+
+  <%= text_area :person, :biography %>
+  <%= check_box_tag "person[admin]", "1", @person.company.admin? %>
+
+  <%= form.submit %>
+<% end %>
+
+ +

Same goes for the methods in FormOptionsHelper and DateHelper designed to work with an object as a base, like FormOptionsHelper#collection_select and DateHelper#datetime_select.

+ +

Setting the method

+ +

You can force the form to use the full array of HTTP verbs by setting

+ +
method: (:get|:post|:patch|:put|:delete)
+
+ +

in the options hash. If the verb is not GET or POST, which are natively supported by HTML forms, the form will be set to POST and a hidden input called _method will carry the intended verb for the server to interpret.

+ +

Setting HTML options

+ +

You can set data attributes directly in a data hash, but HTML options besides id and class must be wrapped in an HTML key:

+ +
<%= form_with(model: @post, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
+  ...
+<% end %>
+
+ +

generates

+ +
<form action="/posts/123" method="post" data-behavior="autosave" name="go">
+  <input name="_method" type="hidden" value="patch" />
+  ...
+</form>
+
+ +

Removing hidden model id's

+ +

The form_with method automatically includes the model id as a hidden field in the form. This is used to maintain the correlation between the form data and its associated model. Some ORM systems do not use IDs on nested models so in this case you want to be able to disable the hidden id.

+ +

In the following example the Post model has many Comments stored within it in a NoSQL database, thus there is no primary key for comments.

+ +
<%= form_with(model: @post) do |form| %>
+  <%= form.fields(:comments, skip_id: true) do |fields| %>
+    ...
+  <% end %>
+<% end %>
+
+ +

Customized form builders

+ +

You can also build forms using a customized FormBuilder class. Subclass FormBuilder and override or define some more helpers, then use your custom builder. For example, let's say you made a helper to automatically add labels to form inputs.

+ +
<%= form_with model: @person, url: { action: "create" }, builder: LabellingFormBuilder do |form| %>
+  <%= form.text_field :first_name %>
+  <%= form.text_field :last_name %>
+  <%= form.text_area :biography %>
+  <%= form.check_box :admin %>
+  <%= form.submit %>
+<% end %>
+
+ +

In this case, if you use:

+ +
<%= render form %>
+
+ +

The rendered template is people/_labelling_form and the local variable referencing the form builder is called labelling_form.

+ +

The custom FormBuilder class is automatically merged with the options of a nested fields call, unless it's explicitly set.

+ +

In many cases you will want to wrap the above in another helper, so you could do something like the following:

+ +
def labelled_form_with(**options, &block)
+  form_with(**options.merge(builder: LabellingFormBuilder), &block)
+end
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 739
+def form_with(model: nil, scope: nil, url: nil, format: nil, **options, &block)
+  options[:allow_method_names_outside_object] = true
+  options[:skip_default_ids] = !form_with_generates_ids
+
+  if model
+    url ||= polymorphic_path(model, format: format)
+
+    model   = model.last if model.is_a?(Array)
+    scope ||= model_name_from_record_or_class(model).param_key
+  end
+
+  if block_given?
+    builder = instantiate_builder(scope, model, options)
+    output  = capture(builder, &block)
+    options[:multipart] ||= builder.multipart?
+
+    html_options = html_options_for_form_with(url, model, options)
+    form_tag_with_body(html_options, output)
+  else
+    html_options = html_options_for_form_with(url, model, options)
+    form_tag_html(html_options)
+  end
+end
+
+
+ +
+ +
+

+ + hidden_field(object_name, method, options = {}) + +

+ + +
+

Returns a hidden input tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

+ +

Examples

+ +
hidden_field(:signup, :pass_confirm)
+# => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
+
+hidden_field(:post, :tag_list)
+# => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="#{@post.tag_list}" />
+
+hidden_field(:user, :token)
+# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1174
+def hidden_field(object_name, method, options = {})
+  Tags::HiddenField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + label(object_name, method, content_or_options = nil, options = nil, &block) + +

+ + +
+

Returns a label tag tailored for labelling an input field for a specified attribute (identified by method) on an object assigned to the template (identified by object). The text of label will default to the attribute name unless a translation is found in the current I18n locale (through helpers.label.<modelname>.<attribute>) or you specify it explicitly. Additional options on the label tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to target labels for radio_button tags (where the value is used in the ID of the input tag).

+ +

Examples

+ +
label(:post, :title)
+# => <label for="post_title">Title</label>
+
+ +

You can localize your labels based on model and attribute names. For example you can define the following in your locale (e.g. en.yml)

+ +
helpers:
+  label:
+    post:
+      body: "Write your entire text here"
+
+ +

Which then will result in

+ +
label(:post, :body)
+# => <label for="post_body">Write your entire text here</label>
+
+ +

Localization can also be based purely on the translation of the attribute-name (if you are using ActiveRecord):

+ +
activerecord:
+  attributes:
+    post:
+      cost: "Total cost"
+
+label(:post, :cost)
+# => <label for="post_cost">Total cost</label>
+
+label(:post, :title, "A short title")
+# => <label for="post_title">A short title</label>
+
+label(:post, :title, "A short title", class: "title_label")
+# => <label for="post_title" class="title_label">A short title</label>
+
+label(:post, :privacy, "Public Post", value: "public")
+# => <label for="post_privacy_public">Public Post</label>
+
+label(:post, :terms) do
+  raw('Accept <a href="/terms">Terms</a>.')
+end
+# => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1114
+def label(object_name, method, content_or_options = nil, options = nil, &block)
+  Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
+end
+
+
+ +
+ +
+

+ + month_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “month”.

+ +
month_field("user", "born_on")
+# => <input id="user_born_on" name="user[born_on]" type="month" />
+
+ +

The default value is generated by trying to call strftime with “%Y-%m” on the object's value, which makes it behave as expected for instances of DateTime and ActiveSupport::TimeWithZone.

+ +
@user.born_on = Date.new(1984, 1, 27)
+month_field("user", "born_on")
+# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1465
+def month_field(object_name, method, options = {})
+  Tags::MonthField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + number_field(object_name, method, options = {}) + +

+ + +
+

Returns an input tag of type “number”.

+ +

Options

+
  • +

    Accepts same options as number_field_tag

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1508
+def number_field(object_name, method, options = {})
+  Tags::NumberField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + password_field(object_name, method, options = {}) + +

+ + +
+

Returns an input tag of the “password” type tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown. For security reasons this field is blank by default; pass in a value via options if this is not desired.

+ +

Examples

+ +
password_field(:login, :pass, size: 20)
+# => <input type="password" id="login_pass" name="login[pass]" size="20" />
+
+password_field(:account, :secret, class: "form_input", value: @account.secret)
+# => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />
+
+password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
+# => <input type="password" id="user_password" name="user[password]" onchange="if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }"/>
+
+password_field(:account, :pin, size: 20, class: 'form_input')
+# => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1156
+def password_field(object_name, method, options = {})
+  Tags::PasswordField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + phone_field(object_name, method, options = {}) + +

+ + +
+

aliases telephone_field

+
+ + + + + +
+ Alias for: telephone_field +
+ + + +
+ +
+

+ + radio_button(object_name, method, tag_value, options = {}) + +

+ + +
+

Returns a radio button tag for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). If the current value of method is tag_value the radio button will be checked.

+ +

To force the radio button to be checked pass checked: true in the options hash. You may pass HTML options there as well.

+ +
# Let's say that @post.category returns "rails":
+radio_button("post", "category", "rails")
+radio_button("post", "category", "java")
+# => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
+#    <input type="radio" id="post_category_java" name="post[category]" value="java" />
+
+# Let's say that @user.receive_newsletter returns "no":
+radio_button("user", "receive_newsletter", "yes")
+radio_button("user", "receive_newsletter", "no")
+# => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
+#    <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1316
+def radio_button(object_name, method, tag_value, options = {})
+  Tags::RadioButton.new(object_name, method, self, tag_value, options).render
+end
+
+
+ +
+ +
+

+ + range_field(object_name, method, options = {}) + +

+ + +
+

Returns an input tag of type “range”.

+ +

Options

+
  • +

    Accepts same options as range_field_tag

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1516
+def range_field(object_name, method, options = {})
+  Tags::RangeField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + search_field(object_name, method, options = {}) + +

+ + +
+

Returns an input of type “search” for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object_name). Inputs of type “search” may be styled differently by some browsers.

+ +
search_field(:user, :name)
+# => <input id="user_name" name="user[name]" type="search" />
+search_field(:user, :name, autosave: false)
+# => <input autosave="false" id="user_name" name="user[name]" type="search" />
+search_field(:user, :name, results: 3)
+# => <input id="user_name" name="user[name]" results="3" type="search" />
+#  Assume request.host returns "www.example.com"
+search_field(:user, :name, autosave: true)
+# => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" />
+search_field(:user, :name, onsearch: true)
+# => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
+search_field(:user, :name, autosave: false, onsearch: true)
+# => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
+search_field(:user, :name, autosave: true, onsearch: true)
+# => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1347
+def search_field(object_name, method, options = {})
+  Tags::SearchField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + telephone_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “tel”.

+ +
telephone_field("user", "phone")
+# => <input id="user_phone" name="user[phone]" type="tel" />
+
+
+ + + +
+ Also aliased as: phone_field +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1356
+def telephone_field(object_name, method, options = {})
+  Tags::TelField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + text_area(object_name, method, options = {}) + +

+ + +
+

Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options.

+ +

Examples

+ +
text_area(:post, :body, cols: 20, rows: 40)
+# => <textarea cols="20" rows="40" id="post_body" name="post[body]">
+#      #{@post.body}
+#    </textarea>
+
+text_area(:comment, :text, size: "20x30")
+# => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
+#      #{@comment.text}
+#    </textarea>
+
+text_area(:application, :notes, cols: 40, rows: 15, class: 'app_input')
+# => <textarea cols="40" rows="15" id="application_notes" name="application[notes]" class="app_input">
+#      #{@application.notes}
+#    </textarea>
+
+text_area(:entry, :body, size: "20x20", disabled: 'disabled')
+# => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled">
+#      #{@entry.body}
+#    </textarea>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1234
+def text_area(object_name, method, options = {})
+  Tags::TextArea.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + text_field(object_name, method, options = {}) + +

+ + +
+

Returns an input tag of the “text” type tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). Additional options on the input tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown.

+ +

Examples

+ +
text_field(:post, :title, size: 20)
+# => <input type="text" id="post_title" name="post[title]" size="20" value="#{@post.title}" />
+
+text_field(:post, :title, class: "create_input")
+# => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" class="create_input" />
+
+text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
+# => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/>
+
+text_field(:snippet, :code, size: 20, class: 'code_input')
+# => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1135
+def text_field(object_name, method, options = {})
+  Tags::TextField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + time_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “time”.

+ +

The default value is generated by trying to call strftime with “%T.%L” on the object's value. It is still possible to override that by passing the “value” option.

+ +

Options

+
  • +

    Accepts same options as time_field_tag

    +
+ +

Example

+ +
time_field("task", "started_at")
+# => <input id="task_started_at" name="task[started_at]" type="time" />
+
+ +

You can create values for the “min” and “max” attributes by passing instances of Date or Time to the options hash.

+ +
time_field("task", "started_at", min: Time.now)
+# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
+
+ +

Alternatively, you can pass a String formatted as an ISO8601 time as the values for “min” and “max.”

+ +
time_field("task", "started_at", min: "01:00:00")
+# => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1417
+def time_field(object_name, method, options = {})
+  Tags::TimeField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + url_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “url”.

+ +
url_field("user", "homepage")
+# => <input id="user_homepage" name="user[homepage]" type="url" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1491
+def url_field(object_name, method, options = {})
+  Tags::UrlField.new(object_name, method, self, options).render
+end
+
+
+ +
+ +
+

+ + week_field(object_name, method, options = {}) + +

+ + +
+

Returns a text_field of type “week”.

+ +
week_field("user", "born_on")
+# => <input id="user_born_on" name="user[born_on]" type="week" />
+
+ +

The default value is generated by trying to call strftime with “%Y-W%W” on the object's value, which makes it behave as expected for instances of DateTime and ActiveSupport::TimeWithZone.

+ +
@user.born_on = Date.new(1984, 5, 12)
+week_field("user", "born_on")
+# => <input id="user_born_on" name="user[born_on]" type="date" value="1984-W19" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_helper.rb, line 1482
+def week_field(object_name, method, options = {})
+  Tags::WeekField.new(object_name, method, self, options).render
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/FormOptionsHelper.html b/src/5.2/classes/ActionView/Helpers/FormOptionsHelper.html new file mode 100644 index 0000000000..7c5239ea42 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/FormOptionsHelper.html @@ -0,0 +1,1166 @@ +--- +title: ActionView::Helpers::FormOptionsHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides a number of methods for turning different kinds of containers into a set of option tags.

+ +

The collection_select, select and time_zone_select methods take an options parameter, a hash:

+
  • +

    :include_blank - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element.

    + +
    select("post", "category", Post::CATEGORIES, {include_blank: true})
    +
    + +

    could become:

    + +
    <select name="post[category]" id="post_category">
    +  <option value=""></option>
    +  <option value="joke">joke</option>
    +  <option value="poem">poem</option>
    +</select>
    +
    + +

    Another common case is a select tag for a belongs_to-associated object.

    + +

    Example with @post.person_id => 2:

    + +
    select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {include_blank: 'None'})
    +
    + +

    could become:

    + +
    <select name="post[person_id]" id="post_person_id">
    +  <option value="">None</option>
    +  <option value="1">David</option>
    +  <option value="2" selected="selected">Eileen</option>
    +  <option value="3">Rafael</option>
    +</select>
    +
    +
  • +

    :prompt - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt – “Please select” – or the given prompt string.

    + +
    select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {prompt: 'Select Person'})
    +
    + +

    could become:

    + +
    <select name="post[person_id]" id="post_person_id">
    +  <option value="">Select Person</option>
    +  <option value="1">David</option>
    +  <option value="2">Eileen</option>
    +  <option value="3">Rafael</option>
    +</select>
    +
    +
  • +

    :index - like the other form helpers, select can accept an :index option to manually set the ID used in the resulting output. Unlike other helpers, select expects this option to be in the html_options parameter.

    + +
    select("album[]", "genre", %w[rap rock country], {}, { index: nil })
    +
    + +

    becomes:

    + +
    <select name="album[][genre]" id="album__genre">
    +  <option value="rap">rap</option>
    +  <option value="rock">rock</option>
    +  <option value="country">country</option>
    +</select>
    +
    +
  • +

    :disabled - can be a single value or an array of values that will be disabled options in the final output.

    + +
    select("post", "category", Post::CATEGORIES, {disabled: 'restricted'})
    +
    + +

    could become:

    + +
    <select name="post[category]" id="post_category">
    +  <option value=""></option>
    +  <option value="joke">joke</option>
    +  <option value="poem">poem</option>
    +  <option disabled="disabled" value="restricted">restricted</option>
    +</select>
    +
    + +

    When used with the collection_select helper, :disabled can also be a Proc that identifies those options that should be disabled.

    + +
    collection_select(:post, :category_id, Category.all, :id, :name, {disabled: -> (category) { category.archived? }})
    +
    + +

    If the categories “2008 stuff” and “Christmas” return true when the method archived? is called, this would return:

    + +
    <select name="post[category_id]" id="post_category_id">
    +  <option value="1" disabled="disabled">2008 stuff</option>
    +  <option value="2" disabled="disabled">Christmas</option>
    +  <option value="3">Jokes</option>
    +  <option value="4">Poems</option>
    +</select>
    +
    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) + +

+ + +
+

Returns check box tags for the collection of existing return values of method for object's class. The value returned from calling method on the instance object will be selected. If calling method returns nil, no selection is made.

+ +

The :value_method and :text_method parameters are methods to be called on each member of collection. The return values are used as the value attribute and contents of each check box tag, respectively. They can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the value/text.

+ +

Example object structure for use with this method:

+ +
class Post < ActiveRecord::Base
+  has_and_belongs_to_many :authors
+end
+class Author < ActiveRecord::Base
+  has_and_belongs_to_many :posts
+  def name_with_initial
+    "#{first_name.first}. #{last_name}"
+  end
+end
+
+ +

Sample usage (selecting the associated Author for an instance of Post, @post):

+ +
collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)
+
+ +

If @post.author_ids is already [1], this would return:

+ +
<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
+<label for="post_author_ids_1">D. Heinemeier Hansson</label>
+<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
+<label for="post_author_ids_2">D. Thomas</label>
+<input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
+<label for="post_author_ids_3">M. Clark</label>
+<input name="post[author_ids][]" type="hidden" value="" />
+
+ +

It is also possible to customize the way the elements will be shown by giving a block to the method:

+ +
collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
+  b.label { b.check_box }
+end
+
+ +

The argument passed to the block is a special kind of builder for this collection, which has the ability to generate the label and check box for the current item in the collection, with proper text and value. Using it, you can change the label and check box display order or even use the label as wrapper, as in the example above.

+ +

The builder methods label and check_box also accept extra HTML options:

+ +
collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
+  b.label(class: "check_box") { b.check_box(class: "check_box") }
+end
+
+ +

There are also three special methods available: object, text and value, which are the current item being rendered, its text and value methods, respectively. You can use them like this:

+ +
collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
+   b.label(:"data-value" => b.value) { b.check_box + b.text }
+end
+
+ +

Gotcha

+ +

When no selection is made for a collection of checkboxes most web browsers will not send any value.

+ +

For example, if we have a User model with category_ids field and we have the following code in our update action:

+ +
@user.update(params[:user])
+
+ +

If no category_ids are selected then we can safely assume this field will not be updated.

+ +

This is possible thanks to a hidden field generated by the helper method for every collection of checkboxes. This hidden field is given the same field name as the checkboxes with a blank value.

+ +

In the rare case you don't want this hidden field, you can pass the include_hidden: false option to the helper method.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 756
+def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
+  Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
+end
+
+
+ +
+ +
+

+ + collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) + +

+ + +
+

Returns radio button tags for the collection of existing return values of method for object's class. The value returned from calling method on the instance object will be selected. If calling method returns nil, no selection is made.

+ +

The :value_method and :text_method parameters are methods to be called on each member of collection. The return values are used as the value attribute and contents of each radio button tag, respectively. They can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the value/text.

+ +

Example object structure for use with this method:

+ +
class Post < ActiveRecord::Base
+  belongs_to :author
+end
+class Author < ActiveRecord::Base
+  has_many :posts
+  def name_with_initial
+    "#{first_name.first}. #{last_name}"
+  end
+end
+
+ +

Sample usage (selecting the associated Author for an instance of Post, @post):

+ +
collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial)
+
+ +

If @post.author_id is already 1, this would return:

+ +
<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" checked="checked" />
+<label for="post_author_id_1">D. Heinemeier Hansson</label>
+<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
+<label for="post_author_id_2">D. Thomas</label>
+<input id="post_author_id_3" name="post[author_id]" type="radio" value="3" />
+<label for="post_author_id_3">M. Clark</label>
+
+ +

It is also possible to customize the way the elements will be shown by giving a block to the method:

+ +
collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
+  b.label { b.radio_button }
+end
+
+ +

The argument passed to the block is a special kind of builder for this collection, which has the ability to generate the label and radio button for the current item in the collection, with proper text and value. Using it, you can change the label and radio button display order or even use the label as wrapper, as in the example above.

+ +

The builder methods label and radio_button also accept extra HTML options:

+ +
collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
+  b.label(class: "radio_button") { b.radio_button(class: "radio_button") }
+end
+
+ +

There are also three special methods available: object, text and value, which are the current item being rendered, its text and value methods, respectively. You can use them like this:

+ +
collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
+   b.label(:"data-value" => b.value) { b.radio_button + b.text }
+end
+
+ +

Gotcha

+ +

The HTML specification says when nothing is select on a collection of radio buttons web browsers do not send any value to server. Unfortunately this introduces a gotcha: if a User model has a category_id field and in the form no category is selected, no category_id parameter is sent. So, any strong parameters idiom like:

+ +
params.require(:user).permit(...)
+
+ +

will raise an error since no {user: ...} will be present.

+ +

To prevent this the helper generates an auxiliary hidden field before every collection of radio buttons. The hidden field has the same name as collection radio button and blank value.

+ +

In case if you don't want the helper to generate this hidden field you can specify include_hidden: false option.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 672
+def collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
+  Tags::CollectionRadioButtons.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
+end
+
+
+ +
+ +
+

+ + collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) + +

+ + +
+

Returns <select> and <option> tags for the collection of existing return values of method for object's class. The value returned from calling method on the instance object will be selected. If calling method returns nil, no selection is made without including :prompt or :include_blank in the options hash.

+ +

The :value_method and :text_method parameters are methods to be called on each member of collection. The return values are used as the value attribute and contents of each <option> tag, respectively. They can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the value/text.

+ +

Example object structure for use with this method:

+ +
class Post < ActiveRecord::Base
+  belongs_to :author
+end
+
+class Author < ActiveRecord::Base
+  has_many :posts
+  def name_with_initial
+    "#{first_name.first}. #{last_name}"
+  end
+end
+
+ +

Sample usage (selecting the associated Author for an instance of Post, @post):

+ +
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, prompt: true)
+
+ +

If @post.author_id is already 1, this would return:

+ +
<select name="post[author_id]" id="post_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>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 203
+def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
+  Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render
+end
+
+
+ +
+ +
+

+ + grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) + +

+ + +
+

Returns <select>, <optgroup> and <option> tags for the collection of existing return values of method for object's class. The value returned from calling method on the instance object will be selected. If calling method returns nil, no selection is made without including :prompt or :include_blank in the options hash.

+ +

Parameters:

+
  • +

    object - The instance of the class to be used for the select tag

    +
  • +

    method - The attribute of object corresponding to the select tag

    +
  • +

    collection - An array of objects representing the <optgroup> tags.

    +
  • +

    group_method - The name of a method which, when called on a member of collection, returns an array of child objects representing the <option> tags. It can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the value.

    +
  • +

    group_label_method - The name of a method which, when called on a member of collection, returns a string to be used as the label attribute for its <optgroup> tag. It can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the label.

    +
  • +

    option_key_method - The name of a method which, when called on a child object of a member of collection, returns a value to be used as the value attribute for its <option> tag.

    +
  • +

    option_value_method - The name of a method which, when called on a child object of a member of collection, returns a value to be used as the contents of its <option> tag.

    +
+ +

Example object structure for use with this method:

+ +
class Continent < ActiveRecord::Base
+  has_many :countries
+  # attribs: id, name
+end
+
+class Country < ActiveRecord::Base
+  belongs_to :continent
+  # attribs: id, name, continent_id
+end
+
+class City < ActiveRecord::Base
+  belongs_to :country
+  # attribs: id, name, country_id
+end
+
+ +

Sample usage:

+ +
grouped_collection_select(:city, :country_id, @continents, :countries, :name, :id, :name)
+
+ +

Possible output:

+ +
<select name="city[country_id]" id="city_country_id">
+  <optgroup label="Africa">
+    <option value="1">South Africa</option>
+    <option value="3">Somalia</option>
+  </optgroup>
+  <optgroup label="Europe">
+    <option value="7" selected="selected">Denmark</option>
+    <option value="2">Ireland</option>
+  </optgroup>
+</select>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 263
+def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
+  Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render
+end
+
+
+ +
+ +
+

+ + grouped_options_for_select(grouped_options, selected_key = nil, options = {}) + +

+ + +
+

Returns a string of <option> tags, like options_for_select, but wraps them with <optgroup> tags:

+ +
grouped_options = [
+ ['North America',
+   [['United States','US'],'Canada']],
+ ['Europe',
+   ['Denmark','Germany','France']]
+]
+grouped_options_for_select(grouped_options)
+
+grouped_options = {
+  'North America' => [['United States','US'], 'Canada'],
+  'Europe' => ['Denmark','Germany','France']
+}
+grouped_options_for_select(grouped_options)
+
+ +

Possible output:

+ +
<optgroup label="North America">
+  <option value="US">United States</option>
+  <option value="Canada">Canada</option>
+</optgroup>
+<optgroup label="Europe">
+  <option value="Denmark">Denmark</option>
+  <option value="Germany">Germany</option>
+  <option value="France">France</option>
+</optgroup>
+
+ +

Parameters:

+
  • +

    grouped_options - Accepts a nested array or hash of strings. The first value serves as the <optgroup> label while the second value must be an array of options. The second value can be a nested array of text-value pairs. See options_for_select for more info.

    + +
    Ex. ["North America",[["United States","US"],["Canada","CA"]]]
    +
    +
  • +

    selected_key - A value equal to the value attribute for one of the <option> tags, which will have the selected attribute set. Note: It is possible for this value to match multiple options as you might have the same option in multiple groups. Each will then get selected="selected".

    +
+ +

Options:

+
  • +

    :prompt - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt - “Please select” - or the given prompt string.

    +
  • +

    :divider - the divider for the options groups.

    + +
    grouped_options = [
    +  [['United States','US'], 'Canada'],
    +  ['Denmark','Germany','France']
    +]
    +grouped_options_for_select(grouped_options, nil, divider: '---------')
    +
    + +

    Possible output:

    + +
    <optgroup label="---------">
    +  <option value="US">United States</option>
    +  <option value="Canada">Canada</option>
    +</optgroup>
    +<optgroup label="---------">
    +  <option value="Denmark">Denmark</option>
    +  <option value="Germany">Germany</option>
    +  <option value="France">France</option>
    +</optgroup>
    +
    +
+ +

Note: Only the <optgroup> and <option> tags are returned, so you still have to wrap the output in an appropriate <select> tag.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 531
+def grouped_options_for_select(grouped_options, selected_key = nil, options = {})
+  prompt  = options[:prompt]
+  divider = options[:divider]
+
+  body = "".html_safe
+
+  if prompt
+    body.safe_concat content_tag("option".freeze, prompt_text(prompt), value: "")
+  end
+
+  grouped_options.each do |container|
+    html_attributes = option_html_attributes(container)
+
+    if divider
+      label = divider
+    else
+      label, container = container
+    end
+
+    html_attributes = { label: label }.merge!(html_attributes)
+    body.safe_concat content_tag("optgroup".freeze, options_for_select(container, selected_key), html_attributes)
+  end
+
+  body
+end
+
+
+ +
+ +
+

+ + option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil) + +

+ + +
+

Returns a string of <option> tags, like options_from_collection_for_select, but groups them by <optgroup> tags based on the object relationships of the arguments.

+ +

Parameters:

+
  • +

    collection - An array of objects representing the <optgroup> tags.

    +
  • +

    group_method - The name of a method which, when called on a member of collection, returns an array of child objects representing the <option> tags.

    +
  • +

    group_label_method - The name of a method which, when called on a member of collection, returns a string to be used as the label attribute for its <optgroup> tag.

    +
  • +

    option_key_method - The name of a method which, when called on a child object of a member of collection, returns a value to be used as the value attribute for its <option> tag.

    +
  • +

    option_value_method - The name of a method which, when called on a child object of a member of collection, returns a value to be used as the contents of its <option> tag.

    +
  • +

    selected_key - A value equal to the value attribute for one of the <option> tags, which will have the selected attribute set. Corresponds to the return value of one of the calls to option_key_method. If nil, no selection is made. Can also be a hash if disabled values are to be specified.

    +
+ +

Example object structure for use with this method:

+ +
class Continent < ActiveRecord::Base
+  has_many :countries
+  # attribs: id, name
+end
+
+class Country < ActiveRecord::Base
+  belongs_to :continent
+  # attribs: id, name, continent_id
+end
+
+ +

Sample usage:

+ +
option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)
+
+ +

Possible output:

+ +
<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>
+
+ +

Note: Only the <optgroup> and <option> tags are returned, so you still have to wrap the output in an appropriate <select> tag.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 461
+def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
+  collection.map do |group|
+    option_tags = options_from_collection_for_select(
+      value_for_collection(group, group_method), option_key_method, option_value_method, selected_key)
+
+    content_tag("optgroup".freeze, option_tags, label: value_for_collection(group, group_label_method))
+  end.join.html_safe
+end
+
+
+ +
+ +
+

+ + options_for_select(container, selected = nil) + +

+ + +
+

Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container where the elements respond to first and last (such as a two-element array), the “lasts” serve as option values and the “firsts” as option text. Hashes are turned into this form automatically, so the keys become “firsts” and values become lasts. If selected is specified, the matching “last” or element will get the selected option-tag. selected may also be an array of values to be selected when using a multiple select.

+ +
options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
+# => <option value="$">Dollar</option>
+# => <option value="DKK">Kroner</option>
+
+options_for_select([ "VISA", "MasterCard" ], "MasterCard")
+# => <option value="VISA">VISA</option>
+# => <option selected="selected" value="MasterCard">MasterCard</option>
+
+options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
+# => <option value="$20">Basic</option>
+# => <option value="$40" selected="selected">Plus</option>
+
+options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
+# => <option selected="selected" value="VISA">VISA</option>
+# => <option value="MasterCard">MasterCard</option>
+# => <option selected="selected" value="Discover">Discover</option>
+
+ +

You can optionally provide HTML attributes as the last element of the array.

+ +
options_for_select([ "Denmark", ["USA", {class: 'bold'}], "Sweden" ], ["USA", "Sweden"])
+# => <option value="Denmark">Denmark</option>
+# => <option value="USA" class="bold" selected="selected">USA</option>
+# => <option value="Sweden" selected="selected">Sweden</option>
+
+options_for_select([["Dollar", "$", {class: "bold"}], ["Kroner", "DKK", {onclick: "alert('HI');"}]])
+# => <option value="$" class="bold">Dollar</option>
+# => <option value="DKK" onclick="alert('HI');">Kroner</option>
+
+ +

If you wish to specify disabled option tags, set selected to be a hash, with :disabled being either a value or array of values to be disabled. In this case, you can use :selected to specify selected option tags.

+ +
options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: "Super Platinum")
+# => <option value="Free">Free</option>
+# => <option value="Basic">Basic</option>
+# => <option value="Advanced">Advanced</option>
+# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>
+
+options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: ["Advanced", "Super Platinum"])
+# => <option value="Free">Free</option>
+# => <option value="Basic">Basic</option>
+# => <option value="Advanced" disabled="disabled">Advanced</option>
+# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>
+
+options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], selected: "Free", disabled: "Super Platinum")
+# => <option value="Free" selected="selected">Free</option>
+# => <option value="Basic">Basic</option>
+# => <option value="Advanced">Advanced</option>
+# => <option value="Super Platinum" disabled="disabled">Super Platinum</option>
+
+ +

NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 357
+def options_for_select(container, selected = nil)
+  return container if String === container
+
+  selected, disabled = extract_selected_and_disabled(selected).map do |r|
+    Array(r).map(&:to_s)
+  end
+
+  container.map do |element|
+    html_attributes = option_html_attributes(element)
+    text, value = option_text_and_value(element).map(&:to_s)
+
+    html_attributes[:selected] ||= option_value_selected?(value, selected)
+    html_attributes[:disabled] ||= disabled && option_value_selected?(value, disabled)
+    html_attributes[:value] = value
+
+    tag_builder.content_tag_string(:option, text, html_attributes)
+  end.join("\n").html_safe
+end
+
+
+ +
+ +
+

+ + options_from_collection_for_select(collection, value_method, text_method, selected = nil) + +

+ + +
+

Returns a string of option tags that have been compiled by iterating over the collection and assigning the result of a call to the value_method as the option value and the text_method as the option text.

+ +
options_from_collection_for_select(@people, 'id', 'name')
+# => <option value="#{person.id}">#{person.name}</option>
+
+ +

This is more often than not used inside a select_tag like this example:

+ +
select_tag 'person', options_from_collection_for_select(@people, 'id', 'name')
+
+ +

If selected is specified as a value or array of values, the element(s) returning a match on value_method will be selected option tag(s).

+ +

If selected is specified as a Proc, those members of the collection that return true for the anonymous function are the selected values.

+ +

selected can also be a hash, specifying both :selected and/or :disabled values as required.

+ +

Be sure to specify the same class as the value_method when specifying selected or disabled options. Failure to do this will produce undesired results. Example:

+ +
options_from_collection_for_select(@people, 'id', 'name', '1')
+
+ +

Will not select a person with the id of 1 because 1 (an Integer) is not the same as '1' (a string)

+ +
options_from_collection_for_select(@people, 'id', 'name', 1)
+
+ +

should produce the desired results.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 400
+def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
+  options = collection.map do |element|
+    [value_for_collection(element, text_method), value_for_collection(element, value_method), option_html_attributes(element)]
+  end
+  selected, disabled = extract_selected_and_disabled(selected)
+  select_deselect = {
+    selected: extract_values_from_collection(collection, value_method, selected),
+    disabled: extract_values_from_collection(collection, value_method, disabled)
+  }
+
+  options_for_select(options, select_deselect)
+end
+
+
+ +
+ +
+

+ + select(object, method, choices = nil, options = {}, html_options = {}, &block) + +

+ + +
+

Create a select tag and a series of contained option tags for the provided object and method. The option currently held by the object will be selected, provided that the object is available.

+ +

There are two possible formats for the choices parameter, corresponding to other helpers' output:

+
  • +

    A flat collection (see options_for_select).

    +
  • +

    A nested collection (see grouped_options_for_select).

    +
+ +

For example:

+ +
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { include_blank: true })
+
+ +

would become:

+ +
<select name="post[person_id]" id="post_person_id">
+  <option value=""></option>
+  <option value="1" selected="selected">David</option>
+  <option value="2">Eileen</option>
+  <option value="3">Rafael</option>
+</select>
+
+ +

assuming the associated person has ID 1.

+ +

This can be used to provide a default set of options in the standard way: before rendering the create form, a new model instance is assigned the default options and bound to @model_name. Usually this model is not saved to the database. Instead, a second model object is created when the create request is received. This allows the user to submit a form page more than once with the expected results of creating multiple records. In addition, this allows a single partial to be used to generate form inputs for both edit and create forms.

+ +

By default, post.person_id is the selected option. Specify selected: value to use a different selection or selected: nil to leave all options unselected. Similarly, you can specify values to be disabled in the option tags by specifying the :disabled option. This can either be a single value or an array of values to be disabled.

+ +

A block can be passed to select to customize how the options tags will be rendered. This is useful when the options tag has complex attributes.

+ +
select(report, "campaign_ids") do
+  available_campaigns.each do |c|
+    content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json })
+  end
+end
+
+ +

Gotcha

+ +

The HTML specification says when multiple parameter passed to select and all options got deselected web browsers do not send any value to server. Unfortunately this introduces a gotcha: if an User model has many roles and have role_ids accessor, and in the form that edits roles of the user the user deselects all roles from role_ids multiple select box, no role_ids parameter is sent. So, any mass-assignment idiom like

+ +
@user.update(params[:user])
+
+ +

wouldn't update roles.

+ +

To prevent this the helper generates an auxiliary hidden field before every multiple select. The hidden field has the same name as multiple select and blank value.

+ +

Note: The client either sends only the hidden field (representing the deselected multiple select box), or both fields. This means that the resulting array always contains a blank string.

+ +

In case if you don't want the helper to generate this hidden field you can specify include_hidden: false option.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 164
+def select(object, method, choices = nil, options = {}, html_options = {}, &block)
+  Tags::Select.new(object, method, self, choices, options, html_options, &block).render
+end
+
+
+ +
+ +
+

+ + time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone) + +

+ + +
+

Returns a string of option tags for pretty much any time zone in the world. Supply an ActiveSupport::TimeZone name as selected to have it marked as the selected option tag. You can also supply an array of ActiveSupport::TimeZone objects as priority_zones, so that they will be listed above the rest of the (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list of the US time zones, or a Regexp to select the zones of your choice)

+ +

The selected parameter must be either nil, or a string that names an ActiveSupport::TimeZone.

+ +

By default, model is the ActiveSupport::TimeZone constant (which can be obtained in Active Record as a value object). The only requirement is that the model parameter be an object that responds to all, and returns an array of objects that represent time zones.

+ +

NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 575
+def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
+  zone_options = "".html_safe
+
+  zones = model.all
+  convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } }
+
+  if priority_zones
+    if priority_zones.is_a?(Regexp)
+      priority_zones = zones.select { |z| z =~ priority_zones }
+    end
+
+    zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
+    zone_options.safe_concat content_tag("option".freeze, "-------------", value: "", disabled: true)
+    zone_options.safe_concat "\n"
+
+    zones = zones - priority_zones
+  end
+
+  zone_options.safe_concat options_for_select(convert_zones[zones], selected)
+end
+
+
+ +
+ +
+

+ + time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) + +

+ + +
+

Returns select and option tags for the given object and method, using time_zone_options_for_select to generate the list of option tags.

+ +

In addition to the :include_blank option documented above, this method also supports a :model option, which defaults to ActiveSupport::TimeZone. This may be used by users to specify a different time zone model object. (See time_zone_options_for_select for more information.)

+ +

You can also supply an array of ActiveSupport::TimeZone objects as priority_zones so that they will be listed above the rest of the (long) list. You can use ActiveSupport::TimeZone.us_zones for a list of US time zones, ActiveSupport::TimeZone.country_zones(country_code) for another country's time zones, or a Regexp to select the zones of your choice.

+ +

Finally, this method supports a :default option, which selects a default ActiveSupport::TimeZone if the object's time zone is nil.

+ +
time_zone_select("user", "time_zone", nil, include_blank: true)
+
+time_zone_select("user", "time_zone", nil, default: "Pacific Time (US & Canada)")
+
+time_zone_select("user", 'time_zone', ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)")
+
+time_zone_select("user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
+
+time_zone_select("user", 'time_zone', /Australia/)
+
+time_zone_select("user", "time_zone", ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone)
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 297
+def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
+  Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/FormTagHelper.html b/src/5.2/classes/ActionView/Helpers/FormTagHelper.html new file mode 100644 index 0000000000..414044bb6d --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/FormTagHelper.html @@ -0,0 +1,1972 @@ +--- +title: ActionView::Helpers::FormTagHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like FormHelper does. Instead, you provide the names and values manually.

+ +

NOTE: The HTML options disabled, readonly, and multiple can all be treated as booleans. So specifying disabled: true will give disabled="disabled".

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + button_tag(content_or_options = nil, options = nil, &block) + +

+ + +
+

Creates a button element that defines a submit button, reset button or a generic button which can be used in JavaScript, for example. You can use the button tag as a regular submit tag but it isn't supported in legacy browsers. However, the button tag does allow for richer labels such as images and emphasis, so this helper will also accept a block. By default, it will create a button tag with type submit, if type is not given.

+ +

Options

+
  • +

    :data - This option can be used to add custom data attributes.

    +
  • +

    :disabled - If true, the user will not be able to use this input.

    +
  • +

    Any other key creates standard HTML options for the tag.

    +
+ +

Data attributes

+
  • +

    confirm: 'question?' - If present, the unobtrusive JavaScript drivers will provide a prompt with the question specified. If the user accepts, the form is processed normally, otherwise no action is taken.

    +
  • +

    :disable_with - Value of this parameter will be used as the value for a disabled version of the submit button when the form is submitted. This feature is provided by the unobtrusive JavaScript driver.

    +
+ +

Examples

+ +
button_tag
+# => <button name="button" type="submit">Button</button>
+
+button_tag 'Reset', type: 'reset'
+# => <button name="button" type="reset">Reset</button>
+
+button_tag 'Button', type: 'button'
+# => <button name="button" type="button">Button</button>
+
+button_tag 'Reset', type: 'reset', disabled: true
+# => <button name="button" type="reset" disabled="disabled">Reset</button>
+
+button_tag(type: 'button') do
+  content_tag(:strong, 'Ask me!')
+end
+# => <button name="button" type="button">
+#     <strong>Ask me!</strong>
+#    </button>
+
+button_tag "Save", data: { confirm: "Are you sure?" }
+# => <button name="button" type="submit" data-confirm="Are you sure?">Save</button>
+
+button_tag "Checkout", data: { disable_with: "Please wait..." }
+# => <button data-disable-with="Please wait..." name="button" type="submit">Checkout</button>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 506
+def button_tag(content_or_options = nil, options = nil, &block)
+  if content_or_options.is_a? Hash
+    options = content_or_options
+  else
+    options ||= {}
+  end
+
+  options = { "name" => "button", "type" => "submit" }.merge!(options.stringify_keys)
+
+  if block_given?
+    content_tag :button, options, &block
+  else
+    content_tag :button, content_or_options || "Button", options
+  end
+end
+
+
+ +
+ +
+

+ + check_box_tag(name, value = "1", checked = false, options = {}) + +

+ + +
+

Creates a check box form input tag.

+ +

Options

+
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    Any other key creates standard HTML options for the tag.

    +
+ +

Examples

+ +
check_box_tag 'accept'
+# => <input id="accept" name="accept" type="checkbox" value="1" />
+
+check_box_tag 'rock', 'rock music'
+# => <input id="rock" name="rock" type="checkbox" value="rock music" />
+
+check_box_tag 'receive_email', 'yes', true
+# => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" />
+
+check_box_tag 'tos', 'yes', false, class: 'accept_tos'
+# => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" />
+
+check_box_tag 'eula', 'accepted', false, disabled: true
+# => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 378
+def check_box_tag(name, value = "1", checked = false, options = {})
+  html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
+  html_options["checked"] = "checked" if checked
+  tag :input, html_options
+end
+
+
+ +
+ +
+

+ + color_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “color”.

+ +

Options

+
  • +

    Accepts the same options as text_field_tag.

    +
+ +

Examples

+ +
color_field_tag 'name'
+# => <input id="name" name="name" type="color" />
+
+color_field_tag 'color', '#DEF726'
+# => <input id="color" name="color" type="color" value="#DEF726" />
+
+color_field_tag 'color', nil, class: 'special_input'
+# => <input class="special_input" id="color" name="color" type="color" />
+
+color_field_tag 'color', '#DEF726', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="color" name="color" type="color" value="#DEF726" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 602
+def color_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :color))
+end
+
+
+ +
+ +
+

+ + date_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “date”.

+ +

Options

+
  • +

    Accepts the same options as text_field_tag.

    +
+ +

Examples

+ +
date_field_tag 'name'
+# => <input id="name" name="name" type="date" />
+
+date_field_tag 'date', '01/01/2014'
+# => <input id="date" name="date" type="date" value="01/01/2014" />
+
+date_field_tag 'date', nil, class: 'special_input'
+# => <input class="special_input" id="date" name="date" type="date" />
+
+date_field_tag 'date', '01/01/2014', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="date" name="date" type="date" value="01/01/2014" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 666
+def date_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :date))
+end
+
+
+ +
+ +
+

+ + datetime_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “datetime-local”.

+ +

Options

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
  • +

    Otherwise accepts the same options as text_field_tag.

    +
+
+ + + +
+ Also aliased as: datetime_local_field_tag +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 688
+def datetime_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: "datetime-local"))
+end
+
+
+ +
+ +
+

+ + datetime_local_field_tag(name, value = nil, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: datetime_field_tag +
+ + + +
+ +
+

+ + email_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “email”.

+ +

Options

+
  • +

    Accepts the same options as text_field_tag.

    +
+ +

Examples

+ +
email_field_tag 'name'
+# => <input id="name" name="name" type="email" />
+
+email_field_tag 'email', 'email@example.com'
+# => <input id="email" name="email" type="email" value="email@example.com" />
+
+email_field_tag 'email', nil, class: 'special_input'
+# => <input class="special_input" id="email" name="email" type="email" />
+
+email_field_tag 'email', 'email@example.com', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="email" name="email" type="email" value="email@example.com" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 754
+def email_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :email))
+end
+
+
+ +
+ +
+

+ + field_set_tag(legend = nil, options = nil, &block) + +

+ + +
+

Creates a field set for grouping HTML form elements.

+ +

legend will become the fieldset's title (optional as per W3C). options accept the same values as tag.

+ +

Examples

+ +
<%= field_set_tag do %>
+  <p><%= text_field_tag 'name' %></p>
+<% end %>
+# => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>
+
+<%= field_set_tag 'Your details' do %>
+  <p><%= text_field_tag 'name' %></p>
+<% end %>
+# => <fieldset><legend>Your details</legend><p><input id="name" name="name" type="text" /></p></fieldset>
+
+<%= field_set_tag nil, class: 'format' do %>
+  <p><%= text_field_tag 'name' %></p>
+<% end %>
+# => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 578
+def field_set_tag(legend = nil, options = nil, &block)
+  output = tag(:fieldset, options, true)
+  output.safe_concat(content_tag("legend".freeze, legend)) unless legend.blank?
+  output.concat(capture(&block)) if block_given?
+  output.safe_concat("</fieldset>")
+end
+
+
+ +
+ +
+

+ + file_field_tag(name, options = {}) + +

+ + +
+

Creates a file upload field. If you are using file uploads then you will also need to set the multipart option for the form tag:

+ +
<%= form_tag '/upload', multipart: true do %>
+  <label for="file">File to Upload</label> <%= file_field_tag "file" %>
+  <%= submit_tag %>
+<% end %>
+
+ +

The specified URL will then be passed a File object containing the selected file, or if the field was left blank, a StringIO object.

+ +

Options

+
  • +

    Creates standard HTML attributes for the tag.

    +
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    :multiple - If set to true, *in most updated browsers* the user will be allowed to select multiple files.

    +
  • +

    :accept - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.

    +
+ +

Examples

+ +
file_field_tag 'attachment'
+# => <input id="attachment" name="attachment" type="file" />
+
+file_field_tag 'avatar', class: 'profile_input'
+# => <input class="profile_input" id="avatar" name="avatar" type="file" />
+
+file_field_tag 'picture', disabled: true
+# => <input disabled="disabled" id="picture" name="picture" type="file" />
+
+file_field_tag 'resume', value: '~/resume.doc'
+# => <input id="resume" name="resume" type="file" value="~/resume.doc" />
+
+file_field_tag 'user_pic', accept: 'image/png,image/gif,image/jpeg'
+# => <input accept="image/png,image/gif,image/jpeg" id="user_pic" name="user_pic" type="file" />
+
+file_field_tag 'file', accept: 'text/html', class: 'upload', value: 'index.html'
+# => <input accept="text/html" class="upload" id="file" name="file" type="file" value="index.html" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 278
+def file_field_tag(name, options = {})
+  text_field_tag(name, nil, convert_direct_upload_option_to_url(options.merge(type: :file)))
+end
+
+
+ +
+ +
+

+ + form_tag(url_for_options = {}, options = {}, &block) + +

+ + +
+

Starts a form tag that points the action to a url configured with url_for_options just like ActionController::Base#url_for. The method for the form defaults to POST.

+ +

Options

+
  • +

    :multipart - If set to true, the enctype is set to “multipart/form-data”.

    +
  • +

    :method - The method to use when submitting the form, usually either “get” or “post”. If “patch”, “put”, “delete”, or another verb is used, a hidden input with name _method is added to simulate the verb over post.

    +
  • +

    :authenticity_token - Authenticity token to use in the form. Use only if you need to pass custom authenticity token string, or to not add authenticity_token field at all (by passing false). Remote forms may omit the embedded authenticity token by setting config.action_view.embed_authenticity_token_in_remote_forms = false. This is helpful when you're fragment-caching the form. Remote forms get the authenticity token from the meta tag, so embedding is unnecessary unless you support browsers without JavaScript.

    +
  • +

    :remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the submit behavior. By default this behavior is an ajax submit.

    +
  • +

    :enforce_utf8 - If set to false, a hidden input with name utf8 is not output.

    +
  • +

    Any other key creates standard HTML attributes for the tag.

    +
+ +

Examples

+ +
form_tag('/posts')
+# => <form action="/posts" method="post">
+
+form_tag('/posts/1', method: :put)
+# => <form action="/posts/1" method="post"> ... <input name="_method" type="hidden" value="put" /> ...
+
+form_tag('/upload', multipart: true)
+# => <form action="/upload" method="post" enctype="multipart/form-data">
+
+<%= form_tag('/posts') do -%>
+  <div><%= submit_tag 'Save' %></div>
+<% end -%>
+# => <form action="/posts" method="post"><div><input type="submit" name="commit" value="Save" /></div></form>
+
+<%= form_tag('/posts', remote: true) %>
+# => <form action="/posts" method="post" data-remote="true">
+
+form_tag('http://far.away.com/form', authenticity_token: false)
+# form without authenticity token
+
+form_tag('http://far.away.com/form', authenticity_token: "cf50faa3fe97702ca1ae")
+# form with custom authenticity token
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 69
+def form_tag(url_for_options = {}, options = {}, &block)
+  html_options = html_options_for_form(url_for_options, options)
+  if block_given?
+    form_tag_with_body(html_options, capture(&block))
+  else
+    form_tag_html(html_options)
+  end
+end
+
+
+ +
+ +
+

+ + hidden_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a hidden form input field used to transmit data that would be lost due to HTTP's statelessness or data that should be hidden from the user.

+ +

Options

+
  • +

    Creates standard HTML attributes for the tag.

    +
+ +

Examples

+ +
hidden_field_tag 'tags_list'
+# => <input id="tags_list" name="tags_list" type="hidden" />
+
+hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
+# => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />
+
+hidden_field_tag 'collected_input', '', onchange: "alert('Input collected!')"
+# => <input id="collected_input" name="collected_input" onchange="alert('Input collected!')"
+#    type="hidden" value="" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 239
+def hidden_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :hidden))
+end
+
+
+ +
+ +
+

+ + image_submit_tag(source, options = {}) + +

+ + +
+

Displays an image which when clicked will submit the form.

+ +

source is passed to AssetTagHelper#path_to_image

+ +

Options

+
  • +

    :data - This option can be used to add custom data attributes.

    +
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    Any other key creates standard HTML options for the tag.

    +
+ +

Data attributes

+
  • +

    confirm: 'question?' - This will add a JavaScript confirm prompt with the question specified. If the user accepts, the form is processed normally, otherwise no action is taken.

    +
+ +

Examples

+ +
image_submit_tag("login.png")
+# => <input src="/assets/login.png" type="image" />
+
+image_submit_tag("purchase.png", disabled: true)
+# => <input disabled="disabled" src="/assets/purchase.png" type="image" />
+
+image_submit_tag("search.png", class: 'search_button', alt: 'Find')
+# => <input class="search_button" src="/assets/search.png" type="image" />
+
+image_submit_tag("agree.png", disabled: true, class: "agree_disagree_button")
+# => <input class="agree_disagree_button" disabled="disabled" src="/assets/agree.png" type="image" />
+
+image_submit_tag("save.png", data: { confirm: "Are you sure?" })
+# => <input src="/assets/save.png" data-confirm="Are you sure?" type="image" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 552
+def image_submit_tag(source, options = {})
+  options = options.stringify_keys
+  src = path_to_image(source, skip_pipeline: options.delete("skip_pipeline"))
+  tag :input, { "type" => "image", "src" => src }.update(options)
+end
+
+
+ +
+ +
+

+ + label_tag(name = nil, content_or_options = nil, options = nil, &block) + +

+ + +
+

Creates a label element. Accepts a block.

+ +

Options

+
  • +

    Creates standard HTML attributes for the tag.

    +
+ +

Examples

+ +
label_tag 'name'
+# => <label for="name">Name</label>
+
+label_tag 'name', 'Your name'
+# => <label for="name">Your name</label>
+
+label_tag 'name', nil, class: 'small_label'
+# => <label for="name" class="small_label">Name</label>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 212
+def label_tag(name = nil, content_or_options = nil, options = nil, &block)
+  if block_given? && content_or_options.is_a?(Hash)
+    options = content_or_options = content_or_options.stringify_keys
+  else
+    options ||= {}
+    options = options.stringify_keys
+  end
+  options["for"] = sanitize_to_id(name) unless name.blank? || options.has_key?("for")
+  content_tag :label, content_or_options || name.to_s.humanize, options, &block
+end
+
+
+ +
+ +
+

+ + month_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “month”.

+ +

Options

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
  • +

    Otherwise accepts the same options as text_field_tag.

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 701
+def month_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :month))
+end
+
+
+ +
+ +
+

+ + number_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a number field.

+ +

Options

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :in - A range specifying the :min and :max values.

    +
  • +

    :within - Same as :in.

    +
  • +

    :step - The acceptable value granularity.

    +
  • +

    Otherwise accepts the same options as text_field_tag.

    +
+ +

Examples

+ +
number_field_tag 'quantity'
+# => <input id="quantity" name="quantity" type="number" />
+
+number_field_tag 'quantity', '1'
+# => <input id="quantity" name="quantity" type="number" value="1" />
+
+number_field_tag 'quantity', nil, class: 'special_input'
+# => <input class="special_input" id="quantity" name="quantity" type="number" />
+
+number_field_tag 'quantity', nil, min: 1
+# => <input id="quantity" name="quantity" min="1" type="number" />
+
+number_field_tag 'quantity', nil, max: 9
+# => <input id="quantity" name="quantity" max="9" type="number" />
+
+number_field_tag 'quantity', nil, in: 1...10
+# => <input id="quantity" name="quantity" min="1" max="9" type="number" />
+
+number_field_tag 'quantity', nil, within: 1...10
+# => <input id="quantity" name="quantity" min="1" max="9" type="number" />
+
+number_field_tag 'quantity', nil, min: 1, max: 10
+# => <input id="quantity" name="quantity" min="1" max="10" type="number" />
+
+number_field_tag 'quantity', nil, min: 1, max: 10, step: 2
+# => <input id="quantity" name="quantity" min="1" max="10" step="2" type="number" />
+
+number_field_tag 'quantity', '1', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="quantity" name="quantity" type="number" value="1" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 799
+def number_field_tag(name, value = nil, options = {})
+  options = options.stringify_keys
+  options["type"] ||= "number"
+  if range = options.delete("in") || options.delete("within")
+    options.update("min" => range.min, "max" => range.max)
+  end
+  text_field_tag(name, value, options)
+end
+
+
+ +
+ +
+

+ + password_field_tag(name = "password", value = nil, options = {}) + +

+ + +
+

Creates a password field, a masked text field that will hide the users input behind a mask character.

+ +

Options

+
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    :size - The number of visible characters that will fit in the input.

    +
  • +

    :maxlength - The maximum number of characters that the browser will allow the user to enter.

    +
  • +

    Any other key creates standard HTML attributes for the tag.

    +
+ +

Examples

+ +
password_field_tag 'pass'
+# => <input id="pass" name="pass" type="password" />
+
+password_field_tag 'secret', 'Your secret here'
+# => <input id="secret" name="secret" type="password" value="Your secret here" />
+
+password_field_tag 'masked', nil, class: 'masked_input_field'
+# => <input class="masked_input_field" id="masked" name="masked" type="password" />
+
+password_field_tag 'token', '', size: 15
+# => <input id="token" name="token" size="15" type="password" value="" />
+
+password_field_tag 'key', nil, maxlength: 16
+# => <input id="key" maxlength="16" name="key" type="password" />
+
+password_field_tag 'confirm_pass', nil, disabled: true
+# => <input disabled="disabled" id="confirm_pass" name="confirm_pass" type="password" />
+
+password_field_tag 'pin', '1234', maxlength: 4, size: 6, class: "pin_input"
+# => <input class="pin_input" id="pin" maxlength="4" name="pin" size="6" type="password" value="1234" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 311
+def password_field_tag(name = "password", value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :password))
+end
+
+
+ +
+ +
+

+ + phone_field_tag(name, value = nil, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: telephone_field_tag +
+ + + +
+ +
+

+ + radio_button_tag(name, value, checked = false, options = {}) + +

+ + +
+

Creates a radio button; use groups of radio buttons named the same to allow users to select from a group of options.

+ +

Options

+
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    Any other key creates standard HTML options for the tag.

    +
+ +

Examples

+ +
radio_button_tag 'gender', 'male'
+# => <input id="gender_male" name="gender" type="radio" value="male" />
+
+radio_button_tag 'receive_updates', 'no', true
+# => <input checked="checked" id="receive_updates_no" name="receive_updates" type="radio" value="no" />
+
+radio_button_tag 'time_slot', "3:00 p.m.", false, disabled: true
+# => <input disabled="disabled" id="time_slot_3:00_p.m." name="time_slot" type="radio" value="3:00 p.m." />
+
+radio_button_tag 'color', "green", true, class: "color_input"
+# => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 403
+def radio_button_tag(name, value, checked = false, options = {})
+  html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys)
+  html_options["checked"] = "checked" if checked
+  tag :input, html_options
+end
+
+
+ +
+ +
+

+ + range_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a range form element.

+ +

Options

+
  • +

    Accepts the same options as number_field_tag.

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 812
+def range_field_tag(name, value = nil, options = {})
+  number_field_tag(name, value, options.merge(type: :range))
+end
+
+
+ +
+ +
+

+ + search_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “search”.

+ +

Options

+
  • +

    Accepts the same options as text_field_tag.

    +
+ +

Examples

+ +
search_field_tag 'name'
+# => <input id="name" name="name" type="search" />
+
+search_field_tag 'search', 'Enter your search query here'
+# => <input id="search" name="search" type="search" value="Enter your search query here" />
+
+search_field_tag 'search', nil, class: 'special_input'
+# => <input class="special_input" id="search" name="search" type="search" />
+
+search_field_tag 'search', 'Enter your search query here', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="search" name="search" type="search" value="Enter your search query here" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 623
+def search_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :search))
+end
+
+
+ +
+ +
+

+ + select_tag(name, option_tags = nil, options = {}) + +

+ + +
+

Creates a dropdown selection box, or if the :multiple option is set to true, a multiple choice selection box.

+ +

Helpers::FormOptions can be used to create common select boxes such as countries, time zones, or associated records. option_tags is a string containing the option tags for the select box.

+ +

Options

+
  • +

    :multiple - If set to true, the selection will allow multiple choices.

    +
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    :include_blank - If set to true, an empty option will be created. If set to a string, the string will be used as the option's content and the value will be empty.

    +
  • +

    :prompt - Create a prompt option with blank value and the text asking user to select something.

    +
  • +

    Any other key creates standard HTML attributes for the tag.

    +
+ +

Examples

+ +
select_tag "people", options_from_collection_for_select(@people, "id", "name")
+# <select id="people" name="people"><option value="1">David</option></select>
+
+select_tag "people", options_from_collection_for_select(@people, "id", "name", "1")
+# <select id="people" name="people"><option value="1" selected="selected">David</option></select>
+
+select_tag "people", raw("<option>David</option>")
+# => <select id="people" name="people"><option>David</option></select>
+
+select_tag "count", raw("<option>1</option><option>2</option><option>3</option><option>4</option>")
+# => <select id="count" name="count"><option>1</option><option>2</option>
+#    <option>3</option><option>4</option></select>
+
+select_tag "colors", raw("<option>Red</option><option>Green</option><option>Blue</option>"), multiple: true
+# => <select id="colors" multiple="multiple" name="colors[]"><option>Red</option>
+#    <option>Green</option><option>Blue</option></select>
+
+select_tag "locations", raw("<option>Home</option><option selected='selected'>Work</option><option>Out</option>")
+# => <select id="locations" name="locations"><option>Home</option><option selected='selected'>Work</option>
+#    <option>Out</option></select>
+
+select_tag "access", raw("<option>Read</option><option>Write</option>"), multiple: true, class: 'form_input', id: 'unique_id'
+# => <select class="form_input" id="unique_id" multiple="multiple" name="access[]"><option>Read</option>
+#    <option>Write</option></select>
+
+select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: true
+# => <select id="people" name="people"><option value="" label=" "></option><option value="1">David</option></select>
+
+select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: "All"
+# => <select id="people" name="people"><option value="">All</option><option value="1">David</option></select>
+
+select_tag "people", options_from_collection_for_select(@people, "id", "name"), prompt: "Select something"
+# => <select id="people" name="people"><option value="">Select something</option><option value="1">David</option></select>
+
+select_tag "destination", raw("<option>NYC</option><option>Paris</option><option>Rome</option>"), disabled: true
+# => <select disabled="disabled" id="destination" name="destination"><option>NYC</option>
+#    <option>Paris</option><option>Rome</option></select>
+
+select_tag "credit_card", options_for_select([ "VISA", "MasterCard" ], "MasterCard")
+# => <select id="credit_card" name="credit_card"><option>VISA</option>
+#    <option selected="selected">MasterCard</option></select>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 133
+def select_tag(name, option_tags = nil, options = {})
+  option_tags ||= ""
+  html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
+
+  if options.include?(:include_blank)
+    include_blank = options.delete(:include_blank)
+    options_for_blank_options_tag = { value: "" }
+
+    if include_blank == true
+      include_blank = ""
+      options_for_blank_options_tag[:label] = " "
+    end
+
+    if include_blank
+      option_tags = content_tag("option".freeze, include_blank, options_for_blank_options_tag).safe_concat(option_tags)
+    end
+  end
+
+  if prompt = options.delete(:prompt)
+    option_tags = content_tag("option".freeze, prompt, value: "").safe_concat(option_tags)
+  end
+
+  content_tag "select".freeze, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
+end
+
+
+ +
+ +
+

+ + submit_tag(value = "Save changes", options = {}) + +

+ + +
+

Creates a submit button with the text value as the caption.

+ +

Options

+
  • +

    :data - This option can be used to add custom data attributes.

    +
  • +

    :disabled - If true, the user will not be able to use this input.

    +
  • +

    Any other key creates standard HTML options for the tag.

    +
+ +

Data attributes

+
  • +

    confirm: 'question?' - If present the unobtrusive JavaScript drivers will provide a prompt with the question specified. If the user accepts, the form is processed normally, otherwise no action is taken.

    +
  • +

    :disable_with - Value of this parameter will be used as the value for a disabled version of the submit button when the form is submitted. This feature is provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag pass :data => { disable_with: false } Defaults to value attribute.

    +
+ +

Examples

+ +
submit_tag
+# => <input name="commit" data-disable-with="Save changes" type="submit" value="Save changes" />
+
+submit_tag "Edit this article"
+# => <input name="commit" data-disable-with="Edit this article" type="submit" value="Edit this article" />
+
+submit_tag "Save edits", disabled: true
+# => <input disabled="disabled" name="commit" data-disable-with="Save edits" type="submit" value="Save edits" />
+
+submit_tag "Complete sale", data: { disable_with: "Submitting..." }
+# => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" />
+
+submit_tag nil, class: "form_submit"
+# => <input class="form_submit" name="commit" type="submit" />
+
+submit_tag "Edit", class: "edit_button"
+# => <input class="edit_button" data-disable-with="Edit" name="commit" type="submit" value="Edit" />
+
+submit_tag "Save", data: { confirm: "Are you sure?" }
+# => <input name='commit' type='submit' value='Save' data-disable-with="Save" data-confirm="Are you sure?" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 448
+def submit_tag(value = "Save changes", options = {})
+  options = options.deep_stringify_keys
+  tag_options = { "type" => "submit", "name" => "commit", "value" => value }.update(options)
+  set_default_disable_with value, tag_options
+  tag :input, tag_options
+end
+
+
+ +
+ +
+

+ + telephone_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “tel”.

+ +

Options

+
  • +

    Accepts the same options as text_field_tag.

    +
+ +

Examples

+ +
telephone_field_tag 'name'
+# => <input id="name" name="name" type="tel" />
+
+telephone_field_tag 'tel', '0123456789'
+# => <input id="tel" name="tel" type="tel" value="0123456789" />
+
+telephone_field_tag 'tel', nil, class: 'special_input'
+# => <input class="special_input" id="tel" name="tel" type="tel" />
+
+telephone_field_tag 'tel', '0123456789', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="tel" name="tel" type="tel" value="0123456789" />
+
+
+ + + +
+ Also aliased as: phone_field_tag +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 644
+def telephone_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :tel))
+end
+
+
+ +
+ +
+

+ + text_area_tag(name, content = nil, options = {}) + +

+ + +
+

Creates a text input area; use a textarea for longer text inputs such as blog posts or descriptions.

+ +

Options

+
  • +

    :size - A string specifying the dimensions (columns by rows) of the textarea (e.g., “25x10”).

    +
  • +

    :rows - Specify the number of rows in the textarea

    +
  • +

    :cols - Specify the number of columns in the textarea

    +
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    :escape - By default, the contents of the text input are HTML escaped. If you need unescaped contents, set this to false.

    +
  • +

    Any other key creates standard HTML attributes for the tag.

    +
+ +

Examples

+ +
text_area_tag 'post'
+# => <textarea id="post" name="post"></textarea>
+
+text_area_tag 'bio', @user.bio
+# => <textarea id="bio" name="bio">This is my biography.</textarea>
+
+text_area_tag 'body', nil, rows: 10, cols: 25
+# => <textarea cols="25" id="body" name="body" rows="10"></textarea>
+
+text_area_tag 'body', nil, size: "25x10"
+# => <textarea name="body" id="body" cols="25" rows="10"></textarea>
+
+text_area_tag 'description', "Description goes here.", disabled: true
+# => <textarea disabled="disabled" id="description" name="description">Description goes here.</textarea>
+
+text_area_tag 'comment', nil, class: 'comment_input'
+# => <textarea class="comment_input" id="comment" name="comment"></textarea>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 344
+def text_area_tag(name, content = nil, options = {})
+  options = options.stringify_keys
+
+  if size = options.delete("size")
+    options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
+  end
+
+  escape = options.delete("escape") { true }
+  content = ERB::Util.html_escape(content) if escape
+
+  content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
+end
+
+
+ +
+ +
+

+ + text_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a standard text field; use these text fields to input smaller chunks of text like a username or a search query.

+ +

Options

+
  • +

    :disabled - If set to true, the user will not be able to use this input.

    +
  • +

    :size - The number of visible characters that will fit in the input.

    +
  • +

    :maxlength - The maximum number of characters that the browser will allow the user to enter.

    +
  • +

    :placeholder - The text contained in the field by default which is removed when the field receives focus. If set to true, use a translation is found in the current I18n locale (through helpers.placeholders.<modelname>.<attribute>).

    +
  • +

    Any other key creates standard HTML attributes for the tag.

    +
+ +

Examples

+ +
text_field_tag 'name'
+# => <input id="name" name="name" type="text" />
+
+text_field_tag 'query', 'Enter your search query here'
+# => <input id="query" name="query" type="text" value="Enter your search query here" />
+
+text_field_tag 'search', nil, placeholder: 'Enter search term...'
+# => <input id="search" name="search" placeholder="Enter search term..." type="text" />
+
+text_field_tag 'request', nil, class: 'special_input'
+# => <input class="special_input" id="request" name="request" type="text" />
+
+text_field_tag 'address', '', size: 75
+# => <input id="address" name="address" size="75" type="text" value="" />
+
+text_field_tag 'zip', nil, maxlength: 5
+# => <input id="zip" maxlength="5" name="zip" type="text" />
+
+text_field_tag 'payment_amount', '$0.00', disabled: true
+# => <input disabled="disabled" id="payment_amount" name="payment_amount" type="text" value="$0.00" />
+
+text_field_tag 'ip', '0.0.0.0', maxlength: 15, size: 20, class: "ip-input"
+# => <input class="ip-input" id="ip" maxlength="15" name="ip" size="20" type="text" value="0.0.0.0" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 194
+def text_field_tag(name, value = nil, options = {})
+  tag :input, { "type" => "text", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
+end
+
+
+ +
+ +
+

+ + time_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “time”.

+ +

Options

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
  • +

    Otherwise accepts the same options as text_field_tag.

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 677
+def time_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :time))
+end
+
+
+ +
+ +
+

+ + url_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “url”.

+ +

Options

+
  • +

    Accepts the same options as text_field_tag.

    +
+ +

Examples

+ +
url_field_tag 'name'
+# => <input id="name" name="name" type="url" />
+
+url_field_tag 'url', 'http://rubyonrails.org'
+# => <input id="url" name="url" type="url" value="http://rubyonrails.org" />
+
+url_field_tag 'url', nil, class: 'special_input'
+# => <input class="special_input" id="url" name="url" type="url" />
+
+url_field_tag 'url', 'http://rubyonrails.org', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="url" name="url" type="url" value="http://rubyonrails.org" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 733
+def url_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :url))
+end
+
+
+ +
+ +
+

+ + utf8_enforcer_tag() + +

+ + +
+

Creates the hidden UTF8 enforcer tag. Override this method in a helper to customize the tag.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 818
+def utf8_enforcer_tag
+  # Use raw HTML to ensure the value is written as an HTML entity; it
+  # needs to be the right character regardless of which encoding the
+  # browser infers.
+  '<input name="utf8" type="hidden" value="&#x2713;" />'.html_safe
+end
+
+
+ +
+ +
+

+ + week_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type “week”.

+ +

Options

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
  • +

    Otherwise accepts the same options as text_field_tag.

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 712
+def week_field_tag(name, value = nil, options = {})
+  text_field_tag(name, value, options.merge(type: :week))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/JavaScriptHelper.html b/src/5.2/classes/ActionView/Helpers/JavaScriptHelper.html new file mode 100644 index 0000000000..2c75781a32 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/JavaScriptHelper.html @@ -0,0 +1,262 @@ +--- +title: ActionView::Helpers::JavaScriptHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
JS_ESCAPE_MAP={ +'\\' => '\\\\', +"</" => '<\/', +"\r\n" => '\n', +"\n" => '\n', +"\r" => '\n', +'"' => '\\"', +"'" => "\\'", +"`" => "\\`", +"$" => "\\$" +}
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + escape_javascript(javascript) + +

+ + +
+

Escapes carriage returns and single and double quotes for JavaScript segments.

+ +

Also available through the alias j(). This is particularly helpful in JavaScript responses, like:

+ +
$('some_element').replaceWith('<%= j render 'some/element_template' %>');
+
+
+ + + +
+ Also aliased as: j +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/javascript_helper.rb, line 29
+def escape_javascript(javascript)
+  if javascript
+    result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"']|[`]|[$])/u) { |match| JS_ESCAPE_MAP[match] }
+    javascript.html_safe? ? result.html_safe : result
+  else
+    ""
+  end
+end
+
+
+ +
+ +
+

+ + j(javascript) + +

+ + +
+ +
+ + + + + +
+ Alias for: escape_javascript +
+ + + +
+ +
+

+ + javascript_tag(content_or_options_with_block = nil, html_options = {}, &block) + +

+ + +
+

Returns a JavaScript tag with the content inside. Example:

+ +
javascript_tag "alert('All is good')"
+
+ +

Returns:

+ +
<script>
+//<![CDATA[
+alert('All is good')
+//]]>
+</script>
+
+ +

html_options may be a hash of attributes for the <script> tag.

+ +
javascript_tag "alert('All is good')", defer: 'defer'
+
+ +

Returns:

+ +
<script defer="defer">
+//<![CDATA[
+alert('All is good')
+//]]>
+</script>
+
+ +

Instead of passing the content as an argument, you can also use a block in which case, you pass your html_options as the first parameter.

+ +
<%= javascript_tag defer: 'defer' do -%>
+  alert('All is good')
+<% end -%>
+
+ +

If you have a content security policy enabled then you can add an automatic nonce value by passing +nonce: true+ as part of html_options. Example:

+ +
<%= javascript_tag nonce: true do -%>
+  alert('All is good')
+<% end -%>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/javascript_helper.rb, line 75
+def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
+  content =
+    if block_given?
+      html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
+      capture(&block)
+    else
+      content_or_options_with_block
+    end
+
+  if html_options[:nonce] == true
+    html_options[:nonce] = content_security_policy_nonce
+  end
+
+  content_tag("script".freeze, javascript_cdata_section(content), html_options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/NumberHelper.html b/src/5.2/classes/ActionView/Helpers/NumberHelper.html new file mode 100644 index 0000000000..4f4dc802e4 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/NumberHelper.html @@ -0,0 +1,665 @@ +--- +title: ActionView::Helpers::NumberHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides methods for converting numbers into formatted strings. Methods are provided for phone numbers, currency, percentage, precision, positional notation, file size and pretty printing.

+ +

Most methods expect a number argument, and will return it unchanged if can't be converted into a valid number.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + number_to_currency(number, options = {}) + +

+ + +
+

Formats a number into a currency string (e.g., $13.65). You can customize the format in the options hash.

+ +

The currency unit and number formatting of the current locale will be used unless otherwise specified in the provided options. No currency conversion is performed. If the user is given a way to change their locale, they will also be able to change the relative value of the currency displayed with this helper. If your application will ever support multiple locales, you may want to specify a constant :locale option or consider using a library capable of currency conversion.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the level of precision (defaults to 2).

    +
  • +

    :unit - Sets the denomination of the currency (defaults to “$”).

    +
  • +

    :separator - Sets the separator between the units (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “,”).

    +
  • +

    :format - Sets the format for non-negative numbers (defaults to “%u%n”). Fields are %u for the currency, and %n for the number.

    +
  • +

    :negative_format - Sets the format for negative numbers (defaults to prepending a hyphen to the formatted number given by :format). Accepts the same fields than :format, except %n is here the absolute value of the number.

    +
  • +

    :raise - If true, raises InvalidNumberError when the argument is invalid.

    +
+ +

Examples

+ +
number_to_currency(1234567890.50)                    # => $1,234,567,890.50
+number_to_currency(1234567890.506)                   # => $1,234,567,890.51
+number_to_currency(1234567890.506, precision: 3)     # => $1,234,567,890.506
+number_to_currency(1234567890.506, locale: :fr)      # => 1 234 567 890,51 €
+number_to_currency("123a456")                        # => $123a456
+
+number_to_currency("123a456", raise: true)           # => InvalidNumberError
+
+number_to_currency(-1234567890.50, negative_format: "(%u%n)")
+# => ($1,234,567,890.50)
+number_to_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "")
+# => R$1234567890,50
+number_to_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "", format: "%n %u")
+# => 1234567890,50 R$
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 120
+def number_to_currency(number, options = {})
+  delegate_number_helper_method(:number_to_currency, number, options)
+end
+
+
+ +
+ +
+

+ + number_to_human(number, options = {}) + +

+ + +
+

Pretty prints (formats and approximates) a number in a way it is more readable by humans (eg.: 1200000000 becomes “1.2 Billion”). This is useful for numbers that can get very large (and too hard to read).

+ +

See number_to_human_size if you want to print a file size.

+ +

You can also define your own unit-quantifier names if you want to use other decimal units (eg.: 1500 becomes “1.5 kilometers”, 0.150 becomes “150 milliliters”, etc). You may define a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3).

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to true)

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to true)

    +
  • +

    :units - A Hash of unit quantifier names. Or a string containing an i18n scope where to find this hash. It might have the following keys:

    +
    • +

      integers: :unit, :ten, :hundred, :thousand, :million, :billion, :trillion, :quadrillion

      +
    • +

      fractionals: :deci, :centi, :mili, :micro, :nano, :pico, :femto

      +
    +
  • +

    :format - Sets the format of the output string (defaults to “%n %u”). The field types are:

    +
    • +

      %u - The quantifier (ex.: 'thousand')

      +
    • +

      %n - The number

      +
    +
  • +

    :raise - If true, raises InvalidNumberError when the argument is invalid.

    +
+ +

Examples

+ +
number_to_human(123)                                          # => "123"
+number_to_human(1234)                                         # => "1.23 Thousand"
+number_to_human(12345)                                        # => "12.3 Thousand"
+number_to_human(1234567)                                      # => "1.23 Million"
+number_to_human(1234567890)                                   # => "1.23 Billion"
+number_to_human(1234567890123)                                # => "1.23 Trillion"
+number_to_human(1234567890123456)                             # => "1.23 Quadrillion"
+number_to_human(1234567890123456789)                          # => "1230 Quadrillion"
+number_to_human(489939, precision: 2)                         # => "490 Thousand"
+number_to_human(489939, precision: 4)                         # => "489.9 Thousand"
+number_to_human(1234567, precision: 4,
+                        significant: false)                   # => "1.2346 Million"
+number_to_human(1234567, precision: 1,
+                        separator: ',',
+                        significant: false)                   # => "1,2 Million"
+
+number_to_human(500000000, precision: 5)                      # => "500 Million"
+number_to_human(12345012345, significant: false)              # => "12.345 Billion"
+
+ +

Non-significant zeros after the decimal separator are stripped out by default (set :strip_insignificant_zeros to false to change that):

+ +

number_to_human(12.00001) # => “12” number_to_human(12.00001, strip_insignificant_zeros: false) # => “12.0”

+ +

Custom Unit Quantifiers

+ +

You can also use your own custom unit quantifiers:

+ +
number_to_human(500000, units: {unit: "ml", thousand: "lt"})  # => "500 lt"
+
+ +

If in your I18n locale you have:

+ +
distance:
+  centi:
+    one: "centimeter"
+    other: "centimeters"
+  unit:
+    one: "meter"
+    other: "meters"
+  thousand:
+    one: "kilometer"
+    other: "kilometers"
+  billion: "gazillion-distance"
+
+ +

Then you could do:

+ +
number_to_human(543934, units: :distance)              # => "544 kilometers"
+number_to_human(54393498, units: :distance)            # => "54400 kilometers"
+number_to_human(54393498000, units: :distance)         # => "54.4 gazillion-distance"
+number_to_human(343, units: :distance, precision: 1)   # => "300 meters"
+number_to_human(1, units: :distance)                   # => "1 meter"
+number_to_human(0.34, units: :distance)                # => "34 centimeters"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 396
+def number_to_human(number, options = {})
+  delegate_number_helper_method(:number_to_human, number, options)
+end
+
+
+ +
+ +
+

+ + number_to_human_size(number, options = {}) + +

+ + +
+

Formats the bytes in number into a more understandable representation (e.g., giving it 1500 yields 1.5 KB). This method is useful for reporting file sizes to users. You can customize the format in the options hash.

+ +

See number_to_human if you want to pretty-print a generic number.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3).

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to true)

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to true)

    +
  • +

    :raise - If true, raises InvalidNumberError when the argument is invalid.

    +
+ +

Examples

+ +
number_to_human_size(123)                                          # => 123 Bytes
+number_to_human_size(1234)                                         # => 1.21 KB
+number_to_human_size(12345)                                        # => 12.1 KB
+number_to_human_size(1234567)                                      # => 1.18 MB
+number_to_human_size(1234567890)                                   # => 1.15 GB
+number_to_human_size(1234567890123)                                # => 1.12 TB
+number_to_human_size(1234567890123456)                             # => 1.1 PB
+number_to_human_size(1234567890123456789)                          # => 1.07 EB
+number_to_human_size(1234567, precision: 2)                        # => 1.2 MB
+number_to_human_size(483989, precision: 2)                         # => 470 KB
+number_to_human_size(1234567, precision: 2, separator: ',')        # => 1,2 MB
+number_to_human_size(1234567890123, precision: 5)                  # => "1.1228 TB"
+number_to_human_size(524288000, precision: 5)                      # => "500 MB"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 290
+def number_to_human_size(number, options = {})
+  delegate_number_helper_method(:number_to_human_size, number, options)
+end
+
+
+ +
+ +
+

+ + number_to_percentage(number, options = {}) + +

+ + +
+

Formats a number as a percentage string (e.g., 65%). You can customize the format in the options hash.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3).

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to false).

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to false).

    +
  • +

    :format - Specifies the format of the percentage string The number field is %n (defaults to “%n%”).

    +
  • +

    :raise - If true, raises InvalidNumberError when the argument is invalid.

    +
+ +

Examples

+ +
number_to_percentage(100)                                        # => 100.000%
+number_to_percentage("98")                                       # => 98.000%
+number_to_percentage(100, precision: 0)                          # => 100%
+number_to_percentage(1000, delimiter: '.', separator: ',')       # => 1.000,000%
+number_to_percentage(302.24398923423, precision: 5)              # => 302.24399%
+number_to_percentage(1000, locale: :fr)                          # => 1 000,000%
+number_to_percentage("98a")                                      # => 98a%
+number_to_percentage(100, format: "%n  %")                       # => 100.000  %
+
+number_to_percentage("98a", raise: true)                         # => InvalidNumberError
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 160
+def number_to_percentage(number, options = {})
+  delegate_number_helper_method(:number_to_percentage, number, options)
+end
+
+
+ +
+ +
+

+ + number_to_phone(number, options = {}) + +

+ + +
+

Formats a number into a phone number (US by default e.g., (555) 123-9876). You can customize the format in the options hash.

+ +

Options

+
  • +

    :area_code - Adds parentheses around the area code.

    +
  • +

    :delimiter - Specifies the delimiter to use (defaults to “-”).

    +
  • +

    :extension - Specifies an extension to add to the end of the generated number.

    +
  • +

    :country_code - Sets the country code for the phone number.

    +
  • +

    :pattern - Specifies how the number is divided into three groups with the custom regexp to override the default format.

    +
  • +

    :raise - If true, raises InvalidNumberError when the argument is invalid.

    +
+ +

Examples

+ +
number_to_phone(5551234)                                           # => 555-1234
+number_to_phone("5551234")                                         # => 555-1234
+number_to_phone(1235551234)                                        # => 123-555-1234
+number_to_phone(1235551234, area_code: true)                       # => (123) 555-1234
+number_to_phone(1235551234, delimiter: " ")                        # => 123 555 1234
+number_to_phone(1235551234, area_code: true, extension: 555)       # => (123) 555-1234 x 555
+number_to_phone(1235551234, country_code: 1)                       # => +1-123-555-1234
+number_to_phone("123a456")                                         # => 123a456
+number_to_phone("1234a567", raise: true)                           # => InvalidNumberError
+
+number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: ".")
+# => +1.123.555.1234 x 1343
+
+number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
+# => "(755) 6123-4567"
+number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/))
+# => "133-1234-5678"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 62
+def number_to_phone(number, options = {})
+  return unless number
+  options = options.symbolize_keys
+
+  parse_float(number, true) if options.delete(:raise)
+  ERB::Util.html_escape(ActiveSupport::NumberHelper.number_to_phone(number, options))
+end
+
+
+ +
+ +
+

+ + number_with_delimiter(number, options = {}) + +

+ + +
+

Formats a number with grouped thousands using delimiter (e.g., 12,324). You can customize the format in the options hash.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “,”).

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter_pattern - Sets a custom regular expression used for deriving the placement of delimiter. Helpful when using currency formats like INR.

    +
  • +

    :raise - If true, raises InvalidNumberError when the argument is invalid.

    +
+ +

Examples

+ +
 number_with_delimiter(12345678)                        # => 12,345,678
+ number_with_delimiter("123456")                        # => 123,456
+ number_with_delimiter(12345678.05)                     # => 12,345,678.05
+ number_with_delimiter(12345678, delimiter: ".")        # => 12.345.678
+ number_with_delimiter(12345678, delimiter: ",")        # => 12,345,678
+ number_with_delimiter(12345678.05, separator: " ")     # => 12,345,678 05
+ number_with_delimiter(12345678.05, locale: :fr)        # => 12 345 678,05
+ number_with_delimiter("112a")                          # => 112a
+ number_with_delimiter(98765432.98, delimiter: " ", separator: ",")
+ # => 98 765 432,98
+
+ number_with_delimiter("123456.78",
+   delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/)    # => "1,23,456.78"
+
+number_with_delimiter("112a", raise: true)              # => raise InvalidNumberError
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 199
+def number_with_delimiter(number, options = {})
+  delegate_number_helper_method(:number_to_delimited, number, options)
+end
+
+
+ +
+ +
+

+ + number_with_precision(number, options = {}) + +

+ + +
+

Formats a number with the specified level of :precision (e.g., 112.32 has a precision of 2 if :significant is false, and 5 if :significant is true). You can customize the format in the options hash.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3).

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to false).

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to false).

    +
  • +

    :raise - If true, raises InvalidNumberError when the argument is invalid.

    +
+ +

Examples

+ +
number_with_precision(111.2345)                                         # => 111.235
+number_with_precision(111.2345, precision: 2)                           # => 111.23
+number_with_precision(13, precision: 5)                                 # => 13.00000
+number_with_precision(389.32314, precision: 0)                          # => 389
+number_with_precision(111.2345, significant: true)                      # => 111
+number_with_precision(111.2345, precision: 1, significant: true)        # => 100
+number_with_precision(13, precision: 5, significant: true)              # => 13.000
+number_with_precision(111.234, locale: :fr)                             # => 111,234
+
+number_with_precision(13, precision: 5, significant: true, strip_insignificant_zeros: true)
+# => 13
+
+number_with_precision(389.32314, precision: 4, significant: true)       # => 389.3
+number_with_precision(1111.2345, precision: 2, separator: ',', delimiter: '.')
+# => 1.111,23
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 244
+def number_with_precision(number, options = {})
+  delegate_number_helper_method(:number_to_rounded, number, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/NumberHelper/InvalidNumberError.html b/src/5.2/classes/ActionView/Helpers/NumberHelper/InvalidNumberError.html new file mode 100644 index 0000000000..8ae846b604 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/NumberHelper/InvalidNumberError.html @@ -0,0 +1,127 @@ +--- +title: ActionView::Helpers::NumberHelper::InvalidNumberError +layout: default +--- +
+ +
+
+ +
+ +

Raised when argument number param given to the helpers is invalid and the option :raise is set to true.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + number
+ + + + +

Class Public methods

+ +
+

+ + new(number) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/number_helper.rb, line 21
+def initialize(number)
+  @number = number
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/OutputSafetyHelper.html b/src/5.2/classes/ActionView/Helpers/OutputSafetyHelper.html new file mode 100644 index 0000000000..6ab1e996fd --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/OutputSafetyHelper.html @@ -0,0 +1,216 @@ +--- +title: ActionView::Helpers::OutputSafetyHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + raw(stringish) + +

+ + +
+

This method outputs without escaping a string. Since escaping tags is now default, this can be used when you don't want Rails to automatically escape tags. This is not recommended if the data is coming from the user's input.

+ +

For example:

+ +
raw @user.name
+# => 'Jimmy <alert>Tables</alert>'
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/output_safety_helper.rb, line 18
+def raw(stringish)
+  stringish.to_s.html_safe
+end
+
+
+ +
+ +
+

+ + safe_join(array, sep = $,) + +

+ + +
+

This method returns an HTML safe string similar to what Array#join would return. The array is flattened, and all items, including the supplied separator, are HTML escaped unless they are HTML safe, and the returned string is marked as HTML safe.

+ +
safe_join([raw("<p>foo</p>"), "<p>bar</p>"], "<br />")
+# => "<p>foo</p>&lt;br /&gt;&lt;p&gt;bar&lt;/p&gt;"
+
+safe_join([raw("<p>foo</p>"), raw("<p>bar</p>")], raw("<br />"))
+# => "<p>foo</p><br /><p>bar</p>"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/output_safety_helper.rb, line 33
+def safe_join(array, sep = $,)
+  sep = ERB::Util.unwrapped_html_escape(sep)
+
+  array.flatten.map! { |i| ERB::Util.unwrapped_html_escape(i) }.join(sep).html_safe
+end
+
+
+ +
+ +
+

+ + to_sentence(array, options = {}) + +

+ + +
+

Converts the array to a comma-separated sentence where the last element is joined by the connector word. This is the html_safe-aware version of ActiveSupport's Array#to_sentence.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/output_safety_helper.rb, line 43
+def to_sentence(array, options = {})
+  options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
+
+  default_connectors = {
+    words_connector: ", ",
+    two_words_connector: " and ",
+    last_word_connector: ", and "
+  }
+  if defined?(I18n)
+    i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
+    default_connectors.merge!(i18n_connectors)
+  end
+  options = default_connectors.merge!(options)
+
+  case array.length
+  when 0
+    "".html_safe
+  when 1
+    ERB::Util.html_escape(array[0])
+  when 2
+    safe_join([array[0], array[1]], options[:two_words_connector])
+  else
+    safe_join([safe_join(array[0...-1], options[:words_connector]), options[:last_word_connector], array[-1]], nil)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/RecordTagHelper.html b/src/5.2/classes/ActionView/Helpers/RecordTagHelper.html new file mode 100644 index 0000000000..aed8216d9d --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/RecordTagHelper.html @@ -0,0 +1,54 @@ +--- +title: ActionView::Helpers::RecordTagHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/RenderingHelper.html b/src/5.2/classes/ActionView/Helpers/RenderingHelper.html new file mode 100644 index 0000000000..868fc35f88 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/RenderingHelper.html @@ -0,0 +1,220 @@ +--- +title: ActionView::Helpers::RenderingHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Rendering

+ +

Implements methods that allow rendering from a view context. In order to use this module, all you need is to implement view_renderer that returns an ActionView::Renderer object.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _layout_for(*args, &block) + +

+ + +
+

Overwrites _layout_for in the context object so it supports the case a block is passed to a partial. Returns the contents that are yielded to a layout, given a name or a block.

+ +

You can think of a layout as a method that is called with a block. If the user calls yield :some_name, the block, by default, returns content_for(:some_name). If the user calls simply yield, the default block returns content_for(:layout).

+ +

The user can override this default by passing a block to the layout:

+ +
# The template
+<%= render layout: "my_layout" do %>
+  Content
+<% end %>
+
+# The layout
+<html>
+  <%= yield %>
+</html>
+
+ +

In this case, instead of the default block, which would return content_for(:layout), this method returns the block that was passed in to render :layout, and the response would be

+ +
<html>
+  Content
+</html>
+
+ +

Finally, the block can take block arguments, which can be passed in by yield:

+ +
# The template
+<%= render layout: "my_layout" do |customer| %>
+  Hello <%= customer.name %>
+<% end %>
+
+# The layout
+<html>
+  <%= yield Struct.new(:name).new("David") %>
+</html>
+
+ +

In this case, the layout would receive the block passed into render :layout, and the struct specified would be passed into the block as an argument. The result would be

+ +
<html>
+  Hello David
+</html>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/rendering_helper.rb, line 88
+def _layout_for(*args, &block)
+  name = args.first
+
+  if block && !name.is_a?(Symbol)
+    capture(*args, &block)
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + render(options = {}, locals = {}, &block) + +

+ + +
+

Returns the result of a render that's dictated by the options hash. The primary options are:

+
  • +

    :partial - See ActionView::PartialRenderer.

    +
  • +

    :file - Renders an explicit template file (this used to be the old default), add :locals to pass in those.

    +
  • +

    :inline - Renders an inline template similar to how it's done in the controller.

    +
  • +

    :plain - Renders the text passed in out. Setting the content type as text/plain.

    +
  • +

    :html - Renders the HTML safe string passed in out, otherwise performs HTML escape on the string first. Setting the content type as text/html.

    +
  • +

    :body - Renders the text passed in, and inherits the content type of text/plain from ActionDispatch::Response object.

    +
+ +

If no options hash is passed or :update specified, the default is to render a partial and use the second parameter as the locals hash.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/rendering_helper.rb, line 27
+def render(options = {}, locals = {}, &block)
+  case options
+  when Hash
+    if block_given?
+      view_renderer.render_partial(self, options.merge(partial: options[:layout]), &block)
+    else
+      view_renderer.render(self, options)
+    end
+  else
+    view_renderer.render_partial(self, partial: options, locals: locals, &block)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/SanitizeHelper.html b/src/5.2/classes/ActionView/Helpers/SanitizeHelper.html new file mode 100644 index 0000000000..3996058105 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/SanitizeHelper.html @@ -0,0 +1,316 @@ +--- +title: ActionView::Helpers::SanitizeHelper +layout: default +--- +
+ +
+
+ +
+ +

The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. These helper methods extend Action View making them callable within your template files.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + sanitize(html, options = {}) + +

+ + +
+

Sanitizes HTML input, stripping all tags and attributes that aren't whitelisted.

+ +

It also strips href/src attributes with unsafe protocols like javascript:, while also protecting against attempts to use Unicode, ASCII, and hex character references to work around these protocol filters. All special characters will be escaped.

+ +

The default sanitizer is Rails::Html::WhiteListSanitizer. See Rails HTML Sanitizers for more information.

+ +

Custom sanitization rules can also be provided.

+ +

Please note that sanitizing user-provided text does not guarantee that the resulting markup is valid or even well-formed.

+ +

Options

+
  • +

    :tags - An array of allowed tags.

    +
  • +

    :attributes - An array of allowed attributes.

    +
  • +

    :scrubber - A Rails::Html scrubber or Loofah::Scrubber object that defines custom sanitization rules. A custom scrubber takes precedence over custom tags and attributes.

    +
+ +

Examples

+ +

Normal use:

+ +
<%= sanitize @comment.body %>
+
+ +

Providing custom whitelisted tags and attributes:

+ +
<%= sanitize @comment.body, tags: %w(strong em a), attributes: %w(href) %>
+
+ +

Providing a custom Rails::Html scrubber:

+ +
class CommentScrubber < Rails::Html::PermitScrubber
+  def initialize
+    super
+    self.tags = %w( form script comment blockquote )
+    self.attributes = %w( style )
+  end
+
+  def skip_node?(node)
+    node.text?
+  end
+end
+
+<%= sanitize @comment.body, scrubber: CommentScrubber.new %>
+
+ +

See Rails HTML Sanitizer for documentation about Rails::Html scrubbers.

+ +

Providing a custom Loofah::Scrubber:

+ +
scrubber = Loofah::Scrubber.new do |node|
+  node.remove if node.name == 'script'
+end
+
+<%= sanitize @comment.body, scrubber: scrubber %>
+
+ +

See Loofah’s documentation for more information about defining custom Loofah::Scrubber objects.

+ +

To set the default allowed tags or attributes across your application:

+ +
# In config/application.rb
+config.action_view.sanitized_allowed_tags = ['strong', 'em', 'a']
+config.action_view.sanitized_allowed_attributes = ['href', 'title']
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/sanitize_helper.rb, line 82
+def sanitize(html, options = {})
+  self.class.white_list_sanitizer.sanitize(html, options).try(:html_safe)
+end
+
+
+ +
+ +
+

+ + sanitize_css(style) + +

+ + +
+

Sanitizes a block of CSS code. Used by sanitize when it comes across a style attribute.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/sanitize_helper.rb, line 87
+def sanitize_css(style)
+  self.class.white_list_sanitizer.sanitize_css(style)
+end
+
+
+ +
+ +
+ + + +
+

Strips all link tags from html leaving just the link text.

+ +
strip_links('<a href="http://www.rubyonrails.org">Ruby on Rails</a>')
+# => Ruby on Rails
+
+strip_links('Please e-mail me at <a href="mailto:me@email.com">me@email.com</a>.')
+# => Please e-mail me at me@email.com.
+
+strip_links('Blog: <a href="http://www.myblog.com/" class="nav" target=\"_blank\">Visit</a>.')
+# => Blog: Visit.
+
+strip_links('<<a href="https://example.org">malformed & link</a>')
+# => &lt;malformed &amp; link
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+

+ + strip_tags(html) + +

+ + +
+

Strips all HTML tags from html, including comments and special characters.

+ +
strip_tags("Strip <i>these</i> tags!")
+# => Strip these tags!
+
+strip_tags("<b>Bold</b> no more!  <a href='more.html'>See more here</a>...")
+# => Bold no more!  See more here...
+
+strip_tags("<div id='top-bar'>Welcome to my website!</div>")
+# => Welcome to my website!
+
+strip_tags("> A quote from Smith & Wesson")
+# => &gt; A quote from Smith &amp; Wesson
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/sanitize_helper.rb, line 104
+def strip_tags(html)
+  self.class.full_sanitizer.sanitize(html)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/TagHelper.html b/src/5.2/classes/ActionView/Helpers/TagHelper.html new file mode 100644 index 0000000000..23aad5c90b --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/TagHelper.html @@ -0,0 +1,462 @@ +--- +title: ActionView::Helpers::TagHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides methods to generate HTML tags programmatically both as a modern HTML5 compliant builder style and legacy XHTML compliant tags.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BOOLEAN_ATTRIBUTES=%w(allowfullscreen async autofocus autoplay checked +compact controls declare default defaultchecked +defaultmuted defaultselected defer disabled +enabled formnovalidate hidden indeterminate inert +ismap itemscope loop multiple muted nohref +noresize noshade novalidate nowrap open +pauseonexit readonly required reversed scoped +seamless selected sortable truespeed typemustmatch +visible).to_set
 
PRE_CONTENT_STRINGS=Hash.new { "" }
 
TAG_PREFIXES=["aria", "data", :aria, :data].to_set
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + cdata_section(content) + +

+ + +
+

Returns a CDATA section with the given content. CDATA sections are used to escape blocks of text containing characters which would otherwise be recognized as markup. CDATA sections begin with the string <![CDATA[ and end with (and may not contain) the string ]]>.

+ +
cdata_section("<hello world>")
+# => <![CDATA[<hello world>]]>
+
+cdata_section(File.read("hello_world.txt"))
+# => <![CDATA[<hello from a text file]]>
+
+cdata_section("hello]]>world")
+# => <![CDATA[hello]]]]><![CDATA[>world]]>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/tag_helper.rb, line 291
+def cdata_section(content)
+  splitted = content.to_s.gsub(/\]\]\>/, "]]]]><![CDATA[>")
+  "<![CDATA[#{splitted}]]>".html_safe
+end
+
+
+ +
+ +
+

+ + content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) + +

+ + +
+

Returns an HTML block tag of type name surrounding the content. Add HTML attributes by passing an attributes hash to options. Instead of passing the content as an argument, you can also use a block in which case, you pass your options as the second parameter. Set escape to false to disable attribute value escaping. Note: this is legacy syntax, see tag method description for details.

+ +

Options

+ +

The options hash can be used with attributes with no value like (disabled and readonly), which you can give a value of true in the options hash. You can use symbols or strings for the attribute names.

+ +

Examples

+ +
content_tag(:p, "Hello world!")
+ # => <p>Hello world!</p>
+content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
+ # => <div class="strong"><p>Hello world!</p></div>
+content_tag(:div, "Hello world!", class: ["strong", "highlight"])
+ # => <div class="strong highlight">Hello world!</div>
+content_tag("select", options, multiple: true)
+ # => <select multiple="multiple">...options...</select>
+
+<%= content_tag :div, class: "strong" do -%>
+  Hello world!
+<% end -%>
+ # => <div class="strong">Hello world!</div>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/tag_helper.rb, line 269
+def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
+  if block_given?
+    options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
+    tag_builder.content_tag_string(name, capture(&block), options, escape)
+  else
+    tag_builder.content_tag_string(name, content_or_options_with_block, options, escape)
+  end
+end
+
+
+ +
+ +
+

+ + escape_once(html) + +

+ + +
+

Returns an escaped version of html without affecting existing escaped entities.

+ +
escape_once("1 < 2 &amp; 3")
+# => "1 &lt; 2 &amp; 3"
+
+escape_once("&lt;&lt; Accept & Checkout")
+# => "&lt;&lt; Accept &amp; Checkout"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/tag_helper.rb, line 303
+def escape_once(html)
+  ERB::Util.html_escape_once(html)
+end
+
+
+ +
+ +
+

+ + tag(name = nil, options = nil, open = false, escape = true) + +

+ + +
+

Returns an HTML tag.

+ +

Building HTML tags

+ +

Builds HTML5 compliant tags with a tag proxy. Every tag can be built with:

+ +
tag.<tag name>(optional content, options)
+
+ +

where tag name can be e.g. br, div, section, article, or any tag really.

+ +

Passing content

+ +

Tags can pass content to embed within it:

+ +
tag.h1 'All titles fit to print' # => <h1>All titles fit to print</h1>
+
+tag.div tag.p('Hello world!')  # => <div><p>Hello world!</p></div>
+
+ +

Content can also be captured with a block, which is useful in templates:

+ +
<%= tag.p do %>
+  The next great American novel starts here.
+<% end %>
+# => <p>The next great American novel starts here.</p>
+
+ +

Options

+ +

Use symbol keyed options to add attributes to the generated tag.

+ +
tag.section class: %w( kitties puppies )
+# => <section class="kitties puppies"></section>
+
+tag.section id: dom_id(@post)
+# => <section id="<generated dom id>"></section>
+
+ +

Pass true for any attributes that can render with no values, like disabled and readonly.

+ +
tag.input type: 'text', disabled: true
+# => <input type="text" disabled="disabled">
+
+ +

HTML5 data-* attributes can be set with a single data key pointing to a hash of sub-attributes.

+ +

To play nicely with JavaScript conventions, sub-attributes are dasherized.

+ +
tag.article data: { user_id: 123 }
+# => <article data-user-id="123"></article>
+
+ +

Thus data-user-id can be accessed as dataset.userId.

+ +

Data attribute values are encoded to JSON, with the exception of strings, symbols and BigDecimals. This may come in handy when using jQuery's HTML5-aware .data() from 1.4.3.

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

The generated attributes are escaped by default. This can be disabled using escape_attributes.

+ +
tag.img src: 'open & shut.png'
+# => <img src="open &amp; shut.png">
+
+tag.img src: 'open & shut.png', escape_attributes: false
+# => <img src="open & shut.png">
+
+ +

The tag builder respects HTML5 void elements if no content is passed, and omits closing tags for those elements.

+ +
# A standard element:
+tag.div # => <div></div>
+
+# A void element:
+tag.br  # => <br>
+
+ +

Legacy syntax

+ +

The following format is for legacy syntax support. It will be deprecated in future versions of Rails.

+ +
tag(name, options = nil, open = false, escape = true)
+
+ +

It returns an empty HTML tag of type name which by default is XHTML compliant. Set open to true to create an open tag compatible with HTML 4.0 and below. Add HTML attributes by passing an attributes hash to options. Set escape to false to disable attribute value escaping.

+ +

Options

+ +

You can use symbols or strings for the attribute names.

+ +

Use true with boolean attributes that can render with no value, like disabled and readonly.

+ +

HTML5 data-* attributes can be set with a single data key pointing to a hash of sub-attributes.

+ +

Examples

+ +
tag("br")
+# => <br />
+
+tag("br", nil, true)
+# => <br>
+
+tag("input", type: 'text', disabled: true)
+# => <input type="text" disabled="disabled" />
+
+tag("input", type: 'text', class: ["strong", "highlight"])
+# => <input class="strong highlight" type="text" />
+
+tag("img", src: "open & shut.png")
+# => <img src="open &amp; shut.png" />
+
+tag("img", {src: "open &amp; shut.png"}, false, false)
+# => <img src="open &amp; shut.png" />
+
+tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
+# => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/tag_helper.rb, line 235
+def tag(name = nil, options = nil, open = false, escape = true)
+  if name.nil?
+    tag_builder
+  else
+    "<#{name}#{tag_builder.tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/TextHelper.html b/src/5.2/classes/ActionView/Helpers/TextHelper.html new file mode 100644 index 0000000000..c018afb15e --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/TextHelper.html @@ -0,0 +1,831 @@ +--- +title: ActionView::Helpers::TextHelper +layout: default +--- +
+ +
+
+ +
+ +

The TextHelper module provides a set of methods for filtering, formatting and transforming strings, which can reduce the amount of inline Ruby code in your views. These helper methods extend Action View making them callable within your template files.

+ +

Sanitization

+ +

Most text helpers that generate HTML output sanitize the given input by default, but do not escape it. This means HTML tags will appear in the page but all malicious code will be removed. Let's look at some examples using the simple_format method:

+ +
simple_format('<a href="http://example.com/">Example</a>')
+# => "<p><a href=\"http://example.com/\">Example</a></p>"
+
+simple_format('<a href="javascript:alert(\'no!\')">Example</a>')
+# => "<p><a>Example</a></p>"
+
+ +

If you want to escape all content, you should invoke the h method before calling the text helper.

+ +
simple_format h('<a href="http://example.com/">Example</a>')
+# => "<p>&lt;a href=\"http://example.com/\"&gt;Example&lt;/a&gt;</p>"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + concat(string) + +

+ + +
+

The preferred method of outputting text in your views is to use the <%= “text” %> eRuby syntax. The regular puts and print methods do not operate as expected in an eRuby code block. If you absolutely must output text within a non-output code block (i.e., <% %>), you can use the concat method.

+ +
<%
+    concat "hello"
+    # is the equivalent of <%= "hello" %>
+
+    if logged_in
+      concat "Logged in!"
+    else
+      concat link_to('login', action: :login)
+    end
+    # will either display "Logged in!" or a login link
+%>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 54
+def concat(string)
+  output_buffer << string
+end
+
+
+ +
+ +
+

+ + current_cycle(name = "default") + +

+ + +
+

Returns the current cycle string after a cycle has been started. Useful for complex table highlighting or any other design need which requires the current cycle string in more than one place.

+ +
# Alternate background colors
+@items = [1,2,3,4]
+<% @items.each do |item| %>
+  <div style="background-color:<%= cycle("red","white","blue") %>">
+    <span style="background-color:<%= current_cycle %>"><%= item %></span>
+  </div>
+<% end %>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 378
+def current_cycle(name = "default")
+  cycle = get_cycle(name)
+  cycle.current_value if cycle
+end
+
+
+ +
+ +
+

+ + cycle(first_value, *values) + +

+ + +
+

Creates a Cycle object whose to_s method cycles through elements of an array every time it is called. This can be used for example, to alternate classes for table rows. You can use named cycles to allow nesting in loops. Passing a Hash as the last parameter with a :name key will create a named cycle. The default name for a cycle without a :name key is "default". You can manually reset a cycle by calling reset_cycle and passing the name of the cycle. The current cycle string can be obtained anytime using the current_cycle method.

+ +
 # Alternate CSS classes for even and odd numbers...
+ @items = [1,2,3,4]
+ <table>
+ <% @items.each do |item| %>
+   <tr class="<%= cycle("odd", "even") -%>">
+     <td><%= item %></td>
+   </tr>
+ <% end %>
+ </table>
+
+ # Cycle CSS classes for rows, and text colors for values within each row
+ @items = x = [{first: 'Robert', middle: 'Daniel', last: 'James'},
+              {first: 'Emily', middle: 'Shannon', maiden: 'Pike', last: 'Hicks'},
+             {first: 'June', middle: 'Dae', last: 'Jones'}]
+ <% @items.each do |item| %>
+   <tr class="<%= cycle("odd", "even", name: "row_class") -%>">
+     <td>
+       <% item.values.each do |value| %>
+         <%# Create a named cycle "colors" %>
+         <span style="color:<%= cycle("red", "green", "blue", name: "colors") -%>">
+           <%= value %>
+         </span>
+       <% end %>
+       <% reset_cycle("colors") %>
+     </td>
+  </tr>
+<% end %>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 354
+def cycle(first_value, *values)
+  options = values.extract_options!
+  name = options.fetch(:name, "default")
+
+  values.unshift(*first_value)
+
+  cycle = get_cycle(name)
+  unless cycle && cycle.values == values
+    cycle = set_cycle(name, Cycle.new(*values))
+  end
+  cycle.to_s
+end
+
+
+ +
+ +
+

+ + excerpt(text, phrase, options = {}) + +

+ + +
+

Extracts an excerpt from text that matches the first instance of phrase. The :radius option expands the excerpt on each side of the first occurrence of phrase by the number of characters defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the text, then the :omission option (which defaults to “…”) will be prepended/appended accordingly. Use the :separator option to choose the delimitation. The resulting string will be stripped in any case. If the phrase isn't found, nil is returned.

+ +
excerpt('This is an example', 'an', radius: 5)
+# => ...s is an exam...
+
+excerpt('This is an example', 'is', radius: 5)
+# => This is a...
+
+excerpt('This is an example', 'is')
+# => This is an example
+
+excerpt('This next thing is an example', 'ex', radius: 2)
+# => ...next...
+
+excerpt('This is also an example', 'an', radius: 8, omission: '<chop> ')
+# => <chop> is also an example
+
+excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1)
+# => ...a very beautiful...
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 175
+def excerpt(text, phrase, options = {})
+  return unless text && phrase
+
+  separator = options.fetch(:separator, nil) || ""
+  case phrase
+  when Regexp
+    regex = phrase
+  else
+    regex = /#{Regexp.escape(phrase)}/i
+  end
+
+  return unless matches = text.match(regex)
+  phrase = matches[0]
+
+  unless separator.empty?
+    text.split(separator).each do |value|
+      if value.match(regex)
+        phrase = value
+        break
+      end
+    end
+  end
+
+  first_part, second_part = text.split(phrase, 2)
+
+  prefix, first_part   = cut_excerpt_part(:first, first_part, separator, options)
+  postfix, second_part = cut_excerpt_part(:second, second_part, separator, options)
+
+  affix = [first_part, separator, phrase, separator, second_part].join.strip
+  [prefix, affix, postfix].join
+end
+
+
+ +
+ +
+

+ + highlight(text, phrases, options = {}) + +

+ + +
+

Highlights one or more phrases everywhere in text by inserting it into a :highlighter string. The highlighter can be specialized by passing :highlighter as a single-quoted string with \1 where the phrase is to be inserted (defaults to '<mark>1</mark>') or passing a block that receives each matched term. By default text is sanitized to prevent possible XSS attacks. If the input is trustworthy, passing false for :sanitize will turn sanitizing off.

+ +
highlight('You searched for: rails', 'rails')
+# => You searched for: <mark>rails</mark>
+
+highlight('You searched for: rails', /for|rails/)
+# => You searched <mark>for</mark>: <mark>rails</mark>
+
+highlight('You searched for: ruby, rails, dhh', 'actionpack')
+# => You searched for: ruby, rails, dhh
+
+highlight('You searched for: rails', ['for', 'rails'], highlighter: '<em>\1</em>')
+# => You searched <em>for</em>: <em>rails</em>
+
+highlight('You searched for: rails', 'rails', highlighter: '<a href="search?q=\1">\1</a>')
+# => You searched for: <a href="search?q=rails">rails</a>
+
+highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match, match)) }
+# => You searched for: <a href="search?q=rails">rails</a>
+
+highlight('<a href="javascript:alert(\'no!\')">ruby</a> on rails', 'rails', sanitize: false)
+# => <a href="javascript:alert('no!')">ruby</a> on <mark>rails</mark>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 132
+def highlight(text, phrases, options = {})
+  text = sanitize(text) if options.fetch(:sanitize, true)
+
+  if text.blank? || phrases.blank?
+    text || ""
+  else
+    match = Array(phrases).map do |p|
+      Regexp === p ? p.to_s : Regexp.escape(p)
+    end.join("|")
+
+    if block_given?
+      text.gsub(/(#{match})(?![^<]*?>)/i) { |found| yield found }
+    else
+      highlighter = options.fetch(:highlighter, '<mark>\1</mark>')
+      text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
+    end
+  end.html_safe
+end
+
+
+ +
+ +
+

+ + pluralize(count, singular, plural_arg = nil, plural: plural_arg, locale: I18n.locale) + +

+ + +
+

Attempts to pluralize the singular word unless count is 1. If plural is supplied, it will use that when count is > 1, otherwise it will use the Inflector to determine the plural form for the given locale, which defaults to I18n.locale

+ +

The word will be pluralized using rules defined for the locale (you must define your own inflection rules for languages other than English). See ActiveSupport::Inflector.pluralize

+ +
pluralize(1, 'person')
+# => 1 person
+
+pluralize(2, 'person')
+# => 2 people
+
+pluralize(3, 'person', plural: 'users')
+# => 3 users
+
+pluralize(0, 'person')
+# => 0 people
+
+pluralize(2, 'Person', locale: :de)
+# => 2 Personen
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 230
+def pluralize(count, singular, plural_arg = nil, plural: plural_arg, locale: I18n.locale)
+  word = if (count == 1 || count.to_s =~ /^1(\.0+)?$/)
+    singular
+  else
+    plural || singular.pluralize(locale)
+  end
+
+  "#{count || 0} #{word}"
+end
+
+
+ +
+ +
+

+ + reset_cycle(name = "default") + +

+ + +
+

Resets a cycle so that it starts from the first element the next time it is called. Pass in name to reset a named cycle.

+ +
# Alternate CSS classes for even and odd numbers...
+@items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]]
+<table>
+<% @items.each do |item| %>
+  <tr class="<%= cycle("even", "odd") -%>">
+      <% item.each do |value| %>
+        <span style="color:<%= cycle("#333", "#666", "#999", name: "colors") -%>">
+          <%= value %>
+        </span>
+      <% end %>
+
+      <% reset_cycle("colors") %>
+  </tr>
+<% end %>
+</table>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 401
+def reset_cycle(name = "default")
+  cycle = get_cycle(name)
+  cycle.reset if cycle
+end
+
+
+ +
+ +
+

+ + safe_concat(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 58
+def safe_concat(string)
+  output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
+end
+
+
+ +
+ +
+

+ + simple_format(text, html_options = {}, options = {}) + +

+ + +
+

Returns text transformed into HTML using simple formatting rules. Two or more consecutive newlines(\n\n or \r\n\r\n) are considered a paragraph and wrapped in <p> tags. One newline (\n or \r\n) is considered a linebreak and a <br /> tag is appended. This method does not remove the newlines from the text.

+ +

You can pass any HTML attributes into html_options. These will be added to all created paragraphs.

+ +

Options

+
  • +

    :sanitize - If false, does not sanitize text.

    +
  • +

    :wrapper_tag - String representing the wrapper tag, defaults to "p"

    +
+ +

Examples

+ +
my_text = "Here is some basic text...\n...with a line break."
+
+simple_format(my_text)
+# => "<p>Here is some basic text...\n<br />...with a line break.</p>"
+
+simple_format(my_text, {}, wrapper_tag: "div")
+# => "<div>Here is some basic text...\n<br />...with a line break.</div>"
+
+more_text = "We want to put a paragraph...\n\n...right there."
+
+simple_format(more_text)
+# => "<p>We want to put a paragraph...</p>\n\n<p>...right there.</p>"
+
+simple_format("Look ma! A class!", class: 'description')
+# => "<p class='description'>Look ma! A class!</p>"
+
+simple_format("<blink>Unblinkable.</blink>")
+# => "<p>Unblinkable.</p>"
+
+simple_format("<blink>Blinkable!</blink> It's true.", {}, sanitize: false)
+# => "<p><blink>Blinkable!</blink> It's true.</p>"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 302
+def simple_format(text, html_options = {}, options = {})
+  wrapper_tag = options.fetch(:wrapper_tag, :p)
+
+  text = sanitize(text) if options.fetch(:sanitize, true)
+  paragraphs = split_paragraphs(text)
+
+  if paragraphs.empty?
+    content_tag(wrapper_tag, nil, html_options)
+  else
+    paragraphs.map! { |paragraph|
+      content_tag(wrapper_tag, raw(paragraph), html_options)
+    }.join("\n\n").html_safe
+  end
+end
+
+
+ +
+ +
+

+ + truncate(text, options = {}, &block) + +

+ + +
+

Truncates a given text after a given :length if text is longer than :length (defaults to 30). The last characters will be replaced with the :omission (defaults to “…”) for a total length not exceeding :length.

+ +

Pass a :separator to truncate text at a natural break.

+ +

Pass a block if you want to show extra content when the text is truncated.

+ +

The result is marked as HTML-safe, but it is escaped by default, unless :escape is false. Care should be taken if text contains HTML tags or entities, because truncation may produce invalid HTML (such as unbalanced or incomplete tags).

+ +
truncate("Once upon a time in a world far far away")
+# => "Once upon a time in a world..."
+
+truncate("Once upon a time in a world far far away", length: 17)
+# => "Once upon a ti..."
+
+truncate("Once upon a time in a world far far away", length: 17, separator: ' ')
+# => "Once upon a..."
+
+truncate("And they found that many people were sleeping better.", length: 25, omission: '... (continued)')
+# => "And they f... (continued)"
+
+truncate("<p>Once upon a time in a world far far away</p>")
+# => "&lt;p&gt;Once upon a time in a wo..."
+
+truncate("<p>Once upon a time in a world far far away</p>", escape: false)
+# => "<p>Once upon a time in a wo..."
+
+truncate("Once upon a time in a world far far away") { link_to "Continue", "#" }
+# => "Once upon a time in a wo...<a href="#">Continue</a>"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 94
+def truncate(text, options = {}, &block)
+  if text
+    length  = options.fetch(:length, 30)
+
+    content = text.truncate(length, options)
+    content = options[:escape] == false ? content.html_safe : ERB::Util.html_escape(content)
+    content << capture(&block) if block_given? && text.length > length
+    content
+  end
+end
+
+
+ +
+ +
+

+ + word_wrap(text, line_width: 80, break_sequence: "\n") + +

+ + +
+

Wraps the text into lines no longer than line_width width. This method breaks on the first whitespace character that does not exceed line_width (which is 80 by default).

+ +
word_wrap('Once upon a time')
+# => Once upon a time
+
+word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
+# => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined...
+
+word_wrap('Once upon a time', line_width: 8)
+# => Once\nupon a\ntime
+
+word_wrap('Once upon a time', line_width: 1)
+# => Once\nupon\na\ntime
+
+You can also specify a custom +break_sequence+ ("\n" by default)
+
+word_wrap('Once upon a time', line_width: 1, break_sequence: "\r\n")
+# => Once\r\nupon\r\na\r\ntime
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/text_helper.rb, line 260
+def word_wrap(text, line_width: 80, break_sequence: "\n")
+  text.split("\n").collect! do |line|
+    line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1#{break_sequence}").strip : line
+  end * break_sequence
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/TranslationHelper.html b/src/5.2/classes/ActionView/Helpers/TranslationHelper.html new file mode 100644 index 0000000000..1421bd0cf4 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/TranslationHelper.html @@ -0,0 +1,301 @@ +--- +title: ActionView::Helpers::TranslationHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + l(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: localize +
+ + + +
+ +
+

+ + localize(*args) + +

+ + +
+

Delegates to I18n.localize with no additional functionality.

+ +

See rubydoc.info/github/svenfuchs/i18n/master/I18n/Backend/Base:localize for more information.

+
+ + + +
+ Also aliased as: l +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/translation_helper.rb, line 126
+def localize(*args)
+  I18n.localize(*args)
+end
+
+
+ +
+ +
+

+ + t(key, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: translate +
+ + + +
+ +
+

+ + translate(key, options = {}) + +

+ + +
+

Delegates to I18n#translate but also performs three additional functions.

+ +

First, it will ensure that any thrown MissingTranslation messages will be rendered as inline spans that:

+
  • +

    Have a translation-missing class applied

    +
  • +

    Contain the missing key as the value of the title attribute

    +
  • +

    Have a titleized version of the last key segment as text

    +
+ +

For example, the value returned for the missing translation key "blog.post.title" will be:

+ +
<span
+  class="translation_missing"
+  title="translation missing: en.blog.post.title">Title</span>
+
+ +

This allows for views to display rather reasonable strings while still giving developers a way to find missing translations.

+ +

If you would prefer missing translations to raise an error, you can opt out of span-wrapping behavior globally by setting ActionView::Base.raise_on_missing_translations = true or individually by passing raise: true as an option to translate.

+ +

Second, if the key starts with a period translate will scope the key by the current partial. Calling translate(".foo") from the people/index.html.erb template is equivalent to calling translate("people.index.foo"). This makes it less repetitive to translate many keys within the same partial and provides a convention to scope keys consistently.

+ +

Third, the translation will be marked as html_safe if the key has the suffix “_html” or the last element of the key is “html”. Calling translate("footer_html") or translate("footer.html") will return an HTML safe string that won't be escaped by other HTML helper methods. This naming convention helps to identify translations that include HTML tags so that you know what kind of output to expect when you call translate in a template and translators know which keys they can provide HTML values for.

+
+ + + +
+ Also aliased as: t +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/translation_helper.rb, line 60
+def translate(key, options = {})
+  options = options.dup
+  has_default = options.has_key?(:default)
+  remaining_defaults = Array(options.delete(:default)).compact
+
+  if has_default && !remaining_defaults.first.kind_of?(Symbol)
+    options[:default] = remaining_defaults
+  end
+
+  # If the user has explicitly decided to NOT raise errors, pass that option to I18n.
+  # Otherwise, tell I18n to raise an exception, which we rescue further in this method.
+  # Note: `raise_error` refers to us re-raising the error in this method. I18n is forced to raise by default.
+  if options[:raise] == false
+    raise_error = false
+    i18n_raise = false
+  else
+    raise_error = options[:raise] || ActionView::Base.raise_on_missing_translations
+    i18n_raise = true
+  end
+
+  if html_safe_translation_key?(key)
+    html_safe_options = options.dup
+
+    options.except(*I18n::RESERVED_KEYS).each do |name, value|
+      unless name == :count && value.is_a?(Numeric)
+        html_safe_options[name] = ERB::Util.html_escape(value.to_s)
+      end
+    end
+
+    html_safe_options[:default] = MISSING_TRANSLATION unless html_safe_options[:default].blank?
+
+    translation = I18n.translate(scope_key_by_partial(key), html_safe_options.merge(raise: i18n_raise))
+
+    if translation.equal?(MISSING_TRANSLATION)
+      options[:default].first
+    else
+      translation.respond_to?(:html_safe) ? translation.html_safe : translation
+    end
+  else
+    I18n.translate(scope_key_by_partial(key), options.merge(raise: i18n_raise))
+  end
+rescue I18n::MissingTranslationData => e
+  if remaining_defaults.present?
+    translate remaining_defaults.shift, options.merge(default: remaining_defaults)
+  else
+    raise e if raise_error
+
+    keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
+    title = "translation missing: #{keys.join('.')}".dup
+
+    interpolations = options.except(:default, :scope)
+    if interpolations.any?
+      title << ", " << interpolations.map { |k, v| "#{k}: #{ERB::Util.html_escape(v)}" }.join(", ")
+    end
+
+    return title unless ActionView::Base.debug_missing_translation
+
+    content_tag("span", keys.last.to_s.titleize, class: "translation_missing", title: title)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/UrlHelper.html b/src/5.2/classes/ActionView/Helpers/UrlHelper.html new file mode 100644 index 0000000000..53f8520180 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/UrlHelper.html @@ -0,0 +1,868 @@ +--- +title: ActionView::Helpers::UrlHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides a set of methods for making links and getting URLs that depend on the routing subsystem (see ActionDispatch::Routing). This allows you to use the same format for links in views and controllers.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
BUTTON_TAG_METHOD_VERBS=%w{patch put delete}
 

This helper may be included in any class that includes the URL helpers of a routes (routes.url_helpers). Some methods provided here will only work in the context of a request (link_to_unless_current, for instance), which must be provided as a method called request on the context.

STRINGIFIED_COMMON_METHODS={ +get: "get", +delete: "delete", +patch: "patch", +post: "post", +put: "put", +}.freeze
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + button_to(name = nil, options = nil, html_options = nil, &block) + +

+ + +
+

Generates a form containing a single button that submits to the URL created by the set of options. This is the safest method to ensure links that cause changes to your data are not triggered by search bots or accelerators. If the HTML button does not work with your layout, you can also consider using the link_to method with the :method modifier as described in the link_to documentation.

+ +

By default, the generated form element has a class name of button_to to allow styling of the form itself and its children. This can be changed using the :form_class modifier within html_options. You can control the form submission and input element behavior using html_options. This method accepts the :method modifier described in the link_to documentation. If no :method modifier is given, it will default to performing a POST operation. You can also disable the button by passing disabled: true in html_options. If you are using RESTful routes, you can pass the :method to change the HTTP verb used to submit the form.

+ +

Options

+ +

The options hash accepts the same options as url_for.

+ +

There are a few special html_options:

+
  • +

    :method - Symbol of HTTP verb. Supported verbs are :post, :get, :delete, :patch, and :put. By default it will be :post.

    +
  • +

    :disabled - If set to true, it will generate a disabled button.

    +
  • +

    :data - This option can be used to add custom data attributes.

    +
  • +

    :remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the submit behavior. By default this behavior is an ajax submit.

    +
  • +

    :form - This hash will be form attributes

    +
  • +

    :form_class - This controls the class of the form within which the submit button will be placed

    +
  • +

    :params - Hash of parameters to be rendered as hidden fields within the form.

    +
+ +

Data attributes

+
  • +

    :confirm - This will use the unobtrusive JavaScript driver to prompt with the question specified. If the user accepts, the link is processed normally, otherwise no action is taken.

    +
  • +

    :disable_with - Value of this parameter will be used as the value for a disabled version of the submit button when the form is submitted. This feature is provided by the unobtrusive JavaScript driver.

    +
+ +

Examples

+ +
<%= button_to "New", action: "new" %>
+# => "<form method="post" action="/controller/new" class="button_to">
+#      <input value="New" type="submit" />
+#    </form>"
+
+<%= button_to "New", new_article_path %>
+# => "<form method="post" action="/articles/new" class="button_to">
+#      <input value="New" type="submit" />
+#    </form>"
+
+<%= button_to [:make_happy, @user] do %>
+  Make happy <strong><%= @user.name %></strong>
+<% end %>
+# => "<form method="post" action="/users/1/make_happy" class="button_to">
+#      <button type="submit">
+#        Make happy <strong><%= @user.name %></strong>
+#      </button>
+#    </form>"
+
+<%= button_to "New", { action: "new" }, form_class: "new-thing" %>
+# => "<form method="post" action="/controller/new" class="new-thing">
+#      <input value="New" type="submit" />
+#    </form>"
+
+<%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
+# => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
+#      <input value="Create" type="submit" />
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
+#    </form>"
+
+<%= button_to "Delete Image", { action: "delete", id: @image.id },
+                                method: :delete, data: { confirm: "Are you sure?" } %>
+# => "<form method="post" action="/images/delete/1" class="button_to">
+#      <input type="hidden" name="_method" value="delete" />
+#      <input data-confirm='Are you sure?' value="Delete Image" type="submit" />
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
+#    </form>"
+
+<%= button_to('Destroy', 'http://www.example.com',
+          method: "delete", remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
+# => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
+#       <input name='_method' value='delete' type='hidden' />
+#       <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
+#       <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
+#     </form>"
+#
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/url_helper.rb, line 300
+def button_to(name = nil, options = nil, html_options = nil, &block)
+  html_options, options = options, name if block_given?
+  options      ||= {}
+  html_options ||= {}
+  html_options = html_options.stringify_keys
+
+  url    = options.is_a?(String) ? options : url_for(options)
+  remote = html_options.delete("remote")
+  params = html_options.delete("params")
+
+  method     = html_options.delete("method").to_s
+  method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".freeze.html_safe
+
+  form_method  = method == "get" ? "get" : "post"
+  form_options = html_options.delete("form") || {}
+  form_options[:class] ||= html_options.delete("form_class") || "button_to"
+  form_options[:method] = form_method
+  form_options[:action] = url
+  form_options[:'data-remote'] = true if remote
+
+  request_token_tag = if form_method == "post"
+    request_method = method.empty? ? "post" : method
+    token_tag(nil, form_options: { action: url, method: request_method })
+  else
+    "".freeze
+  end
+
+  html_options = convert_options_to_data_attributes(options, html_options)
+  html_options["type"] = "submit"
+
+  button = if block_given?
+    content_tag("button", html_options, &block)
+  else
+    html_options["value"] = name || url
+    tag("input", html_options)
+  end
+
+  inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
+  if params
+    to_form_params(params).each do |param|
+      inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value])
+    end
+  end
+  content_tag("form", inner_tags, form_options)
+end
+
+
+ +
+ +
+

+ + current_page?(options, check_parameters: false) + +

+ + +
+

True if the current request URI was generated by the given options.

+ +

Examples

+ +

Let's say we're in the http://www.example.com/shop/checkout?order=desc&page=1 action.

+ +
current_page?(action: 'process')
+# => false
+
+current_page?(action: 'checkout')
+# => true
+
+current_page?(controller: 'library', action: 'checkout')
+# => false
+
+current_page?(controller: 'shop', action: 'checkout')
+# => true
+
+current_page?(controller: 'shop', action: 'checkout', order: 'asc')
+# => false
+
+current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '1')
+# => true
+
+current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '2')
+# => false
+
+current_page?('http://www.example.com/shop/checkout')
+# => true
+
+current_page?('http://www.example.com/shop/checkout', check_parameters: true)
+# => false
+
+current_page?('/shop/checkout')
+# => true
+
+current_page?('http://www.example.com/shop/checkout?order=desc&page=1')
+# => true
+
+ +

Let's say we're in the http://www.example.com/products action with method POST in case of invalid product.

+ +
current_page?(controller: 'product', action: 'index')
+# => false
+
+ +

We can also pass in the symbol arguments instead of strings.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/url_helper.rb, line 543
+def current_page?(options, check_parameters: false)
+  unless request
+    raise "You cannot use helpers that need to determine the current " \
+          "page unless your view context provides a Request object " \
+          "in a #request method"
+  end
+
+  return false unless request.get? || request.head?
+
+  check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
+  url_string = URI.parser.unescape(url_for(options)).force_encoding(Encoding::BINARY)
+
+  # We ignore any extra parameters in the request_uri if the
+  # submitted url doesn't have any either. This lets the function
+  # work with things like ?order=asc
+  # the behaviour can be disabled with check_parameters: true
+  request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
+  request_uri = URI.parser.unescape(request_uri).force_encoding(Encoding::BINARY)
+
+  if url_string.start_with?("/") && url_string != "/"
+    url_string.chomp!("/")
+    request_uri.chomp!("/")
+  end
+
+  if %r{^\w+://}.match?(url_string)
+    url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
+  else
+    url_string == request_uri
+  end
+end
+
+
+ +
+ +
+ + + +
+

Creates an anchor element of the given name using a URL created by the set of options. See the valid options in the documentation for url_for. It's also possible to pass a String instead of an options hash, which generates an anchor element that uses the value of the String as the href for the link. Using a :back Symbol instead of an options hash will generate a link to the referrer (a JavaScript back link will be used in place of a referrer if none exists). If nil is passed as the name the value of the link itself will become the name.

+ + + +
link_to(body, url, html_options = {})
+  # url is a String; you can use URL helpers like
+  # posts_path
+
+link_to(body, url_options = {}, html_options = {})
+  # url_options, except :method, is passed to url_for
+
+link_to(options = {}, html_options = {}) do
+  # name
+end
+
+link_to(url, html_options = {}) do
+  # name
+end
+
+ + +
  • +

    :data - This option can be used to add custom data attributes.

    +
  • +

    method: symbol of HTTP verb - This modifier will dynamically create an HTML form and immediately submit the form for processing using the HTTP verb specified. Useful for having links perform a POST operation in dangerous actions like deleting a record (which search bots can follow while spidering your site). Supported verbs are :post, :delete, :patch, and :put. Note that if the user has JavaScript disabled, the request will fall back to using GET. If href: '#' is used and the user has JavaScript disabled clicking the link will have no effect. If you are relying on the POST behavior, you should check for it in your controller's action by using the request object's methods for post?, delete?, patch?, or put?.

    +
  • +

    remote: true - This will allow the unobtrusive JavaScript driver to make an Ajax request to the URL in question instead of following the link. The drivers each provide mechanisms for listening for the completion of the Ajax request and performing JavaScript operations once they're complete

    +
+ + +
  • +

    confirm: 'question?' - This will allow the unobtrusive JavaScript driver to prompt with the question specified (in this case, the resulting text would be question?. If the user accepts, the link is processed normally, otherwise no action is taken.

    +
  • +

    :disable_with - Value of this parameter will be used as the name for a disabled version of the link. This feature is provided by the unobtrusive JavaScript driver.

    +
+ + + +

Because it relies on url_for, link_to supports both older-style controller/action/id arguments and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base your application on resources and use

+ +
link_to "Profile", profile_path(@profile)
+# => <a href="/profiles/1">Profile</a>
+
+ +

or the even pithier

+ +
link_to "Profile", @profile
+# => <a href="/profiles/1">Profile</a>
+
+ +

in place of the older more verbose, non-resource-oriented

+ +
link_to "Profile", controller: "profiles", action: "show", id: @profile
+# => <a href="/profiles/show/1">Profile</a>
+
+ +

Similarly,

+ +
link_to "Profiles", profiles_path
+# => <a href="/profiles">Profiles</a>
+
+ +

is better than

+ +
link_to "Profiles", controller: "profiles"
+# => <a href="/profiles">Profiles</a>
+
+ +

When name is nil the href is presented instead

+ +
link_to nil, "http://example.com"
+# => <a href="http://www.example.com">http://www.example.com</a>
+
+ +

You can use a block as well if your link target is hard to fit into the name parameter. ERB example:

+ +
<%= link_to(@profile) do %>
+  <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
+<% end %>
+# => <a href="/profiles/1">
+       <strong>David</strong> -- <span>Check it out!</span>
+     </a>
+
+ +

Classes and ids for CSS are easy to produce:

+ +
link_to "Articles", articles_path, id: "news", class: "article"
+# => <a href="/articles" class="article" id="news">Articles</a>
+
+ +

Be careful when using the older argument style, as an extra literal hash is needed:

+ +
link_to "Articles", { controller: "articles" }, id: "news", class: "article"
+# => <a href="/articles" class="article" id="news">Articles</a>
+
+ +

Leaving the hash off gives the wrong link:

+ +
link_to "WRONG!", controller: "articles", id: "news", class: "article"
+# => <a href="/articles/index/news?class=article">WRONG!</a>
+
+ +

link_to can also produce links with anchors or query strings:

+ +
link_to "Comment wall", profile_path(@profile, anchor: "wall")
+# => <a href="/profiles/1#wall">Comment wall</a>
+
+link_to "Ruby on Rails search", controller: "searches", query: "ruby on rails"
+# => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>
+
+link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
+# => <a href="/searches?foo=bar&amp;baz=quux">Nonsense search</a>
+
+ +

The only option specific to link_to (:method) is used as follows:

+ +
link_to("Destroy", "http://www.example.com", method: :delete)
+# => <a href='http://www.example.com' rel="nofollow" data-method="delete">Destroy</a>
+
+ +

You can also use custom data attributes using the :data option:

+ +
link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
+# => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
+
+ +

Also you can set any link attributes such as target, rel, type:

+ +
link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
+# => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+ + + +
+

Creates a link tag of the given name using a URL created by the set of options if condition is true, otherwise only the name is returned. To specialize the default behavior, you can pass a block that accepts the name or the full argument list for link_to_unless (see the examples in link_to_unless).

+ + + +
<%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
+# If the user isn't logged in...
+# => <a href="/sessions/new/">Login</a>
+
+<%=
+   link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do
+     link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user })
+   end
+%>
+# If the user isn't logged in...
+# => <a href="/sessions/new/">Login</a>
+# If they are logged in...
+# => <a href="/accounts/show/3">my_username</a>
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+ + + +
+

Creates a link tag of the given name using a URL created by the set of options unless condition is true, in which case only the name is returned. To specialize the default behavior (i.e., show a login link rather than just the plaintext link text), you can pass a block that accepts the name or the full argument list for link_to_unless.

+ + + +
<%= link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) %>
+# If the user is logged in...
+# => <a href="/controller/reply/">Reply</a>
+
+<%=
+   link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) do |name|
+     link_to(name, { controller: "accounts", action: "signup" })
+   end
+%>
+# If the user is logged in...
+# => <a href="/controller/reply/">Reply</a>
+# If not...
+# => <a href="/accounts/signup">Reply</a>
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+ + + +
+

Creates a link tag of the given name using a URL created by the set of options unless the current request URI is the same as the links, in which case only the name is returned (or the given block is yielded, if one exists). You can give link_to_unless_current a block which will specialize the default behavior (e.g., show a “Start Here” link rather than the link's text).

+ + + +

Let's say you have a navigation menu…

+ +
<ul id="navbar">
+  <li><%= link_to_unless_current("Home", { action: "index" }) %></li>
+  <li><%= link_to_unless_current("About Us", { action: "about" }) %></li>
+</ul>
+
+ +

If in the “about” action, it will render…

+ +
<ul id="navbar">
+  <li><a href="/controller/index">Home</a></li>
+  <li>About Us</li>
+</ul>
+
+ +

…but if in the “index” action, it will render:

+ +
<ul id="navbar">
+  <li>Home</li>
+  <li><a href="/controller/about">About Us</a></li>
+</ul>
+
+ +

The implicit block given to link_to_unless_current is evaluated if the current action is the action given. So, if we had a comments page and wanted to render a “Go Back” link instead of a link to the comments page, we could do something like this…

+ +
<%=
+    link_to_unless_current("Comment", { controller: "comments", action: "new" }) do
+       link_to("Go back", { controller: "posts", action: "index" })
+    end
+ %>
+
+
+ + + + + + + + +
+ + + +
+ +
+ +
+

+ + mail_to(email_address, name = nil, html_options = {}, &block) + +

+ + +
+

Creates a mailto link tag to the specified email_address, which is also used as the name of the link unless name is specified. Additional HTML attributes for the link can be passed in html_options.

+ +

mail_to has several methods for customizing the email itself by passing special keys to html_options.

+ +

Options

+
  • +

    :subject - Preset the subject line of the email.

    +
  • +

    :body - Preset the body of the email.

    +
  • +

    :cc - Carbon Copy additional recipients on the email.

    +
  • +

    :bcc - Blind Carbon Copy additional recipients on the email.

    +
  • +

    :reply_to - Preset the Reply-To field of the email.

    +
+ +

Obfuscation

+ +

Prior to Rails 4.0, mail_to provided options for encoding the address in order to hinder email harvesters. To take advantage of these options, install the actionview-encoded_mail_to gem.

+ +

Examples

+ +
mail_to "me@domain.com"
+# => <a href="mailto:me@domain.com">me@domain.com</a>
+
+mail_to "me@domain.com", "My email"
+# => <a href="mailto:me@domain.com">My email</a>
+
+mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com",
+         subject: "This is an example email"
+# => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>
+
+ +

You can use a block as well if your link target is hard to fit into the name parameter. ERB example:

+ +
<%= mail_to "me@domain.com" do %>
+  <strong>Email me:</strong> <span>me@domain.com</span>
+<% end %>
+# => <a href="mailto:me@domain.com">
+       <strong>Email me:</strong> <span>me@domain.com</span>
+     </a>
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/url_helper.rb, line 482
+def mail_to(email_address, name = nil, html_options = {}, &block)
+  html_options, name = name, nil if block_given?
+  html_options = (html_options || {}).stringify_keys
+
+  extras = %w{ cc bcc body subject reply_to }.map! { |item|
+    option = html_options.delete(item).presence || next
+    "#{item.dasherize}=#{ERB::Util.url_encode(option)}"
+  }.compact
+  extras = extras.empty? ? "".freeze : "?" + extras.join("&")
+
+  encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
+  html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
+
+  content_tag("a".freeze, name || email_address, html_options, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Helpers/UrlHelper/ClassMethods.html b/src/5.2/classes/ActionView/Helpers/UrlHelper/ClassMethods.html new file mode 100644 index 0000000000..178fd7df10 --- /dev/null +++ b/src/5.2/classes/ActionView/Helpers/UrlHelper/ClassMethods.html @@ -0,0 +1,101 @@ +--- +title: ActionView::Helpers::UrlHelper::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _url_for_modules() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/helpers/url_helper.rb, line 27
+def _url_for_modules
+  ActionView::RoutingUrlFor
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Layouts.html b/src/5.2/classes/ActionView/Layouts.html new file mode 100644 index 0000000000..129e6b8f4a --- /dev/null +++ b/src/5.2/classes/ActionView/Layouts.html @@ -0,0 +1,331 @@ +--- +title: ActionView::Layouts +layout: default +--- +
+ +
+
+ +
+ +

Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in repeated setups. The inclusion pattern has pages that look like this:

+ +
<%= render "shared/header" %>
+Hello World
+<%= render "shared/footer" %>
+
+ +

This approach is a decent way of keeping common structures isolated from the changing content, but it's verbose and if you ever want to change the structure of these two includes, you'll have to change all the templates.

+ +

With layouts, you can flip it around and have the common structure know where to insert changing content. This means that the header and footer are only mentioned in one place, like this:

+ +
// The header part of this layout
+<%= yield %>
+// The footer part of this layout
+
+ +

And then you have content pages that look like this:

+ +
hello world
+
+ +

At rendering time, the content page is computed and then inserted in the layout, like this:

+ +
// The header part of this layout
+hello world
+// The footer part of this layout
+
+ +

Accessing shared variables

+ +

Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with references that won't materialize before rendering time:

+ +
<h1><%= @page_title %></h1>
+<%= yield %>
+
+ +

…and content pages that fulfill these references at rendering time:

+ +
<% @page_title = "Welcome" %>
+Off-world colonies offers you a chance to start a new life
+
+ +

The result after rendering is:

+ +
<h1>Welcome</h1>
+Off-world colonies offers you a chance to start a new life
+
+ +

Layout assignment

+ +

You can either specify a layout declaratively (using the layout class method) or give it the same name as your controller, and place it in app/views/layouts. If a subclass does not have a layout specified, it inherits its layout using normal Ruby inheritance.

+ +

For instance, if you have PostsController and a template named app/views/layouts/posts.html.erb, that template will be used for all actions in PostsController and controllers inheriting from PostsController.

+ +

If you use a module, for instance Weblog::PostsController, you will need a template named app/views/layouts/weblog/posts.html.erb.

+ +

Since all your controllers inherit from ApplicationController, they will use app/views/layouts/application.html.erb if no other layout is specified or provided.

+ +

Inheritance Examples

+ +
class BankController < ActionController::Base
+  # bank.html.erb exists
+
+class ExchangeController < BankController
+  # exchange.html.erb exists
+
+class CurrencyController < BankController
+
+class InformationController < BankController
+  layout "information"
+
+class TellerController < InformationController
+  # teller.html.erb exists
+
+class EmployeeController < InformationController
+  # employee.html.erb exists
+  layout nil
+
+class VaultController < BankController
+  layout :access_level_layout
+
+class TillController < BankController
+  layout false
+
+ +

In these examples, we have three implicit lookup scenarios:

+
  • +

    The BankController uses the “bank” layout.

    +
  • +

    The ExchangeController uses the “exchange” layout.

    +
  • +

    The CurrencyController inherits the layout from BankController.

    +
+ +

However, when a layout is explicitly set, the explicitly set layout wins:

+
  • +

    The InformationController uses the “information” layout, explicitly set.

    +
  • +

    The TellerController also uses the “information” layout, because the parent explicitly set it.

    +
  • +

    The EmployeeController uses the “employee” layout, because it set the layout to nil, resetting the parent configuration.

    +
  • +

    The VaultController chooses a layout dynamically by calling the access_level_layout method.

    +
  • +

    The TillController does not use a layout at all.

    +
+ +

Types of layouts

+ +

Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes you want to alternate layouts depending on runtime information, such as whether someone is logged in or not. This can be done either by specifying a method reference as a symbol or using an inline method (as a proc).

+ +

The method reference is the preferred approach to variable layouts and is used like this:

+ +
class WeblogController < ActionController::Base
+  layout :writers_and_readers
+
+  def index
+    # fetching posts
+  end
+
+  private
+    def writers_and_readers
+      logged_in? ? "writer_layout" : "reader_layout"
+    end
+end
+
+ +

Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing is logged in or not.

+ +

If you want to use an inline method, such as a proc, do something like this:

+ +
class WeblogController < ActionController::Base
+  layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
+end
+
+ +

If an argument isn't given to the proc, it's evaluated in the context of the current controller anyway.

+ +
class WeblogController < ActionController::Base
+  layout proc { logged_in? ? "writer_layout" : "reader_layout" }
+end
+
+ +

Of course, the most common way of specifying a layout is still just as a plain template name:

+ +
class WeblogController < ActionController::Base
+  layout "weblog_standard"
+end
+
+ +

The template will be looked always in app/views/layouts/ folder. But you can point layouts folder direct also. layout "layouts/demo" is the same as layout "demo".

+ +

Setting the layout to nil forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists. Setting it to nil is useful to re-enable template lookup overriding a previous configuration set in the parent:

+ +
class ApplicationController < ActionController::Base
+  layout "application"
+end
+
+class PostsController < ApplicationController
+  # Will use "application" layout
+end
+
+class CommentsController < ApplicationController
+  # Will search for "comments" layout and fallback "application" layout
+  layout nil
+end
+
+ +

Conditional layouts

+ +

If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering a given action or set of actions without a layout, or restricting a layout to only a single action or a set of actions. The :only and :except options can be passed to the layout call. For example:

+ +
class WeblogController < ActionController::Base
+  layout "weblog_standard", except: :rss
+
+  # ...
+
+end
+
+ +

This will assign “weblog_standard” as the WeblogController's layout for all actions except for the rss action, which will be rendered directly, without wrapping a layout around the rendered view.

+ +

Both the :only and :except condition can accept an arbitrary number of method references, so #except: [ :rss, :text_only ] is valid, as is except: :rss.

+ +

Using a different layout in the action render call

+ +

If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above. Sometimes you'll have exceptions where one action wants to use a different layout than the rest of the controller. You can do this by passing a :layout option to the render call. For example:

+ +
class WeblogController < ActionController::Base
+  layout "weblog_standard"
+
+  def help
+    render action: "help", layout: "help"
+  end
+end
+
+ +

This will override the controller-wide “weblog_standard” layout, and will render the help action with the “help” layout instead.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + action_has_layout?() + +

+ + +
+

Controls whether an action should be rendered using a layout. If you want to disable any layout settings for the current action so that it is rendered without a layout then either override this method in your controller to return false for that action or set the action_has_layout attribute to false before rendering.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/layouts.rb, line 370
+def action_has_layout?
+  @_action_has_layout
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Layouts/ClassMethods.html b/src/5.2/classes/ActionView/Layouts/ClassMethods.html new file mode 100644 index 0000000000..30310b65b4 --- /dev/null +++ b/src/5.2/classes/ActionView/Layouts/ClassMethods.html @@ -0,0 +1,142 @@ +--- +title: ActionView::Layouts::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + layout(layout, conditions = {}) + +

+ + +
+

Specify the layout to use for this class.

+ +

If the specified layout is a:

+
String +
+

the String is the template name

+
Symbol +
+

call the method specified by the symbol

+
Proc +
+

call the passed Proc

+
false +
+

There is no layout

+
true +
+

raise an ArgumentError

+
nil +
+

Force default layout behavior with inheritance

+
+ +

Return value of Proc and Symbol arguments should be String, false, true or nil with the same meaning as described above.

+ +

Parameters

+
  • +

    layout - The layout to use.

    +
+ +

Options (conditions)

+
  • +

    :only - A list of actions to apply this layout to.

    +
  • +

    :except - Apply this layout to all actions but this one.

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/layouts.rb, line 267
+def layout(layout, conditions = {})
+  include LayoutConditions unless conditions.empty?
+
+  conditions.each { |k, v| conditions[k] = Array(v).map(&:to_s) }
+  self._layout_conditions = conditions
+
+  self._layout = layout
+  _write_layout_method
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/LogSubscriber.html b/src/5.2/classes/ActionView/LogSubscriber.html new file mode 100644 index 0000000000..b8e73a5a6e --- /dev/null +++ b/src/5.2/classes/ActionView/LogSubscriber.html @@ -0,0 +1,533 @@ +--- +title: ActionView::LogSubscriber +layout: default +--- +
+ +
+
+ +
+ +

Action View Log Subscriber

+ +

Provides functionality so that Rails can output logs from Action View.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
EMPTY=""
 
VIEWS_PATTERN=/^app\/views\//
 
+ + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 12
+def initialize
+  @root = nil
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 52
+def logger
+  ActionView::Base.logger
+end
+
+
+ +
+ +
+

+ + render_collection(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 35
+def render_collection(event)
+  identifier = event.payload[:identifier] || "templates"
+
+  info do
+    "  Rendered collection of #{from_rails_root(identifier)}" \
+    " #{render_count(event.payload)} (#{event.duration.round(1)}ms)"
+  end
+end
+
+
+ +
+ +
+

+ + render_partial(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 25
+def render_partial(event)
+  info do
+    message = "  Rendered #{from_rails_root(event.payload[:identifier])}".dup
+    message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
+    message << " (#{event.duration.round(1)}ms)"
+    message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
+    message
+  end
+end
+
+
+ +
+ +
+

+ + render_template(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 17
+def render_template(event)
+  info do
+    message = "  Rendered #{from_rails_root(event.payload[:identifier])}".dup
+    message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
+    message << " (#{event.duration.round(1)}ms)"
+  end
+end
+
+
+ +
+ +
+

+ + start(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 44
+def start(name, id, payload)
+  if name == "render_template.action_view"
+    log_rendering_start(payload)
+  end
+
+  super
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + cache_message(payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 77
+def cache_message(payload) # :doc:
+  case payload[:cache_hit]
+  when :hit
+    "[cache hit]"
+  when :miss
+    "[cache miss]"
+  end
+end
+
+
+ +
+ +
+

+ + from_rails_root(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 59
+def from_rails_root(string) # :doc:
+  string = string.sub(rails_root, EMPTY)
+  string.sub!(VIEWS_PATTERN, EMPTY)
+  string
+end
+
+
+ +
+ +
+

+ + rails_root() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 65
+def rails_root # :doc:
+  @root ||= "#{Rails.root}/"
+end
+
+
+ +
+ +
+

+ + render_count(payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/log_subscriber.rb, line 69
+def render_count(payload) # :doc:
+  if payload[:cache_hits]
+    "[#{payload[:cache_hits]} / #{payload[:count]} cache hits]"
+  else
+    "[#{payload[:count]} times]"
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/LookupContext.html b/src/5.2/classes/ActionView/LookupContext.html new file mode 100644 index 0000000000..6d6075bd42 --- /dev/null +++ b/src/5.2/classes/ActionView/LookupContext.html @@ -0,0 +1,75 @@ +--- +title: ActionView::LookupContext +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/LookupContext/DetailsCache.html b/src/5.2/classes/ActionView/LookupContext/DetailsCache.html new file mode 100644 index 0000000000..8de1a60aea --- /dev/null +++ b/src/5.2/classes/ActionView/LookupContext/DetailsCache.html @@ -0,0 +1,168 @@ +--- +title: ActionView::LookupContext::DetailsCache +layout: default +--- +
+ +
+
+ +
+ +

Add caching behavior on top of Details.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + cache
+ + + + + +

Instance Public methods

+ +
+

+ + disable_cache() + +

+ + +
+

Temporary skip passing the details_key forward.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 89
+def disable_cache
+  old_value, @cache = @cache, false
+  yield
+ensure
+  @cache = old_value
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + _set_detail(key, value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 98
+def _set_detail(key, value) # :doc:
+  @details = @details.dup if @details_key
+  @details_key = nil
+  @details[key] = value
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/LookupContext/ViewPaths.html b/src/5.2/classes/ActionView/LookupContext/ViewPaths.html new file mode 100644 index 0000000000..a4b4ab8722 --- /dev/null +++ b/src/5.2/classes/ActionView/LookupContext/ViewPaths.html @@ -0,0 +1,518 @@ +--- +title: ActionView::LookupContext::ViewPaths +layout: default +--- +
+ +
+
+ +
+ +

Helpers related to template lookup using the lookup context information.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + html_fallback_for_js
+ [R] + view_paths
+ + + + + +

Instance Public methods

+ +
+

+ + any?(name, prefixes = [], partial = false) + +

+ + +
+ +
+ + + +
+ Also aliased as: any_templates? +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 133
+def any?(name, prefixes = [], partial = false)
+  @view_paths.exists?(*args_for_any(name, prefixes, partial))
+end
+
+
+ +
+ +
+

+ + any_templates?(name, prefixes = [], partial = false) + +

+ + +
+ +
+ + + + + +
+ Alias for: any? +
+ + + +
+ +
+

+ + exists?(name, prefixes = [], partial = false, keys = [], **options) + +

+ + +
+ +
+ + + +
+ Also aliased as: template_exists? +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 128
+def exists?(name, prefixes = [], partial = false, keys = [], **options)
+  @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))
+end
+
+
+ +
+ +
+

+ + find(name, prefixes = [], partial = false, keys = [], options = {}) + +

+ + +
+ +
+ + + +
+ Also aliased as: find_template +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 115
+def find(name, prefixes = [], partial = false, keys = [], options = {})
+  @view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options))
+end
+
+
+ +
+ +
+

+ + find_all(name, prefixes = [], partial = false, keys = [], options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 124
+def find_all(name, prefixes = [], partial = false, keys = [], options = {})
+  @view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options))
+end
+
+
+ +
+ +
+

+ + find_file(name, prefixes = [], partial = false, keys = [], options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 120
+def find_file(name, prefixes = [], partial = false, keys = [], options = {})
+  @view_paths.find_file(*args_for_lookup(name, prefixes, partial, keys, options))
+end
+
+
+ +
+ +
+

+ + find_template(name, prefixes = [], partial = false, keys = [], options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: find +
+ + + +
+ +
+

+ + template_exists?(name, prefixes = [], partial = false, keys = [], **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: exists? +
+ + + +
+ +
+

+ + view_paths=(paths) + +

+ + +
+

Whenever setting view paths, makes a copy so that we can manipulate them in instance objects as we wish.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 111
+def view_paths=(paths)
+  @view_paths = ActionView::PathSet.new(Array(paths))
+end
+
+
+ +
+ +
+

+ + with_fallbacks() + +

+ + +
+

Adds fallbacks to the view paths. Useful in cases when you are rendering a :file.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 140
+def with_fallbacks
+  added_resolvers = 0
+  self.class.fallbacks.each do |resolver|
+    next if view_paths.include?(resolver)
+    view_paths.push(resolver)
+    added_resolvers += 1
+  end
+  yield
+ensure
+  added_resolvers.times { view_paths.pop }
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + detail_args_for(options) + +

+ + +
+

Compute details hash and key according to user options (e.g. passed from render).

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/lookup_context.rb, line 161
+def detail_args_for(options) # :doc:
+  return @details, details_key if options.empty? # most common path.
+  user_details = @details.merge(options)
+
+  if @cache
+    details_key = DetailsKey.get(user_details)
+  else
+    details_key = nil
+  end
+
+  [user_details, details_key]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/NullResolver.html b/src/5.2/classes/ActionView/NullResolver.html new file mode 100644 index 0000000000..4a5e73b156 --- /dev/null +++ b/src/5.2/classes/ActionView/NullResolver.html @@ -0,0 +1,108 @@ +--- +title: ActionView::NullResolver +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + query(path, exts, _, _) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/testing/resolvers.rb, line 49
+def query(path, exts, _, _)
+  handler, format, variant = extract_handler_and_format_and_variant(path)
+  [ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: format, variant: variant)]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/PartialIteration.html b/src/5.2/classes/ActionView/PartialIteration.html new file mode 100644 index 0000000000..16bc88dee1 --- /dev/null +++ b/src/5.2/classes/ActionView/PartialIteration.html @@ -0,0 +1,211 @@ +--- +title: ActionView::PartialIteration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + index

The current iteration of the partial.

+ [R] + size

The number of iterations that will be done by the partial.

+ + + + +

Class Public methods

+ +
+

+ + new(size) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 14
+def initialize(size)
+  @size  = size
+  @index = 0
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + first?() + +

+ + +
+

Check if this is the first iteration of the partial.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 20
+def first?
+  index == 0
+end
+
+
+ +
+ +
+

+ + last?() + +

+ + +
+

Check if this is the last iteration of the partial.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 25
+def last?
+  index == size - 1
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/PartialRenderer.html b/src/5.2/classes/ActionView/PartialRenderer.html new file mode 100644 index 0000000000..a4c77a33e3 --- /dev/null +++ b/src/5.2/classes/ActionView/PartialRenderer.html @@ -0,0 +1,461 @@ +--- +title: ActionView::PartialRenderer +layout: default +--- +
+ +
+
+ +
+ +

Action View Partials

+ +

There's also a convenience method for rendering sub templates within the current controller that depends on a single object (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being prefixed with an underscore – as to separate them from regular templates that could be rendered on their own.

+ +

In a template for Advertiser#account:

+ +
<%= render partial: "account" %>
+
+ +

This would render “advertiser/_account.html.erb”.

+ +

In another template for Advertiser#buy, we could have:

+ +
<%= render partial: "account", locals: { account: @buyer } %>
+
+<% @advertisements.each do |ad| %>
+  <%= render partial: "ad", locals: { ad: ad } %>
+<% end %>
+
+ +

This would first render advertiser/_account.html.erb with @buyer passed in as the local variable account, then render advertiser/_ad.html.erb and pass the local variable ad to the template for display.

+ +

The :as and :object options

+ +

By default ActionView::PartialRenderer doesn't have any local variables. The :object option can be used to pass an object to the partial. For instance:

+ +
<%= render partial: "account", object: @buyer %>
+
+ +

would provide the @buyer object to the partial, available under the local variable account and is equivalent to:

+ +
<%= render partial: "account", locals: { account: @buyer } %>
+
+ +

With the :as option we can specify a different name for said local variable. For example, if we wanted it to be user instead of account we'd do:

+ +
<%= render partial: "account", object: @buyer, as: 'user' %>
+
+ +

This is equivalent to

+ +
<%= render partial: "account", locals: { user: @buyer } %>
+
+ +

Rendering a collection of partials

+ +

The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders a partial by the same name as the elements contained within. So the three-lined example in “Using partials” can be rewritten with a single line:

+ +
<%= render partial: "ad", collection: @advertisements %>
+
+ +

This will render advertiser/_ad.html.erb and pass the local variable ad to the template for display. An iteration object will automatically be made available to the template with a name of the form partial_name_iteration. The iteration object has knowledge about which index the current object has in the collection and the total size of the collection. The iteration object also has two convenience methods, first? and last?. In the case of the example above, the template would be fed ad_iteration. For backwards compatibility the partial_name_counter is still present and is mapped to the iteration's index method.

+ +

The :as option may be used when rendering partials.

+ +

You can specify a partial to be rendered between elements via the :spacer_template option. The following example will render advertiser/_ad_divider.html.erb between each ad partial:

+ +
<%= render partial: "ad", collection: @advertisements, spacer_template: "ad_divider" %>
+
+ +

If the given :collection is nil or empty, render will return nil. This will allow you to specify a text which will be displayed instead by using this form:

+ +
<%= render(partial: "ad", collection: @advertisements) || "There's no ad to be displayed" %>
+
+ +

NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also just keep domain objects, like Active Records, in there.

+ +

Rendering shared partials

+ +

Two controllers can share a set of partials and render them like this:

+ +
<%= render partial: "advertisement/ad", locals: { ad: @advertisement } %>
+
+ +

This will render the partial advertisement/_ad.html.erb regardless of which controller this is being called from.

+ +

Rendering objects that respond to to_partial_path

+ +

Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work and pick the proper path by checking to_partial_path method.

+ +
# @account.to_partial_path returns 'accounts/account', so it can be used to replace:
+# <%= render partial: "accounts/account", locals: { account: @account} %>
+<%= render partial: @account %>
+
+# @posts is an array of Post instances, so every post record returns 'posts/post' on +to_partial_path+,
+# that's why we can replace:
+# <%= render partial: "posts/post", collection: @posts %>
+<%= render partial: @posts %>
+
+ +

Rendering the default case

+ +

If you're not going to be using any of the options like collections or layouts, you can also use the short-hand defaults of render to render partials. Examples:

+ +
# Instead of <%= render partial: "account" %>
+<%= render "account" %>
+
+# Instead of <%= render partial: "account", locals: { account: @buyer } %>
+<%= render "account", account: @buyer %>
+
+# @account.to_partial_path returns 'accounts/account', so it can be used to replace:
+# <%= render partial: "accounts/account", locals: { account: @account} %>
+<%= render @account %>
+
+# @posts is an array of Post instances, so every post record returns 'posts/post' on +to_partial_path+,
+# that's why we can replace:
+# <%= render partial: "posts/post", collection: @posts %>
+<%= render @posts %>
+
+ +

Rendering partials with layouts

+ +

Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types of users:

+ +
<%# app/views/users/index.html.erb %>
+Here's the administrator:
+<%= render partial: "user", layout: "administrator", locals: { user: administrator } %>
+
+Here's the editor:
+<%= render partial: "user", layout: "editor", locals: { user: editor } %>
+
+<%# app/views/users/_user.html.erb %>
+Name: <%= user.name %>
+
+<%# app/views/users/_administrator.html.erb %>
+<div id="administrator">
+  Budget: $<%= user.budget %>
+  <%= yield %>
+</div>
+
+<%# app/views/users/_editor.html.erb %>
+<div id="editor">
+  Deadline: <%= user.deadline %>
+  <%= yield %>
+</div>
+
+ +

…this will return:

+ +
Here's the administrator:
+<div id="administrator">
+  Budget: $<%= user.budget %>
+  Name: <%= user.name %>
+</div>
+
+Here's the editor:
+<div id="editor">
+  Deadline: <%= user.deadline %>
+  Name: <%= user.name %>
+</div>
+
+ +

If a collection is given, the layout will be rendered once for each item in the collection. For example, these two snippets have the same output:

+ +
<%# app/views/users/_user.html.erb %>
+Name: <%= user.name %>
+
+<%# app/views/users/index.html.erb %>
+<%# This does not use layouts %>
+<ul>
+  <% users.each do |user| -%>
+    <li>
+      <%= render partial: "user", locals: { user: user } %>
+    </li>
+  <% end -%>
+</ul>
+
+<%# app/views/users/_li_layout.html.erb %>
+<li>
+  <%= yield %>
+</li>
+
+<%# app/views/users/index.html.erb %>
+<ul>
+  <%= render partial: "user", layout: "li_layout", collection: users %>
+</ul>
+
+ +

Given two users whose names are Alice and Bob, these snippets return:

+ +
<ul>
+  <li>
+    Name: Alice
+  </li>
+  <li>
+    Name: Bob
+  </li>
+</ul>
+
+ +

The current object being rendered, as well as the object_counter, will be available as local variables inside the layout template under the same names as available in the partial.

+ +

You can also apply a layout to a block within any template:

+ +
<%# app/views/users/_chief.html.erb %>
+<%= render(layout: "administrator", locals: { user: chief }) do %>
+  Title: <%= chief.title %>
+<% end %>
+
+ +

…this will return:

+ +
<div id="administrator">
+  Budget: $<%= user.budget %>
+  Title: <%= chief.name %>
+</div>
+
+ +

As you can see, the :locals hash is shared between both the partial and its layout.

+ +

If you pass arguments to “yield” then this will be passed to the block. One way to use this is to pass an array to layout and treat it as an enumerable.

+ +
<%# app/views/users/_user.html.erb %>
+<div class="user">
+  Budget: $<%= user.budget %>
+  <%= yield user %>
+</div>
+
+<%# app/views/users/index.html.erb %>
+<%= render layout: @users do |user| %>
+  Title: <%= user.title %>
+<% end %>
+
+ +

This will render the layout for each user and yield to the block, passing the user, each time.

+ +

You can also yield multiple times in one layout and use block arguments to differentiate the sections.

+ +
<%# app/views/users/_user.html.erb %>
+<div class="user">
+  <%= yield user, :header %>
+  Budget: $<%= user.budget %>
+  <%= yield user, :footer %>
+</div>
+
+<%# app/views/users/index.html.erb %>
+<%= render layout: @users do |user, section| %>
+  <%- case section when :header -%>
+    Title: <%= user.title %>
+  <%- when :footer -%>
+    Deadline: <%= user.deadline %>
+  <%- end -%>
+<% end %>
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDENTIFIER_ERROR_MESSAGE="The partial name (%s) is not a valid Ruby identifier; " \ +"make sure your partial name starts with underscore."
 
OPTION_AS_ERROR_MESSAGE="The value (%s) of the option `as` is not a valid Ruby identifier; " \ +"make sure it starts with lowercase letter, " \ +"and is followed by any combination of letters, numbers and underscores."
 
PREFIXED_PARTIAL_NAMES=Concurrent::Map.new do |h, k| +h[k] = Concurrent::Map.new +end
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 292
+def initialize(*)
+  super
+  @context_prefix = @lookup_context.prefixes.first
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + render(context, options, block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 297
+def render(context, options, block)
+  setup(context, options, block)
+  @template = find_partial
+
+  @lookup_context.rendered_format ||= begin
+    if @template && @template.formats.present?
+      @template.formats.first
+    else
+      formats.first
+    end
+  end
+
+  if @collection
+    render_collection
+  else
+    render_partial
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/RecordIdentifier.html b/src/5.2/classes/ActionView/RecordIdentifier.html new file mode 100644 index 0000000000..5769f3f481 --- /dev/null +++ b/src/5.2/classes/ActionView/RecordIdentifier.html @@ -0,0 +1,288 @@ +--- +title: ActionView::RecordIdentifier +layout: default +--- +
+ +
+
+ +
+ +

RecordIdentifier encapsulates methods used by various ActionView helpers to associate records with DOM elements.

+ +

Consider for example the following code that form of post:

+ +
<%= form_for(post) do |f| %>
+  <%= f.text_field :body %>
+<% end %>
+
+ +

When post is a new, unsaved ActiveRecord::Base instance, the resulting HTML is:

+ +
<form class="new_post" id="new_post" action="/posts" accept-charset="UTF-8" method="post">
+  <input type="text" name="post[body]" id="post_body" />
+</form>
+
+ +

When post is a persisted ActiveRecord::Base instance, the resulting HTML is:

+ +
<form class="edit_post" id="edit_post_42" action="/posts/42" accept-charset="UTF-8" method="post">
+  <input type="text" value="What a wonderful world!" name="post[body]" id="post_body" />
+</form>
+
+ +

In both cases, the id and class of the wrapping DOM element are automatically generated, following naming conventions encapsulated by the RecordIdentifier methods dom_id and dom_class:

+ +
dom_id(Post.new)         # => "new_post"
+dom_class(Post.new)      # => "post"
+dom_id(Post.find 42)     # => "post_42"
+dom_class(Post.find 42)  # => "post"
+
+ +

Note that these methods do not strictly require Post to be a subclass of ActiveRecord::Base. Any Post class will work as long as its instances respond to to_key and model_name, given that model_name responds to param_key. For instance:

+ +
class Post
+  attr_accessor :to_key
+
+  def model_name
+    OpenStruct.new param_key: 'post'
+  end
+
+  def self.find(id)
+    new.tap { |post| post.to_key = [id] }
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
JOIN="_".freeze
 
NEW="new".freeze
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + dom_class(record_or_class, prefix = nil) + +

+ + +
+

The DOM class convention is to use the singular form of an object or class.

+ +
dom_class(post)   # => "post"
+dom_class(Person) # => "person"
+
+ +

If you need to address multiple instances of the same class in the same view, you can prefix the dom_class:

+ +
dom_class(post, :edit)   # => "edit_post"
+dom_class(Person, :edit) # => "edit_person"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/record_identifier.rb, line 74
+def dom_class(record_or_class, prefix = nil)
+  singular = model_name_from_record_or_class(record_or_class).param_key
+  prefix ? "#{prefix}#{JOIN}#{singular}" : singular
+end
+
+
+ +
+ +
+

+ + dom_id(record, prefix = nil) + +

+ + +
+

The DOM id convention is to use the singular form of an object or class with the id following an underscore. If no id is found, prefix with “new_” instead.

+ +
dom_id(Post.find(45))       # => "post_45"
+dom_id(Post.new)            # => "new_post"
+
+ +

If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:

+ +
dom_id(Post.find(45), :edit) # => "edit_post_45"
+dom_id(Post.new, :custom)    # => "custom_post"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/record_identifier.rb, line 89
+def dom_id(record, prefix = nil)
+  if record_id = record_key_for_dom_id(record)
+    "#{dom_class(record, prefix)}#{JOIN}#{record_id}"
+  else
+    dom_class(record, prefix || NEW)
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + record_key_for_dom_id(record) + +

+ + +
+

Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id. This can be overwritten to customize the default generated string representation if desired. If you need to read back a key from a dom_id in order to query for the underlying database record, you should write a helper like 'person_record_from_dom_id' that will extract the key either based on the default implementation (which just joins all key attributes with '_') or on your own overwritten version of the method. By default, this implementation passes the key string through a method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to make sure yourself that your dom ids are valid, in case you overwrite this method.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/record_identifier.rb, line 107
+def record_key_for_dom_id(record) # :doc:
+  key = convert_to_model(record).to_key
+  key ? key.join(JOIN) : key
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Renderer.html b/src/5.2/classes/ActionView/Renderer.html new file mode 100644 index 0000000000..04dcdeb41a --- /dev/null +++ b/src/5.2/classes/ActionView/Renderer.html @@ -0,0 +1,220 @@ +--- +title: ActionView::Renderer +layout: default +--- +
+ +
+
+ +
+ +

This is the main entry point for rendering. It basically delegates to other objects like TemplateRenderer and PartialRenderer which actually renders the template.

+ +

The Renderer will parse the options from the render or render_body method and render a partial or a template based on the options. The TemplateRenderer and PartialRenderer objects are wrappers which do all the setup and logic necessary to render a view and a new object is created each time render is called.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + lookup_context
+ + + + +

Class Public methods

+ +
+

+ + new(lookup_context) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/renderer.rb, line 16
+def initialize(lookup_context)
+  @lookup_context = lookup_context
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + render(context, options) + +

+ + +
+

Main render entry point shared by Action View and Action Controller.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/renderer.rb, line 21
+def render(context, options)
+  if options.key?(:partial)
+    render_partial(context, options)
+  else
+    render_template(context, options)
+  end
+end
+
+
+ +
+ +
+

+ + render_body(context, options) + +

+ + +
+

Render but returns a valid Rack body. If fibers are defined, we return a streaming body that renders the template piece by piece.

+ +

Note that partials are not supported to be rendered with streaming, so in such cases, we just wrap them in an array.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/renderer/renderer.rb, line 34
+def render_body(context, options)
+  if options.key?(:partial)
+    [render_partial(context, options)]
+  else
+    StreamingTemplateRenderer.new(@lookup_context).render(context, options)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Rendering.html b/src/5.2/classes/ActionView/Rendering.html new file mode 100644 index 0000000000..19eabbf539 --- /dev/null +++ b/src/5.2/classes/ActionView/Rendering.html @@ -0,0 +1,258 @@ +--- +title: ActionView::Rendering +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + render_to_body(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/rendering.rb, line 82
+def render_to_body(options = {})
+  _process_options(options)
+  _render_template(options)
+end
+
+
+ +
+ +
+

+ + rendered_format() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/rendering.rb, line 87
+def rendered_format
+  Template::Types[lookup_context.rendered_format]
+end
+
+
+ +
+ +
+

+ + view_context() + +

+ + +
+

An instance of a view class. The default view class is ActionView::Base.

+ +

The view class must have the following methods: View.new[lookup_context, assigns, controller]

+ +
Create a new ActionView instance for a controller and we can also pass the arguments.
+
+ +

View#render(option)

+ +
Returns String with the rendered template
+
+ +

Override this method in a module to change the default behavior.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/rendering.rb, line 73
+def view_context
+  view_context_class.new(view_renderer, view_assigns, self)
+end
+
+
+ +
+ +
+

+ + view_context_class() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/rendering.rb, line 60
+def view_context_class
+  @_view_context_class ||= self.class.view_context_class
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Rendering/ClassMethods.html b/src/5.2/classes/ActionView/Rendering/ClassMethods.html new file mode 100644 index 0000000000..c1d1c9e5a8 --- /dev/null +++ b/src/5.2/classes/ActionView/Rendering/ClassMethods.html @@ -0,0 +1,116 @@ +--- +title: ActionView::Rendering::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + view_context_class() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/rendering.rb, line 38
+def view_context_class
+  @view_context_class ||= begin
+    supports_path = supports_path?
+    routes  = respond_to?(:_routes)  && _routes
+    helpers = respond_to?(:_helpers) && _helpers
+
+    Class.new(ActionView::Base) do
+      if routes
+        include routes.url_helpers(supports_path)
+        include routes.mounted_helpers
+      end
+
+      if helpers
+        include helpers
+      end
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Resolver.html b/src/5.2/classes/ActionView/Resolver.html new file mode 100644 index 0000000000..2641b0bfec --- /dev/null +++ b/src/5.2/classes/ActionView/Resolver.html @@ -0,0 +1,252 @@ +--- +title: ActionView::Resolver +layout: default +--- +
+ +
+
+ +
+ +

Action View Resolver

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 136
+def initialize
+  @cache = Cache.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + clear_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 140
+def clear_cache
+  @cache.clear
+end
+
+
+ +
+ +
+

+ + find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = []) + +

+ + +
+

Normalizes the arguments and passes it on to find_templates.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 145
+def find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = [])
+  cached(key, [name, prefix, partial], details, locals) do
+    find_templates(name, prefix, partial, details)
+  end
+end
+
+
+ +
+ +
+

+ + find_all_anywhere(name, prefix, partial = false, details = {}, key = nil, locals = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 151
+def find_all_anywhere(name, prefix, partial = false, details = {}, key = nil, locals = [])
+  cached(key, [name, prefix, partial], details, locals) do
+    find_templates(name, prefix, partial, details, true)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Resolver/Cache.html b/src/5.2/classes/ActionView/Resolver/Cache.html new file mode 100644 index 0000000000..677716734c --- /dev/null +++ b/src/5.2/classes/ActionView/Resolver/Cache.html @@ -0,0 +1,73 @@ +--- +title: ActionView::Resolver::Cache +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Resolver/Cache/SmallCache.html b/src/5.2/classes/ActionView/Resolver/Cache/SmallCache.html new file mode 100644 index 0000000000..04844e6474 --- /dev/null +++ b/src/5.2/classes/ActionView/Resolver/Cache/SmallCache.html @@ -0,0 +1,107 @@ +--- +title: ActionView::Resolver::Cache::SmallCache +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 41
+def initialize(options = {})
+  super(options.merge(initial_capacity: 2))
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Resolver/Path.html b/src/5.2/classes/ActionView/Resolver/Path.html new file mode 100644 index 0000000000..821854a75f --- /dev/null +++ b/src/5.2/classes/ActionView/Resolver/Path.html @@ -0,0 +1,278 @@ +--- +title: ActionView::Resolver::Path +layout: default +--- +
+ +
+
+ +
+ +

Keeps all information about view path and builds virtual path.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + name
+ [R] + partial
+ [R] + partial?
+ [R] + prefix
+ [R] + virtual
+ + + + +

Class Public methods

+ +
+

+ + build(name, prefix, partial) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 18
+def self.build(name, prefix, partial)
+  virtual = "".dup
+  virtual << "#{prefix}/" unless prefix.empty?
+  virtual << (partial ? "_#{name}" : name)
+  new name, prefix, partial, virtual
+end
+
+
+ +
+ +
+

+ + new(name, prefix, partial, virtual) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 25
+def initialize(name, prefix, partial, virtual)
+  @name    = name
+  @prefix  = prefix
+  @partial = partial
+  @virtual = virtual
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_str +
+ + + +
+ +
+

+ + to_str() + +

+ + +
+ +
+ + + +
+ Also aliased as: to_s +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/template/resolver.rb, line 32
+def to_str
+  @virtual
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/RoutingUrlFor.html b/src/5.2/classes/ActionView/RoutingUrlFor.html new file mode 100644 index 0000000000..ab913dc4b5 --- /dev/null +++ b/src/5.2/classes/ActionView/RoutingUrlFor.html @@ -0,0 +1,213 @@ +--- +title: ActionView::RoutingUrlFor +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + url_for(options = nil) + +

+ + +
+

Returns the URL for the set of options provided. This takes the same options as url_for in Action Controller (see the documentation for ActionController::Base#url_for). Note that by default :only_path is true so you'll get the relative “/controller/action” instead of the fully qualified URL like “example.com/controller/action”.

+ +

Options

+
  • +

    :anchor - Specifies the anchor name to be appended to the path.

    +
  • +

    :only_path - If true, returns the relative URL (omitting the protocol, host name, and port) (true by default unless :host is specified).

    +
  • +

    :trailing_slash - If true, adds a trailing slash, as in “/archive/2005/”. Note that this is currently not recommended since it breaks caching.

    +
  • +

    :host - Overrides the default (current) host if provided.

    +
  • +

    :protocol - Overrides the default (current) protocol if provided.

    +
  • +

    :user - Inline HTTP authentication (only plucked out if :password is also present).

    +
  • +

    :password - Inline HTTP authentication (only plucked out if :user is also present).

    +
+ +

Relying on named routes

+ +

Passing a record (like an Active Record) instead of a hash as the options parameter will trigger the named route for that record. The lookup will happen on the name of the class. So passing a Workshop object will attempt to use the workshop_path route. If you have a nested route, such as admin_workshop_path you'll have to call that explicitly (it's impossible for url_for to guess that route).

+ +

Implicit Controller Namespacing

+ +

Controllers passed in using the :controller option will retain their namespace unless it is an absolute one.

+ +

Examples

+ +
<%= url_for(action: 'index') %>
+# => /blogs/
+
+<%= url_for(action: 'find', controller: 'books') %>
+# => /books/find
+
+<%= url_for(action: 'login', controller: 'members', only_path: false, protocol: 'https') %>
+# => https://www.example.com/members/login/
+
+<%= url_for(action: 'play', anchor: 'player') %>
+# => /messages/play/#player
+
+<%= url_for(action: 'jump', anchor: 'tax&ship') %>
+# => /testing/jump/#tax&ship
+
+<%= url_for(Workshop.new) %>
+# relies on Workshop answering a persisted? call (and in this case returning false)
+# => /workshops
+
+<%= url_for(@workshop) %>
+# calls @workshop.to_param which by default returns the id
+# => /workshops/5
+
+# to_param can be re-defined in a model to provide different URL names:
+# => /workshops/1-workshop-name
+
+<%= url_for("http://www.example.com") %>
+# => http://www.example.com
+
+<%= url_for(:back) %>
+# if request.env["HTTP_REFERER"] is set to "http://www.example.com"
+# => http://www.example.com
+
+<%= url_for(:back) %>
+# if request.env["HTTP_REFERER"] is not set or is blank
+# => javascript:history.back()
+
+<%= url_for(action: 'index', controller: 'users') %>
+# Assuming an "admin" namespace
+# => /admin/users
+
+<%= url_for(action: 'index', controller: '/users') %>
+# Specify absolute path with beginning slash
+# => /users
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/routing_url_for.rb, line 79
+def url_for(options = nil)
+  case options
+  when String
+    options
+  when nil
+    super(only_path: _generate_paths_by_default)
+  when Hash
+    options = options.symbolize_keys
+    unless options.key?(:only_path)
+      options[:only_path] = only_path?(options[:host])
+    end
+
+    super(options)
+  when ActionController::Parameters
+    unless options.key?(:only_path)
+      options[:only_path] = only_path?(options[:host])
+    end
+
+    super(options)
+  when :back
+    _back_url
+  when Array
+    components = options.dup
+    if _generate_paths_by_default
+      polymorphic_path(components, components.extract_options!)
+    else
+      polymorphic_url(components, components.extract_options!)
+    end
+  else
+    method = _generate_paths_by_default ? :path : :url
+    builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.send(method)
+
+    case options
+    when Symbol
+      builder.handle_string_call(self, options)
+    when Class
+      builder.handle_class_call(self, options)
+    else
+      builder.handle_model_call(self, options)
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Template.html b/src/5.2/classes/ActionView/Template.html new file mode 100644 index 0000000000..4423107658 --- /dev/null +++ b/src/5.2/classes/ActionView/Template.html @@ -0,0 +1,627 @@ +--- +title: ActionView::Template +layout: default +--- +
+ +
+
+ +
+ +

Action View Template

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + formats
+ [R] + handler
+ [R] + identifier
+ [RW] + locals
+ [R] + original_encoding
+ [R] + source
+ [R] + updated_at
+ [RW] + variants
+ [RW] + virtual_path
+ + + + +

Class Public methods

+ +
+

+ + new(source, identifier, handler, details) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 128
+def initialize(source, identifier, handler, details)
+  format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))
+
+  @source            = source
+  @identifier        = identifier
+  @handler           = handler
+  @compiled          = false
+  @original_encoding = nil
+  @locals            = details[:locals] || []
+  @virtual_path      = details[:virtual_path]
+  @updated_at        = details[:updated_at] || Time.now
+  @formats           = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f  }
+  @variants          = [details[:variant]]
+  @compile_mutex     = Mutex.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + encode!() + +

+ + +
+

This method is responsible for properly setting the encoding of the source. Until this point, we assume that the source is BINARY data. If no additional information is supplied, we assume the encoding is the same as Encoding.default_external.

+ +

The user can also specify the encoding via a comment on the first line of the template (# encoding: NAME-OF-ENCODING). This will work with any template engine, as we process out the encoding comment before passing the source on to the template engine, leaving a blank line in its stead.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 202
+def encode!
+  return unless source.encoding == Encoding::BINARY
+
+  # Look for # encoding: *. If we find one, we'll encode the
+  # String in that encoding, otherwise, we'll use the
+  # default external encoding.
+  if source.sub!(/\A#{ENCODING_FLAG}/, "")
+    encoding = magic_encoding = $1
+  else
+    encoding = Encoding.default_external
+  end
+
+  # Tag the source with the default external encoding
+  # or the encoding specified in the file
+  source.force_encoding(encoding)
+
+  # If the user didn't specify an encoding, and the handler
+  # handles encodings, we simply pass the String as is to
+  # the handler (with the default_external tag)
+  if !magic_encoding && @handler.respond_to?(:handles_encoding?) && @handler.handles_encoding?
+    source
+  # Otherwise, if the String is valid in the encoding,
+  # encode immediately to default_internal. This means
+  # that if a handler doesn't handle encodings, it will
+  # always get Strings in the default_internal
+  elsif source.valid_encoding?
+    source.encode!
+  # Otherwise, since the String is invalid in the encoding
+  # specified, raise an exception
+  else
+    raise WrongEncodingError.new(source, encoding)
+  end
+end
+
+
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 188
+def inspect
+  @inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", "".freeze) : identifier
+end
+
+
+ +
+ +
+

+ + local_assigns + +

+ + +
+

Returns a hash with the defined local variables.

+ +

Given this sub template rendering:

+ +
<%= render "shared/header", { headline: "Welcome", person: person } %>
+
+ +

You can use local_assigns in the sub templates to access the local variables:

+ +
local_assigns[:headline] # => "Welcome"
+
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 104
+eager_autoload do
+  autoload :Error
+  autoload :Handlers
+  autoload :HTML
+  autoload :Text
+  autoload :Types
+end
+
+
+ +
+ +
+

+ + refresh(view) + +

+ + +
+

Receives a view object and return a template similar to self by using @virtual_path.

+ +

This method is useful if you have a template object but it does not contain its source anymore since it was already compiled. In such cases, all you need to do is to call refresh passing in the view object.

+ +

Notice this method raises an error if the template to be refreshed does not have a virtual path set (true just for inline templates).

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 177
+def refresh(view)
+  raise "A template needs to have a virtual path in order to be refreshed" unless @virtual_path
+  lookup  = view.lookup_context
+  pieces  = @virtual_path.split("/")
+  name    = pieces.pop
+  partial = !!name.sub!(/^_/, "")
+  lookup.disable_cache do
+    lookup.find_template(name, [ pieces.join("/") ], partial, @locals)
+  end
+end
+
+
+ +
+ +
+

+ + render(view, locals, buffer = nil, &block) + +

+ + +
+

Render a template. If the template was not compiled yet, it is done exactly before rendering.

+ +

This method is instrumented as “!render_template.action_view”. Notice that we use a bang in this instrumentation because you don't want to consume this in production. This is only slow if it's being listened to.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 156
+def render(view, locals, buffer = nil, &block)
+  instrument_render_template do
+    compile!(view)
+    view.send(method_name, locals, buffer, &block)
+  end
+rescue => e
+  handle_render_error(view, e)
+end
+
+
+ +
+ +
+

+ + supports_streaming?() + +

+ + +
+

Returns whether the underlying handler supports streaming. If so, a streaming buffer may be passed when it starts rendering.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 146
+def supports_streaming?
+  handler.respond_to?(:supports_streaming?) && handler.supports_streaming?
+end
+
+
+ +
+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 165
+def type
+  @type ||= Types[@formats.first] if @formats.first
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + instrument(action, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template.rb, line 349
+def instrument(action, &block) # :doc:
+  ActiveSupport::Notifications.instrument("#{action}.action_view", instrument_payload, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Template/Handlers.html b/src/5.2/classes/ActionView/Template/Handlers.html new file mode 100644 index 0000000000..36b37b9328 --- /dev/null +++ b/src/5.2/classes/ActionView/Template/Handlers.html @@ -0,0 +1,83 @@ +--- +title: ActionView::Template::Handlers +layout: default +--- + diff --git a/src/5.2/classes/ActionView/Template/Handlers/Builder.html b/src/5.2/classes/ActionView/Template/Handlers/Builder.html new file mode 100644 index 0000000000..a164ac9eb3 --- /dev/null +++ b/src/5.2/classes/ActionView/Template/Handlers/Builder.html @@ -0,0 +1,156 @@ +--- +title: ActionView::Template::Handlers::Builder +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + call(template) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/builder.rb, line 8
+def call(template)
+  require_engine
+  "xml = ::Builder::XmlMarkup.new(:indent => 2);" \
+    "self.output_buffer = xml.target!;" +
+    template.source +
+    ";xml.target!;"
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + require_engine() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/builder.rb, line 17
+def require_engine # :doc:
+  @required ||= begin
+    require "builder"
+    true
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Template/Handlers/ERB.html b/src/5.2/classes/ActionView/Template/Handlers/ERB.html new file mode 100644 index 0000000000..c6b9b85ca7 --- /dev/null +++ b/src/5.2/classes/ActionView/Template/Handlers/ERB.html @@ -0,0 +1,265 @@ +--- +title: ActionView::Template::Handlers::ERB +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ENCODING_TAG=Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
 
+ + + + + + +

Class Public methods

+ +
+

+ + call(template) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/erb.rb, line 21
+def self.call(template)
+  new.call(template)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(template) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/erb.rb, line 33
+def call(template)
+  # First, convert to BINARY, so in case the encoding is
+  # wrong, we can still find an encoding tag
+  # (<%# encoding %>) inside the String using a regular
+  # expression
+  template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)
+
+  erb = template_source.gsub(ENCODING_TAG, "")
+  encoding = $2
+
+  erb.force_encoding valid_encoding(template.source.dup, encoding)
+
+  # Always make sure we return a String in the default_internal
+  erb.encode!
+
+  self.class.erb_implementation.new(
+    erb,
+    escape: (self.class.escape_whitelist.include? template.type),
+    trim: (self.class.erb_trim_mode == "-")
+  ).src
+end
+
+
+ +
+ +
+

+ + handles_encoding?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/erb.rb, line 29
+def handles_encoding?
+  true
+end
+
+
+ +
+ +
+

+ + supports_streaming?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/erb.rb, line 25
+def supports_streaming?
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Template/Handlers/Html.html b/src/5.2/classes/ActionView/Template/Handlers/Html.html new file mode 100644 index 0000000000..296239d512 --- /dev/null +++ b/src/5.2/classes/ActionView/Template/Handlers/Html.html @@ -0,0 +1,107 @@ +--- +title: ActionView::Template::Handlers::Html +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + call(template) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/html.rb, line 6
+def call(template)
+  "ActionView::OutputBuffer.new #{super}"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Template/Handlers/Raw.html b/src/5.2/classes/ActionView/Template/Handlers/Raw.html new file mode 100644 index 0000000000..8bbf740c01 --- /dev/null +++ b/src/5.2/classes/ActionView/Template/Handlers/Raw.html @@ -0,0 +1,107 @@ +--- +title: ActionView::Template::Handlers::Raw +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + call(template) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/handlers/raw.rb, line 6
+def call(template)
+  "#{template.source.inspect}.html_safe;"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Template/Types.html b/src/5.2/classes/ActionView/Template/Types.html new file mode 100644 index 0000000000..1531a2bde1 --- /dev/null +++ b/src/5.2/classes/ActionView/Template/Types.html @@ -0,0 +1,198 @@ +--- +title: ActionView::Template::Types +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + [](type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 48
+def self.[](type)
+  type_klass[type]
+end
+
+
+ +
+ +
+

+ + delegate_to(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 42
+def self.delegate_to(klass)
+  self.type_klass = klass
+end
+
+
+ +
+ +
+

+ + symbols() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 52
+def self.symbols
+  type_klass::SET.symbols
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/Template/Types/Type.html b/src/5.2/classes/ActionView/Template/Types/Type.html new file mode 100644 index 0000000000..ff1750947e --- /dev/null +++ b/src/5.2/classes/ActionView/Template/Types/Type.html @@ -0,0 +1,366 @@ +--- +title: ActionView::Template::Types::Type +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
SET=Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + symbol
+ + + + +

Class Public methods

+ +
+

+ + [](type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 11
+def self.[](type)
+  if type.is_a?(self)
+    type
+  else
+    new(type)
+  end
+end
+
+
+ +
+ +
+

+ + new(symbol) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 21
+def initialize(symbol)
+  @symbol = symbol.to_sym
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 35
+def ==(type)
+  @symbol == type.to_sym unless type.blank?
+end
+
+
+ +
+ +
+

+ + ref() + +

+ + +
+ +
+ + + +
+ Also aliased as: to_sym +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 30
+def ref
+  @symbol
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + +
+ Also aliased as: to_str +
+ + + + + + +
+ + +
+
# File actionview/lib/action_view/template/types.rb, line 25
+def to_s
+  @symbol.to_s
+end
+
+
+ +
+ +
+

+ + to_str() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_sym() + +

+ + +
+ +
+ + + + + +
+ Alias for: ref +
+ + + +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/TestCase.html b/src/5.2/classes/ActionView/TestCase.html new file mode 100644 index 0000000000..84054f9487 --- /dev/null +++ b/src/5.2/classes/ActionView/TestCase.html @@ -0,0 +1,100 @@ +--- +title: ActionView::TestCase +layout: default +--- +
+ +
+
+ +
+ +

Action View Test Case

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/TestCase/Behavior.html b/src/5.2/classes/ActionView/TestCase/Behavior.html new file mode 100644 index 0000000000..ffb2cc27eb --- /dev/null +++ b/src/5.2/classes/ActionView/TestCase/Behavior.html @@ -0,0 +1,443 @@ +--- +title: ActionView::TestCase::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
INTERNAL_IVARS=[ +:@NAME, +:@failures, +:@assertions, +:@__io__, +:@_assertion_wrapped, +:@_assertions, +:@_result, +:@_routes, +:@controller, +:@_layouts, +:@_files, +:@_rendered_views, +:@method_name, +:@output_buffer, +:@_partials, +:@passed, +:@rendered, +:@request, +:@routes, +:@tagged_logger, +:@_templates, +:@options, +:@test_passed, +:@view, +:@view_context_class, +:@view_flow, +:@_subscribers, +:@html_document +]
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [RW] + controller
+ [RW] + output_buffer
+ [RW] + rendered
+ + + + + +

Instance Public methods

+ +
+

+ + _routes() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 130
+def _routes
+  @controller._routes if @controller.respond_to?(:_routes)
+end
+
+
+ +
+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 116
+def config
+  @controller.config if @controller.respond_to?(:config)
+end
+
+
+ +
+ +
+

+ + render(options = {}, local_assigns = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 120
+def render(options = {}, local_assigns = {}, &block)
+  view.assign(view_assigns)
+  @rendered << output = view.render(options, local_assigns, &block)
+  output
+end
+
+
+ +
+ +
+

+ + rendered_views() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 126
+def rendered_views
+  @_rendered_views ||= RenderedViewsCollection.new
+end
+
+
+ +
+ +
+

+ + setup_with_controller() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 103
+def setup_with_controller
+  @controller = ActionView::TestCase::TestController.new
+  @request = @controller.request
+  @view_flow = ActionView::OutputFlow.new
+  # empty string ensures buffer has UTF-8 encoding as
+  # new without arguments returns ASCII-8BIT encoded buffer like String#new
+  @output_buffer = ActiveSupport::SafeBuffer.new ""
+  @rendered = "".dup
+
+  make_test_case_available_to_view!
+  say_no_to_protect_against_forgery!
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/TestCase/Behavior/ClassMethods.html b/src/5.2/classes/ActionView/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..e20b9eba34 --- /dev/null +++ b/src/5.2/classes/ActionView/TestCase/Behavior/ClassMethods.html @@ -0,0 +1,286 @@ +--- +title: ActionView::TestCase::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [W] + helper_class
+ + + + + +

Instance Public methods

+ +
+

+ + determine_default_helper_class(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 67
+def determine_default_helper_class(name)
+  determine_constant_from_test_name(name) do |constant|
+    Module === constant && !(Class === constant)
+  end
+end
+
+
+ +
+ +
+

+ + helper_class() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 86
+def helper_class
+  @helper_class ||= determine_default_helper_class(name)
+end
+
+
+ +
+ +
+

+ + helper_method(*methods) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 73
+        def helper_method(*methods)
+          # Almost a duplicate from ActionController::Helpers
+          methods.flatten.each do |method|
+            _helpers.module_eval <<-end_eval, __FILE__, __LINE__ + 1
+              def #{method}(*args, &block)                    # def current_user(*args, &block)
+                _test_case.send(%(#{method}), *args, &block)  #   _test_case.send(%(current_user), *args, &block)
+              end                                             # end
+            end_eval
+          end
+        end
+
+
+ +
+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 90
+def new(*)
+  include_helper_modules!
+  super
+end
+
+
+ +
+ +
+

+ + tests(helper_class) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 58
+def tests(helper_class)
+  case helper_class
+  when String, Symbol
+    self.helper_class = "#{helper_class.to_s.underscore}_helper".camelize.safe_constantize
+  when Module
+    self.helper_class = helper_class
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/TestCase/Behavior/Locals.html b/src/5.2/classes/ActionView/TestCase/Behavior/Locals.html new file mode 100644 index 0000000000..0c7e8449b1 --- /dev/null +++ b/src/5.2/classes/ActionView/TestCase/Behavior/Locals.html @@ -0,0 +1,126 @@ +--- +title: ActionView::TestCase::Behavior::Locals +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + rendered_views
+ + + + + +

Instance Public methods

+ +
+

+ + render(options = {}, local_assigns = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 194
+def render(options = {}, local_assigns = {})
+  case options
+  when Hash
+    if block_given?
+      rendered_views.add options[:layout], options[:locals]
+    elsif options.key?(:partial)
+      rendered_views.add options[:partial], options[:locals]
+    end
+  else
+    rendered_views.add options, local_assigns
+  end
+
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/TestCase/Behavior/RenderedViewsCollection.html b/src/5.2/classes/ActionView/TestCase/Behavior/RenderedViewsCollection.html new file mode 100644 index 0000000000..3e095081f2 --- /dev/null +++ b/src/5.2/classes/ActionView/TestCase/Behavior/RenderedViewsCollection.html @@ -0,0 +1,275 @@ +--- +title: ActionView::TestCase::Behavior::RenderedViewsCollection +layout: default +--- +
+ +
+
+ +
+ +

Need to experiment if this priority is the best one: rendered => output_buffer

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 136
+def initialize
+  @rendered_views ||= Hash.new { |hash, key| hash[key] = [] }
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(view, locals) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 140
+def add(view, locals)
+  @rendered_views[view] ||= []
+  @rendered_views[view] << locals
+end
+
+
+ +
+ +
+

+ + locals_for(view) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 145
+def locals_for(view)
+  @rendered_views[view]
+end
+
+
+ +
+ +
+

+ + rendered_views() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 149
+def rendered_views
+  @rendered_views.keys
+end
+
+
+ +
+ +
+

+ + view_rendered?(view, expected_locals) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 153
+def view_rendered?(view, expected_locals)
+  locals_for(view).any? do |actual_locals|
+    expected_locals.all? { |key, value| value == actual_locals[key] }
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/TestCase/TestController.html b/src/5.2/classes/ActionView/TestCase/TestController.html new file mode 100644 index 0000000000..d93b54d96c --- /dev/null +++ b/src/5.2/classes/ActionView/TestCase/TestController.html @@ -0,0 +1,207 @@ +--- +title: ActionView::TestCase::TestController +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [W] + controller_path
+ [RW] + params
+ [RW] + request
+ [RW] + response
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 26
+def initialize
+  super
+  self.class.controller_path = ""
+  @request = ActionController::TestRequest.create(self.class)
+  @response = ActionDispatch::TestResponse.new
+
+  @request.env.delete("PATH_INFO")
+  @params = ActionController::Parameters.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + controller_path=(path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/test_case.rb, line 22
+def controller_path=(path)
+  self.class.controller_path = (path)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/VERSION.html b/src/5.2/classes/ActionView/VERSION.html new file mode 100644 index 0000000000..938f9bb68f --- /dev/null +++ b/src/5.2/classes/ActionView/VERSION.html @@ -0,0 +1,120 @@ +--- +title: ActionView::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/ViewPaths.html b/src/5.2/classes/ActionView/ViewPaths.html new file mode 100644 index 0000000000..f3847b48e9 --- /dev/null +++ b/src/5.2/classes/ActionView/ViewPaths.html @@ -0,0 +1,242 @@ +--- +title: ActionView::ViewPaths +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + append_view_path(path) + +

+ + +
+

Append a path to the list of view paths for the current LookupContext.

+ +

Parameters

+
  • +

    path - If a String is provided, it gets converted into the default view path. You may also provide a custom view path (see ActionView::PathSet for more information)

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 55
+def append_view_path(path)
+  lookup_context.view_paths.push(*path)
+end
+
+
+ +
+ +
+

+ + details_for_lookup() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 45
+def details_for_lookup
+  {}
+end
+
+
+ +
+ +
+

+ + lookup_context() + +

+ + +
+

LookupContext is the object responsible for holding all information required for looking up templates, i.e. view paths and details. Check ActionView::LookupContext for more information.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 40
+def lookup_context
+  @_lookup_context ||=
+    ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
+end
+
+
+ +
+ +
+

+ + prepend_view_path(path) + +

+ + +
+

Prepend a path to the list of view paths for the current LookupContext.

+ +

Parameters

+
  • +

    path - If a String is provided, it gets converted into the default view path. You may also provide a custom view path (see ActionView::PathSet for more information)

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 65
+def prepend_view_path(path)
+  lookup_context.view_paths.unshift(*path)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActionView/ViewPaths/ClassMethods.html b/src/5.2/classes/ActionView/ViewPaths/ClassMethods.html new file mode 100644 index 0000000000..5f5e97fb1f --- /dev/null +++ b/src/5.2/classes/ActionView/ViewPaths/ClassMethods.html @@ -0,0 +1,233 @@ +--- +title: ActionView::ViewPaths::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + append_view_path(path) + +

+ + +
+

Append a path to the list of view paths for this controller.

+ +

Parameters

+
  • +

    path - If a String is provided, it gets converted into the default view path. You may also provide a custom view path (see ActionView::PathSet for more information)

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 76
+def append_view_path(path)
+  self._view_paths = view_paths + Array(path)
+end
+
+
+ +
+ +
+

+ + prepend_view_path(path) + +

+ + +
+

Prepend a path to the list of view paths for this controller.

+ +

Parameters

+
  • +

    path - If a String is provided, it gets converted into the default view path. You may also provide a custom view path (see ActionView::PathSet for more information)

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 86
+def prepend_view_path(path)
+  self._view_paths = ActionView::PathSet.new(Array(path) + view_paths)
+end
+
+
+ +
+ +
+

+ + view_paths() + +

+ + +
+

A list of all of the default view paths for this controller.

+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 91
+def view_paths
+  _view_paths
+end
+
+
+ +
+ +
+

+ + view_paths=(paths) + +

+ + +
+

Set the view paths.

+ +

Parameters

+
  • +

    paths - If a PathSet is provided, use that; otherwise, process the parameter into a PathSet.

    +
+
+ + + + + + + + +
+ + +
+
# File actionview/lib/action_view/view_paths.rb, line 100
+def view_paths=(paths)
+  self._view_paths = ActionView::PathSet.new(Array(paths))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob.html b/src/5.2/classes/ActiveJob.html new file mode 100644 index 0000000000..433e909a8d --- /dev/null +++ b/src/5.2/classes/ActiveJob.html @@ -0,0 +1,246 @@ +--- +title: ActiveJob +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Active Job as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded Active Job as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/version.rb, line 7
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Base.html b/src/5.2/classes/ActiveJob/Base.html new file mode 100644 index 0000000000..cec91d31ee --- /dev/null +++ b/src/5.2/classes/ActiveJob/Base.html @@ -0,0 +1,183 @@ +--- +title: ActiveJob::Base +layout: default +--- +
+ +
+
+ +
+ +

Active Job

+ +

Active Job objects can be configured to work with different backend queuing frameworks. To specify a queue adapter to use:

+ +
ActiveJob::Base.queue_adapter = :inline
+
+ +

A list of supported adapters can be found in QueueAdapters.

+ +

Active Job objects can be defined by creating a class that inherits from the ActiveJob::Base class. The only necessary method to implement is the “perform” method.

+ +

To define an Active Job object:

+ +
class ProcessPhotoJob < ActiveJob::Base
+  def perform(photo)
+    photo.watermark!('Rails')
+    photo.rotate!(90.degrees)
+    photo.resize_to_fit!(300, 300)
+    photo.upload!
+  end
+end
+
+ +

Records that are passed in are serialized/deserialized using Global ID. More information can be found in Arguments.

+ +

To enqueue a job to be performed as soon as the queueing system is free:

+ +
ProcessPhotoJob.perform_later(photo)
+
+ +

To enqueue a job to be processed at some point in the future:

+ +
ProcessPhotoJob.set(wait_until: Date.tomorrow.noon).perform_later(photo)
+
+ +

More information can be found in ActiveJob::Core::ClassMethods#set

+ +

A job can also be processed immediately without sending to the queue:

+ +
ProcessPhotoJob.perform_now(photo)
+
+ +

Exceptions

+ + +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Callbacks.html b/src/5.2/classes/ActiveJob/Callbacks.html new file mode 100644 index 0000000000..c7b229c1bd --- /dev/null +++ b/src/5.2/classes/ActiveJob/Callbacks.html @@ -0,0 +1,104 @@ +--- +title: ActiveJob::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Active Job Callbacks

+ +

Active Job provides hooks during the life cycle of a job. Callbacks allow you to trigger logic during this cycle. Available callbacks are:

+
  • +

    before_enqueue

    +
  • +

    around_enqueue

    +
  • +

    after_enqueue

    +
  • +

    before_perform

    +
  • +

    around_perform

    +
  • +

    after_perform

    +
+ +

NOTE: Calling the same callback multiple times will overwrite previous callback definitions.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Callbacks/ClassMethods.html b/src/5.2/classes/ActiveJob/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..0714954c4c --- /dev/null +++ b/src/5.2/classes/ActiveJob/Callbacks/ClassMethods.html @@ -0,0 +1,384 @@ +--- +title: ActiveJob::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

These methods will be included into any Active Job object, adding callbacks for perform and enqueue methods.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + after_enqueue(*filters, &blk) + +

+ + +
+

Defines a callback that will get called right after the job is enqueued.

+ +
class VideoProcessJob < ActiveJob::Base
+  queue_as :default
+
+  after_enqueue do |job|
+    $statsd.increment "enqueue-video-job.success"
+  end
+
+  def perform(video_id)
+    Video.find(video_id).process
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/callbacks.rb, line 129
+def after_enqueue(*filters, &blk)
+  set_callback(:enqueue, :after, *filters, &blk)
+end
+
+
+ +
+ +
+

+ + after_perform(*filters, &blk) + +

+ + +
+

Defines a callback that will get called right after the job's perform method has finished.

+ +
class VideoProcessJob < ActiveJob::Base
+  queue_as :default
+
+  after_perform do |job|
+    UserMailer.notify_video_processed(job.arguments.first)
+  end
+
+  def perform(video_id)
+    Video.find(video_id).process
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/callbacks.rb, line 71
+def after_perform(*filters, &blk)
+  set_callback(:perform, :after, *filters, &blk)
+end
+
+
+ +
+ +
+

+ + around_enqueue(*filters, &blk) + +

+ + +
+

Defines a callback that will get called around the enqueueing of the job.

+ +
class VideoProcessJob < ActiveJob::Base
+  queue_as :default
+
+  around_enqueue do |job, block|
+    $statsd.time "video-job.process" do
+      block.call
+    end
+  end
+
+  def perform(video_id)
+    Video.find(video_id).process
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/callbacks.rb, line 150
+def around_enqueue(*filters, &blk)
+  set_callback(:enqueue, :around, *filters, &blk)
+end
+
+
+ +
+ +
+

+ + around_perform(*filters, &blk) + +

+ + +
+

Defines a callback that will get called around the job's perform method.

+ +
class VideoProcessJob < ActiveJob::Base
+  queue_as :default
+
+  around_perform do |job, block|
+    UserMailer.notify_video_started_processing(job.arguments.first)
+    block.call
+    UserMailer.notify_video_processed(job.arguments.first)
+  end
+
+  def perform(video_id)
+    Video.find(video_id).process
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/callbacks.rb, line 91
+def around_perform(*filters, &blk)
+  set_callback(:perform, :around, *filters, &blk)
+end
+
+
+ +
+ +
+

+ + before_enqueue(*filters, &blk) + +

+ + +
+

Defines a callback that will get called right before the job is enqueued.

+ +
class VideoProcessJob < ActiveJob::Base
+  queue_as :default
+
+  before_enqueue do |job|
+    $statsd.increment "enqueue-video-job.try"
+  end
+
+  def perform(video_id)
+    Video.find(video_id).process
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/callbacks.rb, line 110
+def before_enqueue(*filters, &blk)
+  set_callback(:enqueue, :before, *filters, &blk)
+end
+
+
+ +
+ +
+

+ + before_perform(*filters, &blk) + +

+ + +
+

Defines a callback that will get called right before the job's perform method is executed.

+ +
class VideoProcessJob < ActiveJob::Base
+  queue_as :default
+
+  before_perform do |job|
+    UserMailer.notify_video_started_processing(job.arguments.first)
+  end
+
+  def perform(video_id)
+    Video.find(video_id).process
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/callbacks.rb, line 52
+def before_perform(*filters, &blk)
+  set_callback(:perform, :before, *filters, &blk)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Core.html b/src/5.2/classes/ActiveJob/Core.html new file mode 100644 index 0000000000..a51c6825af --- /dev/null +++ b/src/5.2/classes/ActiveJob/Core.html @@ -0,0 +1,245 @@ +--- +title: ActiveJob::Core +layout: default +--- +
+ +
+
+ +
+ +

Provides general behavior that will be included into every Active Job object that inherits from ActiveJob::Base.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(*arguments) + +

+ + +
+

Creates a new job instance. Takes the arguments that will be passed to the perform method.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/core.rb, line 71
+def initialize(*arguments)
+  @arguments  = arguments
+  @job_id     = SecureRandom.uuid
+  @queue_name = self.class.queue_name
+  @priority   = self.class.priority
+  @executions = 0
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + deserialize(job_data) + +

+ + +
+

Attaches the stored job data to the current instance. Receives a hash returned from serialize

+ +

Examples

+ +
class DeliverWebhookJob < ActiveJob::Base
+  attr_writer :attempt_number
+
+  def attempt_number
+    @attempt_number ||= 0
+  end
+
+  def serialize
+    super.merge('attempt_number' => attempt_number + 1)
+  end
+
+  def deserialize(job_data)
+    super
+    self.attempt_number = job_data['attempt_number']
+  end
+
+  rescue_from(Timeout::Error) do |exception|
+    raise exception if attempt_number > 5
+    retry_job(wait: 10)
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/core.rb, line 120
+def deserialize(job_data)
+  self.job_id               = job_data["job_id"]
+  self.provider_job_id      = job_data["provider_job_id"]
+  self.queue_name           = job_data["queue_name"]
+  self.priority             = job_data["priority"]
+  self.serialized_arguments = job_data["arguments"]
+  self.executions           = job_data["executions"]
+  self.locale               = job_data["locale"] || I18n.locale.to_s
+end
+
+
+ +
+ +
+

+ + serialize() + +

+ + +
+

Returns a hash with the job data that can safely be passed to the queueing adapter.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/core.rb, line 81
+def serialize
+  {
+    "job_class"  => self.class.name,
+    "job_id"     => job_id,
+    "provider_job_id" => provider_job_id,
+    "queue_name" => queue_name,
+    "priority"   => priority,
+    "arguments"  => serialize_arguments_if_needed(arguments),
+    "executions" => executions,
+    "locale"     => I18n.locale.to_s
+  }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Core/ClassMethods.html b/src/5.2/classes/ActiveJob/Core/ClassMethods.html new file mode 100644 index 0000000000..622e68a6ce --- /dev/null +++ b/src/5.2/classes/ActiveJob/Core/ClassMethods.html @@ -0,0 +1,169 @@ +--- +title: ActiveJob::Core::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

These methods will be included into any Active Job object, adding helpers for de/serialization and creation of job instances.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + deserialize(job_data) + +

+ + +
+

Creates a new job instance from a hash created with serialize

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/core.rb, line 40
+def deserialize(job_data)
+  job = job_data["job_class"].constantize.new
+  job.deserialize(job_data)
+  job
+end
+
+
+ +
+ +
+

+ + set(options = {}) + +

+ + +
+

Creates a job preconfigured with the given options. You can call perform_later with the job arguments to enqueue the job with the preconfigured options

+ +

Options

+
  • +

    :wait - Enqueues the job with the specified delay

    +
  • +

    :wait_until - Enqueues the job at the time specified

    +
  • +

    :queue - Enqueues the job on the specified queue

    +
  • +

    :priority - Enqueues the job with the specified priority

    +
+ +

Examples

+ +
VideoJob.set(queue: :some_queue).perform_later(Video.last)
+VideoJob.set(wait: 5.minutes).perform_later(Video.last)
+VideoJob.set(wait_until: Time.now.tomorrow).perform_later(Video.last)
+VideoJob.set(queue: :some_queue, wait: 5.minutes).perform_later(Video.last)
+VideoJob.set(queue: :some_queue, wait_until: Time.now.tomorrow).perform_later(Video.last)
+VideoJob.set(queue: :some_queue, wait: 5.minutes, priority: 10).perform_later(Video.last)
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/core.rb, line 64
+def set(options = {})
+  ConfiguredJob.new(self, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/DeserializationError.html b/src/5.2/classes/ActiveJob/DeserializationError.html new file mode 100644 index 0000000000..27fb31c9c4 --- /dev/null +++ b/src/5.2/classes/ActiveJob/DeserializationError.html @@ -0,0 +1,68 @@ +--- +title: ActiveJob::DeserializationError +layout: default +--- +
+ +
+
+ +
+ +

Raised when an exception is raised during job arguments deserialization.

+ +

Wraps the original exception raised as cause.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Enqueuing.html b/src/5.2/classes/ActiveJob/Enqueuing.html new file mode 100644 index 0000000000..f2bd313fab --- /dev/null +++ b/src/5.2/classes/ActiveJob/Enqueuing.html @@ -0,0 +1,151 @@ +--- +title: ActiveJob::Enqueuing +layout: default +--- +
+ +
+
+ +
+ +

Provides behavior for enqueuing jobs.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + enqueue(options = {}) + +

+ + +
+

Enqueues the job to be performed by the queue adapter.

+ +

Options

+
  • +

    :wait - Enqueues the job with the specified delay

    +
  • +

    :wait_until - Enqueues the job at the time specified

    +
  • +

    :queue - Enqueues the job on the specified queue

    +
  • +

    :priority - Enqueues the job with the specified priority

    +
+ +

Examples

+ +
my_job_instance.enqueue
+my_job_instance.enqueue wait: 5.minutes
+my_job_instance.enqueue queue: :important
+my_job_instance.enqueue wait_until: Date.tomorrow.midnight
+my_job_instance.enqueue priority: 10
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/enqueuing.rb, line 44
+def enqueue(options = {})
+  self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait]
+  self.scheduled_at = options[:wait_until].to_f if options[:wait_until]
+  self.queue_name   = self.class.queue_name_from_part(options[:queue]) if options[:queue]
+  self.priority     = options[:priority].to_i if options[:priority]
+  run_callbacks :enqueue do
+    if scheduled_at
+      self.class.queue_adapter.enqueue_at self, scheduled_at
+    else
+      self.class.queue_adapter.enqueue self
+    end
+  end
+  self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Enqueuing/ClassMethods.html b/src/5.2/classes/ActiveJob/Enqueuing/ClassMethods.html new file mode 100644 index 0000000000..7a4ca1e17c --- /dev/null +++ b/src/5.2/classes/ActiveJob/Enqueuing/ClassMethods.html @@ -0,0 +1,151 @@ +--- +title: ActiveJob::Enqueuing::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Includes the perform_later method for job initialization.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + perform_later(*args) + +

+ + +
+

Push a job onto the queue. The arguments must be legal JSON types (string, int, float, nil, true, false, hash or array) or GlobalID::Identification instances. Arbitrary Ruby objects are not supported.

+ +

Returns an instance of the job class queued with arguments available in Job#arguments.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/enqueuing.rb, line 19
+def perform_later(*args)
+  job_or_instantiate(*args).enqueue
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + job_or_instantiate(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/enqueuing.rb, line 24
+def job_or_instantiate(*args) # :doc:
+  args.first.is_a?(self) ? args.first : new(*args)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Exceptions.html b/src/5.2/classes/ActiveJob/Exceptions.html new file mode 100644 index 0000000000..35653e1fd9 --- /dev/null +++ b/src/5.2/classes/ActiveJob/Exceptions.html @@ -0,0 +1,144 @@ +--- +title: ActiveJob::Exceptions +layout: default +--- +
+ +
+
+ +
+ +

Provides behavior for retrying and discarding jobs on exceptions.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + retry_job(options = {}) + +

+ + +
+

Reschedules the job to be re-executed. This is useful in combination with the rescue_from option. When you rescue an exception from your job you can ask Active Job to retry performing your job.

+ +

Options

+
  • +

    :wait - Enqueues the job with the specified delay in seconds

    +
  • +

    :wait_until - Enqueues the job at the time specified

    +
  • +

    :queue - Enqueues the job on the specified queue

    +
  • +

    :priority - Enqueues the job with the specified priority

    +
+ +

Examples

+ +
class SiteScraperJob < ActiveJob::Base
+  rescue_from(ErrorLoadingSite) do
+    retry_job queue: :low_priority
+  end
+
+  def perform(*args)
+    # raise ErrorLoadingSite if cannot scrape
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/exceptions.rb, line 111
+def retry_job(options = {})
+  enqueue options
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Exceptions/ClassMethods.html b/src/5.2/classes/ActiveJob/Exceptions/ClassMethods.html new file mode 100644 index 0000000000..e3a1043b2f --- /dev/null +++ b/src/5.2/classes/ActiveJob/Exceptions/ClassMethods.html @@ -0,0 +1,207 @@ +--- +title: ActiveJob::Exceptions::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + discard_on(exception) + +

+ + +
+

Discard the job with no attempts to retry, if the exception is raised. This is useful when the subject of the job, like an Active Record, is no longer available, and the job is thus no longer relevant.

+ +

You can also pass a block that'll be invoked. This block is yielded with the job instance as the first and the error instance as the second parameter.

+ +

Example

+ +
class SearchIndexingJob < ActiveJob::Base
+  discard_on ActiveJob::DeserializationError
+  discard_on(CustomAppException) do |job, error|
+    ExceptionNotifier.caught(error)
+  end
+
+  def perform(record)
+    # Will raise ActiveJob::DeserializationError if the record can't be deserialized
+    # Might raise CustomAppException for something domain specific
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/exceptions.rb, line 79
+def discard_on(exception)
+  rescue_from exception do |error|
+    if block_given?
+      yield self, error
+    else
+      logger.error "Discarded #{self.class} due to a #{exception}. The original exception was #{error.cause.inspect}."
+    end
+  end
+end
+
+
+ +
+ +
+

+ + retry_on(exception, wait: 3.seconds, attempts: 5, queue: nil, priority: nil) + +

+ + +
+

Catch the exception and reschedule job for re-execution after so many seconds, for a specific number of attempts. If the exception keeps getting raised beyond the specified number of attempts, the exception is allowed to bubble up to the underlying queuing system, which may have its own retry mechanism or place it in a holding queue for inspection.

+ +

You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.

+ +

Options

+
  • +

    :wait - Re-enqueues the job with a delay specified either in seconds (default: 3 seconds), as a computing proc that the number of executions so far as an argument, or as a symbol reference of :exponentially_longer, which applies the wait algorithm of (executions ** 4) + 2 (first wait 3s, then 18s, then 83s, etc)

    +
  • +

    :attempts - Re-enqueues the job the specified number of times (default: 5 attempts)

    +
  • +

    :queue - Re-enqueues the job on a different queue

    +
  • +

    :priority - Re-enqueues the job with a different priority

    +
+ +

Examples

+ +
class RemoteServiceJob < ActiveJob::Base
+  retry_on CustomAppException # defaults to 3s wait, 5 attempts
+  retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
+  retry_on(YetAnotherCustomAppException) do |job, error|
+    ExceptionNotifier.caught(error)
+  end
+  retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
+  retry_on Net::OpenTimeout, wait: :exponentially_longer, attempts: 10
+
+  def perform(*args)
+    # Might raise CustomAppException, AnotherCustomAppException, or YetAnotherCustomAppException for something domain specific
+    # Might raise ActiveRecord::Deadlocked when a local db deadlock is detected
+    # Might raise Net::OpenTimeout when the remote service is down
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/exceptions.rb, line 45
+def retry_on(exception, wait: 3.seconds, attempts: 5, queue: nil, priority: nil)
+  rescue_from exception do |error|
+    if executions < attempts
+      logger.error "Retrying #{self.class} in #{wait} seconds, due to a #{exception}. The original exception was #{error.cause.inspect}."
+      retry_job wait: determine_delay(wait), queue: queue, priority: priority
+    else
+      if block_given?
+        yield self, error
+      else
+        logger.error "Stopped retrying #{self.class} due to a #{exception}, which reoccurred on #{executions} attempts. The original exception was #{error.cause.inspect}."
+        raise error
+      end
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Execution.html b/src/5.2/classes/ActiveJob/Execution.html new file mode 100644 index 0000000000..0cfa863756 --- /dev/null +++ b/src/5.2/classes/ActiveJob/Execution.html @@ -0,0 +1,178 @@ +--- +title: ActiveJob::Execution +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + perform(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/execution.rb, line 45
+def perform(*)
+  fail NotImplementedError
+end
+
+
+ +
+ +
+

+ + perform_now() + +

+ + +
+

Performs the job immediately. The job is not sent to the queueing adapter but directly executed by blocking the execution of others until it's finished.

+ +
MyJob.new(*args).perform_now
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/execution.rb, line 33
+def perform_now
+  # Guard against jobs that were persisted before we started counting executions by zeroing out nil counters
+  self.executions = (executions || 0) + 1
+
+  deserialize_arguments_if_needed
+  run_callbacks :perform do
+    perform(*arguments)
+  end
+rescue => exception
+  rescue_with_handler(exception) || raise
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/Execution/ClassMethods.html b/src/5.2/classes/ActiveJob/Execution/ClassMethods.html new file mode 100644 index 0000000000..d5503a1a1c --- /dev/null +++ b/src/5.2/classes/ActiveJob/Execution/ClassMethods.html @@ -0,0 +1,110 @@ +--- +title: ActiveJob::Execution::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Includes methods for executing and performing jobs instantly.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + perform_now(*args) + +

+ + +
+

Performs the job immediately.

+ +
MyJob.perform_now("mike")
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/execution.rb, line 17
+def perform_now(*args)
+  job_or_instantiate(*args).perform_now
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapter.html new file mode 100644 index 0000000000..b30ff21f0f --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapter.html @@ -0,0 +1,67 @@ +--- +title: ActiveJob::QueueAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapter/ClassMethods.html b/src/5.2/classes/ActiveJob/QueueAdapter/ClassMethods.html new file mode 100644 index 0000000000..feb002c175 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapter/ClassMethods.html @@ -0,0 +1,214 @@ +--- +title: ActiveJob::QueueAdapter::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Includes the setter method for changing the active queue adapter.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
QUEUE_ADAPTER_METHODS=[:enqueue, :enqueue_at].freeze
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + queue_adapter() + +

+ + +
+

Returns the backend queue provider. The default queue adapter is the :async queue. See QueueAdapters for more information.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapter.rb, line 21
+def queue_adapter
+  _queue_adapter
+end
+
+
+ +
+ +
+

+ + queue_adapter=(name_or_adapter) + +

+ + +
+

Specify the backend queue provider. The default queue adapter is the :async queue. See QueueAdapters for more information.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapter.rb, line 32
+def queue_adapter=(name_or_adapter)
+  case name_or_adapter
+  when Symbol, String
+    queue_adapter = ActiveJob::QueueAdapters.lookup(name_or_adapter).new
+    assign_adapter(name_or_adapter.to_s, queue_adapter)
+  else
+    if queue_adapter?(name_or_adapter)
+      adapter_name = "#{name_or_adapter.class.name.demodulize.remove('Adapter').underscore}"
+      assign_adapter(adapter_name, name_or_adapter)
+    else
+      raise ArgumentError
+    end
+  end
+end
+
+
+ +
+ +
+

+ + queue_adapter_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapter.rb, line 25
+def queue_adapter_name
+  _queue_adapter_name
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters.html b/src/5.2/classes/ActiveJob/QueueAdapters.html new file mode 100644 index 0000000000..bed2205ff6 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters.html @@ -0,0 +1,276 @@ +--- +title: ActiveJob::QueueAdapters +layout: default +--- +
+ +
+
+ +
+ +

Active Job adapters

+ +

Active Job has adapters for the following queueing backends:

+ + +

Backends Features

+ +
|                   | Async | Queues | Delayed    | Priorities | Timeout | Retries |
+|-------------------|-------|--------|------------|------------|---------|---------|
+| Backburner        | Yes   | Yes    | Yes        | Yes        | Job     | Global  |
+| Delayed Job       | Yes   | Yes    | Yes        | Job        | Global  | Global  |
+| Qu                | Yes   | Yes    | No         | No         | No      | Global  |
+| Que               | Yes   | Yes    | Yes        | Job        | No      | Job     |
+| queue_classic     | Yes   | Yes    | Yes*       | No         | No      | No      |
+| Resque            | Yes   | Yes    | Yes (Gem)  | Queue      | Global  | Yes     |
+| Sidekiq           | Yes   | Yes    | Yes        | Queue      | No      | Job     |
+| Sneakers          | Yes   | Yes    | No         | Queue      | Queue   | No      |
+| Sucker Punch      | Yes   | Yes    | Yes        | No         | No      | No      |
+| Active Job Async  | Yes   | Yes    | Yes        | No         | No      | No      |
+| Active Job Inline | No    | Yes    | N/A        | N/A        | N/A     | N/A     |
+
+ +

Async

+ +

Yes: The Queue Adapter has the ability to run the job in a non-blocking manner. It either runs on a separate or forked process, or on a different thread.

+ +

No: The job is run in the same process.

+ +

Queues

+ +

Yes: Jobs may set which queue they are run in with queue_as or by using the set method.

+ +

Delayed

+ +

Yes: The adapter will run the job in the future through perform_later.

+ +

(Gem): An additional gem is required to use perform_later with this adapter.

+ +

No: The adapter will run jobs at the next opportunity and cannot use perform_later.

+ +

N/A: The adapter does not support queueing.

+ +

NOTE: queue_classic supports job scheduling since version 3.1. For older versions you can use the queue_classic-later gem.

+ +

Priorities

+ +

The order in which jobs are processed can be configured differently depending on the adapter.

+ +

Job: Any class inheriting from the adapter may set the priority on the job object relative to other jobs.

+ +

Queue: The adapter can set the priority for job queues, when setting a queue with Active Job this will be respected.

+ +

Yes: Allows the priority to be set on the job object, at the queue level or as default configuration option.

+ +

No: Does not allow the priority of jobs to be configured.

+ +

N/A: The adapter does not support queueing, and therefore sorting them.

+ +

Timeout

+ +

When a job will stop after the allotted time.

+ +

Job: The timeout can be set for each instance of the job class.

+ +

Queue: The timeout is set for all jobs on the queue.

+ +

Global: The adapter is configured that all jobs have a maximum run time.

+ +

N/A: This adapter does not run in a separate process, and therefore timeout is unsupported.

+ +

Retries

+ +

Job: The number of retries can be set per instance of the job class.

+ +

Yes: The Number of retries can be configured globally, for each instance or on the queue. This adapter may also present failed instances of the job class that can be restarted.

+ +

Global: The adapter has a global number of retries.

+ +

N/A: The adapter does not run in a separate process, and therefore doesn't support retries.

+ +

Async and Inline Queue Adapters

+ +

Active Job has two built-in queue adapters intended for development and testing: :async and :inline.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + lookup(name) + +

+ + +
+

Returns adapter for specified name.

+ +
ActiveJob::QueueAdapters.lookup(:sidekiq)
+# => ActiveJob::QueueAdapters::SidekiqAdapter
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapters.rb, line 134
+def lookup(name)
+  const_get(name.to_s.camelize << ADAPTER)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/AsyncAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/AsyncAdapter.html new file mode 100644 index 0000000000..ffb9753ee5 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/AsyncAdapter.html @@ -0,0 +1,132 @@ +--- +title: ActiveJob::QueueAdapters::AsyncAdapter +layout: default +--- +
+ +
+
+ +
+ +

Active Job Async adapter

+ +

The Async adapter runs jobs with an in-process thread pool.

+ +

This is the default queue adapter. It's well-suited for dev/test since it doesn't need an external infrastructure, but it's a poor fit for production since it drops pending jobs on restart.

+ +

To use this adapter, set queue adapter to :async:

+ +
config.active_job.queue_adapter = :async
+
+ +

To configure the adapter's thread pool, instantiate the adapter and pass your own config:

+ +
config.active_job.queue_adapter = ActiveJob::QueueAdapters::AsyncAdapter.new \
+  min_threads: 1,
+  max_threads: 2 * Concurrent.processor_count,
+  idletime: 600.seconds
+
+ +

The adapter uses a Concurrent Ruby thread pool to schedule and execute jobs. Since jobs share a single thread pool, long-running jobs will block short-lived jobs. Fine for dev/test; bad for production.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(**executor_options) + +

+ + +
+

See Concurrent::ThreadPoolExecutor for executor options.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapters/async_adapter.rb, line 35
+def initialize(**executor_options)
+  @scheduler = Scheduler.new(**executor_options)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/BackburnerAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/BackburnerAdapter.html new file mode 100644 index 0000000000..78a3f10828 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/BackburnerAdapter.html @@ -0,0 +1,73 @@ +--- +title: ActiveJob::QueueAdapters::BackburnerAdapter +layout: default +--- +
+ +
+
+ +
+ +

Backburner adapter for Active Job

+ +

Backburner is a beanstalkd-powered job queue that can handle a very high volume of jobs. You create background jobs and place them on multiple work queues to be processed later. Read more about Backburner here.

+ +

To use Backburner set the queue_adapter config to :backburner.

+ +
Rails.application.config.active_job.queue_adapter = :backburner
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/DelayedJobAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/DelayedJobAdapter.html new file mode 100644 index 0000000000..8ce9e23c84 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/DelayedJobAdapter.html @@ -0,0 +1,73 @@ +--- +title: ActiveJob::QueueAdapters::DelayedJobAdapter +layout: default +--- +
+ +
+
+ +
+ +

Delayed Job adapter for Active Job

+ +

Delayed::Job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background. Although DJ can have many storage backends, one of the most used is based on Active Record. Read more about Delayed Job here.

+ +

To use Delayed Job, set the queue_adapter config to :delayed_job.

+ +
Rails.application.config.active_job.queue_adapter = :delayed_job
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/InlineAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/InlineAdapter.html new file mode 100644 index 0000000000..405571b670 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/InlineAdapter.html @@ -0,0 +1,73 @@ +--- +title: ActiveJob::QueueAdapters::InlineAdapter +layout: default +--- +
+ +
+
+ +
+ +

Active Job Inline adapter

+ +

When enqueuing jobs with the Inline adapter the job will be executed immediately.

+ +

To use the Inline set the queue_adapter config to :inline.

+ +
Rails.application.config.active_job.queue_adapter = :inline
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/QuAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/QuAdapter.html new file mode 100644 index 0000000000..736132d61e --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/QuAdapter.html @@ -0,0 +1,75 @@ +--- +title: ActiveJob::QueueAdapters::QuAdapter +layout: default +--- +
+ +
+
+ +
+ +

Qu adapter for Active Job

+ +

Qu is a Ruby library for queuing and processing background jobs. It is heavily inspired by delayed_job and Resque. Qu was created to overcome some shortcomings in the existing queuing libraries. The advantages of Qu are: Multiple backends (redis, mongo), jobs are requeued when worker is killed, resque-like API.

+ +

Read more about Qu here.

+ +

To use Qu set the queue_adapter config to :qu.

+ +
Rails.application.config.active_job.queue_adapter = :qu
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/QueAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/QueAdapter.html new file mode 100644 index 0000000000..5fa72aa791 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/QueAdapter.html @@ -0,0 +1,75 @@ +--- +title: ActiveJob::QueueAdapters::QueAdapter +layout: default +--- +
+ +
+
+ +
+ +

Que adapter for Active Job

+ +

Que is a high-performance alternative to DelayedJob or QueueClassic that improves the reliability of your application by protecting your jobs with the same ACID guarantees as the rest of your data. Que is a queue for Ruby and PostgreSQL that manages jobs using advisory locks.

+ +

Read more about Que here.

+ +

To use Que set the queue_adapter config to :que.

+ +
Rails.application.config.active_job.queue_adapter = :que
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/QueueClassicAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/QueueClassicAdapter.html new file mode 100644 index 0000000000..8d92d1c3d5 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/QueueClassicAdapter.html @@ -0,0 +1,124 @@ +--- +title: ActiveJob::QueueAdapters::QueueClassicAdapter +layout: default +--- +
+ +
+
+ +
+ +

queue_classic adapter for Active Job

+ +

queue_classic provides a simple interface to a PostgreSQL-backed message queue. queue_classic specializes in concurrent locking and minimizing database load while providing a simple, intuitive developer experience. queue_classic assumes that you are already using PostgreSQL in your production environment and that adding another dependency (e.g. redis, beanstalkd, 0mq) is undesirable.

+ +

Read more about queue_classic here.

+ +

To use queue_classic set the queue_adapter config to :queue_classic.

+ +
Rails.application.config.active_job.queue_adapter = :queue_classic
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + build_queue(queue_name) + +

+ + +
+

Builds a QC::Queue object to schedule jobs on.

+ +

If you have a custom QC::Queue subclass you'll need to subclass ActiveJob::QueueAdapters::QueueClassicAdapter and override the build_queue method.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb, line 45
+def build_queue(queue_name)
+  QC::Queue.new(queue_name)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/ResqueAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/ResqueAdapter.html new file mode 100644 index 0000000000..fde9b657cd --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/ResqueAdapter.html @@ -0,0 +1,75 @@ +--- +title: ActiveJob::QueueAdapters::ResqueAdapter +layout: default +--- +
+ +
+
+ +
+ +

Resque adapter for Active Job

+ +

Resque (pronounced like “rescue”) is a Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them later.

+ +

Read more about Resque here.

+ +

To use Resque set the queue_adapter config to :resque.

+ +
Rails.application.config.active_job.queue_adapter = :resque
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/SidekiqAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/SidekiqAdapter.html new file mode 100644 index 0000000000..b2883c93bf --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/SidekiqAdapter.html @@ -0,0 +1,75 @@ +--- +title: ActiveJob::QueueAdapters::SidekiqAdapter +layout: default +--- +
+ +
+
+ +
+ +

Sidekiq adapter for Active Job

+ +

Simple, efficient background processing for Ruby. Sidekiq uses threads to handle many jobs at the same time in the same process. It does not require Rails but will integrate tightly with it to make background processing dead simple.

+ +

Read more about Sidekiq here.

+ +

To use Sidekiq set the queue_adapter config to :sidekiq.

+ +
Rails.application.config.active_job.queue_adapter = :sidekiq
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/SneakersAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/SneakersAdapter.html new file mode 100644 index 0000000000..051802b126 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/SneakersAdapter.html @@ -0,0 +1,122 @@ +--- +title: ActiveJob::QueueAdapters::SneakersAdapter +layout: default +--- +
+ +
+
+ +
+ +

Sneakers adapter for Active Job

+ +

A high-performance RabbitMQ background processing framework for Ruby. Sneakers is being used in production for both I/O and CPU intensive workloads, and have achieved the goals of high-performance and 0-maintenance, as designed.

+ +

Read more about Sneakers here.

+ +

To use Sneakers set the queue_adapter config to :sneakers.

+ +
Rails.application.config.active_job.queue_adapter = :sneakers
+
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapters/sneakers_adapter.rb, line 21
+def initialize
+  @monitor = Monitor.new
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/SuckerPunchAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/SuckerPunchAdapter.html new file mode 100644 index 0000000000..2ef31fa8ed --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/SuckerPunchAdapter.html @@ -0,0 +1,75 @@ +--- +title: ActiveJob::QueueAdapters::SuckerPunchAdapter +layout: default +--- +
+ +
+
+ +
+ +

Sucker Punch adapter for Active Job

+ +

Sucker Punch is a single-process Ruby asynchronous processing library. This reduces the cost of hosting on a service like Heroku along with the memory footprint of having to maintain additional jobs if hosting on a dedicated server. All queues can run within a single application (eg. Rails, Sinatra, etc.) process.

+ +

Read more about Sucker Punch here.

+ +

To use Sucker Punch set the queue_adapter config to :sucker_punch.

+ +
Rails.application.config.active_job.queue_adapter = :sucker_punch
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueAdapters/TestAdapter.html b/src/5.2/classes/ActiveJob/QueueAdapters/TestAdapter.html new file mode 100644 index 0000000000..68626910e5 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueAdapters/TestAdapter.html @@ -0,0 +1,213 @@ +--- +title: ActiveJob::QueueAdapters::TestAdapter +layout: default +--- +
+ +
+
+ +
+ +

Test adapter for Active Job

+ +

The test adapter should be used only in testing. Along with ActiveJob::TestCase and ActiveJob::TestHelper it makes a great tool to test your Rails application.

+ +

To use the test adapter set queue_adapter config to :test.

+ +
Rails.application.config.active_job.queue_adapter = :test
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [W] + enqueued_jobs
+ [RW] + filter
+ [RW] + perform_enqueued_at_jobs
+ [RW] + perform_enqueued_jobs
+ [W] + performed_jobs
+ [RW] + reject
+ + + + + +

Instance Public methods

+ +
+

+ + enqueued_jobs() + +

+ + +
+

Provides a store of all the enqueued jobs with the TestAdapter so you can check them.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapters/test_adapter.rb, line 19
+def enqueued_jobs
+  @enqueued_jobs ||= []
+end
+
+
+ +
+ +
+

+ + performed_jobs() + +

+ + +
+

Provides a store of all the performed jobs with the TestAdapter so you can check them.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_adapters/test_adapter.rb, line 24
+def performed_jobs
+  @performed_jobs ||= []
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueName.html b/src/5.2/classes/ActiveJob/QueueName.html new file mode 100644 index 0000000000..1691548408 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueName.html @@ -0,0 +1,117 @@ +--- +title: ActiveJob::QueueName +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + queue_name() + +

+ + +
+

Returns the name of the queue the job will be run on.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_name.rb, line 42
+def queue_name
+  if @queue_name.is_a?(Proc)
+    @queue_name = self.class.queue_name_from_part(instance_exec(&@queue_name))
+  end
+  @queue_name
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueueName/ClassMethods.html b/src/5.2/classes/ActiveJob/QueueName/ClassMethods.html new file mode 100644 index 0000000000..af11dae22b --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueueName/ClassMethods.html @@ -0,0 +1,120 @@ +--- +title: ActiveJob::QueueName::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Includes the ability to override the default queue name and prefix.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + queue_as(part_name = nil, &block) + +

+ + +
+

Specifies the name of the queue to process the job on.

+ +
class PublishToFeedJob < ActiveJob::Base
+  queue_as :feeds
+
+  def perform(post)
+    post.to_feed!
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_name.rb, line 21
+def queue_as(part_name = nil, &block)
+  if block_given?
+    self.queue_name = block
+  else
+    self.queue_name = queue_name_from_part(part_name)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueuePriority.html b/src/5.2/classes/ActiveJob/QueuePriority.html new file mode 100644 index 0000000000..7bdeb1baae --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueuePriority.html @@ -0,0 +1,117 @@ +--- +title: ActiveJob::QueuePriority +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + priority() + +

+ + +
+

Returns the priority that the job will be created with

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_priority.rb, line 36
+def priority
+  if @priority.is_a?(Proc)
+    @priority = instance_exec(&@priority)
+  end
+  @priority
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/QueuePriority/ClassMethods.html b/src/5.2/classes/ActiveJob/QueuePriority/ClassMethods.html new file mode 100644 index 0000000000..9ff3193072 --- /dev/null +++ b/src/5.2/classes/ActiveJob/QueuePriority/ClassMethods.html @@ -0,0 +1,122 @@ +--- +title: ActiveJob::QueuePriority::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Includes the ability to override the default queue priority.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + queue_with_priority(priority = nil, &block) + +

+ + +
+

Specifies the priority of the queue to create the job with.

+ +
class PublishToFeedJob < ActiveJob::Base
+  queue_with_priority 50
+
+  def perform(post)
+    post.to_feed!
+  end
+end
+
+ +

Specify either an argument or a block.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/queue_priority.rb, line 22
+def queue_with_priority(priority = nil, &block)
+  if block_given?
+    self.priority = block
+  else
+    self.priority = priority
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/SerializationError.html b/src/5.2/classes/ActiveJob/SerializationError.html new file mode 100644 index 0000000000..e15e3540b2 --- /dev/null +++ b/src/5.2/classes/ActiveJob/SerializationError.html @@ -0,0 +1,66 @@ +--- +title: ActiveJob::SerializationError +layout: default +--- +
+ +
+
+ +
+ +

Raised when an unsupported argument type is set as a job argument. We currently support NilClass, Integer, Fixnum, Float, String, TrueClass, FalseClass, Bignum, BigDecimal, and objects that can be represented as GlobalIDs (ex: Active Record). Raised if you set the key for a Hash something else than a string or a symbol. Also raised when trying to serialize an object which can't be identified with a Global ID - such as an unpersisted Active Record model.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/TestCase.html b/src/5.2/classes/ActiveJob/TestCase.html new file mode 100644 index 0000000000..754a929385 --- /dev/null +++ b/src/5.2/classes/ActiveJob/TestCase.html @@ -0,0 +1,74 @@ +--- +title: ActiveJob::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/TestHelper.html b/src/5.2/classes/ActiveJob/TestHelper.html new file mode 100644 index 0000000000..33178a335a --- /dev/null +++ b/src/5.2/classes/ActiveJob/TestHelper.html @@ -0,0 +1,743 @@ +--- +title: ActiveJob::TestHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides helper methods for testing Active Job

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_enqueued_jobs(number, only: nil, except: nil, queue: nil) + +

+ + +
+

Asserts that the number of enqueued jobs matches the given number.

+ +
def test_jobs
+  assert_enqueued_jobs 0
+  HelloJob.perform_later('david')
+  assert_enqueued_jobs 1
+  HelloJob.perform_later('abdelkader')
+  assert_enqueued_jobs 2
+end
+
+ +

If a block is passed, that block will cause the specified number of jobs to be enqueued.

+ +
def test_jobs_again
+  assert_enqueued_jobs 1 do
+    HelloJob.perform_later('cristian')
+  end
+
+  assert_enqueued_jobs 2 do
+    HelloJob.perform_later('aaron')
+    HelloJob.perform_later('rafael')
+  end
+end
+
+ +

The number of times a specific job was enqueued can be asserted.

+ +
def test_logging_job
+  assert_enqueued_jobs 1, only: LoggingJob do
+    LoggingJob.perform_later
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

The number of times a job except specific class was enqueued can be asserted.

+ +
def test_logging_job
+  assert_enqueued_jobs 1, except: HelloJob do
+    LoggingJob.perform_later
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

The number of times a job is enqueued to a specific queue can also be asserted.

+ +
def test_logging_job
+  assert_enqueued_jobs 2, queue: 'default' do
+    LoggingJob.perform_later
+    HelloJob.perform_later('elfassy')
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 118
+def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil)
+  if block_given?
+    original_count = enqueued_jobs_size(only: only, except: except, queue: queue)
+    yield
+    new_count = enqueued_jobs_size(only: only, except: except, queue: queue)
+    assert_equal number, new_count - original_count, "#{number} jobs expected, but #{new_count - original_count} were enqueued"
+  else
+    actual_count = enqueued_jobs_size(only: only, except: except, queue: queue)
+    assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
+  end
+end
+
+
+ +
+ +
+

+ + assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil) + +

+ + +
+

Asserts that the job passed in the block has been enqueued with the given arguments.

+ +
def test_assert_enqueued_with
+  assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do
+    MyJob.perform_later(1,2,3)
+  end
+
+  assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon) do
+    MyJob.set(wait_until: Date.tomorrow.noon).perform_later
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 300
+def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil)
+  original_enqueued_jobs_count = enqueued_jobs.count
+  expected = { job: job, args: args, at: at, queue: queue }.compact
+  expected_args = prepare_args_for_assertion(expected)
+  yield
+  in_block_jobs = enqueued_jobs.drop(original_enqueued_jobs_count)
+  matching_job = in_block_jobs.find do |in_block_job|
+    deserialized_job = deserialize_args_for_assertion(in_block_job)
+    expected_args.all? { |key, value| value == deserialized_job[key] }
+  end
+  assert matching_job, "No enqueued job found with #{expected}"
+  instantiate_job(matching_job)
+end
+
+
+ +
+ +
+

+ + assert_no_enqueued_jobs(only: nil, except: nil, &block) + +

+ + +
+

Asserts that no jobs have been enqueued.

+ +
def test_jobs
+  assert_no_enqueued_jobs
+  HelloJob.perform_later('jeremy')
+  assert_enqueued_jobs 1
+end
+
+ +

If a block is passed, that block should not cause any job to be enqueued.

+ +
def test_jobs_again
+  assert_no_enqueued_jobs do
+    # No job should be enqueued from this block
+  end
+end
+
+ +

It can be asserted that no jobs of a specific kind are enqueued:

+ +
def test_no_logging
+  assert_no_enqueued_jobs only: LoggingJob do
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

It can be asserted that no jobs except specific class are enqueued:

+ +
def test_no_logging
+  assert_no_enqueued_jobs except: HelloJob do
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

Note: This assertion is simply a shortcut for:

+ +
assert_enqueued_jobs 0, &block
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 165
+def assert_no_enqueued_jobs(only: nil, except: nil, &block)
+  assert_enqueued_jobs 0, only: only, except: except, &block
+end
+
+
+ +
+ +
+

+ + assert_no_performed_jobs(only: nil, except: nil, &block) + +

+ + +
+

Asserts that no jobs have been performed.

+ +
def test_jobs
+  assert_no_performed_jobs
+
+  perform_enqueued_jobs do
+    HelloJob.perform_later('matthew')
+    assert_performed_jobs 1
+  end
+end
+
+ +

If a block is passed, that block should not cause any job to be performed.

+ +
def test_jobs_again
+  assert_no_performed_jobs do
+    # No job should be performed from this block
+  end
+end
+
+ +

The block form supports filtering. If the :only option is specified, then only the listed job(s) will not be performed.

+ +
def test_no_logging
+  assert_no_performed_jobs only: LoggingJob do
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

Also if the :except option is specified, then the job(s) except specific class will not be performed.

+ +
def test_no_logging
+  assert_no_performed_jobs except: HelloJob do
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

Note: This assertion is simply a shortcut for:

+ +
assert_performed_jobs 0, &block
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 285
+def assert_no_performed_jobs(only: nil, except: nil, &block)
+  assert_performed_jobs 0, only: only, except: except, &block
+end
+
+
+ +
+ +
+

+ + assert_performed_jobs(number, only: nil, except: nil) + +

+ + +
+

Asserts that the number of performed jobs matches the given number. If no block is passed, perform_enqueued_jobs must be called around the job call.

+ +
def test_jobs
+  assert_performed_jobs 0
+
+  perform_enqueued_jobs do
+    HelloJob.perform_later('xavier')
+  end
+  assert_performed_jobs 1
+
+  perform_enqueued_jobs do
+    HelloJob.perform_later('yves')
+    assert_performed_jobs 2
+  end
+end
+
+ +

If a block is passed, that block should cause the specified number of jobs to be performed.

+ +
def test_jobs_again
+  assert_performed_jobs 1 do
+    HelloJob.perform_later('robin')
+  end
+
+  assert_performed_jobs 2 do
+    HelloJob.perform_later('carlos')
+    HelloJob.perform_later('sean')
+  end
+end
+
+ +

The block form supports filtering. If the :only option is specified, then only the listed job(s) will be performed.

+ +
def test_hello_job
+  assert_performed_jobs 1, only: HelloJob do
+    HelloJob.perform_later('jeremy')
+    LoggingJob.perform_later
+  end
+end
+
+ +

Also if the :except option is specified, then the job(s) except specific class will be performed.

+ +
def test_hello_job
+  assert_performed_jobs 1, except: LoggingJob do
+    HelloJob.perform_later('jeremy')
+    LoggingJob.perform_later
+  end
+end
+
+ +

An array may also be specified, to support testing multiple jobs.

+ +
def test_hello_and_logging_jobs
+  assert_nothing_raised do
+    assert_performed_jobs 2, only: [HelloJob, LoggingJob] do
+      HelloJob.perform_later('jeremy')
+      LoggingJob.perform_later('stewie')
+      RescueJob.perform_later('david')
+    end
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 232
+def assert_performed_jobs(number, only: nil, except: nil)
+  if block_given?
+    original_count = performed_jobs.size
+    perform_enqueued_jobs(only: only, except: except) { yield }
+    new_count = performed_jobs.size
+    assert_equal number, new_count - original_count,
+      "#{number} jobs expected, but #{new_count - original_count} were performed"
+  else
+    performed_jobs_size = performed_jobs.size
+    assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
+  end
+end
+
+
+ +
+ +
+

+ + assert_performed_with(job: nil, args: nil, at: nil, queue: nil) + +

+ + +
+

Asserts that the job passed in the block has been performed with the given arguments.

+ +
def test_assert_performed_with
+  assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do
+    MyJob.perform_later(1,2,3)
+  end
+
+  assert_performed_with(job: MyJob, at: Date.tomorrow.noon) do
+    MyJob.set(wait_until: Date.tomorrow.noon).perform_later
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 325
+def assert_performed_with(job: nil, args: nil, at: nil, queue: nil)
+  original_performed_jobs_count = performed_jobs.count
+  expected = { job: job, args: args, at: at, queue: queue }.compact
+  expected_args = prepare_args_for_assertion(expected)
+  perform_enqueued_jobs { yield }
+  in_block_jobs = performed_jobs.drop(original_performed_jobs_count)
+  matching_job = in_block_jobs.find do |in_block_job|
+    deserialized_job = deserialize_args_for_assertion(in_block_job)
+    expected_args.all? { |key, value| value == deserialized_job[key] }
+  end
+  assert matching_job, "No performed job found with #{expected}"
+  instantiate_job(matching_job)
+end
+
+
+ +
+ +
+

+ + perform_enqueued_jobs(only: nil, except: nil) + +

+ + +
+

Performs all enqueued jobs in the duration of the block.

+ +
def test_perform_enqueued_jobs
+  perform_enqueued_jobs do
+    MyJob.perform_later(1, 2, 3)
+  end
+  assert_performed_jobs 1
+end
+
+ +

This method also supports filtering. If the :only option is specified, then only the listed job(s) will be performed.

+ +
def test_perform_enqueued_jobs_with_only
+  perform_enqueued_jobs(only: MyJob) do
+    MyJob.perform_later(1, 2, 3) # will be performed
+    HelloJob.perform_later(1, 2, 3) # will not be performed
+  end
+  assert_performed_jobs 1
+end
+
+ +

Also if the :except option is specified, then the job(s) except specific class will be performed.

+ +
def test_perform_enqueued_jobs_with_except
+  perform_enqueued_jobs(except: HelloJob) do
+    MyJob.perform_later(1, 2, 3) # will be performed
+    HelloJob.perform_later(1, 2, 3) # will not be performed
+  end
+  assert_performed_jobs 1
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 370
+def perform_enqueued_jobs(only: nil, except: nil)
+  validate_option(only: only, except: except)
+  old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs
+  old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs
+  old_filter = queue_adapter.filter
+  old_reject = queue_adapter.reject
+
+  begin
+    queue_adapter.perform_enqueued_jobs = true
+    queue_adapter.perform_enqueued_at_jobs = true
+    queue_adapter.filter = only
+    queue_adapter.reject = except
+    yield
+  ensure
+    queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
+    queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
+    queue_adapter.filter = old_filter
+    queue_adapter.reject = old_reject
+  end
+end
+
+
+ +
+ +
+

+ + queue_adapter() + +

+ + +
+

Accesses the queue_adapter set by ActiveJob::Base.

+ +
def test_assert_job_has_custom_queue_adapter_set
+  assert_instance_of CustomQueueAdapter, HelloJob.queue_adapter
+end
+
+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 396
+def queue_adapter
+  ActiveJob::Base.queue_adapter
+end
+
+
+ +
+ +
+

+ + queue_adapter_for_test() + +

+ + +
+

Specifies the queue adapter to use with all active job test helpers.

+ +

Returns an instance of the queue adapter and defaults to ActiveJob::QueueAdapters::TestAdapter.

+ +

Note: The adapter provided by this method must provide some additional methods from those expected of a standard ActiveJob::QueueAdapter in order to be used with the active job test helpers. Refer to ActiveJob::QueueAdapters::TestAdapter.

+
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 64
+def queue_adapter_for_test
+  ActiveJob::QueueAdapters::TestAdapter.new
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter.html b/src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter.html new file mode 100644 index 0000000000..a3e90538b8 --- /dev/null +++ b/src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter.html @@ -0,0 +1,67 @@ +--- +title: ActiveJob::TestHelper::TestQueueAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter/ClassMethods.html b/src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter/ClassMethods.html new file mode 100644 index 0000000000..ee4118236f --- /dev/null +++ b/src/5.2/classes/ActiveJob/TestHelper/TestQueueAdapter/ClassMethods.html @@ -0,0 +1,179 @@ +--- +title: ActiveJob::TestHelper::TestQueueAdapter::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + disable_test_adapter() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 25
+def disable_test_adapter
+  self._test_adapter = nil
+end
+
+
+ +
+ +
+

+ + enable_test_adapter(test_adapter) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 29
+def enable_test_adapter(test_adapter)
+  self._test_adapter = test_adapter
+end
+
+
+ +
+ +
+

+ + queue_adapter() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activejob/lib/active_job/test_helper.rb, line 21
+def queue_adapter
+  self._test_adapter.nil? ? super : self._test_adapter
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveJob/VERSION.html b/src/5.2/classes/ActiveJob/VERSION.html new file mode 100644 index 0000000000..b822c6f6b0 --- /dev/null +++ b/src/5.2/classes/ActiveJob/VERSION.html @@ -0,0 +1,120 @@ +--- +title: ActiveJob::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel.html b/src/5.2/classes/ActiveModel.html new file mode 100644 index 0000000000..0570cd42b7 --- /dev/null +++ b/src/5.2/classes/ActiveModel.html @@ -0,0 +1,332 @@ +--- +title: ActiveModel +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Active Model as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded Active Model as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/version.rb, line 7
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/AttributeAssignment.html b/src/5.2/classes/ActiveModel/AttributeAssignment.html new file mode 100644 index 0000000000..f741683a21 --- /dev/null +++ b/src/5.2/classes/ActiveModel/AttributeAssignment.html @@ -0,0 +1,155 @@ +--- +title: ActiveModel::AttributeAssignment +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assign_attributes(new_attributes) + +

+ + +
+

Allows you to set all the attributes by passing in a hash of attributes with keys matching the attribute names.

+ +

If the passed hash responds to permitted? method and the return value of this method is false an ActiveModel::ForbiddenAttributesError exception is raised.

+ +
class Cat
+  include ActiveModel::AttributeAssignment
+  attr_accessor :name, :status
+end
+
+cat = Cat.new
+cat.assign_attributes(name: "Gorby", status: "yawning")
+cat.name # => 'Gorby'
+cat.status # => 'yawning'
+cat.assign_attributes(status: "sleeping")
+cat.name # => 'Gorby'
+cat.status # => 'sleeping'
+
+
+ + + +
+ Also aliased as: attributes= +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_assignment.rb, line 28
+def assign_attributes(new_attributes)
+  if !new_attributes.respond_to?(:stringify_keys)
+    raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
+  end
+  return if new_attributes.empty?
+
+  attributes = new_attributes.stringify_keys
+  _assign_attributes(sanitize_for_mass_assignment(attributes))
+end
+
+
+ +
+ +
+

+ + attributes=(new_attributes) + +

+ + +
+ +
+ + + + + +
+ Alias for: assign_attributes +
+ + + +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/AttributeMethods.html b/src/5.2/classes/ActiveModel/AttributeMethods.html new file mode 100644 index 0000000000..a4d665713c --- /dev/null +++ b/src/5.2/classes/ActiveModel/AttributeMethods.html @@ -0,0 +1,324 @@ +--- +title: ActiveModel::AttributeMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Model Attribute Methods

+ +

Provides a way to add prefixes and suffixes to your methods as well as handling the creation of ActiveRecord::Base-like class methods such as table_name.

+ +

The requirements to implement ActiveModel::AttributeMethods are to:

+
  • +

    include ActiveModel::AttributeMethods in your class.

    +
  • +

    Call each of its methods you want to add, such as attribute_method_suffix or attribute_method_prefix.

    +
  • +

    Call define_attribute_methods after the other methods are called.

    +
  • +

    Define the various generic _attribute methods that you have declared.

    +
  • +

    Define an attributes method which returns a hash with each attribute name in your model as hash key and the attribute value as hash value. Hash keys must be strings.

    +
+ +

A minimal implementation could be:

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attribute_method_affix  prefix: 'reset_', suffix: '_to_default!'
+  attribute_method_suffix '_contrived?'
+  attribute_method_prefix 'clear_'
+  define_attribute_methods :name
+
+  attr_accessor :name
+
+  def attributes
+    { 'name' => @name }
+  end
+
+  private
+
+  def attribute_contrived?(attr)
+    true
+  end
+
+  def clear_attribute(attr)
+    send("#{attr}=", nil)
+  end
+
+  def reset_attribute_to_default!(attr)
+    send("#{attr}=", 'Default Name')
+  end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CALL_COMPILABLE_REGEXP=/\A[a-zA-Z_]\w*[!?]?\z/
 
NAME_COMPILABLE_REGEXP=/\A[a-zA-Z_]\w*[!?=]?\z/
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + attribute_missing(match, *args, &block) + +

+ + +
+

attribute_missing is like method_missing, but for attributes. When method_missing is called we check to see if there is a matching attribute method. If so, we tell attribute_missing to dispatch the attribute. This method can be overloaded to customize the behavior.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 438
+def attribute_missing(match, *args, &block)
+  __send__(match.target, match.attr_name, *args, &block)
+end
+
+
+ +
+ +
+

+ + method_missing(method, *args, &block) + +

+ + +
+

Allows access to the object attributes, which are held in the hash returned by attributes, as though they were first-class methods. So a Person class with a name attribute can for example use Person#name and Person#name= and never directly use the attributes hash – except for multiple assignments with ActiveRecord::Base#attributes=.

+ +

It's also possible to instantiate related objects, so a Client class belonging to the clients table with a master_id foreign key can instantiate master through Client#master.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 425
+def method_missing(method, *args, &block)
+  if respond_to_without_attributes?(method, true)
+    super
+  else
+    match = matched_attribute_method(method.to_s)
+    match ? attribute_missing(match, *args, &block) : super
+  end
+end
+
+
+ +
+ +
+

+ + respond_to?(method, include_private_methods = false) + +

+ + +
+ +
+ + + +
+ Also aliased as: respond_to_without_attributes? +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 446
+def respond_to?(method, include_private_methods = false)
+  if super
+    true
+  elsif !include_private_methods && super(method, true)
+    # If we're here then we haven't found among non-private methods
+    # but found among all methods. Which means that the given method is private.
+    false
+  else
+    !matched_attribute_method(method.to_s).nil?
+  end
+end
+
+
+ +
+ +
+

+ + respond_to_without_attributes?(method, include_private_methods = false) + +

+ + +
+

A Person instance with a name attribute can ask person.respond_to?(:name), person.respond_to?(:name=), and person.respond_to?(:name?) which will all return true.

+
+ + + + + +
+ Alias for: respond_to? +
+ + + +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/AttributeMethods/ClassMethods.html b/src/5.2/classes/ActiveModel/AttributeMethods/ClassMethods.html new file mode 100644 index 0000000000..c2485ab8f6 --- /dev/null +++ b/src/5.2/classes/ActiveModel/AttributeMethods/ClassMethods.html @@ -0,0 +1,622 @@ +--- +title: ActiveModel::AttributeMethods::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + alias_attribute(new_name, old_name) + +

+ + +
+

Allows you to make aliases for attributes.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name
+  attribute_method_suffix '_short?'
+  define_attribute_methods :name
+
+  alias_attribute :nickname, :name
+
+  private
+
+  def attribute_short?(attr)
+    send(attr).length < 5
+  end
+end
+
+person = Person.new
+person.name = 'Bob'
+person.name            # => "Bob"
+person.nickname        # => "Bob"
+person.name_short?     # => true
+person.nickname_short? # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 208
+def alias_attribute(new_name, old_name)
+  self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s)
+  attribute_method_matchers.each do |matcher|
+    matcher_new = matcher.method_name(new_name).to_s
+    matcher_old = matcher.method_name(old_name).to_s
+    define_proxy_call false, self, matcher_new, matcher_old
+  end
+end
+
+
+ +
+ +
+

+ + attribute_alias(name) + +

+ + +
+

Returns the original name for the alias name

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 223
+def attribute_alias(name)
+  attribute_aliases[name.to_s]
+end
+
+
+ +
+ +
+

+ + attribute_alias?(new_name) + +

+ + +
+

Is new_name an alias?

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 218
+def attribute_alias?(new_name)
+  attribute_aliases.key? new_name.to_s
+end
+
+
+ +
+ +
+

+ + attribute_method_affix(*affixes) + +

+ + +
+

Declares a method available for all attributes with the given prefix and suffix. Uses method_missing and respond_to? to rewrite the method.

+ +
#{prefix}#{attr}#{suffix}(*args, &block)
+
+ +

to

+ +
#{prefix}attribute#{suffix}(#{attr}, *args, &block)
+
+ +

An #{prefix}attribute#{suffix} instance method must exist and accept at least the attr argument.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name
+  attribute_method_affix prefix: 'reset_', suffix: '_to_default!'
+  define_attribute_methods :name
+
+  private
+
+  def reset_attribute_to_default!(attr)
+    send("#{attr}=", 'Default Name')
+  end
+end
+
+person = Person.new
+person.name                         # => 'Gem'
+person.reset_name_to_default!
+person.name                         # => 'Default Name'
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 179
+def attribute_method_affix(*affixes)
+  self.attribute_method_matchers += affixes.map! { |affix| AttributeMethodMatcher.new prefix: affix[:prefix], suffix: affix[:suffix] }
+  undefine_attribute_methods
+end
+
+
+ +
+ +
+

+ + attribute_method_prefix(*prefixes) + +

+ + +
+

Declares a method available for all attributes with the given prefix. Uses method_missing and respond_to? to rewrite the method.

+ +
#{prefix}#{attr}(*args, &block)
+
+ +

to

+ +
#{prefix}attribute(#{attr}, *args, &block)
+
+ +

An instance method #{prefix}attribute must exist and accept at least the attr argument.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name
+  attribute_method_prefix 'clear_'
+  define_attribute_methods :name
+
+  private
+
+  def clear_attribute(attr)
+    send("#{attr}=", nil)
+  end
+end
+
+person = Person.new
+person.name = 'Bob'
+person.name          # => "Bob"
+person.clear_name
+person.name          # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 108
+def attribute_method_prefix(*prefixes)
+  self.attribute_method_matchers += prefixes.map! { |prefix| AttributeMethodMatcher.new prefix: prefix }
+  undefine_attribute_methods
+end
+
+
+ +
+ +
+

+ + attribute_method_suffix(*suffixes) + +

+ + +
+

Declares a method available for all attributes with the given suffix. Uses method_missing and respond_to? to rewrite the method.

+ +
#{attr}#{suffix}(*args, &block)
+
+ +

to

+ +
attribute#{suffix}(#{attr}, *args, &block)
+
+ +

An attribute#{suffix} instance method must exist and accept at least the attr argument.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name
+  attribute_method_suffix '_short?'
+  define_attribute_methods :name
+
+  private
+
+  def attribute_short?(attr)
+    send(attr).length < 5
+  end
+end
+
+person = Person.new
+person.name = 'Bob'
+person.name          # => "Bob"
+person.name_short?   # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 143
+def attribute_method_suffix(*suffixes)
+  self.attribute_method_matchers += suffixes.map! { |suffix| AttributeMethodMatcher.new suffix: suffix }
+  undefine_attribute_methods
+end
+
+
+ +
+ +
+

+ + define_attribute_method(attr_name) + +

+ + +
+

Declares an attribute that should be prefixed and suffixed by ActiveModel::AttributeMethods.

+ +

To use, pass an attribute name (as string or symbol). Be sure to declare define_attribute_method after you define any prefix, suffix or affix method, or they will not hook in.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name
+  attribute_method_suffix '_short?'
+
+  # Call to define_attribute_method must appear after the
+  # attribute_method_prefix, attribute_method_suffix or
+  # attribute_method_affix declarations.
+  define_attribute_method :name
+
+  private
+
+  def attribute_short?(attr)
+    send(attr).length < 5
+  end
+end
+
+person = Person.new
+person.name = 'Bob'
+person.name        # => "Bob"
+person.name_short? # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 284
+def define_attribute_method(attr_name)
+  attribute_method_matchers.each do |matcher|
+    method_name = matcher.method_name(attr_name)
+
+    unless instance_method_already_implemented?(method_name)
+      generate_method = "define_method_#{matcher.method_missing_target}"
+
+      if respond_to?(generate_method, true)
+        send(generate_method, attr_name.to_s)
+      else
+        define_proxy_call true, generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s
+      end
+    end
+  end
+  attribute_method_matchers_cache.clear
+end
+
+
+ +
+ +
+

+ + define_attribute_methods(*attr_names) + +

+ + +
+

Declares the attributes that should be prefixed and suffixed by ActiveModel::AttributeMethods.

+ +

To use, pass attribute names (as strings or symbols). Be sure to declare define_attribute_methods after you define any prefix, suffix or affix methods, or they will not hook in.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name, :age, :address
+  attribute_method_prefix 'clear_'
+
+  # Call to define_attribute_methods must appear after the
+  # attribute_method_prefix, attribute_method_suffix or
+  # attribute_method_affix declarations.
+  define_attribute_methods :name, :age, :address
+
+  private
+
+  def clear_attribute(attr)
+    send("#{attr}=", nil)
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 251
+def define_attribute_methods(*attr_names)
+  attr_names.flatten.each { |attr_name| define_attribute_method(attr_name) }
+end
+
+
+ +
+ +
+

+ + undefine_attribute_methods() + +

+ + +
+

Removes all the previously dynamically defined methods from the class.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name
+  attribute_method_suffix '_short?'
+  define_attribute_method :name
+
+  private
+
+  def attribute_short?(attr)
+    send(attr).length < 5
+  end
+end
+
+person = Person.new
+person.name = 'Bob'
+person.name_short? # => true
+
+Person.undefine_attribute_methods
+
+person.name_short? # => NoMethodError
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attribute_methods.rb, line 324
+def undefine_attribute_methods
+  generated_attribute_methods.module_eval do
+    instance_methods.each { |m| undef_method(m) }
+  end
+  attribute_method_matchers_cache.clear
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Attributes.html b/src/5.2/classes/ActiveModel/Attributes.html new file mode 100644 index 0000000000..88d026609f --- /dev/null +++ b/src/5.2/classes/ActiveModel/Attributes.html @@ -0,0 +1,67 @@ +--- +title: ActiveModel::Attributes +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Attributes/ClassMethods.html b/src/5.2/classes/ActiveModel/Attributes/ClassMethods.html new file mode 100644 index 0000000000..46d599cd99 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Attributes/ClassMethods.html @@ -0,0 +1,107 @@ +--- +title: ActiveModel::Attributes::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attribute(name, type = Type::Value.new, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/attributes.rb, line 19
+def attribute(name, type = Type::Value.new, **options)
+  name = name.to_s
+  if type.is_a?(Symbol)
+    type = ActiveModel::Type.lookup(type, **options.except(:default))
+  end
+  self.attribute_types = attribute_types.merge(name => type)
+  define_default_attribute(name, options.fetch(:default, NO_DEFAULT_PROVIDED), type)
+  define_attribute_method(name)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Callbacks.html b/src/5.2/classes/ActiveModel/Callbacks.html new file mode 100644 index 0000000000..5cb0d0c772 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Callbacks.html @@ -0,0 +1,220 @@ +--- +title: ActiveModel::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Active Model Callbacks

+ +

Provides an interface for any class to have Active Record like callbacks.

+ +

Like the Active Record methods, the callback chain is aborted as soon as one of the methods throws :abort.

+ +

First, extend ActiveModel::Callbacks from the class you are creating:

+ +
class MyModel
+  extend ActiveModel::Callbacks
+end
+
+ +

Then define a list of methods that you want callbacks attached to:

+ +
define_model_callbacks :create, :update
+
+ +

This will provide all three standard callbacks (before, around and after) for both the :create and :update methods. To implement, you need to wrap the methods you want callbacks on in a block so that the callbacks get a chance to fire:

+ +
def create
+  run_callbacks :create do
+    # Your create action methods here
+  end
+end
+
+ +

Then in your class, you can use the before_create, after_create and around_create methods, just as you would in an Active Record model.

+ +
before_create :action_before_create
+
+def action_before_create
+  # Your code here
+end
+
+ +

When defining an around callback remember to yield to the block, otherwise it won't be executed:

+ +
around_create :log_status
+
+def log_status
+  puts 'going to call the block...'
+  yield
+  puts 'block successfully called.'
+end
+
+ +

You can choose to have only specific callbacks by passing a hash to the define_model_callbacks method.

+ +
define_model_callbacks :create, only: [:after, :before]
+
+ +

Would only create the after_create and before_create callback methods in your class.

+ +

NOTE: Calling the same callback multiple times will overwrite previous callback definitions.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + define_model_callbacks(*callbacks) + +

+ + +
+

define_model_callbacks accepts the same options define_callbacks does, in case you want to overwrite a default. Besides that, it also accepts an :only option, where you can choose if you want all types (before, around or after) or just some.

+ +
define_model_callbacks :initializer, only: :after
+
+ +

Note, the only: <type> hash will apply to all callbacks defined on that method call. To get around this you can call the define_model_callbacks method as many times as you need.

+ +
define_model_callbacks :create,  only: :after
+define_model_callbacks :update,  only: :before
+define_model_callbacks :destroy, only: :around
+
+ +

Would create after_create, before_update and around_destroy methods only.

+ +

You can pass in a class to before_<type>, after_<type> and around_<type>, in which case the callback will call that class's <action>_<type> method passing the object that the callback is being called on.

+ +
class MyModel
+  extend ActiveModel::Callbacks
+  define_model_callbacks :create
+
+  before_create AnotherClass
+end
+
+class AnotherClass
+  def self.before_create( obj )
+    # obj is the MyModel instance that the callback is being called on
+  end
+end
+
+ +

NOTE: method_name passed to define_model_callbacks must not end with !, ? or =.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/callbacks.rb, line 108
+def define_model_callbacks(*callbacks)
+  options = callbacks.extract_options!
+  options = {
+    skip_after_callbacks_if_terminated: true,
+    scope: [:kind, :name],
+    only: [:before, :around, :after]
+  }.merge!(options)
+
+  types = Array(options.delete(:only))
+
+  callbacks.each do |callback|
+    define_callbacks(callback, options)
+
+    types.each do |type|
+      send("_define_#{type}_model_callback", self, callback)
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Conversion.html b/src/5.2/classes/ActiveModel/Conversion.html new file mode 100644 index 0000000000..41384d6ad7 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Conversion.html @@ -0,0 +1,293 @@ +--- +title: ActiveModel::Conversion +layout: default +--- +
+ +
+
+ +
+ +

Active Model Conversion

+ +

Handles default conversions: to_model, to_key, to_param, and to_partial_path.

+ +

Let's take for example this non-persisted object.

+ +
class ContactMessage
+  include ActiveModel::Conversion
+
+  # ContactMessage are never persisted in the DB
+  def persisted?
+    false
+  end
+end
+
+cm = ContactMessage.new
+cm.to_model == cm  # => true
+cm.to_key          # => nil
+cm.to_param        # => nil
+cm.to_partial_path # => "contact_messages/contact_message"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + to_key() + +

+ + +
+

Returns an Array of all key attributes if any of the attributes is set, whether or not the object is persisted. Returns nil if there are no key attributes.

+ +
class Person
+  include ActiveModel::Conversion
+  attr_accessor :id
+
+  def initialize(id)
+    @id = id
+  end
+end
+
+person = Person.new(1)
+person.to_key # => [1]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/conversion.rb, line 59
+def to_key
+  key = respond_to?(:id) && id
+  key ? [key] : nil
+end
+
+
+ +
+ +
+

+ + to_model() + +

+ + +
+

If your object is already designed to implement all of the Active Model you can use the default :to_model implementation, which simply returns self.

+ +
class Person
+  include ActiveModel::Conversion
+end
+
+person = Person.new
+person.to_model == person # => true
+
+ +

If your model does not act like an Active Model object, then you should define :to_model yourself returning a proxy object that wraps your object with Active Model compliant methods.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/conversion.rb, line 41
+def to_model
+  self
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns a string representing the object's key suitable for use in URLs, or nil if persisted? is false.

+ +
class Person
+  include ActiveModel::Conversion
+  attr_accessor :id
+
+  def initialize(id)
+    @id = id
+  end
+
+  def persisted?
+    true
+  end
+end
+
+person = Person.new(1)
+person.to_param # => "1"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/conversion.rb, line 82
+def to_param
+  (persisted? && key = to_key) ? key.join("-") : nil
+end
+
+
+ +
+ +
+

+ + to_partial_path() + +

+ + +
+

Returns a string identifying the path associated with the object. ActionPack uses this to find a suitable partial to represent the object.

+ +
class Person
+  include ActiveModel::Conversion
+end
+
+person = Person.new
+person.to_partial_path # => "people/person"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/conversion.rb, line 95
+def to_partial_path
+  self.class._to_partial_path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Dirty.html b/src/5.2/classes/ActiveModel/Dirty.html new file mode 100644 index 0000000000..0036010d83 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Dirty.html @@ -0,0 +1,600 @@ +--- +title: ActiveModel::Dirty +layout: default +--- +
+ +
+
+ +
+ +

Active Model Dirty

+ +

Provides a way to track changes in your object in the same way as Active Record does.

+ +

The requirements for implementing ActiveModel::Dirty are:

+
  • +

    include ActiveModel::Dirty in your object.

    +
  • +

    Call define_attribute_methods passing each method you want to track.

    +
  • +

    Call [attr_name]_will_change! before each change to the tracked attribute.

    +
  • +

    Call changes_applied after the changes are persisted.

    +
  • +

    Call clear_changes_information when you want to reset the changes information.

    +
  • +

    Call restore_attributes when you want to restore previous data.

    +
+ +

A minimal implementation could be:

+ +
class Person
+  include ActiveModel::Dirty
+
+  define_attribute_methods :name
+
+  def initialize
+    @name = nil
+  end
+
+  def name
+    @name
+  end
+
+  def name=(val)
+    name_will_change! unless val == @name
+    @name = val
+  end
+
+  def save
+    # do persistence work
+
+    changes_applied
+  end
+
+  def reload!
+    # get the values from the persistence layer
+
+    clear_changes_information
+  end
+
+  def rollback!
+    restore_attributes
+  end
+end
+
+ +

A newly instantiated Person object is unchanged:

+ +
person = Person.new
+person.changed? # => false
+
+ +

Change the name:

+ +
person.name = 'Bob'
+person.changed?       # => true
+person.name_changed?  # => true
+person.name_changed?(from: nil, to: "Bob") # => true
+person.name_was       # => nil
+person.name_change    # => [nil, "Bob"]
+person.name = 'Bill'
+person.name_change    # => [nil, "Bill"]
+
+ +

Save the changes:

+ +
person.save
+person.changed?      # => false
+person.name_changed? # => false
+
+ +

Reset the changes:

+ +
person.previous_changes         # => {"name" => [nil, "Bill"]}
+person.name_previously_changed? # => true
+person.name_previous_change     # => [nil, "Bill"]
+person.reload!
+person.previous_changes         # => {}
+
+ +

Rollback the changes:

+ +
person.name = "Uncle Bob"
+person.rollback!
+person.name          # => "Bill"
+person.name_changed? # => false
+
+ +

Assigning the same value leaves the attribute unchanged:

+ +
person.name = 'Bill'
+person.name_changed? # => false
+person.name_change   # => nil
+
+ +

Which attributes have changed?

+ +
person.name = 'Bob'
+person.changed # => ["name"]
+person.changes # => {"name" => ["Bill", "Bob"]}
+
+ +

If an attribute is modified in-place then make use of [attribute_name]_will_change! to mark that the attribute is changing. Otherwise Active Model can't track changes to in-place attributes. Note that Active Record can detect in-place modifications automatically. You do not need to call [attribute_name]_will_change! on Active Record models.

+ +
person.name_will_change!
+person.name_change # => ["Bill", "Bill"]
+person.name << 'y'
+person.name_change # => ["Bill", "Billy"]
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + changed() + +

+ + +
+

Returns an array with the name of the attributes with unsaved changes.

+ +
person.changed # => []
+person.name = 'bob'
+person.changed # => ["name"]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 170
+def changed
+  changed_attributes.keys
+end
+
+
+ +
+ +
+

+ + changed?() + +

+ + +
+

Returns true if any of the attributes have unsaved changes, false otherwise.

+ +
person.changed? # => false
+person.name = 'bob'
+person.changed? # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 161
+def changed?
+  changed_attributes.present?
+end
+
+
+ +
+ +
+

+ + changed_attributes() + +

+ + +
+

Returns a hash of the attributes with unsaved changes indicating their original values like attr => original value.

+ +
person.name # => "bob"
+person.name = 'robert'
+person.changed_attributes # => {"name" => "bob"}
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 218
+def changed_attributes
+  # This should only be set by methods which will call changed_attributes
+  # multiple times when it is known that the computed value cannot change.
+  if defined?(@cached_changed_attributes)
+    @cached_changed_attributes
+  else
+    attributes_changed_by_setter.reverse_merge(mutations_from_database.changed_values).freeze
+  end
+end
+
+
+ +
+ +
+

+ + changes() + +

+ + +
+

Returns a hash of changed attributes indicating their original and new values like attr => [original value, new value].

+ +
person.changes # => {}
+person.name = 'bob'
+person.changes # => { "name" => ["bill", "bob"] }
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 234
+def changes
+  cache_changed_attributes do
+    ActiveSupport::HashWithIndifferentAccess[changed.map { |attr| [attr, attribute_change(attr)] }]
+  end
+end
+
+
+ +
+ +
+

+ + changes_applied() + +

+ + +
+

Clears dirty data and moves changes to previously_changed and mutations_from_database to mutations_before_last_save respectively.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 146
+def changes_applied
+  unless defined?(@attributes)
+    @previously_changed = changes
+  end
+  @mutations_before_last_save = mutations_from_database
+  @attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
+  forget_attribute_assignments
+  @mutations_from_database = nil
+end
+
+
+ +
+ +
+

+ + clear_attribute_changes(attr_names) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 205
+def clear_attribute_changes(attr_names)
+  attributes_changed_by_setter.except!(*attr_names)
+  attr_names.each do |attr_name|
+    clear_attribute_change(attr_name)
+  end
+end
+
+
+ +
+ +
+

+ + clear_changes_information() + +

+ + +
+

Clears all dirty data: current changes and previous changes.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 197
+def clear_changes_information
+  @previously_changed = ActiveSupport::HashWithIndifferentAccess.new
+  @mutations_before_last_save = nil
+  @attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
+  forget_attribute_assignments
+  @mutations_from_database = nil
+end
+
+
+ +
+ +
+

+ + previous_changes() + +

+ + +
+

Returns a hash of attributes that were changed before the model was saved.

+ +
person.name # => "bob"
+person.name = 'robert'
+person.save
+person.previous_changes # => {"name" => ["bob", "robert"]}
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 246
+def previous_changes
+  @previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new
+  @previously_changed.merge(mutations_before_last_save.changes)
+end
+
+
+ +
+ +
+

+ + restore_attributes(attributes = changed) + +

+ + +
+

Restore all previous data of the provided attributes.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/dirty.rb, line 192
+def restore_attributes(attributes = changed)
+  attributes.each { |attr| restore_attribute! attr }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Errors.html b/src/5.2/classes/ActiveModel/Errors.html new file mode 100644 index 0000000000..95b1a80297 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Errors.html @@ -0,0 +1,1370 @@ +--- +title: ActiveModel::Errors +layout: default +--- +
+ +
+
+ +
+ +

Active Model Errors

+ +

Provides a modified Hash that you can include in your object for handling error messages and interacting with Action View helpers.

+ +

A minimal implementation could be:

+ +
class Person
+  # Required dependency for ActiveModel::Errors
+  extend ActiveModel::Naming
+
+  def initialize
+    @errors = ActiveModel::Errors.new(self)
+  end
+
+  attr_accessor :name
+  attr_reader   :errors
+
+  def validate!
+    errors.add(:name, :blank, message: "cannot be nil") if name.nil?
+  end
+
+  # The following methods are needed to be minimally implemented
+
+  def read_attribute_for_validation(attr)
+    send(attr)
+  end
+
+  def self.human_attribute_name(attr, options = {})
+    attr
+  end
+
+  def self.lookup_ancestors
+    [self]
+  end
+end
+
+ +

The last three methods are required in your object for Errors to be able to generate error messages correctly and also handle multiple languages. Of course, if you extend your object with ActiveModel::Translation you will not need to implement the last two. Likewise, using ActiveModel::Validations will handle the validation related methods for you.

+ +

The above allows you to do:

+ +
person = Person.new
+person.validate!            # => ["cannot be nil"]
+person.errors.full_messages # => ["name cannot be nil"]
+# etc..
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CALLBACKS_OPTIONS=[:if, :unless, :on, :allow_nil, :allow_blank, :strict]
 
MESSAGE_OPTIONS=[:message]
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + details
+ [R] + messages
+ + + + +

Class Public methods

+ +
+

+ + new(base) + +

+ + +
+

Pass in the instance of the object that is using the errors object.

+ +
class Person
+  def initialize
+    @errors = ActiveModel::Errors.new(self)
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 74
+def initialize(base)
+  @base     = base
+  @messages = apply_default_array({})
+  @details = apply_default_array({})
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](attribute) + +

+ + +
+

When passed a symbol or a name of a method, returns an array of errors for the method.

+ +
person.errors[:name]  # => ["cannot be nil"]
+person.errors['name'] # => ["cannot be nil"]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 149
+def [](attribute)
+  messages[attribute.to_sym]
+end
+
+
+ +
+ +
+

+ + add(attribute, message = :invalid, options = {}) + +

+ + +
+

Adds message to the error messages and used validator type to details on attribute. More than one error can be added to the same attribute. If no message is supplied, :invalid is assumed.

+ +
person.errors.add(:name)
+# => ["is invalid"]
+person.errors.add(:name, :not_implemented, message: "must be implemented")
+# => ["is invalid", "must be implemented"]
+
+person.errors.messages
+# => {:name=>["is invalid", "must be implemented"]}
+
+person.errors.details
+# => {:name=>[{error: :not_implemented}, {error: :invalid}]}
+
+ +

If message is a symbol, it will be translated using the appropriate scope (see generate_message).

+ +

If message is a proc, it will be called, allowing for things like Time.now to be used within an error.

+ +

If the :strict option is set to true, it will raise ActiveModel::StrictValidationFailed instead of adding the error. :strict option can also be set to any other exception.

+ +
person.errors.add(:name, :invalid, strict: true)
+# => ActiveModel::StrictValidationFailed: Name is invalid
+person.errors.add(:name, :invalid, strict: NameIsInvalid)
+# => NameIsInvalid: Name is invalid
+
+person.errors.messages # => {}
+
+ +

attribute should be set to :base if the error is not directly associated with a single attribute.

+ +
person.errors.add(:base, :name_or_email_blank,
+  message: "either name or email must be present")
+person.errors.messages
+# => {:base=>["either name or email must be present"]}
+person.errors.details
+# => {:base=>[{error: :name_or_email_blank}]}
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 295
+def add(attribute, message = :invalid, options = {})
+  message = message.call if message.respond_to?(:call)
+  detail  = normalize_detail(message, options)
+  message = normalize_message(attribute, message, options)
+  if exception = options[:strict]
+    exception = ActiveModel::StrictValidationFailed if exception == true
+    raise exception, full_message(attribute, message)
+  end
+
+  details[attribute.to_sym]  << detail
+  messages[attribute.to_sym] << message
+end
+
+
+ +
+ +
+

+ + added?(attribute, message = :invalid, options = {}) + +

+ + +
+

Returns true if an error on the attribute with the given message is present, or false otherwise. message is treated the same as for add.

+ +
person.errors.add :name, :blank
+person.errors.added? :name, :blank           # => true
+person.errors.added? :name, "can't be blank" # => true
+
+ +

If the error message requires an option, then it returns true with the correct option, or false with an incorrect or missing option.

+ +
person.errors.add :name, :too_long, { count: 25 }
+person.errors.added? :name, :too_long, count: 25                     # => true
+person.errors.added? :name, "is too long (maximum is 25 characters)" # => true
+person.errors.added? :name, :too_long, count: 24                     # => false
+person.errors.added? :name, :too_long                                # => false
+person.errors.added? :name, "is too long"                            # => false
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 324
+def added?(attribute, message = :invalid, options = {})
+  message = message.call if message.respond_to?(:call)
+
+  if message.is_a? Symbol
+    details[attribute.to_sym].include? normalize_detail(message, options)
+  else
+    self[attribute].include? message
+  end
+end
+
+
+ +
+ +
+

+ + as_json(options = nil) + +

+ + +
+

Returns a Hash that can be used as the JSON representation for this object. You can pass the :full_messages option. This determines if the json object should contain full messages or not (false by default).

+ +
person.errors.as_json                      # => {:name=>["cannot be nil"]}
+person.errors.as_json(full_messages: true) # => {:name=>["name cannot be nil"]}
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 235
+def as_json(options = nil)
+  to_hash(options && options[:full_messages])
+end
+
+
+ +
+ +
+

+ + blank?() + +

+ + +
+ +
+ + + + + +
+ Alias for: empty? +
+ + + +
+ +
+

+ + clear() + +

+ + +
+

Clear the error messages.

+ +
person.errors.full_messages # => ["name cannot be nil"]
+person.errors.clear
+person.errors.full_messages # => []
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 115
+def clear
+  messages.clear
+  details.clear
+end
+
+
+ +
+ +
+

+ + count() + +

+ + +
+ +
+ + + + + +
+ Alias for: size +
+ + + +
+ +
+

+ + delete(key) + +

+ + +
+

Delete messages for key. Returns the deleted messages.

+ +
person.errors[:name]        # => ["cannot be nil"]
+person.errors.delete(:name) # => ["cannot be nil"]
+person.errors[:name]        # => []
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 138
+def delete(key)
+  attribute = key.to_sym
+  details.delete(attribute)
+  messages.delete(attribute)
+end
+
+
+ +
+ +
+

+ + each() + +

+ + +
+

Iterates through each error key, value pair in the error messages hash. Yields the attribute and the error for that attribute. If the attribute has more than one error message, yields once for each error message.

+ +
person.errors.add(:name, :blank, message: "can't be blank")
+person.errors.each do |attribute, error|
+  # Will yield :name and "can't be blank"
+end
+
+person.errors.add(:name, :not_specified, message: "must be specified")
+person.errors.each do |attribute, error|
+  # Will yield :name and "can't be blank"
+  # then yield :name and "must be specified"
+end
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 167
+def each
+  messages.each_key do |attribute|
+    messages[attribute].each { |error| yield attribute, error }
+  end
+end
+
+
+ +
+ +
+

+ + empty?() + +

+ + +
+

Returns true if no errors are found, false otherwise. If the error message is a string it can be empty.

+ +
person.errors.full_messages # => ["name cannot be nil"]
+person.errors.empty?        # => false
+
+
+ + + +
+ Also aliased as: blank? +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 209
+def empty?
+  size.zero?
+end
+
+
+ +
+ +
+

+ + full_message(attribute, message) + +

+ + +
+

Returns a full message for a given attribute.

+ +
person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 367
+def full_message(attribute, message)
+  return message if attribute == :base
+  attr_name = attribute.to_s.tr(".", "_").humanize
+  attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
+  I18n.t(:"errors.format",
+    default:  "%{attribute} %{message}",
+    attribute: attr_name,
+    message:   message)
+end
+
+
+ +
+ +
+

+ + full_messages() + +

+ + +
+

Returns all the full error messages in an array.

+ +
class Person
+  validates_presence_of :name, :address, :email
+  validates_length_of :name, in: 5..30
+end
+
+person = Person.create(address: '123 First St.')
+person.errors.full_messages
+# => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
+
+
+ + + +
+ Also aliased as: to_a +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 344
+def full_messages
+  map { |attribute, message| full_message(attribute, message) }
+end
+
+
+ +
+ +
+

+ + full_messages_for(attribute) + +

+ + +
+

Returns all the full error messages for a given attribute in an array.

+ +
class Person
+  validates_presence_of :name, :email
+  validates_length_of :name, in: 5..30
+end
+
+person = Person.create()
+person.errors.full_messages_for(:name)
+# => ["Name is too short (minimum is 5 characters)", "Name can't be blank"]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 359
+def full_messages_for(attribute)
+  attribute = attribute.to_sym
+  messages[attribute].map { |message| full_message(attribute, message) }
+end
+
+
+ +
+ +
+

+ + generate_message(attribute, type = :invalid, options = {}) + +

+ + +
+

Translates an error message in its default scope (activemodel.errors.messages).

+ +

Error messages are first looked up in activemodel.errors.models.MODEL.attributes.ATTRIBUTE.MESSAGE, if it's not there, it's looked up in activemodel.errors.models.MODEL.MESSAGE and if that is not there also, it returns the translation of the default message (e.g. activemodel.errors.messages.MESSAGE). The translated model name, translated attribute name and the value are available for interpolation.

+ +

When using inheritance in your models, it will check all the inherited models too, but only if the model itself hasn't been found. Say you have class Admin < User; end and you wanted the translation for the :blank error message for the title attribute, it looks for these translations:

+
  • +

    activemodel.errors.models.admin.attributes.title.blank

    +
  • +

    activemodel.errors.models.admin.blank

    +
  • +

    activemodel.errors.models.user.attributes.title.blank

    +
  • +

    activemodel.errors.models.user.blank

    +
  • +

    any default you provided through the options hash (in the activemodel.errors scope)

    +
  • +

    activemodel.errors.messages.blank

    +
  • +

    errors.attributes.title.blank

    +
  • +

    errors.messages.blank

    +
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 401
+def generate_message(attribute, type = :invalid, options = {})
+  type = options.delete(:message) if options[:message].is_a?(Symbol)
+
+  if @base.class.respond_to?(:i18n_scope)
+    i18n_scope = @base.class.i18n_scope.to_s
+    defaults = @base.class.lookup_ancestors.flat_map do |klass|
+      [ :"#{i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}",
+        :"#{i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ]
+    end
+    defaults << :"#{i18n_scope}.errors.messages.#{type}"
+  else
+    defaults = []
+  end
+
+  defaults << :"errors.attributes.#{attribute}.#{type}"
+  defaults << :"errors.messages.#{type}"
+
+  key = defaults.shift
+  defaults = options.delete(:message) if options[:message]
+  value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil)
+
+  options = {
+    default: defaults,
+    model: @base.model_name.human,
+    attribute: @base.class.human_attribute_name(attribute),
+    value: value,
+    object: @base
+  }.merge!(options)
+
+  I18n.translate(key, options)
+end
+
+
+ +
+ +
+

+ + has_key?(attribute) + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + +
+ +
+

+ + include?(attribute) + +

+ + +
+

Returns true if the error messages include an error for the given key attribute, false otherwise.

+ +
person.errors.messages        # => {:name=>["cannot be nil"]}
+person.errors.include?(:name) # => true
+person.errors.include?(:age)  # => false
+
+
+ + + +
+ Also aliased as: has_key?, key? +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 126
+def include?(attribute)
+  attribute = attribute.to_sym
+  messages.key?(attribute) && messages[attribute].present?
+end
+
+
+ +
+ +
+

+ + key?(attribute) + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + +
+ +
+

+ + keys() + +

+ + +
+

Returns all message keys.

+ +
person.errors.messages # => {:name=>["cannot be nil", "must be specified"]}
+person.errors.keys     # => [:name]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 198
+def keys
+  messages.select do |key, value|
+    !value.empty?
+  end.keys
+end
+
+
+ +
+ +
+

+ + merge!(other) + +

+ + +
+

Merges the errors from other.

+ +

other - The ActiveModel::Errors instance.

+ +

Examples

+ +
person.errors.merge!(other)
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 105
+def merge!(other)
+  @messages.merge!(other.messages) { |_, ary1, ary2| ary1 + ary2 }
+  @details.merge!(other.details) { |_, ary1, ary2| ary1 + ary2 }
+end
+
+
+ +
+ +
+

+ + size() + +

+ + +
+

Returns the number of error messages.

+ +
person.errors.add(:name, :blank, message: "can't be blank")
+person.errors.size # => 1
+person.errors.add(:name, :not_specified, message: "must be specified")
+person.errors.size # => 2
+
+
+ + + +
+ Also aliased as: count +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 179
+def size
+  values.flatten.size
+end
+
+
+ +
+ +
+

+ + to_a() + +

+ + +
+ +
+ + + + + +
+ Alias for: full_messages +
+ + + +
+ +
+

+ + to_hash(full_messages = false) + +

+ + +
+

Returns a Hash of attributes with their error messages. If full_messages is true, it will contain full messages (see full_message).

+ +
person.errors.to_hash       # => {:name=>["cannot be nil"]}
+person.errors.to_hash(true) # => {:name=>["name cannot be nil"]}
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 244
+def to_hash(full_messages = false)
+  if full_messages
+    messages.each_with_object({}) do |(attribute, array), messages|
+      messages[attribute] = array.map { |message| full_message(attribute, message) }
+    end
+  else
+    without_default_proc(messages)
+  end
+end
+
+
+ +
+ +
+

+ + to_xml(options = {}) + +

+ + +
+

Returns an xml formatted representation of the Errors hash.

+ +
person.errors.add(:name, :blank, message: "can't be blank")
+person.errors.add(:name, :not_specified, message: "must be specified")
+person.errors.to_xml
+# =>
+#  <?xml version=\"1.0\" encoding=\"UTF-8\"?>
+#  <errors>
+#    <error>name can't be blank</error>
+#    <error>name must be specified</error>
+#  </errors>
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 225
+def to_xml(options = {})
+  to_a.to_xml({ root: "errors", skip_types: true }.merge!(options))
+end
+
+
+ +
+ +
+

+ + values() + +

+ + +
+

Returns all message values.

+ +
person.errors.messages # => {:name=>["cannot be nil", "must be specified"]}
+person.errors.values   # => [["cannot be nil", "must be specified"]]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 188
+def values
+  messages.select do |key, value|
+    !value.empty?
+  end.values
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/ForbiddenAttributesError.html b/src/5.2/classes/ActiveModel/ForbiddenAttributesError.html new file mode 100644 index 0000000000..141047ed8b --- /dev/null +++ b/src/5.2/classes/ActiveModel/ForbiddenAttributesError.html @@ -0,0 +1,78 @@ +--- +title: ActiveModel::ForbiddenAttributesError +layout: default +--- +
+ +
+
+ +
+ +

Raised when forbidden attributes are used for mass assignment.

+ +
class Person < ActiveRecord::Base
+end
+
+params = ActionController::Parameters.new(name: 'Bob')
+Person.new(params)
+# => ActiveModel::ForbiddenAttributesError
+
+params.permit!
+Person.new(params)
+# => #<Person id: nil, name: "Bob">
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Lint.html b/src/5.2/classes/ActiveModel/Lint.html new file mode 100644 index 0000000000..85497b14c0 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Lint.html @@ -0,0 +1,67 @@ +--- +title: ActiveModel::Lint +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Lint/Tests.html b/src/5.2/classes/ActiveModel/Lint/Tests.html new file mode 100644 index 0000000000..9caa238ad9 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Lint/Tests.html @@ -0,0 +1,338 @@ +--- +title: ActiveModel::Lint::Tests +layout: default +--- +
+ +
+
+ +
+ +

Active Model Lint Tests

+ +

You can test whether an object is compliant with the Active Model API by including ActiveModel::Lint::Tests in your TestCase. It will include tests that tell you whether your object is fully compliant, or if not, which aspects of the API are not implemented.

+ +

Note an object is not required to implement all APIs in order to work with Action Pack. This module only intends to provide guidance in case you want all features out of the box.

+ +

These tests do not attempt to determine the semantic correctness of the returned values. For instance, you could implement valid? to always return true, and the tests would pass. It is up to you to ensure that the values are semantically meaningful.

+ +

Objects you pass in are expected to return a compliant object from a call to to_model. It is perfectly fine for to_model to return self.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + test_errors_aref() + +

+ + +
+

Passes if the object's model responds to errors and if calling [](attribute) on the result of this method returns an array. Fails otherwise.

+ +

errors[attribute] is used to retrieve the errors of a model for a given attribute. If errors are present, the method should return an array of strings that are the errors for the attribute in question. If localization is used, the strings should be localized for the current locale. If no error is present, the method should return an empty array.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/lint.rb, line 102
+def test_errors_aref
+  assert_respond_to model, :errors
+  assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array"
+end
+
+
+ +
+ +
+

+ + test_model_naming() + +

+ + +
+

Passes if the object's model responds to model_name both as an instance method and as a class method, and if calling this method returns a string with some convenience methods: :human, :singular and :plural.

+ +

Check ActiveModel::Naming for more information.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/lint.rb, line 81
+def test_model_naming
+  assert_respond_to model.class, :model_name
+  model_name = model.class.model_name
+  assert_respond_to model_name, :to_str
+  assert_respond_to model_name.human, :to_str
+  assert_respond_to model_name.singular, :to_str
+  assert_respond_to model_name.plural, :to_str
+
+  assert_respond_to model, :model_name
+  assert_equal model.model_name, model.class.model_name
+end
+
+
+ +
+ +
+

+ + test_persisted?() + +

+ + +
+

Passes if the object's model responds to persisted? and if calling this method returns either true or false. Fails otherwise.

+ +

persisted? is used when calculating the URL for an object. If the object is not persisted, a form for that object, for instance, will route to the create action. If it is persisted, a form for the object will route to the update action.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/lint.rb, line 70
+def test_persisted?
+  assert_respond_to model, :persisted?
+  assert_boolean model.persisted?, "persisted?"
+end
+
+
+ +
+ +
+

+ + test_to_key() + +

+ + +
+

Passes if the object's model responds to to_key and if calling this method returns nil when the object is not persisted. Fails otherwise.

+ +

to_key returns an Enumerable of all (primary) key attributes of the model, and is used to a generate unique DOM id for the object.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/lint.rb, line 31
+def test_to_key
+  assert_respond_to model, :to_key
+  def model.persisted?() false end
+  assert model.to_key.nil?, "to_key should return nil when `persisted?` returns false"
+end
+
+
+ +
+ +
+

+ + test_to_param() + +

+ + +
+

Passes if the object's model responds to to_param and if calling this method returns nil when the object is not persisted. Fails otherwise.

+ +

to_param is used to represent the object's key in URLs. Implementers can decide to either raise an exception or provide a default in case the record uses a composite primary key. There are no tests for this behavior in lint because it doesn't make sense to force any of the possible implementation strategies on the implementer.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/lint.rb, line 46
+def test_to_param
+  assert_respond_to model, :to_param
+  def model.to_key() [1] end
+  def model.persisted?() false end
+  assert model.to_param.nil?, "to_param should return nil when `persisted?` returns false"
+end
+
+
+ +
+ +
+

+ + test_to_partial_path() + +

+ + +
+

Passes if the object's model responds to to_partial_path and if calling this method returns a string. Fails otherwise.

+ +

to_partial_path is used for looking up partials. For example, a BlogPost model might return “blog_posts/blog_post”.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/lint.rb, line 58
+def test_to_partial_path
+  assert_respond_to model, :to_partial_path
+  assert_kind_of String, model.to_partial_path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/MissingAttributeError.html b/src/5.2/classes/ActiveModel/MissingAttributeError.html new file mode 100644 index 0000000000..6d96ec7c21 --- /dev/null +++ b/src/5.2/classes/ActiveModel/MissingAttributeError.html @@ -0,0 +1,75 @@ +--- +title: ActiveModel::MissingAttributeError +layout: default +--- +
+ +
+
+ +
+ +

Raised when an attribute is not defined.

+ +
class User < ActiveRecord::Base
+  has_many :pets
+end
+
+user = User.first
+user.pets.select(:id).first.user_id
+# => ActiveModel::MissingAttributeError: missing attribute: user_id
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Model.html b/src/5.2/classes/ActiveModel/Model.html new file mode 100644 index 0000000000..1827db6e5b --- /dev/null +++ b/src/5.2/classes/ActiveModel/Model.html @@ -0,0 +1,247 @@ +--- +title: ActiveModel::Model +layout: default +--- +
+ +
+
+ +
+ +

Active Model Basic Model

+ +

Includes the required interface for an object to interact with Action Pack and Action View, using different Active Model modules. It includes model name introspections, conversions, translations and validations. Besides that, it allows you to initialize the object with a hash of attributes, pretty much like Active Record does.

+ +

A minimal implementation could be:

+ +
class Person
+  include ActiveModel::Model
+  attr_accessor :name, :age
+end
+
+person = Person.new(name: 'bob', age: '18')
+person.name # => "bob"
+person.age  # => "18"
+
+ +

Note that, by default, ActiveModel::Model implements persisted? to return false, which is the most common case. You may want to override it in your class to simulate a different scenario:

+ +
class Person
+  include ActiveModel::Model
+  attr_accessor :id, :name
+
+  def persisted?
+    self.id == 1
+  end
+end
+
+person = Person.new(id: 1, name: 'bob')
+person.persisted? # => true
+
+ +

Also, if for some reason you need to run code on initialize, make sure you call super if you want the attributes hash initialization to happen.

+ +
class Person
+  include ActiveModel::Model
+  attr_accessor :id, :name, :omg
+
+  def initialize(attributes={})
+    super
+    @omg ||= true
+  end
+end
+
+person = Person.new(id: 1, name: 'bob')
+person.omg # => true
+
+ +

For more detailed information on other functionalities available, please refer to the specific modules included in ActiveModel::Model (see below).

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(attributes = {}) + +

+ + +
+

Initializes a new model with the given params.

+ +
class Person
+  include ActiveModel::Model
+  attr_accessor :name, :age
+end
+
+person = Person.new(name: 'bob', age: '18')
+person.name # => "bob"
+person.age  # => "18"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/model.rb, line 80
+def initialize(attributes = {})
+  assign_attributes(attributes) if attributes
+
+  super()
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + persisted?() + +

+ + +
+

Indicates if the model is persisted. Default is false.

+ +
class Person
+  include ActiveModel::Model
+  attr_accessor :id, :name
+end
+
+person = Person.new(id: 1, name: 'bob')
+person.persisted? # => false
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/model.rb, line 95
+def persisted?
+  false
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Name.html b/src/5.2/classes/ActiveModel/Name.html new file mode 100644 index 0000000000..72f04e4b22 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Name.html @@ -0,0 +1,654 @@ +--- +title: ActiveModel::Name +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Comparable + +
  • + +
+ + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + cache_key
+ [R] + collection
+ [R] + element
+ [R] + i18n_key
+ [R] + name
+ [R] + param_key
+ [R] + plural
+ [R] + route_key
+ [R] + singular
+ [R] + singular_route_key
+ + + + +

Class Public methods

+ +
+

+ + new(klass, namespace = nil, name = nil) + +

+ + +
+

Returns a new ActiveModel::Name instance. By default, the namespace and name option will take the namespace and name of the given class respectively.

+ +
module Foo
+  class Bar
+  end
+end
+
+ActiveModel::Name.new(Foo::Bar).to_s
+# => "Foo::Bar"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 148
+def initialize(klass, namespace = nil, name = nil)
+  @name = name || klass.name
+
+  raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank?
+
+  @unnamespaced = @name.sub(/^#{namespace.name}::/, "") if namespace
+  @klass        = klass
+  @singular     = _singularize(@name)
+  @plural       = ActiveSupport::Inflector.pluralize(@singular)
+  @element      = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(@name))
+  @human        = ActiveSupport::Inflector.humanize(@element)
+  @collection   = ActiveSupport::Inflector.tableize(@name)
+  @param_key    = (namespace ? _singularize(@unnamespaced) : @singular)
+  @i18n_key     = @name.underscore.to_sym
+
+  @route_key          = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural.dup)
+  @singular_route_key = ActiveSupport::Inflector.singularize(@route_key)
+  @route_key << "_index" if @plural == @singular
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + !~(regexp) + + +

+ + +
+

Equivalent to String#!~. Match the class name against the given regexp. Returns true if there is no match, otherwise false.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name !~ /Post/ # => false
+BlogPost.model_name !~ /\d/   # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 82
+    
+
+
+ +
+ +
+

+ + <=>(other) + + +

+ + +
+

Equivalent to String#<=>.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name <=> 'BlogPost'  # => 0
+BlogPost.model_name <=> 'Blog'      # => 1
+BlogPost.model_name <=> 'BlogPosts' # => -1
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 49
+    
+
+
+ +
+ +
+

+ + ==(other) + + +

+ + +
+

Equivalent to String#==. Returns true if the class name and other are equal, otherwise false.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name == 'BlogPost'  # => true
+BlogPost.model_name == 'Blog Post' # => false
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 18
+    
+
+
+ +
+ +
+

+ + ===(other) + + +

+ + +
+

Equivalent to #==.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name === 'BlogPost'  # => true
+BlogPost.model_name === 'Blog Post' # => false
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 34
+    
+
+
+ +
+ +
+

+ + =~(regexp) + + +

+ + +
+

Equivalent to String#=~. Match the class name against the given regexp. Returns the position where the match starts or nil if there is no match.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name =~ /Post/ # => 4
+BlogPost.model_name =~ /\d/   # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 65
+    
+
+
+ +
+ +
+

+ + eql?(other) + + +

+ + +
+

Equivalent to String#eql?. Returns true if the class name and other have the same length and content, otherwise false.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name.eql?('BlogPost')  # => true
+BlogPost.model_name.eql?('Blog Post') # => false
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 98
+    
+
+
+ +
+ +
+

+ + human(options = {}) + +

+ + +
+

Transform the model name into a more human format, using I18n. By default, it will underscore then humanize the class name.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name.human # => "Blog post"
+
+ +

Specify options with additional translating options.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 178
+def human(options = {})
+  return @human unless @klass.respond_to?(:lookup_ancestors) &&
+                       @klass.respond_to?(:i18n_scope)
+
+  defaults = @klass.lookup_ancestors.map do |klass|
+    klass.model_name.i18n_key
+  end
+
+  defaults << options[:default] if options[:default]
+  defaults << @human
+
+  options = { scope: [@klass.i18n_scope, :models], count: 1, default: defaults }.merge!(options.except(:default))
+  I18n.translate(defaults.shift, options)
+end
+
+
+ +
+ +
+

+ + to_s() + + +

+ + +
+

Returns the class name.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name.to_s # => "BlogPost"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 114
+    
+
+
+ +
+ +
+

+ + to_str() + + +

+ + +
+

Equivalent to to_s.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 134
+delegate :==, :===, :<=>, :=~, :"!~", :eql?, :to_s,
+         :to_str, :as_json, to: :name
+
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Naming.html b/src/5.2/classes/ActiveModel/Naming.html new file mode 100644 index 0000000000..cd6c8777c1 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Naming.html @@ -0,0 +1,411 @@ +--- +title: ActiveModel::Naming +layout: default +--- +
+ +
+
+ +
+ +

Active Model Naming

+ +

Creates a model_name method on your object.

+ +

To implement, just extend ActiveModel::Naming in your object:

+ +
class BookCover
+  extend ActiveModel::Naming
+end
+
+BookCover.model_name.name   # => "BookCover"
+BookCover.model_name.human  # => "Book cover"
+
+BookCover.model_name.i18n_key              # => :book_cover
+BookModule::BookCover.model_name.i18n_key  # => :"book_module/book_cover"
+
+ +

Providing the functionality that ActiveModel::Naming provides in your object is required to pass the Active Model Lint test. So either extending the provided method below, or rolling your own is required.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + param_key(record_or_class) + +

+ + +
+

Returns string to use for params names. It differs for namespaced models regarding whether it's inside isolated engine.

+ +
# For isolated engine:
+ActiveModel::Naming.param_key(Blog::Post) # => "post"
+
+# For shared engine:
+ActiveModel::Naming.param_key(Blog::Post) # => "blog_post"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 305
+def self.param_key(record_or_class)
+  model_name_from_record_or_class(record_or_class).param_key
+end
+
+
+ +
+ +
+

+ + plural(record_or_class) + +

+ + +
+

Returns the plural class name of a record or class.

+ +
ActiveModel::Naming.plural(post)             # => "posts"
+ActiveModel::Naming.plural(Highrise::Person) # => "highrise_people"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 250
+def self.plural(record_or_class)
+  model_name_from_record_or_class(record_or_class).plural
+end
+
+
+ +
+ +
+

+ + route_key(record_or_class) + +

+ + +
+

Returns string to use while generating route names. It differs for namespaced models regarding whether it's inside isolated engine.

+ +
# For isolated engine:
+ActiveModel::Naming.route_key(Blog::Post) # => "posts"
+
+# For shared engine:
+ActiveModel::Naming.route_key(Blog::Post) # => "blog_posts"
+
+ +

The route key also considers if the noun is uncountable and, in such cases, automatically appends _index.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 293
+def self.route_key(record_or_class)
+  model_name_from_record_or_class(record_or_class).route_key
+end
+
+
+ +
+ +
+

+ + singular(record_or_class) + +

+ + +
+

Returns the singular class name of a record or class.

+ +
ActiveModel::Naming.singular(post)             # => "post"
+ActiveModel::Naming.singular(Highrise::Person) # => "highrise_person"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 258
+def self.singular(record_or_class)
+  model_name_from_record_or_class(record_or_class).singular
+end
+
+
+ +
+ +
+

+ + singular_route_key(record_or_class) + +

+ + +
+

Returns string to use while generating route names. It differs for namespaced models regarding whether it's inside isolated engine.

+ +
# For isolated engine:
+ActiveModel::Naming.singular_route_key(Blog::Post) # => "post"
+
+# For shared engine:
+ActiveModel::Naming.singular_route_key(Blog::Post) # => "blog_post"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 278
+def self.singular_route_key(record_or_class)
+  model_name_from_record_or_class(record_or_class).singular_route_key
+end
+
+
+ +
+ +
+

+ + uncountable?(record_or_class) + +

+ + +
+

Identifies whether the class name of a record or class is uncountable.

+ +
ActiveModel::Naming.uncountable?(Sheep) # => true
+ActiveModel::Naming.uncountable?(Post)  # => false
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 266
+def self.uncountable?(record_or_class)
+  plural(record_or_class) == singular(record_or_class)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + model_name() + +

+ + +
+

Returns an ActiveModel::Name object for module. It can be used to retrieve all kinds of naming-related information (See ActiveModel::Name for more information).

+ +
class Person
+  extend ActiveModel::Naming
+end
+
+Person.model_name.name     # => "Person"
+Person.model_name.class    # => ActiveModel::Name
+Person.model_name.singular # => "person"
+Person.model_name.plural   # => "people"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/naming.rb, line 237
+def model_name
+  @_model_name ||= begin
+    namespace = parents.detect do |n|
+      n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
+    end
+    ActiveModel::Name.new(self, namespace)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/RangeError.html b/src/5.2/classes/ActiveModel/RangeError.html new file mode 100644 index 0000000000..ac3c75b5ed --- /dev/null +++ b/src/5.2/classes/ActiveModel/RangeError.html @@ -0,0 +1,66 @@ +--- +title: ActiveModel::RangeError +layout: default +--- +
+ +
+
+ +
+ +

Raised when attribute values are out of range.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/SecurePassword.html b/src/5.2/classes/ActiveModel/SecurePassword.html new file mode 100644 index 0000000000..f8d01da1c0 --- /dev/null +++ b/src/5.2/classes/ActiveModel/SecurePassword.html @@ -0,0 +1,87 @@ +--- +title: ActiveModel::SecurePassword +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
MAX_PASSWORD_LENGTH_ALLOWED=72
 

BCrypt hash function can handle maximum 72 bytes, and if we pass password of length more than 72 bytes it ignores extra characters. Hence need to put a restriction on password length.

+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/SecurePassword/ClassMethods.html b/src/5.2/classes/ActiveModel/SecurePassword/ClassMethods.html new file mode 100644 index 0000000000..a50438c41f --- /dev/null +++ b/src/5.2/classes/ActiveModel/SecurePassword/ClassMethods.html @@ -0,0 +1,185 @@ +--- +title: ActiveModel::SecurePassword::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + has_secure_password(options = {}) + +

+ + +
+

Adds methods to set and authenticate against a BCrypt password. This mechanism requires you to have a password_digest attribute.

+ +

The following validations are added automatically:

+
  • +

    Password must be present on creation

    +
  • +

    Password length should be less than or equal to 72 bytes

    +
  • +

    Confirmation of password (using a password_confirmation attribute)

    +
+ +

If password confirmation validation is not needed, simply leave out the value for password_confirmation (i.e. don't provide a form field for it). When this attribute has a nil value, the validation will not be triggered.

+ +

For further customizability, it is possible to suppress the default validations by passing validations: false as an argument.

+ +

Add bcrypt (~> 3.1.7) to Gemfile to use has_secure_password:

+ +
gem 'bcrypt', '~> 3.1.7'
+
+ +

Example using Active Record (which automatically includes ActiveModel::SecurePassword):

+ +
# Schema: User(name:string, password_digest:string)
+class User < ActiveRecord::Base
+  has_secure_password
+end
+
+user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
+user.save                                                       # => false, password required
+user.password = 'mUc3m00RsqyRe'
+user.save                                                       # => false, confirmation doesn't match
+user.password_confirmation = 'mUc3m00RsqyRe'
+user.save                                                       # => true
+user.authenticate('notright')                                   # => false
+user.authenticate('mUc3m00RsqyRe')                              # => user
+User.find_by(name: 'david').try(:authenticate, 'notright')      # => false
+User.find_by(name: 'david').try(:authenticate, 'mUc3m00RsqyRe') # => user
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/secure_password.rb, line 55
+def has_secure_password(options = {})
+  # Load bcrypt gem only when has_secure_password is used.
+  # This is to avoid ActiveModel (and by extension the entire framework)
+  # being dependent on a binary library.
+  begin
+    require "bcrypt"
+  rescue LoadError
+    $stderr.puts "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install"
+    raise
+  end
+
+  include InstanceMethodsOnActivation
+
+  if options.fetch(:validations, true)
+    include ActiveModel::Validations
+
+    # This ensures the model has a password by checking whether the password_digest
+    # is present, so that this works with both new and existing records. However,
+    # when there is an error, the message is added to the password attribute instead
+    # so that the error message will make sense to the end-user.
+    validate do |record|
+      record.errors.add(:password, :blank) unless record.password_digest.present?
+    end
+
+    validates_length_of :password, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
+    validates_confirmation_of :password, allow_blank: true
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html b/src/5.2/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html new file mode 100644 index 0000000000..5f107f2d9f --- /dev/null +++ b/src/5.2/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html @@ -0,0 +1,220 @@ +--- +title: ActiveModel::SecurePassword::InstanceMethodsOnActivation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + password
+ + + + + +

Instance Public methods

+ +
+

+ + authenticate(unencrypted_password) + +

+ + +
+

Returns self if the password is correct, otherwise false.

+ +
class User < ActiveRecord::Base
+  has_secure_password validations: false
+end
+
+user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
+user.save
+user.authenticate('notright')      # => false
+user.authenticate('mUc3m00RsqyRe') # => user
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/secure_password.rb, line 96
+def authenticate(unencrypted_password)
+  BCrypt::Password.new(password_digest).is_password?(unencrypted_password) && self
+end
+
+
+ +
+ +
+

+ + password=(unencrypted_password) + +

+ + +
+

Encrypts the password into the password_digest attribute, only if the new password is not empty.

+ +
class User < ActiveRecord::Base
+  has_secure_password validations: false
+end
+
+user = User.new
+user.password = nil
+user.password_digest # => nil
+user.password = 'mUc3m00RsqyRe'
+user.password_digest # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/secure_password.rb, line 114
+def password=(unencrypted_password)
+  if unencrypted_password.nil?
+    self.password_digest = nil
+  elsif !unencrypted_password.empty?
+    @password = unencrypted_password
+    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
+    self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost)
+  end
+end
+
+
+ +
+ +
+

+ + password_confirmation=(unencrypted_password) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/secure_password.rb, line 124
+def password_confirmation=(unencrypted_password)
+  @password_confirmation = unencrypted_password
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Serialization.html b/src/5.2/classes/ActiveModel/Serialization.html new file mode 100644 index 0000000000..f81dc45c4d --- /dev/null +++ b/src/5.2/classes/ActiveModel/Serialization.html @@ -0,0 +1,245 @@ +--- +title: ActiveModel::Serialization +layout: default +--- +
+ +
+
+ +
+ +

Active Model Serialization

+ +

Provides a basic serialization to a serializable_hash for your objects.

+ +

A minimal implementation could be:

+ +
class Person
+  include ActiveModel::Serialization
+
+  attr_accessor :name
+
+  def attributes
+    {'name' => nil}
+  end
+end
+
+ +

Which would provide you with:

+ +
person = Person.new
+person.serializable_hash   # => {"name"=>nil}
+person.name = "Bob"
+person.serializable_hash   # => {"name"=>"Bob"}
+
+ +

An attributes hash must be defined and should contain any attributes you need to be serialized. Attributes must be strings, not symbols. When called, serializable hash will use instance methods that match the name of the attributes hash's keys. In order to override this behavior, take a look at the private method read_attribute_for_serialization.

+ +

ActiveModel::Serializers::JSON module automatically includes the ActiveModel::Serialization module, so there is no need to explicitly include ActiveModel::Serialization.

+ +

A minimal implementation including JSON would be:

+ +
class Person
+  include ActiveModel::Serializers::JSON
+
+  attr_accessor :name
+
+  def attributes
+    {'name' => nil}
+  end
+end
+
+ +

Which would provide you with:

+ +
person = Person.new
+person.serializable_hash   # => {"name"=>nil}
+person.as_json             # => {"name"=>nil}
+person.to_json             # => "{\"name\":null}"
+
+person.name = "Bob"
+person.serializable_hash   # => {"name"=>"Bob"}
+person.as_json             # => {"name"=>"Bob"}
+person.to_json             # => "{\"name\":\"Bob\"}"
+
+ +

Valid options are :only, :except, :methods and :include. The following are all valid examples:

+ +
person.serializable_hash(only: 'name')
+person.serializable_hash(include: :address)
+person.serializable_hash(include: { address: { only: 'city' }})
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + serializable_hash(options = nil) + +

+ + +
+

Returns a serialized hash of your object.

+ +
class Person
+  include ActiveModel::Serialization
+
+  attr_accessor :name, :age
+
+  def attributes
+    {'name' => nil, 'age' => nil}
+  end
+
+  def capitalized_name
+    name.capitalize
+  end
+end
+
+person = Person.new
+person.name = 'bob'
+person.age  = 22
+person.serializable_hash                # => {"name"=>"bob", "age"=>22}
+person.serializable_hash(only: :name)   # => {"name"=>"bob"}
+person.serializable_hash(except: :name) # => {"age"=>22}
+person.serializable_hash(methods: :capitalized_name)
+# => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
+
+ +

Example with :include option

+ +
class User
+  include ActiveModel::Serializers::JSON
+  attr_accessor :name, :notes # Emulate has_many :notes
+  def attributes
+    {'name' => nil}
+  end
+end
+
+class Note
+  include ActiveModel::Serializers::JSON
+  attr_accessor :title, :text
+  def attributes
+    {'title' => nil, 'text' => nil}
+  end
+end
+
+note = Note.new
+note.title = 'Battle of Austerlitz'
+note.text = 'Some text here'
+
+user = User.new
+user.name = 'Napoleon'
+user.notes = [note]
+
+user.serializable_hash
+# => {"name" => "Napoleon"}
+user.serializable_hash(include: { notes: { only: 'title' }})
+# => {"name" => "Napoleon", "notes" => [{"title"=>"Battle of Austerlitz"}]}
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/serialization.rb, line 126
+def serializable_hash(options = nil)
+  options ||= {}
+
+  attribute_names = attributes.keys
+  if only = options[:only]
+    attribute_names &= Array(only).map(&:to_s)
+  elsif except = options[:except]
+    attribute_names -= Array(except).map(&:to_s)
+  end
+
+  hash = {}
+  attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) }
+
+  Array(options[:methods]).each { |m| hash[m.to_s] = send(m) }
+
+  serializable_add_includes(options) do |association, records, opts|
+    hash[association.to_s] = if records.respond_to?(:to_ary)
+      records.to_ary.map { |a| a.serializable_hash(opts) }
+    else
+      records.serializable_hash(opts)
+    end
+  end
+
+  hash
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Serializers.html b/src/5.2/classes/ActiveModel/Serializers.html new file mode 100644 index 0000000000..a45359270a --- /dev/null +++ b/src/5.2/classes/ActiveModel/Serializers.html @@ -0,0 +1,67 @@ +--- +title: ActiveModel::Serializers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Serializers/JSON.html b/src/5.2/classes/ActiveModel/Serializers/JSON.html new file mode 100644 index 0000000000..0e58be5aa5 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Serializers/JSON.html @@ -0,0 +1,278 @@ +--- +title: ActiveModel::Serializers::JSON +layout: default +--- +
+ +
+
+ +
+ +

Active Model JSON Serializer

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + as_json(options = nil) + +

+ + +
+

Returns a hash representing the model. Some configuration can be passed through options.

+ +

The option include_root_in_json controls the top-level behavior of as_json. If true, as_json will emit a single root node named after the object's type. The default value for include_root_in_json option is false.

+ +
user = User.find(1)
+user.as_json
+# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#     "created_at" => "2006/08/01", "awesome" => true}
+
+ActiveRecord::Base.include_root_in_json = true
+
+user.as_json
+# => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#                  "created_at" => "2006/08/01", "awesome" => true } }
+
+ +

This behavior can also be achieved by setting the :root option to true as in:

+ +
user = User.find(1)
+user.as_json(root: true)
+# => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#                  "created_at" => "2006/08/01", "awesome" => true } }
+
+ +

Without any options, the returned Hash will include all the model's attributes.

+ +
user = User.find(1)
+user.as_json
+# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#      "created_at" => "2006/08/01", "awesome" => true}
+
+ +

The :only and :except options can be used to limit the attributes included, and work similar to the attributes method.

+ +
user.as_json(only: [:id, :name])
+# => { "id" => 1, "name" => "Konata Izumi" }
+
+user.as_json(except: [:id, :created_at, :age])
+# => { "name" => "Konata Izumi", "awesome" => true }
+
+ +

To include the result of some method calls on the model use :methods:

+ +
user.as_json(methods: :permalink)
+# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#      "created_at" => "2006/08/01", "awesome" => true,
+#      "permalink" => "1-konata-izumi" }
+
+ +

To include associations use :include:

+ +
user.as_json(include: :posts)
+# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#      "created_at" => "2006/08/01", "awesome" => true,
+#      "posts" => [ { "id" => 1, "author_id" => 1, "title" => "Welcome to the weblog" },
+#                   { "id" => 2, "author_id" => 1, "title" => "So I was thinking" } ] }
+
+ +

Second level and higher order associations work as well:

+ +
user.as_json(include: { posts: {
+                           include: { comments: {
+                                          only: :body } },
+                           only: :title } })
+# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#      "created_at" => "2006/08/01", "awesome" => true,
+#      "posts" => [ { "comments" => [ { "body" => "1st post!" }, { "body" => "Second!" } ],
+#                     "title" => "Welcome to the weblog" },
+#                   { "comments" => [ { "body" => "Don't think too hard" } ],
+#                     "title" => "So I was thinking" } ] }
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/serializers/json.rb, line 89
+def as_json(options = nil)
+  root = if options && options.key?(:root)
+    options[:root]
+  else
+    include_root_in_json
+  end
+
+  if root
+    root = model_name.element if root == true
+    { root => serializable_hash(options) }
+  else
+    serializable_hash(options)
+  end
+end
+
+
+ +
+ +
+

+ + from_json(json, include_root = include_root_in_json) + +

+ + +
+

Sets the model attributes from a JSON string. Returns self.

+ +
class Person
+  include ActiveModel::Serializers::JSON
+
+  attr_accessor :name, :age, :awesome
+
+  def attributes=(hash)
+    hash.each do |key, value|
+      send("#{key}=", value)
+    end
+  end
+
+  def attributes
+    instance_values
+  end
+end
+
+json = { name: 'bob', age: 22, awesome:true }.to_json
+person = Person.new
+person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
+person.name            # => "bob"
+person.age             # => 22
+person.awesome         # => true
+
+ +

The default value for include_root is false. You can change it to true if the given JSON string includes a single root node.

+ +
json = { person: { name: 'bob', age: 22, awesome:true } }.to_json
+person = Person.new
+person.from_json(json, true) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
+person.name                  # => "bob"
+person.age                   # => 22
+person.awesome               # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/serializers/json.rb, line 138
+def from_json(json, include_root = include_root_in_json)
+  hash = ActiveSupport::JSON.decode(json)
+  hash = hash.values.first if include_root
+  self.attributes = hash
+  self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/StrictValidationFailed.html b/src/5.2/classes/ActiveModel/StrictValidationFailed.html new file mode 100644 index 0000000000..f475806de3 --- /dev/null +++ b/src/5.2/classes/ActiveModel/StrictValidationFailed.html @@ -0,0 +1,80 @@ +--- +title: ActiveModel::StrictValidationFailed +layout: default +--- +
+ +
+
+ +
+ +

Raised when a validation cannot be corrected by end users and are considered exceptional.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+
+  validates_presence_of :name, strict: true
+end
+
+person = Person.new
+person.name = nil
+person.valid?
+# => ActiveModel::StrictValidationFailed: Name can't be blank
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Translation.html b/src/5.2/classes/ActiveModel/Translation.html new file mode 100644 index 0000000000..72e149bbbe --- /dev/null +++ b/src/5.2/classes/ActiveModel/Translation.html @@ -0,0 +1,240 @@ +--- +title: ActiveModel::Translation +layout: default +--- +
+ +
+
+ +
+ +

Active Model Translation

+ +

Provides integration between your object and the Rails internationalization (i18n) framework.

+ +

A minimal implementation could be:

+ +
class TranslatedPerson
+  extend ActiveModel::Translation
+end
+
+TranslatedPerson.human_attribute_name('my_attribute')
+# => "My attribute"
+
+ +

This also provides the required class methods for hooking into the Rails internationalization API, including being able to define a class based i18n_scope and lookup_ancestors to find translations in parent classes.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + human_attribute_name(attribute, options = {}) + +

+ + +
+

Transforms attribute names into a more human format, such as “First name” instead of “first_name”.

+ +
Person.human_attribute_name("first_name") # => "First name"
+
+ +

Specify options with additional translating options.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/translation.rb, line 44
+def human_attribute_name(attribute, options = {})
+  options   = { count: 1 }.merge!(options)
+  parts     = attribute.to_s.split(".")
+  attribute = parts.pop
+  namespace = parts.join("/") unless parts.empty?
+  attributes_scope = "#{i18n_scope}.attributes"
+
+  if namespace
+    defaults = lookup_ancestors.map do |klass|
+      :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
+    end
+    defaults << :"#{attributes_scope}.#{namespace}.#{attribute}"
+  else
+    defaults = lookup_ancestors.map do |klass|
+      :"#{attributes_scope}.#{klass.model_name.i18n_key}.#{attribute}"
+    end
+  end
+
+  defaults << :"attributes.#{attribute}"
+  defaults << options.delete(:default) if options[:default]
+  defaults << attribute.humanize
+
+  options[:default] = defaults
+  I18n.translate(defaults.shift, options)
+end
+
+
+ +
+ +
+

+ + i18n_scope() + +

+ + +
+

Returns the i18n_scope for the class. Overwrite if you want custom lookup.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/translation.rb, line 26
+def i18n_scope
+  :activemodel
+end
+
+
+ +
+ +
+

+ + lookup_ancestors() + +

+ + +
+

When localizing a string, it goes through the lookup returned by this method, which is used in ActiveModel::Name#human, ActiveModel::Errors#full_messages and ActiveModel::Translation#human_attribute_name.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/translation.rb, line 34
+def lookup_ancestors
+  ancestors.select { |x| x.respond_to?(:model_name) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type.html b/src/5.2/classes/ActiveModel/Type.html new file mode 100644 index 0000000000..43f98d9364 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type.html @@ -0,0 +1,165 @@ +--- +title: ActiveModel::Type +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + register(type_name, klass = nil, **options, &block) + +

+ + +
+

Add a new type to the registry, allowing it to be gotten through ActiveModel::Type#lookup

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type.rb, line 28
+def register(type_name, klass = nil, **options, &block)
+  registry.register(type_name, klass, **options, &block)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/BigInteger.html b/src/5.2/classes/ActiveModel/Type/BigInteger.html new file mode 100644 index 0000000000..bfe48f3b00 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/BigInteger.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::BigInteger +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Binary.html b/src/5.2/classes/ActiveModel/Type/Binary.html new file mode 100644 index 0000000000..4f5847ac7d --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Binary.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Type::Binary +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Boolean.html b/src/5.2/classes/ActiveModel/Type/Boolean.html new file mode 100644 index 0000000000..62280d388c --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Boolean.html @@ -0,0 +1,108 @@ +--- +title: ActiveRecord::Type::Boolean +layout: default +--- +
+ +
+
+ +
+ +

Active Model Type Boolean

+ +

A class that behaves like a boolean type, including rules for coercion of user input.

+ +

Coercion

+ +

Values set from user input will first be coerced into the appropriate ruby type. Coercion behavior is roughly mapped to Ruby's boolean semantics.

+
  • +

    “false”, “f” , “0”, 0 or any other value in FALSE_VALUES will be coerced to false

    +
  • +

    Empty strings are coerced to nil

    +
  • +

    All other values will be coerced to true

    +
+ +
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
FALSE_VALUES=[ +false, 0, +"0", :"0", +"f", :f, +"F", :F, +"false", :false, +"FALSE", :FALSE, +"off", :off, +"OFF", :OFF, +].to_set.freeze
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Decimal.html b/src/5.2/classes/ActiveModel/Type/Decimal.html new file mode 100644 index 0000000000..bf028034af --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Decimal.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::Decimal +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Float.html b/src/5.2/classes/ActiveModel/Type/Float.html new file mode 100644 index 0000000000..b4fb0f91d1 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Float.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::Float +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Helpers.html b/src/5.2/classes/ActiveModel/Type/Helpers.html new file mode 100644 index 0000000000..1ae2b01bbc --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Helpers.html @@ -0,0 +1,88 @@ +--- +title: ActiveRecord::Type::Helpers +layout: default +--- + diff --git a/src/5.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime.html b/src/5.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime.html new file mode 100644 index 0000000000..f3422c465c --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime.html @@ -0,0 +1,60 @@ +--- +title: ActiveModel::Type::Helpers::AcceptsMultiparameterTime +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Helpers/Mutable.html b/src/5.2/classes/ActiveModel/Type/Helpers/Mutable.html new file mode 100644 index 0000000000..790056452e --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Helpers/Mutable.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::Mutable +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Helpers/Numeric.html b/src/5.2/classes/ActiveModel/Type/Helpers/Numeric.html new file mode 100644 index 0000000000..b915c3823c --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Helpers/Numeric.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::Numeric +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Helpers/TimeValue.html b/src/5.2/classes/ActiveModel/Type/Helpers/TimeValue.html new file mode 100644 index 0000000000..1f3c14d2b8 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Helpers/TimeValue.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::TimeValue +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Helpers/Timezone.html b/src/5.2/classes/ActiveModel/Type/Helpers/Timezone.html new file mode 100644 index 0000000000..f40efcc3f5 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Helpers/Timezone.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::Timezone +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Integer.html b/src/5.2/classes/ActiveModel/Type/Integer.html new file mode 100644 index 0000000000..5aa3572b2b --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Integer.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::Integer +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Registration.html b/src/5.2/classes/ActiveModel/Type/Registration.html new file mode 100644 index 0000000000..6a1f20bcb4 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Registration.html @@ -0,0 +1,60 @@ +--- +title: ActiveModel::Type::Registration +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Registry.html b/src/5.2/classes/ActiveModel/Type/Registry.html new file mode 100644 index 0000000000..e3768096c6 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Registry.html @@ -0,0 +1,60 @@ +--- +title: ActiveModel::Type::Registry +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/String.html b/src/5.2/classes/ActiveModel/Type/String.html new file mode 100644 index 0000000000..e04ae53cf8 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/String.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::String +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Type/Value.html b/src/5.2/classes/ActiveModel/Type/Value.html new file mode 100644 index 0000000000..92d5e030a9 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Type/Value.html @@ -0,0 +1,548 @@ +--- +title: ActiveRecord::Type::Value +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + limit
+ [R] + precision
+ [R] + scale
+ + + + +

Class Public methods

+ +
+

+ + new(precision: nil, limit: nil, scale: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 8
+def initialize(precision: nil, limit: nil, scale: nil)
+  @precision = precision
+  @scale = scale
+  @limit = limit
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+ +
+ + + +
+ Also aliased as: eql? +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 101
+def ==(other)
+  self.class == other.class &&
+    precision == other.precision &&
+    scale == other.scale &&
+    limit == other.limit
+end
+
+
+ +
+ +
+

+ + assert_valid_value(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 113
+def assert_valid_value(*)
+end
+
+
+ +
+ +
+

+ + cast(value) + +

+ + +
+

Type casts a value from user input (e.g. from a setter). This value may be a string from the form builder, or a ruby object passed to a setter. There is currently no way to differentiate between which source it came from.

+ +

The return value of this method will be returned from ActiveRecord::AttributeMethods::Read#read_attribute. See also: Value#cast_value.

+ +

value The raw input, as provided to the attribute setter.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 37
+def cast(value)
+  cast_value(value) unless value.nil?
+end
+
+
+ +
+ +
+

+ + changed?(old_value, new_value, _new_value_before_type_cast) + +

+ + +
+

Determines whether a value has changed for dirty checking. old_value and new_value will always be type-cast. Types should not need to override this method.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 64
+def changed?(old_value, new_value, _new_value_before_type_cast)
+  old_value != new_value
+end
+
+
+ +
+ +
+

+ + changed_in_place?(raw_old_value, new_value) + +

+ + +
+

Determines whether the mutable value has been modified since it was read. Returns false by default. If your type returns an object which could be mutated, you should override this method. You will need to either:

+ + +

or

+ + +

raw_old_value The original value, before being passed to deserialize.

+ +

new_value The current value, after type casting.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 85
+def changed_in_place?(raw_old_value, new_value)
+  false
+end
+
+
+ +
+ +
+

+ + deserialize(value) + +

+ + +
+

Converts a value from database input to the appropriate ruby type. The return value of this method will be returned from ActiveRecord::AttributeMethods::Read#read_attribute. The default implementation just calls Value#cast.

+ +

value The raw input, as provided from the database.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 23
+def deserialize(value)
+  cast(value)
+end
+
+
+ +
+ +
+

+ + eql?(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: == +
+ + + +
+ +
+

+ + hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 109
+def hash
+  [self.class, precision, scale, limit].hash
+end
+
+
+ +
+ +
+

+ + serialize(value) + +

+ + +
+

Casts a value from the ruby type to a type that the database knows how to understand. The returned value from this method should be a String, Numeric, Date, Time, Symbol, true, false, or nil.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 45
+def serialize(value)
+  value
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + cast_value(value) + +

+ + +
+

Convenience method for types which do not need separate type casting behavior for user and database inputs. Called by Value#cast for values except nil.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/type/value.rb, line 121
+def cast_value(value) # :doc:
+  value
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/UnknownAttributeError.html b/src/5.2/classes/ActiveModel/UnknownAttributeError.html new file mode 100644 index 0000000000..b3d02084f3 --- /dev/null +++ b/src/5.2/classes/ActiveModel/UnknownAttributeError.html @@ -0,0 +1,147 @@ +--- +title: ActiveRecord::UnknownAttributeError +layout: default +--- +
+ +
+
+ +
+ +

Raised when unknown attributes are supplied via mass assignment.

+ +
class Person
+  include ActiveModel::AttributeAssignment
+  include ActiveModel::Validations
+end
+
+person = Person.new
+person.assign_attributes(name: 'Gorby')
+# => ActiveModel::UnknownAttributeError: unknown attribute 'name' for Person.
+
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + attribute
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(record, attribute) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/errors.rb, line 511
+def initialize(record, attribute)
+  @record = record
+  @attribute = attribute
+  super("unknown attribute '#{attribute}' for #{@record.class}.")
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/VERSION.html b/src/5.2/classes/ActiveModel/VERSION.html new file mode 100644 index 0000000000..aaaa07b926 --- /dev/null +++ b/src/5.2/classes/ActiveModel/VERSION.html @@ -0,0 +1,120 @@ +--- +title: ActiveModel::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/ValidationError.html b/src/5.2/classes/ActiveModel/ValidationError.html new file mode 100644 index 0000000000..9b4097879a --- /dev/null +++ b/src/5.2/classes/ActiveModel/ValidationError.html @@ -0,0 +1,138 @@ +--- +title: ActiveModel::ValidationError +layout: default +--- +
+ +
+
+ +
+ +

Active Model ValidationError

+ +

Raised by validate! when the model is invalid. Use the model method to retrieve the record which did not validate.

+ +
begin
+  complex_operation_that_internally_calls_validate!
+rescue ActiveModel::ValidationError => invalid
+  puts invalid.model.errors
+end
+
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + model
+ + + + +

Class Public methods

+ +
+

+ + new(model) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 431
+def initialize(model)
+  @model = model
+  errors = @model.errors.full_messages.join(", ")
+  super(I18n.t(:"#{@model.class.i18n_scope}.errors.messages.model_invalid", errors: errors, default: :"errors.messages.model_invalid"))
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations.html b/src/5.2/classes/ActiveModel/Validations.html new file mode 100644 index 0000000000..e72b5ec22d --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations.html @@ -0,0 +1,542 @@ +--- +title: ActiveModel::Validations +layout: default +--- +
+ +
+
+ +
+ +

Active Model Validations

+ +

Provides a full validation framework to your objects.

+ +

A minimal implementation could be:

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :first_name, :last_name
+
+  validates_each :first_name, :last_name do |record, attr, value|
+    record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
+  end
+end
+
+ +

Which provides you with the full standard validation stack that you know from Active Record:

+ +
person = Person.new
+person.valid?                   # => true
+person.invalid?                 # => false
+
+person.first_name = 'zoolander'
+person.valid?                   # => false
+person.invalid?                 # => true
+person.errors.messages          # => {first_name:["starts with z."]}
+
+ +

Note that ActiveModel::Validations automatically adds an errors method to your instances initialized with a new ActiveModel::Errors object, so there is no need for you to do this manually.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + errors() + +

+ + +
+

Returns the Errors object that holds all information about attribute error messages.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+  validates_presence_of :name
+end
+
+person = Person.new
+person.valid? # => false
+person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["can't be blank"]}>
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 303
+def errors
+  @errors ||= Errors.new(self)
+end
+
+
+ +
+ +
+

+ + invalid?(context = nil) + +

+ + +
+

Performs the opposite of valid?. Returns true if errors were added, false otherwise.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+  validates_presence_of :name
+end
+
+person = Person.new
+person.name = ''
+person.invalid? # => true
+person.name = 'david'
+person.invalid? # => false
+
+ +

Context can optionally be supplied to define which callbacks to test against (the context is defined on the validations using :on).

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+  validates_presence_of :name, on: :new
+end
+
+person = Person.new
+person.invalid?       # => false
+person.invalid?(:new) # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 375
+def invalid?(context = nil)
+  !valid?(context)
+end
+
+
+ +
+ +
+

+ + valid?(context = nil) + +

+ + +
+

Runs all the specified validations and returns true if no errors were added otherwise false.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+  validates_presence_of :name
+end
+
+person = Person.new
+person.name = ''
+person.valid? # => false
+person.name = 'david'
+person.valid? # => true
+
+ +

Context can optionally be supplied to define which callbacks to test against (the context is defined on the validations using :on).

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+  validates_presence_of :name, on: :new
+end
+
+person = Person.new
+person.valid?       # => true
+person.valid?(:new) # => false
+
+
+ + + +
+ Also aliased as: validate +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 336
+def valid?(context = nil)
+  current_context, self.validation_context = validation_context, context
+  errors.clear
+  run_validations!
+ensure
+  self.validation_context = current_context
+end
+
+
+ +
+ +
+

+ + validate(context = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: valid? +
+ + + +
+ +
+

+ + validate!(context = nil) + +

+ + +
+

Runs all the validations within the specified context. Returns true if no errors are found, raises ValidationError otherwise.

+ +

Validations with no :on option will run no matter the context. Validations with some :on option will only run in the specified context.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 384
+def validate!(context = nil)
+  valid?(context) || raise_validation_error
+end
+
+
+ +
+ +
+

+ + validates_with(*args, &block) + +

+ + +
+

Passes the record off to the class or classes specified and allows them to add errors based on more complex conditions.

+ +
class Person
+  include ActiveModel::Validations
+
+  validate :instance_validations
+
+  def instance_validations
+    validates_with MyValidator
+  end
+end
+
+ +

Please consult the class method documentation for more information on creating your own validator.

+ +

You may also pass it multiple classes, like so:

+ +
class Person
+  include ActiveModel::Validations
+
+  validate :instance_validations, on: :create
+
+  def instance_validations
+    validates_with MyValidator, MyOtherValidator
+  end
+end
+
+ +

Standard configuration options (:on, :if and :unless), which are available on the class version of validates_with, should instead be placed on the validates method as these are applied and tested in the callback.

+ +

If you pass any additional configuration options, they will be passed to the class and available as options, please refer to the class version of this method for more information.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/with.rb, line 137
+def validates_with(*args, &block)
+  options = args.extract_options!
+  options[:class] = self.class
+
+  args.each do |klass|
+    validator = klass.new(options, &block)
+    validator.validate(self)
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + raise_validation_error() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 413
+def raise_validation_error # :doc:
+  raise(ValidationError.new(self))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator.html b/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator.html new file mode 100644 index 0000000000..d79b12b281 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator.html @@ -0,0 +1,75 @@ +--- +title: ActiveModel::Validations::AcceptanceValidator +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/AttributeDefinition.html b/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/AttributeDefinition.html new file mode 100644 index 0000000000..f7692e2ea9 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/AttributeDefinition.html @@ -0,0 +1,206 @@ +--- +title: ActiveModel::Validations::AcceptanceValidator::AttributeDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + attributes

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ + + + +

Class Public methods

+ +
+

+ + new(attributes) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/acceptance.rb, line 45
+def initialize(attributes)
+  @attributes = attributes.map(&:to_s)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + define_on(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/acceptance.rb, line 54
+def define_on(klass)
+  attr_readers = attributes.reject { |name| klass.attribute_method?(name) }
+  attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") }
+  klass.send(:attr_reader, *attr_readers)
+  klass.send(:attr_writer, *attr_writers)
+end
+
+
+ +
+ +
+

+ + matches?(method_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/acceptance.rb, line 49
+def matches?(method_name)
+  attr_name = convert_to_reader_name(method_name)
+  attributes.include?(attr_name)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/LazilyDefineAttributes.html b/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/LazilyDefineAttributes.html new file mode 100644 index 0000000000..bf7045f246 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations/AcceptanceValidator/LazilyDefineAttributes.html @@ -0,0 +1,118 @@ +--- +title: ActiveModel::Validations::AcceptanceValidator::LazilyDefineAttributes +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(attribute_definition) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/acceptance.rb, line 28
+def initialize(attribute_definition)
+  define_method(:respond_to_missing?) do |method_name, include_private = false|
+    super(method_name, include_private) || attribute_definition.matches?(method_name)
+  end
+
+  define_method(:method_missing) do |method_name, *args, &block|
+    if attribute_definition.matches?(method_name)
+      attribute_definition.define_on(self.class)
+      send(method_name, *args, &block)
+    else
+      super(method_name, *args, &block)
+    end
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations/Callbacks.html b/src/5.2/classes/ActiveModel/Validations/Callbacks.html new file mode 100644 index 0000000000..8cf593e81c --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations/Callbacks.html @@ -0,0 +1,101 @@ +--- +title: ActiveModel::Validations::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Active Model Validation Callbacks

+ +

Provides an interface for any class to have before_validation and after_validation callbacks.

+ +

First, include ActiveModel::Validations::Callbacks from the class you are creating:

+ +
class MyModel
+  include ActiveModel::Validations::Callbacks
+
+  before_validation :do_stuff_before_validation
+  after_validation  :do_stuff_after_validation
+end
+
+ +

Like other before_* callbacks if before_validation throws :abort then valid? will not be called.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations/Callbacks/ClassMethods.html b/src/5.2/classes/ActiveModel/Validations/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..091340d58c --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations/Callbacks/ClassMethods.html @@ -0,0 +1,212 @@ +--- +title: ActiveModel::Validations::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + after_validation(*args, &block) + +

+ + +
+

Defines a callback that will get called right after validation.

+ +
class Person
+  include ActiveModel::Validations
+  include ActiveModel::Validations::Callbacks
+
+  attr_accessor :name, :status
+
+  validates_presence_of :name
+
+  after_validation :set_status
+
+  private
+
+  def set_status
+    self.status = errors.empty?
+  end
+end
+
+person = Person.new
+person.name = ''
+person.valid? # => false
+person.status # => false
+person.name = 'bob'
+person.valid? # => true
+person.status # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/callbacks.rb, line 97
+def after_validation(*args, &block)
+  options = args.extract_options!
+  options = options.dup
+  options[:prepend] = true
+
+  if options.key?(:on)
+    options[:on] = Array(options[:on])
+    options[:if] = Array(options[:if])
+    options[:if].unshift ->(o) {
+      !(options[:on] & Array(o.validation_context)).empty?
+    }
+  end
+
+  set_callback(:validation, :after, *args, options, &block)
+end
+
+
+ +
+ +
+

+ + before_validation(*args, &block) + +

+ + +
+

Defines a callback that will get called right before validation.

+ +
class Person
+  include ActiveModel::Validations
+  include ActiveModel::Validations::Callbacks
+
+  attr_accessor :name
+
+  validates_length_of :name, maximum: 6
+
+  before_validation :remove_whitespaces
+
+  private
+
+  def remove_whitespaces
+    name.strip!
+  end
+end
+
+person = Person.new
+person.name = '  bob  '
+person.valid? # => true
+person.name   # => "bob"
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/callbacks.rb, line 56
+def before_validation(*args, &block)
+  options = args.extract_options!
+
+  if options.key?(:on)
+    options = options.dup
+    options[:on] = Array(options[:on])
+    options[:if] = Array(options[:if])
+    options[:if].unshift ->(o) {
+      !(options[:on] & Array(o.validation_context)).empty?
+    }
+  end
+
+  set_callback(:validation, :before, *args, options, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations/ClassMethods.html b/src/5.2/classes/ActiveModel/Validations/ClassMethods.html new file mode 100644 index 0000000000..da9da39666 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations/ClassMethods.html @@ -0,0 +1,775 @@ +--- +title: ActiveModel::Validations::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attribute_method?(attribute) + +

+ + +
+

Returns true if attribute is an attribute method, false otherwise.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+end
+
+User.attribute_method?(:name) # => true
+User.attribute_method?(:age)  # => false
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 272
+def attribute_method?(attribute)
+  method_defined?(attribute)
+end
+
+
+ +
+ +
+

+ + clear_validators!() + +

+ + +
+

Clears all of the validators and validations.

+ +

Note that this will clear anything that is being used to validate the model for both the validates_with and validate methods. It clears the validators that are created with an invocation of validates_with and the callbacks that are set by an invocation of validate.

+ +
class Person
+  include ActiveModel::Validations
+
+  validates_with MyValidator
+  validates_with OtherValidator, on: :create
+  validates_with StrictValidator, strict: true
+  validate :cannot_be_robot
+
+  def cannot_be_robot
+    errors.add(:base, 'A person cannot be a robot') if person_is_robot
+  end
+end
+
+Person.validators
+# => [
+#      #<MyValidator:0x007fbff403e808 @options={}>,
+#      #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
+#      #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
+#    ]
+
+ +

If one runs Person.clear_validators! and then checks to see what validators this class has, you would obtain:

+ +
Person.validators # => []
+
+ +

Also, the callback set by validate :cannot_be_robot will be erased so that:

+ +
Person._validate_callbacks.empty?  # => true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 236
+def clear_validators!
+  reset_callbacks(:validate)
+  _validators.clear
+end
+
+
+ +
+ +
+

+ + validate(*args, &block) + +

+ + +
+

Adds a validation method or block to the class. This is useful when overriding the validate instance method becomes too unwieldy and you're looking for more descriptive declaration of your validations.

+ +

This can be done with a symbol pointing to a method:

+ +
class Comment
+  include ActiveModel::Validations
+
+  validate :must_be_friends
+
+  def must_be_friends
+    errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
+  end
+end
+
+ +

With a block which is passed with the current record to be validated:

+ +
class Comment
+  include ActiveModel::Validations
+
+  validate do |comment|
+    comment.must_be_friends
+  end
+
+  def must_be_friends
+    errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
+  end
+end
+
+ +

Or with a block where self points to the current record to be validated:

+ +
class Comment
+  include ActiveModel::Validations
+
+  validate do
+    errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
+  end
+end
+
+ +

Note that the return value of validation methods is not relevant. It's not possible to halt the validate callback chain.

+ +

Options:

+
  • +

    :on - Specifies the contexts where this validation is active. Runs in all validation contexts by default nil. You can pass a symbol or an array of symbols. (e.g. on: :create or on: :custom_validation_context or on: [:create, :custom_validation_context])

    +
  • +

    :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
+ +

NOTE: Calling validate multiple times on the same method will overwrite previous definitions.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 154
+def validate(*args, &block)
+  options = args.extract_options!
+
+  if args.all? { |arg| arg.is_a?(Symbol) }
+    options.each_key do |k|
+      unless VALID_OPTIONS_FOR_VALIDATE.include?(k)
+        raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{VALID_OPTIONS_FOR_VALIDATE.map(&:inspect).join(', ')}. Perhaps you meant to call `validates` instead of `validate`?")
+      end
+    end
+  end
+
+  if options.key?(:on)
+    options = options.dup
+    options[:on] = Array(options[:on])
+    options[:if] = Array(options[:if])
+    options[:if].unshift ->(o) {
+      !(options[:on] & Array(o.validation_context)).empty?
+    }
+  end
+
+  set_callback(:validate, *args, options, &block)
+end
+
+
+ +
+ +
+

+ + validates(*attributes) + +

+ + +
+

This method is a shortcut to all default validators and any custom validator classes ending in 'Validator'. Note that Rails default validators can be overridden inside specific classes by creating custom validator classes in their place such as PresenceValidator.

+ +

Examples of using the default rails validators:

+ +
validates :terms, acceptance: true
+validates :password, confirmation: true
+validates :username, exclusion: { in: %w(admin superuser) }
+validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
+validates :age, inclusion: { in: 0..9 }
+validates :first_name, length: { maximum: 30 }
+validates :age, numericality: true
+validates :username, presence: true
+
+ +

The power of the validates method comes when using custom validators and default validators in one call for a given attribute.

+ +
class EmailValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    record.errors.add attribute, (options[:message] || "is not an email") unless
+      value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
+  end
+end
+
+class Person
+  include ActiveModel::Validations
+  attr_accessor :name, :email
+
+  validates :name, presence: true, length: { maximum: 100 }
+  validates :email, presence: true, email: true
+end
+
+ +

Validator classes may also exist within the class being validated allowing custom modules of validators to be included as needed.

+ +
class Film
+  include ActiveModel::Validations
+
+  class TitleValidator < ActiveModel::EachValidator
+    def validate_each(record, attribute, value)
+      record.errors.add attribute, "must start with 'the'" unless value =~ /\Athe/i
+    end
+  end
+
+  validates :name, title: true
+end
+
+ +

Additionally validator classes may be in another namespace and still used within any class.

+ +
validates :name, :'film/title' => true
+
+ +

The validators hash can also handle regular expressions, ranges, arrays and strings in shortcut form.

+ +
validates :email, format: /@/
+validates :gender, inclusion: %w(male female)
+validates :password, length: 6..20
+
+ +

When using shortcut form, ranges and arrays are passed to your validator's initializer as options[:in] while other types including regular expressions and strings are passed as options[:with].

+ +

There is also a list of options that could be used along with validators:

+
  • +

    :on - Specifies the contexts where this validation is active. Runs in all validation contexts by default nil. You can pass a symbol or an array of symbols. (e.g. on: :create or on: :custom_validation_context or on: [:create, :custom_validation_context])

    +
  • +

    :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :allow_nil - Skip validation if the attribute is nil.

    +
  • +

    :allow_blank - Skip validation if the attribute is blank.

    +
  • +

    :strict - If the :strict option is set to true will raise ActiveModel::StrictValidationFailed instead of adding the error. :strict option can also be set to any other exception.

    +
+ +

Example:

+ +
validates :password, presence: true, confirmation: true, if: :password_required?
+validates :token, length: 24, strict: TokenLengthException
+
+ +

Finally, the options :if, :unless, :on, :allow_blank, :allow_nil, :strict and :message can be given to one specific validator, as a hash:

+ +
validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/validates.rb, line 105
+def validates(*attributes)
+  defaults = attributes.extract_options!.dup
+  validations = defaults.slice!(*_validates_default_keys)
+
+  raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
+  raise ArgumentError, "You need to supply at least one validation" if validations.empty?
+
+  defaults[:attributes] = attributes
+
+  validations.each do |key, options|
+    next unless options
+    key = "#{key.to_s.camelize}Validator"
+
+    begin
+      validator = key.include?("::".freeze) ? key.constantize : const_get(key)
+    rescue NameError
+      raise ArgumentError, "Unknown validator: '#{key}'"
+    end
+
+    validates_with(validator, defaults.merge(_parse_validates_options(options)))
+  end
+end
+
+
+ +
+ +
+

+ + validates!(*attributes) + +

+ + +
+

This method is used to define validations that cannot be corrected by end users and are considered exceptional. So each validator defined with bang or :strict option set to true will always raise ActiveModel::StrictValidationFailed instead of adding error when validation fails. See validates for more information about the validation itself.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+  validates! :name, presence: true
+end
+
+person = Person.new
+person.name = ''
+person.valid?
+# => ActiveModel::StrictValidationFailed: Name can't be blank
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/validates.rb, line 146
+def validates!(*attributes)
+  options = attributes.extract_options!
+  options[:strict] = true
+  validates(*(attributes << options))
+end
+
+
+ +
+ +
+

+ + validates_each(*attr_names, &block) + +

+ + +
+

Validates each attribute against a block.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :first_name, :last_name
+
+  validates_each :first_name, :last_name, allow_blank: true do |record, attr, value|
+    record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
+  end
+end
+
+ +

Options:

+
  • +

    :on - Specifies the contexts where this validation is active. Runs in all validation contexts by default nil. You can pass a symbol or an array of symbols. (e.g. on: :create or on: :custom_validation_context or on: [:create, :custom_validation_context])

    +
  • +

    :allow_nil - Skip validation if attribute is nil.

    +
  • +

    :allow_blank - Skip validation if attribute is blank.

    +
  • +

    :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 87
+def validates_each(*attr_names, &block)
+  validates_with BlockValidator, _merge_attributes(attr_names), &block
+end
+
+
+ +
+ +
+

+ + validates_with(*args, &block) + +

+ + +
+

Passes the record off to the class or classes specified and allows them to add errors based on more complex conditions.

+ +
class Person
+  include ActiveModel::Validations
+  validates_with MyValidator
+end
+
+class MyValidator < ActiveModel::Validator
+  def validate(record)
+    if some_complex_logic
+      record.errors.add :base, 'This record is invalid'
+    end
+  end
+
+  private
+    def some_complex_logic
+      # ...
+    end
+end
+
+ +

You may also pass it multiple classes, like so:

+ +
class Person
+  include ActiveModel::Validations
+  validates_with MyValidator, MyOtherValidator, on: :create
+end
+
+ +

Configuration options:

+
  • +

    :on - Specifies the contexts where this validation is active. Runs in all validation contexts by default nil. You can pass a symbol or an array of symbols. (e.g. on: :create or on: :custom_validation_context or on: [:create, :custom_validation_context])

    +
  • +

    :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :strict - Specifies whether validation should be strict. See ActiveModel::Validations#validates! for more information.

    +
+ +

If you pass any additional configuration options, they will be passed to the class and available as options:

+ +
class Person
+  include ActiveModel::Validations
+  validates_with MyValidator, my_custom_key: 'my custom value'
+end
+
+class MyValidator < ActiveModel::Validator
+  def validate(record)
+    options[:my_custom_key] # => "my custom value"
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/with.rb, line 81
+def validates_with(*args, &block)
+  options = args.extract_options!
+  options[:class] = self
+
+  args.each do |klass|
+    validator = klass.new(options, &block)
+
+    if validator.respond_to?(:attributes) && !validator.attributes.empty?
+      validator.attributes.each do |attribute|
+        _validators[attribute.to_sym] << validator
+      end
+    else
+      _validators[nil] << validator
+    end
+
+    validate(validator, options)
+  end
+end
+
+
+ +
+ +
+

+ + validators() + +

+ + +
+

List all validators that are being used to validate the model using validates_with method.

+ +
class Person
+  include ActiveModel::Validations
+
+  validates_with MyValidator
+  validates_with OtherValidator, on: :create
+  validates_with StrictValidator, strict: true
+end
+
+Person.validators
+# => [
+#      #<MyValidator:0x007fbff403e808 @options={}>,
+#      #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
+#      #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 194
+def validators
+  _validators.values.flatten.uniq
+end
+
+
+ +
+ +
+

+ + validators_on(*attributes) + +

+ + +
+

List all validators that are being used to validate a specific attribute.

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name , :age
+
+  validates_presence_of :name
+  validates_inclusion_of :age, in: 0..99
+end
+
+Person.validators_on(:name)
+# => [
+#       #<ActiveModel::Validations::PresenceValidator:0x007fe604914e60 @attributes=[:name], @options={}>,
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations.rb, line 256
+def validators_on(*attributes)
+  attributes.flat_map do |attribute|
+    _validators[attribute.to_sym]
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validations/HelperMethods.html b/src/5.2/classes/ActiveModel/Validations/HelperMethods.html new file mode 100644 index 0000000000..1ae5948085 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validations/HelperMethods.html @@ -0,0 +1,724 @@ +--- +title: ActiveModel::Validations::HelperMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + validates_absence_of(*attr_names) + +

+ + +
+

Validates that the specified attributes are blank (as defined by Object#blank?). Happens by default on save.

+ +
class Person < ActiveRecord::Base
+  validates_absence_of :first_name
+end
+
+ +

The first_name attribute must be in the object and it must be blank.

+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “must be blank”).

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict. See ActiveModel::Validations#validates for more information

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/absence.rb, line 28
+def validates_absence_of(*attr_names)
+  validates_with AbsenceValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_acceptance_of(*attr_names) + +

+ + +
+

Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement).

+ +
class Person < ActiveRecord::Base
+  validates_acceptance_of :terms_of_service
+  validates_acceptance_of :eula, message: 'must be abided'
+end
+
+ +

If the database column does not exist, the terms_of_service attribute is entirely virtual. This check is performed only if terms_of_service is not nil and by default on save.

+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “must be accepted”).

    +
  • +

    :accept - Specifies a value that is considered accepted. Also accepts an array of possible values. The default value is an array [“1”, true], which makes it easy to relate to an HTML checkbox. This should be set to, or include, true if you are validating a database column, since the attribute is typecast from “1” to true before validation.

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict. See ActiveModel::Validations#validates for more information.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/acceptance.rb, line 101
+def validates_acceptance_of(*attr_names)
+  validates_with AcceptanceValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_confirmation_of(*attr_names) + +

+ + +
+

Encapsulates the pattern of wanting to validate a password or email address field with a confirmation.

+ +
Model:
+  class Person < ActiveRecord::Base
+    validates_confirmation_of :user_name, :password
+    validates_confirmation_of :email_address,
+                              message: 'should match confirmation'
+  end
+
+View:
+  <%= password_field "person", "password" %>
+  <%= password_field "person", "password_confirmation" %>
+
+ +

The added password_confirmation attribute is virtual; it exists only as an in-memory attribute for validating the password. To achieve this, the validation adds accessors to the model for the confirmation attribute.

+ +

NOTE: This check is performed only if password_confirmation is not nil. To require confirmation, make sure to add a presence check for the confirmation attribute:

+ +
validates_presence_of :password_confirmation, if: :password_changed?
+
+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “doesn't match %{translated_attribute_name}”).

    +
  • +

    :case_sensitive - Looks for an exact match. Ignored by non-text columns (true by default).

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict. See ActiveModel::Validations#validates for more information

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/confirmation.rb, line 75
+def validates_confirmation_of(*attr_names)
+  validates_with ConfirmationValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_exclusion_of(*attr_names) + +

+ + +
+

Validates that the value of the specified attribute is not in a particular enumerable object.

+ +
class Person < ActiveRecord::Base
+  validates_exclusion_of :username, in: %w( admin superuser ), message: "You don't belong here"
+  validates_exclusion_of :age, in: 30..60, message: 'This site is only for under 30 and over 60'
+  validates_exclusion_of :format, in: %w( mov avi ), message: "extension %{value} is not allowed"
+  validates_exclusion_of :password, in: ->(person) { [person.username, person.first_name] },
+                         message: 'should not be the same as your username or first name'
+  validates_exclusion_of :karma, in: :reserved_karmas
+end
+
+ +

Configuration options:

+
  • +

    :in - An enumerable object of items that the value shouldn't be part of. This can be supplied as a proc, lambda or symbol which returns an enumerable. If the enumerable is a numerical, time or datetime range the test is performed with Range#cover?, otherwise with include?. When using a proc or lambda the instance under validation is passed as an argument.

    +
  • +

    :within - A synonym(or alias) for :in Range#cover?, otherwise with include?.

    +
  • +

    :message - Specifies a custom error message (default is: “is reserved”).

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict. See ActiveModel::Validations#validates for more information

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/exclusion.rb, line 44
+def validates_exclusion_of(*attr_names)
+  validates_with ExclusionValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_format_of(*attr_names) + +

+ + +
+

Validates whether the value of the specified attribute is of the correct form, going by the regular expression provided. You can require that the attribute matches the regular expression:

+ +
class Person < ActiveRecord::Base
+  validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create
+end
+
+ +

Alternatively, you can require that the specified attribute does not match the regular expression:

+ +
class Person < ActiveRecord::Base
+  validates_format_of :email, without: /NOSPAM/
+end
+
+ +

You can also provide a proc or lambda which will determine the regular expression that will be used to validate the attribute.

+ +
class Person < ActiveRecord::Base
+  # Admin can have number as a first letter in their screen name
+  validates_format_of :screen_name,
+                      with: ->(person) { person.admin? ? /\A[a-z0-9][a-z0-9_\-]*\z/i : /\A[a-z][a-z0-9_\-]*\z/i }
+end
+
+ +

Note: use \A and \z to match the start and end of the string, ^ and $ match the start/end of a line.

+ +

Due to frequent misuse of ^ and $, you need to pass the multiline: true option in case you use any of these two anchors in the provided regular expression. In most cases, you should be using \A and \z.

+ +

You must pass either :with or :without as an option. In addition, both must be a regular expression or a proc or lambda, or else an exception will be raised.

+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “is invalid”).

    +
  • +

    :with - Regular expression that if the attribute matches will result in a successful validation. This can be provided as a proc or lambda returning regular expression which will be called at runtime.

    +
  • +

    :without - Regular expression that if the attribute does not match will result in a successful validation. This can be provided as a proc or lambda returning regular expression which will be called at runtime.

    +
  • +

    :multiline - Set to true if your regular expression contains anchors that match the beginning or end of lines as opposed to the beginning or end of the string. These anchors are ^ and $.

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict. See ActiveModel::Validations#validates for more information

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/format.rb, line 109
+def validates_format_of(*attr_names)
+  validates_with FormatValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_inclusion_of(*attr_names) + +

+ + +
+

Validates whether the value of the specified attribute is available in a particular enumerable object.

+ +
class Person < ActiveRecord::Base
+  validates_inclusion_of :gender, in: %w( m f )
+  validates_inclusion_of :age, in: 0..99
+  validates_inclusion_of :format, in: %w( jpg gif png ), message: "extension %{value} is not included in the list"
+  validates_inclusion_of :states, in: ->(person) { STATES[person.country] }
+  validates_inclusion_of :karma, in: :available_karmas
+end
+
+ +

Configuration options:

+
  • +

    :in - An enumerable object of available items. This can be supplied as a proc, lambda or symbol which returns an enumerable. If the enumerable is a numerical, time or datetime range the test is performed with Range#cover?, otherwise with include?. When using a proc or lambda the instance under validation is passed as an argument.

    +
  • +

    :within - A synonym(or alias) for :in

    +
  • +

    :message - Specifies a custom error message (default is: “is not included in the list”).

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict. See ActiveModel::Validations#validates for more information

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/inclusion.rb, line 42
+def validates_inclusion_of(*attr_names)
+  validates_with InclusionValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_length_of(*attr_names) + +

+ + +
+

Validates that the specified attributes match the length restrictions supplied. Only one constraint option can be used at a time apart from :minimum and :maximum that can be combined together:

+ +
class Person < ActiveRecord::Base
+  validates_length_of :first_name, maximum: 30
+  validates_length_of :last_name, maximum: 30, message: "less than 30 if you don't mind"
+  validates_length_of :fax, in: 7..32, allow_nil: true
+  validates_length_of :phone, in: 7..32, allow_blank: true
+  validates_length_of :user_name, within: 6..20, too_long: 'pick a shorter name', too_short: 'pick a longer name'
+  validates_length_of :zip_code, minimum: 5, too_short: 'please enter at least 5 characters'
+  validates_length_of :smurf_leader, is: 4, message: "papa is spelled with 4 characters... don't play me."
+  validates_length_of :words_in_essay, minimum: 100, too_short: 'Your essay must be at least 100 words.'
+
+  private
+
+  def words_in_essay
+    essay.scan(/\w+/)
+  end
+end
+
+ +

Constraint options:

+
  • +

    :minimum - The minimum size of the attribute.

    +
  • +

    :maximum - The maximum size of the attribute. Allows nil by default if not used with :minimum.

    +
  • +

    :is - The exact size of the attribute.

    +
  • +

    :within - A range specifying the minimum and maximum size of the attribute.

    +
  • +

    :in - A synonym (or alias) for :within.

    +
+ +

Other options:

+
  • +

    :allow_nil - Attribute may be nil; skip validation.

    +
  • +

    :allow_blank - Attribute may be blank; skip validation.

    +
  • +

    :too_long - The error message if the attribute goes over the maximum (default is: “is too long (maximum is %{count} characters)”).

    +
  • +

    :too_short - The error message if the attribute goes under the minimum (default is: “is too short (minimum is %{count} characters)”).

    +
  • +

    :wrong_length - The error message if using the :is method and the attribute is the wrong size (default is: “is the wrong length (should be %{count} characters)”).

    +
  • +

    :message - The error message to use for a :minimum, :maximum, or :is violation. An alias of the appropriate too_long/too_short/wrong_length message.

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on and :strict. See ActiveModel::Validations#validates for more information

+
+ + + +
+ Also aliased as: validates_size_of +
+ + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/length.rb, line 122
+def validates_length_of(*attr_names)
+  validates_with LengthValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_numericality_of(*attr_names) + +

+ + +
+

Validates whether the value of the specified attribute is numeric by trying to convert it to a float with Kernel.Float (if only_integer is false) or applying it to the regular expression /\A[+\-]?\d+\z/ (if only_integer is set to true).

+ +
class Person < ActiveRecord::Base
+  validates_numericality_of :value, on: :create
+end
+
+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “is not a number”).

    +
  • +

    :only_integer - Specifies whether the value has to be an integer, e.g. an integral value (default is false).

    +
  • +

    :allow_nil - Skip validation if attribute is nil (default is false). Notice that for Integer and Float columns empty strings are converted to nil.

    +
  • +

    :greater_than - Specifies the value must be greater than the supplied value.

    +
  • +

    :greater_than_or_equal_to - Specifies the value must be greater than or equal the supplied value.

    +
  • +

    :equal_to - Specifies the value must be equal to the supplied value.

    +
  • +

    :less_than - Specifies the value must be less than the supplied value.

    +
  • +

    :less_than_or_equal_to - Specifies the value must be less than or equal the supplied value.

    +
  • +

    :other_than - Specifies the value must be other than the supplied value.

    +
  • +

    :odd - Specifies the value must be an odd number.

    +
  • +

    :even - Specifies the value must be an even number.

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict . See ActiveModel::Validations#validates for more information

+ +

The following checks can also be supplied with a proc or a symbol which corresponds to a method:

+
  • +

    :greater_than

    +
  • +

    :greater_than_or_equal_to

    +
  • +

    :equal_to

    +
  • +

    :less_than

    +
  • +

    :less_than_or_equal_to

    +
  • +

    :only_integer

    +
+ +

For example:

+ +
class Person < ActiveRecord::Base
+  validates_numericality_of :width, less_than: ->(person) { person.height }
+  validates_numericality_of :width, greater_than: :minimum_weight
+end
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/numericality.rb, line 184
+def validates_numericality_of(*attr_names)
+  validates_with NumericalityValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_presence_of(*attr_names) + +

+ + +
+

Validates that the specified attributes are not blank (as defined by Object#blank?). Happens by default on save.

+ +
class Person < ActiveRecord::Base
+  validates_presence_of :first_name
+end
+
+ +

The first_name attribute must be in the object and it cannot be blank.

+ +

If you want to validate the presence of a boolean field (where the real values are true and false), you will want to use validates_inclusion_of :field_name, in: [true, false].

+ +

This is due to the way Object#blank? handles boolean values: false.blank? # => true.

+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “can't be blank”).

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict. See ActiveModel::Validations#validates for more information

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validations/presence.rb, line 34
+def validates_presence_of(*attr_names)
+  validates_with PresenceValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_size_of(*attr_names) + +

+ + +
+ +
+ + + + + +
+ Alias for: validates_length_of +
+ + + +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveModel/Validator.html b/src/5.2/classes/ActiveModel/Validator.html new file mode 100644 index 0000000000..32ac33b502 --- /dev/null +++ b/src/5.2/classes/ActiveModel/Validator.html @@ -0,0 +1,343 @@ +--- +title: ActiveModel::Validator +layout: default +--- +
+ +
+
+ +
+ +

Active Model Validator

+ +

A simple base class that can be used along with ActiveModel::Validations::ClassMethods.validates_with

+ +
class Person
+  include ActiveModel::Validations
+  validates_with MyValidator
+end
+
+class MyValidator < ActiveModel::Validator
+  def validate(record)
+    if some_complex_logic
+      record.errors.add(:base, "This record is invalid")
+    end
+  end
+
+  private
+    def some_complex_logic
+      # ...
+    end
+end
+
+ +

Any class that inherits from ActiveModel::Validator must implement a method called validate which accepts a record.

+ +
class Person
+  include ActiveModel::Validations
+  validates_with MyValidator
+end
+
+class MyValidator < ActiveModel::Validator
+  def validate(record)
+    record # => The person instance being validated
+    options # => Any non-standard options passed to validates_with
+  end
+end
+
+ +

To cause a validation error, you must add to the record's errors directly from within the validators message.

+ +
class MyValidator < ActiveModel::Validator
+  def validate(record)
+    record.errors.add :base, "This is some custom error message"
+    record.errors.add :first_name, "This is some complex validation"
+    # etc...
+  end
+end
+
+ +

To add behavior to the initialize method, use the following signature:

+ +
class MyValidator < ActiveModel::Validator
+  def initialize(options)
+    super
+    @my_custom_field = options[:field_name] || :first_name
+  end
+end
+
+ +

Note that the validator is initialized only once for the whole application life cycle, and not on each validation run.

+ +

The easiest way to add custom validators for validating individual attributes is with the convenient ActiveModel::EachValidator.

+ +
class TitleValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value)
+  end
+end
+
+ +

This can now be used in combination with the validates method (see ActiveModel::Validations::ClassMethods.validates for more on this).

+ +
class Person
+  include ActiveModel::Validations
+  attr_accessor :title
+
+  validates :title, presence: true, title: true
+end
+
+ +

It can be useful to access the class that is using that validator when there are prerequisites such as an attr_accessor being present. This class is accessible via options[:class] in the constructor. To setup your validator override the constructor.

+ +
class MyValidator < ActiveModel::Validator
+  def initialize(options={})
+    super
+    options[:class].send :attr_accessor, :custom_attribute
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + options
+ + + + +

Class Public methods

+ +
+

+ + kind() + +

+ + +
+

Returns the kind of the validator.

+ +
PresenceValidator.kind   # => :presence
+AcceptanceValidator.kind # => :acceptance
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validator.rb, line 103
+def self.kind
+  @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous?
+end
+
+
+ +
+ +
+

+ + new(options = {}) + +

+ + +
+

Accepts options that will be made available through the options reader.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validator.rb, line 108
+def initialize(options = {})
+  @options = options.except(:class).freeze
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + kind() + +

+ + +
+

Returns the kind for this validator.

+ +
PresenceValidator.new(attributes: [:username]).kind # => :presence
+AcceptanceValidator.new(attributes: [:terms]).kind  # => :acceptance
+
+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validator.rb, line 116
+def kind
+  self.class.kind
+end
+
+
+ +
+ +
+

+ + validate(record) + +

+ + +
+

Override this method in subclasses with validation logic, adding errors to the records errors array where necessary.

+
+ + + + + + + + +
+ + +
+
# File activemodel/lib/active_model/validator.rb, line 122
+def validate(record)
+  raise NotImplementedError, "Subclasses must implement a validate(record) method."
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord.html b/src/5.2/classes/ActiveRecord.html new file mode 100644 index 0000000000..ad6698f53d --- /dev/null +++ b/src/5.2/classes/ActiveRecord.html @@ -0,0 +1,904 @@ +--- +title: ActiveRecord +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MigrationProxy=Struct.new(:name, :version, :filename, :scope) do +def initialize(name, version, filename, scope) +super +@migration = nil +end + +def basename +File.basename(filename) +end + +def mtime +File.mtime filename +end + +delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration + +private + +def migration +@migration ||= load_migration +end + +def load_migration +require(File.expand_path(filename)) +name.constantize.new(name, version) +end +end
 

MigrationProxy is used to defer loading of the actual migration classes until they are needed

Point=Struct.new(:x, :y)
 
UnknownAttributeError=ActiveModel::UnknownAttributeError
 

Raised when unknown attributes are supplied via mass assignment.

+ +
class Person
+  include ActiveModel::AttributeAssignment
+  include ActiveModel::Validations
+end
+
+person = Person.new
+person.assign_attributes(name: 'Gorby')
+# => ActiveModel::UnknownAttributeError: unknown attribute 'name' for Person.
+
+ + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Active Record as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded ActiveRecord as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/version.rb, line 7
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ActiveRecordError.html b/src/5.2/classes/ActiveRecord/ActiveRecordError.html new file mode 100644 index 0000000000..8e66827347 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ActiveRecordError.html @@ -0,0 +1,68 @@ +--- +title: ActiveRecord::ActiveRecordError +layout: default +--- +
+ +
+
+ +
+ +

Active Record Errors

+ +

Generic Active Record exception class.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AdapterNotFound.html b/src/5.2/classes/ActiveRecord/AdapterNotFound.html new file mode 100644 index 0000000000..aaef556aca --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AdapterNotFound.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::AdapterNotFound +layout: default +--- +
+ +
+
+ +
+ +

Raised when Active Record cannot find database adapter specified in config/database.yml or programmatically.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AdapterNotSpecified.html b/src/5.2/classes/ActiveRecord/AdapterNotSpecified.html new file mode 100644 index 0000000000..0f3ea52ae8 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AdapterNotSpecified.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::AdapterNotSpecified +layout: default +--- +
+ +
+
+ +
+ +

Raised when adapter not specified on connection (or configuration file config/database.yml misses adapter field).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Aggregations.html b/src/5.2/classes/ActiveRecord/Aggregations.html new file mode 100644 index 0000000000..63140df236 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Aggregations.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Aggregations +layout: default +--- +
+ +
+
+ +
+ +

See ActiveRecord::Aggregations::ClassMethods for documentation

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Aggregations/ClassMethods.html b/src/5.2/classes/ActiveRecord/Aggregations/ClassMethods.html new file mode 100644 index 0000000000..70303dbb77 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Aggregations/ClassMethods.html @@ -0,0 +1,276 @@ +--- +title: ActiveRecord::Aggregations::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record implements aggregation through a macro-like class method called composed_of for representing attributes as value objects. It expresses relationships like “Account [is] composed of Money [among other things]” or “Person [is] composed of [an] address”. Each call to the macro adds a description of how the value objects are created from the attributes of the entity object (when the entity is initialized either as a new object or from finding an existing object) and how it can be turned back into attributes (when the entity is saved to the database).

+ +
class Customer < ActiveRecord::Base
+  composed_of :balance, class_name: "Money", mapping: %w(balance amount)
+  composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
+end
+
+ +

The customer class now has the following methods to manipulate the value objects:

+
  • +

    Customer#balance, Customer#balance=(money)

    +
  • +

    Customer#address, Customer#address=(address)

    +
+ +

These methods will operate with value objects like the ones described below:

+ +
class Money
+  include Comparable
+  attr_reader :amount, :currency
+  EXCHANGE_RATES = { "USD_TO_DKK" => 6 }
+
+  def initialize(amount, currency = "USD")
+    @amount, @currency = amount, currency
+  end
+
+  def exchange_to(other_currency)
+    exchanged_amount = (amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor
+    Money.new(exchanged_amount, other_currency)
+  end
+
+  def ==(other_money)
+    amount == other_money.amount && currency == other_money.currency
+  end
+
+  def <=>(other_money)
+    if currency == other_money.currency
+      amount <=> other_money.amount
+    else
+      amount <=> other_money.exchange_to(currency).amount
+    end
+  end
+end
+
+class Address
+  attr_reader :street, :city
+  def initialize(street, city)
+    @street, @city = street, city
+  end
+
+  def close_to?(other_address)
+    city == other_address.city
+  end
+
+  def ==(other_address)
+    city == other_address.city && street == other_address.street
+  end
+end
+
+ +

Now it's possible to access attributes from the database through the value objects instead. If you choose to name the composition the same as the attribute's name, it will be the only way to access that attribute. That's the case with our balance attribute. You interact with the value objects just like you would with any other attribute:

+ +
customer.balance = Money.new(20)     # sets the Money value object and the attribute
+customer.balance                     # => Money value object
+customer.balance.exchange_to("DKK")  # => Money.new(120, "DKK")
+customer.balance > Money.new(10)     # => true
+customer.balance == Money.new(20)    # => true
+customer.balance < Money.new(5)      # => false
+
+ +

Value objects can also be composed of multiple attributes, such as the case of Address. The order of the mappings will determine the order of the parameters.

+ +
customer.address_street = "Hyancintvej"
+customer.address_city   = "Copenhagen"
+customer.address        # => Address.new("Hyancintvej", "Copenhagen")
+
+customer.address = Address.new("May Street", "Chicago")
+customer.address_street # => "May Street"
+customer.address_city   # => "Chicago"
+
+ +

Writing value objects

+ +

Value objects are immutable and interchangeable objects that represent a given value, such as a Money object representing $5. Two Money objects both representing $5 should be equal (through methods such as == and <=> from Comparable if ranking makes sense). This is unlike entity objects where equality is determined by identity. An entity class such as Customer can easily have two different objects that both have an address on Hyancintvej. Entity identity is determined by object or relational unique identifiers (such as primary keys). Normal ActiveRecord::Base classes are entity objects.

+ +

It's also important to treat the value objects as immutable. Don't allow the Money object to have its amount changed after creation. Create a new Money object with the new value instead. The Money#exchange_to method is an example of this. It returns a new value object instead of changing its own values. Active Record won't persist value objects that have been changed through means other than the writer method.

+ +

The immutable requirement is enforced by Active Record by freezing any object assigned as a value object. Attempting to change it afterwards will result in a RuntimeError.

+ +

Read more about value objects on c2.com/cgi/wiki?ValueObject and on the dangers of not keeping value objects immutable on c2.com/cgi/wiki?ValueObjectsShouldBeImmutable

+ +

Custom constructors and converters

+ +

By default value objects are initialized by calling the new constructor of the value class passing each of the mapped attributes, in the order specified by the :mapping option, as arguments. If the value class doesn't support this convention then composed_of allows a custom constructor to be specified.

+ +

When a new value is assigned to the value object, the default assumption is that the new value is an instance of the value class. Specifying a custom converter allows the new value to be automatically converted to an instance of value class if necessary.

+ +

For example, the NetworkResource model has network_address and cidr_range attributes that should be aggregated using the NetAddr::CIDR value class (www.rubydoc.info/gems/netaddr/1.5.0/NetAddr/CIDR). The constructor for the value class is called create and it expects a CIDR address string as a parameter. New values can be assigned to the value object using either another NetAddr::CIDR object, a string or an array. The :constructor and :converter options can be used to meet these requirements:

+ +
class NetworkResource < ActiveRecord::Base
+  composed_of :cidr,
+              class_name: 'NetAddr::CIDR',
+              mapping: [ %w(network_address network), %w(cidr_range bits) ],
+              allow_nil: true,
+              constructor: Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
+              converter: Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
+end
+
+# This calls the :constructor
+network_resource = NetworkResource.new(network_address: '192.168.0.1', cidr_range: 24)
+
+# These assignments will both use the :converter
+network_resource.cidr = [ '192.168.2.1', 8 ]
+network_resource.cidr = '192.168.0.1/24'
+
+# This assignment won't use the :converter as the value is already an instance of the value class
+network_resource.cidr = NetAddr::CIDR.create('192.168.2.1/8')
+
+# Saving and then reloading will use the :constructor on reload
+network_resource.save
+network_resource.reload
+
+ +

Finding records by a value object

+ +

Once a composed_of relationship is specified for a model, records can be loaded from the database by specifying an instance of the value object in the conditions hash. The following example finds all customers with address_street equal to “May Street” and address_city equal to “Chicago”:

+ +
Customer.where(address: Address.new("May Street", "Chicago"))
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + composed_of(part_id, options = {}) + +

+ + +
+

Adds reader and writer methods for manipulating a value object: composed_of :address adds address and address=(new_address) methods.

+ +

Options are:

+
  • +

    :class_name - Specifies the class name of the association. Use it only if that name can't be inferred from the part id. So composed_of :address will by default be linked to the Address class, but if the real class name is CompanyAddress, you'll have to specify it with this option.

    +
  • +

    :mapping - Specifies the mapping of entity attributes to attributes of the value object. Each mapping is represented as an array where the first item is the name of the entity attribute and the second item is the name of the attribute in the value object. The order in which mappings are defined determines the order in which attributes are sent to the value class constructor.

    +
  • +

    :allow_nil - Specifies that the value object will not be instantiated when all mapped attributes are nil. Setting the value object to nil has the effect of writing nil to all mapped attributes. This defaults to false.

    +
  • +

    :constructor - A symbol specifying the name of the constructor method or a Proc that is called to initialize the value object. The constructor is passed all of the mapped attributes, in the order that they are defined in the :mapping option, as arguments and uses them to instantiate a :class_name object. The default is :new.

    +
  • +

    :converter - A symbol specifying the name of a class method of :class_name or a Proc that is called when a new value is assigned to the value object. The converter is passed the single value that is used in the assignment and is only called if the new value is not an instance of :class_name. If :allow_nil is set to true, the converter can return nil to skip the assignment.

    +
+ +

Option examples:

+ +
composed_of :temperature, mapping: %w(reading celsius)
+composed_of :balance, class_name: "Money", mapping: %w(balance amount)
+composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
+composed_of :gps_location
+composed_of :gps_location, allow_nil: true
+composed_of :ip_address,
+            class_name: 'IPAddr',
+            mapping: %w(ip to_i),
+            constructor: Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
+            converter: Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/aggregations.rb, line 225
+def composed_of(part_id, options = {})
+  options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter)
+
+  name        = part_id.id2name
+  class_name  = options[:class_name]  || name.camelize
+  mapping     = options[:mapping]     || [ name, name ]
+  mapping     = [ mapping ] unless mapping.first.is_a?(Array)
+  allow_nil   = options[:allow_nil]   || false
+  constructor = options[:constructor] || :new
+  converter   = options[:converter]
+
+  reader_method(name, class_name, mapping, allow_nil, constructor)
+  writer_method(name, class_name, mapping, allow_nil, converter)
+
+  reflection = ActiveRecord::Reflection.create(:composed_of, part_id, nil, options, self)
+  Reflection.add_aggregate_reflection self, part_id, reflection
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AssociationRelation.html b/src/5.2/classes/ActiveRecord/AssociationRelation.html new file mode 100644 index 0000000000..89126f3d74 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AssociationRelation.html @@ -0,0 +1,338 @@ +--- +title: ActiveRecord::AssociationRelation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(klass, association) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/association_relation.rb, line 5
+def initialize(klass, association)
+  super(klass)
+  @association = association
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/association_relation.rb, line 14
+def ==(other)
+  other == records
+end
+
+
+ +
+ +
+

+ + build(*args, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: new +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/association_relation.rb, line 18
+def build(*args, &block)
+  scoping { @association.build(*args, &block) }
+end
+
+
+ +
+ +
+

+ + create(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/association_relation.rb, line 23
+def create(*args, &block)
+  scoping { @association.create(*args, &block) }
+end
+
+
+ +
+ +
+

+ + create!(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/association_relation.rb, line 27
+def create!(*args, &block)
+  scoping { @association.create!(*args, &block) }
+end
+
+
+ +
+ +
+

+ + new(*args, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: build +
+ + + +
+ +
+

+ + proxy_association() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/association_relation.rb, line 10
+def proxy_association
+  @association
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AssociationTypeMismatch.html b/src/5.2/classes/ActiveRecord/AssociationTypeMismatch.html new file mode 100644 index 0000000000..389b124dfa --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AssociationTypeMismatch.html @@ -0,0 +1,78 @@ +--- +title: ActiveRecord::AssociationTypeMismatch +layout: default +--- +
+ +
+
+ +
+ +

Raised when an object assigned to an association has an incorrect type.

+ +
class Ticket < ActiveRecord::Base
+  has_many :patches
+end
+
+class Patch < ActiveRecord::Base
+  belongs_to :ticket
+end
+
+# Comments are not patches, this assignment raises AssociationTypeMismatch.
+@ticket.patches << Comment.new(content: "Please attach tests to your patch.")
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Associations.html b/src/5.2/classes/ActiveRecord/Associations.html new file mode 100644 index 0000000000..86c544540e --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Associations.html @@ -0,0 +1,146 @@ +--- +title: ActiveRecord::Associations +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Associations/ClassMethods.html b/src/5.2/classes/ActiveRecord/Associations/ClassMethods.html new file mode 100644 index 0000000000..8ffd0da9cf --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Associations/ClassMethods.html @@ -0,0 +1,1626 @@ +--- +title: ActiveRecord::Associations::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Associations are a set of macro-like class methods for tying objects together through foreign keys. They express relationships like “Project has one Project Manager” or “Project belongs to a Portfolio”. Each macro adds a number of methods to the class which are specialized according to the collection or association symbol and the options hash. It works much the same way as Ruby's own attr* methods.

+ +
class Project < ActiveRecord::Base
+  belongs_to              :portfolio
+  has_one                 :project_manager
+  has_many                :milestones
+  has_and_belongs_to_many :categories
+end
+
+ +

The project class now has the following methods (and more) to ease the traversal and manipulation of its relationships:

+
  • +

    Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?

    +
  • +

    Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,

    +
  • +

    Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone), Project#milestones.delete(milestone), Project#milestones.destroy(milestone), Project#milestones.find(milestone_id), Project#milestones.build, Project#milestones.create

    +
  • +

    Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1), Project#categories.delete(category1), Project#categories.destroy(category1)

    +
+ +

A word of warning

+ +

Don't create associations that have the same name as instance methods of ActiveRecord::Base. Since the association adds a method with that name to its model, using an association with the same name as one provided by ActiveRecord::Base will override the method inherited through ActiveRecord::Base and will break things. For instance, attributes and connection would be bad choices for association names, because those names already exist in the list of ActiveRecord::Base instance methods.

+ +

Auto-generated methods

+ +

See also Instance Public methods below for more details.

+ +

Singular associations (one-to-one)

+ +
                                  |            |  belongs_to  |
+generated methods                 | belongs_to | :polymorphic | has_one
+----------------------------------+------------+--------------+---------
+other                             |     X      |      X       |    X
+other=(other)                     |     X      |      X       |    X
+build_other(attributes={})        |     X      |              |    X
+create_other(attributes={})       |     X      |              |    X
+create_other!(attributes={})      |     X      |              |    X
+reload_other                      |     X      |      X       |    X
+
+ +

Collection associations (one-to-many / many-to-many)

+ +
                                  |       |          | has_many
+generated methods                 | habtm | has_many | :through
+----------------------------------+-------+----------+----------
+others                            |   X   |    X     |    X
+others=(other,other,...)          |   X   |    X     |    X
+other_ids                         |   X   |    X     |    X
+other_ids=(id,id,...)             |   X   |    X     |    X
+others<<                          |   X   |    X     |    X
+others.push                       |   X   |    X     |    X
+others.concat                     |   X   |    X     |    X
+others.build(attributes={})       |   X   |    X     |    X
+others.create(attributes={})      |   X   |    X     |    X
+others.create!(attributes={})     |   X   |    X     |    X
+others.size                       |   X   |    X     |    X
+others.length                     |   X   |    X     |    X
+others.count                      |   X   |    X     |    X
+others.sum(*args)                 |   X   |    X     |    X
+others.empty?                     |   X   |    X     |    X
+others.clear                      |   X   |    X     |    X
+others.delete(other,other,...)    |   X   |    X     |    X
+others.delete_all                 |   X   |    X     |    X
+others.destroy(other,other,...)   |   X   |    X     |    X
+others.destroy_all                |   X   |    X     |    X
+others.find(*args)                |   X   |    X     |    X
+others.exists?                    |   X   |    X     |    X
+others.distinct                   |   X   |    X     |    X
+others.reset                      |   X   |    X     |    X
+others.reload                     |   X   |    X     |    X
+
+ +

Overriding generated methods

+ +

Association methods are generated in a module included into the model class, making overrides easy. The original generated method can thus be called with super:

+ +
class Car < ActiveRecord::Base
+  belongs_to :owner
+  belongs_to :old_owner
+
+  def owner=(new_owner)
+    self.old_owner = self.owner
+    super
+  end
+end
+
+ +

The association methods module is included immediately after the generated attributes methods module, meaning an association will override the methods for an attribute with the same name.

+ +

Cardinality and associations

+ +

Active Record associations can be used to describe one-to-one, one-to-many and many-to-many relationships between models. Each model uses an association to describe its role in the relation. The belongs_to association is always used in the model that has the foreign key.

+ +

One-to-one

+ +

Use has_one in the base, and belongs_to in the associated model.

+ +
class Employee < ActiveRecord::Base
+  has_one :office
+end
+class Office < ActiveRecord::Base
+  belongs_to :employee    # foreign key - employee_id
+end
+
+ +

One-to-many

+ +

Use has_many in the base, and belongs_to in the associated model.

+ +
class Manager < ActiveRecord::Base
+  has_many :employees
+end
+class Employee < ActiveRecord::Base
+  belongs_to :manager     # foreign key - manager_id
+end
+
+ +

Many-to-many

+ +

There are two ways to build a many-to-many relationship.

+ +

The first way uses a has_many association with the :through option and a join model, so there are two stages of associations.

+ +
class Assignment < ActiveRecord::Base
+  belongs_to :programmer  # foreign key - programmer_id
+  belongs_to :project     # foreign key - project_id
+end
+class Programmer < ActiveRecord::Base
+  has_many :assignments
+  has_many :projects, through: :assignments
+end
+class Project < ActiveRecord::Base
+  has_many :assignments
+  has_many :programmers, through: :assignments
+end
+
+ +

For the second way, use has_and_belongs_to_many in both models. This requires a join table that has no corresponding model or primary key.

+ +
class Programmer < ActiveRecord::Base
+  has_and_belongs_to_many :projects       # foreign keys in the join table
+end
+class Project < ActiveRecord::Base
+  has_and_belongs_to_many :programmers    # foreign keys in the join table
+end
+
+ +

Choosing which way to build a many-to-many relationship is not always simple. If you need to work with the relationship model as its own entity, use has_many :through. Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.

+ +

Is it a belongs_to or has_one association?

+ +

Both express a 1-1 relationship. The difference is mostly where to place the foreign key, which goes on the table for the class declaring the belongs_to relationship.

+ +
class User < ActiveRecord::Base
+  # I reference an account.
+  belongs_to :account
+end
+
+class Account < ActiveRecord::Base
+  # One user references me.
+  has_one :user
+end
+
+ +

The tables for these classes could look something like:

+ +
CREATE TABLE users (
+  id bigint NOT NULL auto_increment,
+  account_id bigint default NULL,
+  name varchar default NULL,
+  PRIMARY KEY  (id)
+)
+
+CREATE TABLE accounts (
+  id bigint NOT NULL auto_increment,
+  name varchar default NULL,
+  PRIMARY KEY  (id)
+)
+
+ +

Unsaved objects and associations

+ +

You can manipulate objects and associations before they are saved to the database, but there is some special behavior you should be aware of, mostly involving the saving of associated objects.

+ +

You can set the :autosave option on a has_one, belongs_to, has_many, or has_and_belongs_to_many association. Setting it to true will always save the members, whereas setting it to false will never save the members. More details about :autosave option is available at AutosaveAssociation.

+ +

One-to-one associations

+
  • +

    Assigning an object to a has_one association automatically saves that object and the object being replaced (if there is one), in order to update their foreign keys - except if the parent object is unsaved (new_record? == true).

    +
  • +

    If either of these saves fail (due to one of the objects being invalid), an ActiveRecord::RecordNotSaved exception is raised and the assignment is cancelled.

    +
  • +

    If you wish to assign an object to a has_one association without saving it, use the #build_association method (documented below). The object being replaced will still be saved to update its foreign key.

    +
  • +

    Assigning an object to a belongs_to association does not save the object, since the foreign key field belongs on the parent. It does not save the parent either.

    +
+ +

Collections

+
  • +

    Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object (the owner of the collection) is not yet stored in the database.

    +
  • +

    If saving any of the objects being added to a collection (via push or similar) fails, then push returns false.

    +
  • +

    If saving fails while replacing the collection (via association=), an ActiveRecord::RecordNotSaved exception is raised and the assignment is cancelled.

    +
  • +

    You can add an object to a collection without automatically saving it by using the collection.build method (documented below).

    +
  • +

    All unsaved (new_record? == true) members of the collection are automatically saved when the parent is saved.

    +
+ +

Customizing the query

+ +

Associations are built from Relation objects, and you can use the Relation syntax to customize them. For example, to add a condition:

+ +
class Blog < ActiveRecord::Base
+  has_many :published_posts, -> { where(published: true) }, class_name: 'Post'
+end
+
+ +

Inside the -> { ... } block you can use all of the usual Relation methods.

+ +

Accessing the owner object

+ +

Sometimes it is useful to have access to the owner object when building the query. The owner is passed as a parameter to the block. For example, the following association would find all events that occur on the user's birthday:

+ +
class User < ActiveRecord::Base
+  has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
+end
+
+ +

Note: Joining, eager loading and preloading of these associations is not possible. These operations happen before instance creation and the scope will be called with a nil argument.

+ +

Association callbacks

+ +

Similar to the normal callbacks that hook into the life cycle of an Active Record object, you can also define callbacks that get triggered when you add an object to or remove an object from an association collection.

+ +
class Project
+  has_and_belongs_to_many :developers, after_add: :evaluate_velocity
+
+  def evaluate_velocity(developer)
+    ...
+  end
+end
+
+ +

It's possible to stack callbacks by passing them as an array. Example:

+ +
class Project
+  has_and_belongs_to_many :developers,
+                          after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
+end
+
+ +

Possible callbacks are: before_add, after_add, before_remove and after_remove.

+ +

If any of the before_add callbacks throw an exception, the object will not be added to the collection.

+ +

Similarly, if any of the before_remove callbacks throw an exception, the object will not be removed from the collection.

+ +

Association extensions

+ +

The proxy objects that control the access to associations can be extended through anonymous modules. This is especially beneficial for adding new finders, creators, and other factory-type methods that are only used as part of this association.

+ +
class Account < ActiveRecord::Base
+  has_many :people do
+    def find_or_create_by_name(name)
+      first_name, last_name = name.split(" ", 2)
+      find_or_create_by(first_name: first_name, last_name: last_name)
+    end
+  end
+end
+
+person = Account.first.people.find_or_create_by_name("David Heinemeier Hansson")
+person.first_name # => "David"
+person.last_name  # => "Heinemeier Hansson"
+
+ +

If you need to share the same extensions between many associations, you can use a named extension module.

+ +
module FindOrCreateByNameExtension
+  def find_or_create_by_name(name)
+    first_name, last_name = name.split(" ", 2)
+    find_or_create_by(first_name: first_name, last_name: last_name)
+  end
+end
+
+class Account < ActiveRecord::Base
+  has_many :people, -> { extending FindOrCreateByNameExtension }
+end
+
+class Company < ActiveRecord::Base
+  has_many :people, -> { extending FindOrCreateByNameExtension }
+end
+
+ +

Some extensions can only be made to work with knowledge of the association's internals. Extensions can access relevant state using the following methods (where items is the name of the association):

+
  • +

    record.association(:items).owner - Returns the object the association is part of.

    +
  • +

    record.association(:items).reflection - Returns the reflection object that describes the association.

    +
  • +

    record.association(:items).target - Returns the associated object for belongs_to and has_one, or the collection of associated objects for has_many and has_and_belongs_to_many.

    +
+ +

However, inside the actual extension code, you will not have access to the record as above. In this case, you can access proxy_association. For example, record.association(:items) and record.items.proxy_association will return the same object, allowing you to make calls like proxy_association.owner inside association extensions.

+ +

Association Join Models

+ +

Has Many associations can be configured with the :through option to use an explicit join model to retrieve the data. This operates similarly to a has_and_belongs_to_many association. The advantage is that you're able to add validations, callbacks, and extra attributes on the join model. Consider the following schema:

+ +
class Author < ActiveRecord::Base
+  has_many :authorships
+  has_many :books, through: :authorships
+end
+
+class Authorship < ActiveRecord::Base
+  belongs_to :author
+  belongs_to :book
+end
+
+@author = Author.first
+@author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
+@author.books                              # selects all books by using the Authorship join model
+
+ +

You can also go through a has_many association on the join model:

+ +
class Firm < ActiveRecord::Base
+  has_many   :clients
+  has_many   :invoices, through: :clients
+end
+
+class Client < ActiveRecord::Base
+  belongs_to :firm
+  has_many   :invoices
+end
+
+class Invoice < ActiveRecord::Base
+  belongs_to :client
+end
+
+@firm = Firm.first
+@firm.clients.flat_map { |c| c.invoices } # select all invoices for all clients of the firm
+@firm.invoices                            # selects all invoices by going through the Client join model
+
+ +

Similarly you can go through a has_one association on the join model:

+ +
class Group < ActiveRecord::Base
+  has_many   :users
+  has_many   :avatars, through: :users
+end
+
+class User < ActiveRecord::Base
+  belongs_to :group
+  has_one    :avatar
+end
+
+class Avatar < ActiveRecord::Base
+  belongs_to :user
+end
+
+@group = Group.first
+@group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group
+@group.avatars                                # selects all avatars by going through the User join model.
+
+ +

An important caveat with going through has_one or has_many associations on the join model is that these associations are read-only. For example, the following would not work following the previous example:

+ +
@group.avatars << Avatar.new   # this would work if User belonged_to Avatar rather than the other way around
+@group.avatars.delete(@group.avatars.last)  # so would this
+
+ +

Setting Inverses

+ +

If you are using a belongs_to on the join model, it is a good idea to set the :inverse_of option on the belongs_to, which will mean that the following example works correctly (where tags is a has_many :through association):

+ +
@post = Post.first
+@tag = @post.tags.build name: "ruby"
+@tag.save
+
+ +

The last line ought to save the through record (a Tagging). This will only work if the :inverse_of is set:

+ +
class Tagging < ActiveRecord::Base
+  belongs_to :post
+  belongs_to :tag, inverse_of: :taggings
+end
+
+ +

If you do not set the :inverse_of record, the association will do its best to match itself up with the correct inverse. Automatic inverse detection only works on has_many, has_one, and belongs_to associations.

+ +

Extra options on the associations, as defined in the AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS constant, will also prevent the association's inverse from being found automatically.

+ +

The automatic guessing of the inverse association uses a heuristic based on the name of the class, so it may not work for all associations, especially the ones with non-standard names.

+ +

You can turn off the automatic detection of inverse associations by setting the :inverse_of option to false like so:

+ +
class Tagging < ActiveRecord::Base
+  belongs_to :tag, inverse_of: false
+end
+
+ +

Nested Associations

+ +

You can actually specify any association with the :through option, including an association which has a :through option itself. For example:

+ +
class Author < ActiveRecord::Base
+  has_many :posts
+  has_many :comments, through: :posts
+  has_many :commenters, through: :comments
+end
+
+class Post < ActiveRecord::Base
+  has_many :comments
+end
+
+class Comment < ActiveRecord::Base
+  belongs_to :commenter
+end
+
+@author = Author.first
+@author.commenters # => People who commented on posts written by the author
+
+ +

An equivalent way of setting up this association this would be:

+ +
class Author < ActiveRecord::Base
+  has_many :posts
+  has_many :commenters, through: :posts
+end
+
+class Post < ActiveRecord::Base
+  has_many :comments
+  has_many :commenters, through: :comments
+end
+
+class Comment < ActiveRecord::Base
+  belongs_to :commenter
+end
+
+ +

When using a nested association, you will not be able to modify the association because there is not enough information to know what modification to make. For example, if you tried to add a Commenter in the example above, there would be no way to tell how to set up the intermediate Post and Comment objects.

+ +

Polymorphic Associations

+ +

Polymorphic associations on models are not restricted on what types of models they can be associated with. Rather, they specify an interface that a has_many association must adhere to.

+ +
class Asset < ActiveRecord::Base
+  belongs_to :attachable, polymorphic: true
+end
+
+class Post < ActiveRecord::Base
+  has_many :assets, as: :attachable         # The :as option specifies the polymorphic interface to use.
+end
+
+@asset.attachable = @post
+
+ +

This works by using a type column in addition to a foreign key to specify the associated record. In the Asset example, you'd need an attachable_id integer column and an attachable_type string column.

+ +

Using polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order for the associations to work as expected, ensure that you store the base model for the STI models in the type column of the polymorphic association. To continue with the asset example above, suppose there are guest posts and member posts that use the posts table for STI. In this case, there must be a type column in the posts table.

+ +

Note: The attachable_type= method is being called when assigning an attachable. The class_name of the attachable is passed as a String.

+ +
class Asset < ActiveRecord::Base
+  belongs_to :attachable, polymorphic: true
+
+  def attachable_type=(class_name)
+     super(class_name.constantize.base_class.to_s)
+  end
+end
+
+class Post < ActiveRecord::Base
+  # because we store "Post" in attachable_type now dependent: :destroy will work
+  has_many :assets, as: :attachable, dependent: :destroy
+end
+
+class GuestPost < Post
+end
+
+class MemberPost < Post
+end
+
+ +

Caching

+ +

All of the methods are built on a simple caching principle that will keep the result of the last query around unless specifically instructed not to. The cache is even shared across methods to make it even cheaper to use the macro-added methods without worrying too much about performance at the first go.

+ +
project.milestones             # fetches milestones from the database
+project.milestones.size        # uses the milestone cache
+project.milestones.empty?      # uses the milestone cache
+project.milestones.reload.size # fetches milestones from the database
+project.milestones             # uses the milestone cache
+
+ +

Eager loading of associations

+ +

Eager loading is a way to find objects of a certain class and a number of named associations. It is one of the easiest ways to prevent the dreaded N+1 problem in which fetching 100 posts that each need to display their author triggers 101 database queries. Through the use of eager loading, the number of queries will be reduced from 101 to 2.

+ +
class Post < ActiveRecord::Base
+  belongs_to :author
+  has_many   :comments
+end
+
+ +

Consider the following loop using the class above:

+ +
Post.all.each do |post|
+  puts "Post:            " + post.title
+  puts "Written by:      " + post.author.name
+  puts "Last comment on: " + post.comments.first.created_on
+end
+
+ +

To iterate over these one hundred posts, we'll generate 201 database queries. Let's first just optimize it for retrieving the author:

+ +
Post.includes(:author).each do |post|
+
+ +

This references the name of the belongs_to association that also used the :author symbol. After loading the posts, find will collect the author_id from each one and load all of the referenced authors with one query. Doing so will cut down the number of queries from 201 to 102.

+ +

We can improve upon the situation further by referencing both associations in the finder with:

+ +
Post.includes(:author, :comments).each do |post|
+
+ +

This will load all comments with a single query. This reduces the total number of queries to 3. In general, the number of queries will be 1 plus the number of associations named (except if some of the associations are polymorphic belongs_to - see below).

+ +

To include a deep hierarchy of associations, use a hash:

+ +
Post.includes(:author, { comments: { author: :gravatar } }).each do |post|
+
+ +

The above code will load all the comments and all of their associated authors and gravatars. You can mix and match any combination of symbols, arrays, and hashes to retrieve the associations you want to load.

+ +

All of this power shouldn't fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you've reduced the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it's no catch-all for performance problems, but it's a great way to cut down on the number of queries in a situation as the one described above.

+ +

Since only one table is loaded at a time, conditions or orders cannot reference tables other than the main one. If this is the case, Active Record falls back to the previously used LEFT OUTER JOIN based strategy. For example:

+ +
Post.includes([:author, :comments]).where(['comments.approved = ?', true])
+
+ +

This will result in a single SQL query with joins along the lines of: LEFT OUTER JOIN comments ON comments.post_id = posts.id and LEFT OUTER JOIN authors ON authors.id = posts.author_id. Note that using conditions like this can have unintended consequences. In the above example, posts with no approved comments are not returned at all because the conditions apply to the SQL statement as a whole and not just to the association.

+ +

You must disambiguate column references for this fallback to happen, for example order: "author.name DESC" will work but order: "name DESC" will not.

+ +

If you want to load all posts (including posts with no approved comments), then write your own LEFT OUTER JOIN query using ON:

+ +
Post.joins("LEFT OUTER JOIN comments ON comments.post_id = posts.id AND comments.approved = '1'")
+
+ +

In this case, it is usually more natural to include an association which has conditions defined on it:

+ +
class Post < ActiveRecord::Base
+  has_many :approved_comments, -> { where(approved: true) }, class_name: 'Comment'
+end
+
+Post.includes(:approved_comments)
+
+ +

This will load posts and eager load the approved_comments association, which contains only those comments that have been approved.

+ +

If you eager load an association with a specified :limit option, it will be ignored, returning all the associated objects:

+ +
class Picture < ActiveRecord::Base
+  has_many :most_recent_comments, -> { order('id DESC').limit(10) }, class_name: 'Comment'
+end
+
+Picture.includes(:most_recent_comments).first.most_recent_comments # => returns all associated comments.
+
+ +

Eager loading is supported with polymorphic associations.

+ +
class Address < ActiveRecord::Base
+  belongs_to :addressable, polymorphic: true
+end
+
+ +

A call that tries to eager load the addressable model

+ +
Address.includes(:addressable)
+
+ +

This will execute one query to load the addresses and load the addressables with one query per addressable type. For example, if all the addressables are either of class Person or Company, then a total of 3 queries will be executed. The list of addressable types to load is determined on the back of the addresses loaded. This is not supported if Active Record has to fallback to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError. The reason is that the parent model's type is a column value so its corresponding table name cannot be put in the FROM/JOIN clauses of that query.

+ +

Table Aliasing

+ +

Active Record uses table aliasing in the case that a table is referenced multiple times in a join. If a table is referenced only once, the standard table name is used. The second time, the table is aliased as #{reflection_name}_#{parent_table_name}. Indexes are appended for any more successive uses of the table name.

+ +
Post.joins(:comments)
+# => SELECT ... FROM posts INNER JOIN comments ON ...
+Post.joins(:special_comments) # STI
+# => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
+Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
+# => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
+
+ +

Acts as tree example:

+ +
TreeMixin.joins(:children)
+# => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
+TreeMixin.joins(children: :parent)
+# => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
+                            INNER JOIN parents_mixins ...
+TreeMixin.joins(children: {parent: :children})
+# => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
+                            INNER JOIN parents_mixins ...
+                            INNER JOIN mixins childrens_mixins_2
+
+ +

Has and Belongs to Many join tables use the same idea, but add a _join suffix:

+ +
Post.joins(:categories)
+# => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
+Post.joins(categories: :posts)
+# => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
+                           INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
+Post.joins(categories: {posts: :categories})
+# => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
+                           INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
+                           INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
+
+ +

If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table names will take precedence over the eager associations:

+ +
Post.joins(:comments).joins("inner join comments ...")
+# => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
+Post.joins(:comments, :special_comments).joins("inner join comments ...")
+# => SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
+                           INNER JOIN comments special_comments_posts ...
+                           INNER JOIN comments ...
+
+ +

Table aliases are automatically truncated according to the maximum length of table identifiers according to the specific database.

+ +

Modules

+ +

By default, associations will look for objects within the current module scope. Consider:

+ +
module MyApplication
+  module Business
+    class Firm < ActiveRecord::Base
+      has_many :clients
+    end
+
+    class Client < ActiveRecord::Base; end
+  end
+end
+
+ +

When Firm#clients is called, it will in turn call MyApplication::Business::Client.find_all_by_firm_id(firm.id). If you want to associate with a class in another module scope, this can be done by specifying the complete class name.

+ +
module MyApplication
+  module Business
+    class Firm < ActiveRecord::Base; end
+  end
+
+  module Billing
+    class Account < ActiveRecord::Base
+      belongs_to :firm, class_name: "MyApplication::Business::Firm"
+    end
+  end
+end
+
+ +

Bi-directional associations

+ +

When you specify an association, there is usually an association on the associated model that specifies the same relationship in reverse. For example, with the following models:

+ +
class Dungeon < ActiveRecord::Base
+  has_many :traps
+  has_one :evil_wizard
+end
+
+class Trap < ActiveRecord::Base
+  belongs_to :dungeon
+end
+
+class EvilWizard < ActiveRecord::Base
+  belongs_to :dungeon
+end
+
+ +

The traps association on Dungeon and the dungeon association on Trap are the inverse of each other, and the inverse of the dungeon association on EvilWizard is the evil_wizard association on Dungeon (and vice-versa). By default, Active Record can guess the inverse of the association based on the name of the class. The result is the following:

+ +
d = Dungeon.first
+t = d.traps.first
+d.object_id == t.dungeon.object_id # => true
+
+ +

The Dungeon instances d and t.dungeon in the above example refer to the same in-memory instance since the association matches the name of the class. The result would be the same if we added :inverse_of to our model definitions:

+ +
class Dungeon < ActiveRecord::Base
+  has_many :traps, inverse_of: :dungeon
+  has_one :evil_wizard, inverse_of: :dungeon
+end
+
+class Trap < ActiveRecord::Base
+  belongs_to :dungeon, inverse_of: :traps
+end
+
+class EvilWizard < ActiveRecord::Base
+  belongs_to :dungeon, inverse_of: :evil_wizard
+end
+
+ +

For more information, see the documentation for the :inverse_of option.

+ +

Deleting from associations

+ +

Dependent associations

+ +

has_many, has_one, and belongs_to associations support the :dependent option. This allows you to specify that associated records should be deleted when the owner is deleted.

+ +

For example:

+ +
class Author
+  has_many :posts, dependent: :destroy
+end
+Author.find(1).destroy # => Will destroy all of the author's posts, too
+
+ +

The :dependent option can have different values which specify how the deletion is done. For more information, see the documentation for this option on the different specific association types. When no option is given, the behavior is to do nothing with the associated records when destroying a record.

+ +

Note that :dependent is implemented using Rails' callback system, which works by processing callbacks in order. Therefore, other callbacks declared either before or after the :dependent option can affect what it does.

+ +

Note that :dependent option is ignored for has_one :through associations.

+ +

Delete or destroy?

+ +

has_many and has_and_belongs_to_many associations have the methods destroy, delete, destroy_all and delete_all.

+ +

For has_and_belongs_to_many, delete and destroy are the same: they cause the records in the join table to be removed.

+ +

For has_many, destroy and destroy_all will always call the destroy method of the record(s) being removed so that callbacks are run. However delete and delete_all will either do the deletion according to the strategy specified by the :dependent option, or if no :dependent option is given, then it will follow the default strategy. The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for has_many :through, where the default strategy is delete_all (delete the join records, without running their callbacks).

+ +

There is also a clear method which is the same as delete_all, except that it returns the association rather than the records which have been deleted.

+ +

What gets deleted?

+ +

There is a potential pitfall here: has_and_belongs_to_many and has_many :through associations have records in join tables, as well as the associated records. So when we call one of these deletion methods, what exactly should be deleted?

+ +

The answer is that it is assumed that deletion on an association is about removing the link between the owner and the associated object(s), rather than necessarily the associated objects themselves. So with has_and_belongs_to_many and has_many :through, the join records will be deleted, but the associated records won't.

+ +

This makes sense if you think about it: if you were to call post.tags.delete(Tag.find_by(name: 'food')) you would want the 'food' tag to be unlinked from the post, rather than for the tag itself to be removed from the database.

+ +

However, there are examples where this strategy doesn't make sense. For example, suppose a person has many projects, and each project has many tasks. If we deleted one of a person's tasks, we would probably not want the project to be deleted. In this scenario, the delete method won't actually work: it can only be used if the association on the join model is a belongs_to. In other situations you are expected to perform operations directly on either the associated records or the :through association.

+ +

With a regular has_many there is no distinction between the “associated records” and the “link”, so there is only one choice for what gets deleted.

+ +

With has_and_belongs_to_many and has_many :through, if you want to delete the associated records themselves, you can always do something along the lines of person.tasks.each(&:destroy).

+ +

Type safety with ActiveRecord::AssociationTypeMismatch

+ +

If you attempt to assign an object to an association that doesn't match the inferred or specified :class_name, you'll get an ActiveRecord::AssociationTypeMismatch.

+ +

Options

+ +

All of the association macros can be specialized through options. This makes cases more complex than the simple and guessable ones possible.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + belongs_to(name, scope = nil, **options) + +

+ + +
+

Specifies a one-to-one association with another class. This method should only be used if this class contains the foreign key. If the other class contains the foreign key, then you should use has_one instead. See also ActiveRecord::Associations::ClassMethods's overview on when to use has_one and when to use belongs_to.

+ +

Methods will be added for retrieval and query for a single associated object, for which this object holds an id:

+ +

association is a placeholder for the symbol passed as the name argument, so belongs_to :author would add among others author.nil?.

+
association +
+

Returns the associated object. nil is returned if none is found.

+
association=(associate) +
+

Assigns the associate object, extracts the primary key, and sets it as the foreign key.

+
build_association(attributes = {}) +
+

Returns a new object of the associated type that has been instantiated with attributes and linked to this object through a foreign key, but has not yet been saved.

+
create_association(attributes = {}) +
+

Returns a new object of the associated type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation).

+
create_association!(attributes = {}) +
+

Does the same as create_association, but raises ActiveRecord::RecordInvalid if the record is invalid.

+
reload_association +
+

Returns the associated object, forcing a database read.

+
+ +

Example

+ +

A Post class declares belongs_to :author, which will add:

+
  • +

    Post#author (similar to Author.find(author_id))

    +
  • +

    Post#author=(author) (similar to post.author_id = author.id)

    +
  • +

    Post#build_author (similar to post.author = Author.new)

    +
  • +

    Post#create_author (similar to post.author = Author.new; post.author.save; post.author)

    +
  • +

    Post#create_author! (similar to post.author = Author.new; post.author.save!; post.author)

    +
  • +

    Post#reload_author

    +
+ +

The declaration can also include an options hash to specialize the behavior of the association.

+ +

Scopes

+ +

You can pass a second argument scope as a callable (i.e. proc or lambda) to retrieve a specific record or customize the generated query when you access the associated object.

+ +

Scope examples:

+ +
belongs_to :firm, -> { where(id: 2) }
+belongs_to :user, -> { joins(:friends) }
+belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
+
+ +

Options

+
:class_name +
+

Specify the class name of the association. Use it only if that name can't be inferred from the association name. So belongs_to :author will by default be linked to the Author class, but if the real class name is Person, you'll have to specify it with this option.

+
:foreign_key +
+

Specify the foreign key used for the association. By default this is guessed to be the name of the association with an “_id” suffix. So a class that defines a belongs_to :person association will use “person_id” as the default :foreign_key. Similarly, belongs_to :favorite_person, class_name: "Person" will use a foreign key of “favorite_person_id”.

+ +

If you are going to modify the association (rather than just read from it), then it is a good idea to set the :inverse_of option.

+
:foreign_type +
+

Specify the column used to store the associated object's type, if this is a polymorphic association. By default this is guessed to be the name of the association with a “_type” suffix. So a class that defines a belongs_to :taggable, polymorphic: true association will use “taggable_type” as the default :foreign_type.

+
:primary_key +
+

Specify the method that returns the primary key of associated object used for the association. By default this is id.

+
:dependent +
+

If set to :destroy, the associated object is destroyed when this object is. If set to :delete, the associated object is deleted without calling its destroy method. This option should not be specified when belongs_to is used in conjunction with a has_many relationship on another class because of the potential to leave orphaned records behind.

+
:counter_cache +
+

Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this class is created and decremented when it's destroyed. This requires that a column named #{table_name}_count (such as comments_count for a belonging Comment class) is used on the associate class (such as a Post class) - that is the migration for #{table_name}_count is created on the associate class (such that Post.comments_count will return the count cached, see note below). You can also specify a custom counter cache column by providing a column name instead of a true/false value to this option (e.g., counter_cache: :my_custom_counter.) Note: Specifying a counter cache will add it to that model's list of readonly attributes using attr_readonly.

+
:polymorphic +
+

Specify this association is a polymorphic association by passing true. Note: If you've enabled the counter cache, then you may want to add the counter cache attribute to the attr_readonly list in the associated classes (e.g. class Post; attr_readonly :comments_count; end).

+
:validate +
+

When set to true, validates new objects added to association when saving the parent object. false by default. If you want to ensure associated objects are revalidated on every update, use validates_associated.

+
:autosave +
+

If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. If false, never save or destroy the associated object. By default, only save the associated object if it's a new record.

+ +

Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets :autosave to true.

+
:touch +
+

If true, the associated object will be touched (the updated_at/on attributes set to current time) when this record is either saved or destroyed. If you specify a symbol, that attribute will be updated with the current time in addition to the updated_at/on attribute. Please note that with touching no validation is performed and only the after_touch, after_commit and after_rollback callbacks are executed.

+
:inverse_of +
+

Specifies the name of the has_one or has_many association on the associated object that is the inverse of this belongs_to association. See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.

+
:optional +
+

When set to true, the association will not have its presence validated.

+
:required +
+

When set to true, the association will also have its presence validated. This will validate the association itself, not the id. You can use :inverse_of to avoid an extra query during validation. NOTE: required is set to true by default and is deprecated. If you don't want to have association presence validated, use optional: true.

+
:default +
+

Provide a callable (i.e. proc or lambda) to specify that the association should be initialized with a particular record before validation.

+
+ +

Option examples:

+ +
belongs_to :firm, foreign_key: "client_of"
+belongs_to :person, primary_key: "name", foreign_key: "person_name"
+belongs_to :author, class_name: "Person", foreign_key: "author_id"
+belongs_to :valid_coupon, ->(o) { where "discounts > ?", o.payments_count },
+                          class_name: "Coupon", foreign_key: "coupon_id"
+belongs_to :attachable, polymorphic: true
+belongs_to :project, -> { readonly }
+belongs_to :post, counter_cache: true
+belongs_to :comment, touch: true
+belongs_to :company, touch: :employees_last_updated_at
+belongs_to :user, optional: true
+belongs_to :account, default: -> { company.account }
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations.rb, line 1653
+def belongs_to(name, scope = nil, **options)
+  reflection = Builder::BelongsTo.build(self, name, scope, options)
+  Reflection.add_reflection self, name, reflection
+end
+
+
+ +
+ +
+

+ + has_and_belongs_to_many(name, scope = nil, **options, &extension) + +

+ + +
+

Specifies a many-to-many relationship with another class. This associates two classes via an intermediate join table. Unless the join table is explicitly specified as an option, it is guessed using the lexical order of the class names. So a join between Developer and Project will give the default join table name of “developers_projects” because “D” precedes “P” alphabetically. Note that this precedence is calculated using the < operator for String. This means that if the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered of higher lexical precedence than the shorter one. For example, one would expect the tables “paper_boxes” and “papers” to generate a join table name of “papers_paper_boxes” because of the length of the name “paper_boxes”, but it in fact generates a join table name of “paper_boxes_papers”. Be aware of this caveat, and use the custom :join_table option if you need to. If your tables share a common prefix, it will only appear once at the beginning. For example, the tables “catalog_categories” and “catalog_products” generate a join table name of “catalog_categories_products”.

+ +

The join table should not have a primary key or a model associated with it. You must manually generate the join table with a migration such as this:

+ +
class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[5.0]
+  def change
+    create_join_table :developers, :projects
+  end
+end
+
+ +

It's also a good idea to add indexes to each of those columns to speed up the joins process. However, in MySQL it is advised to add a compound index for both of the columns as MySQL only uses one index per table during the lookup.

+ +

Adds the following methods for retrieval and query:

+ +

collection is a placeholder for the symbol passed as the name argument, so has_and_belongs_to_many :categories would add among others categories.empty?.

+
collection +
+

Returns a Relation of all the associated objects. An empty Relation is returned if none are found.

+
collection<<(object, …) +
+

Adds one or more objects to the collection by creating associations in the join table (collection.push and collection.concat are aliases to this method). Note that this operation instantly fires update SQL without waiting for the save or update call on the parent object, unless the parent object is a new record.

+
collection.delete(object, …) +
+

Removes one or more objects from the collection by removing their associations from the join table. This does not destroy the objects.

+
collection.destroy(object, …) +
+

Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option. This does not destroy the objects.

+
collection=objects +
+

Replaces the collection's content by deleting and adding objects as appropriate.

+
collection_singular_ids +
+

Returns an array of the associated objects' ids.

+
collection_singular_ids=ids +
+

Replace the collection by the objects identified by the primary keys in ids.

+
collection.clear +
+

Removes every object from the collection. This does not destroy the objects.

+
collection.empty? +
+

Returns true if there are no associated objects.

+
collection.size +
+

Returns the number of associated objects.

+
collection.find(id) +
+

Finds an associated object responding to the id and that meets the condition that it has to be associated with this object. Uses the same rules as ActiveRecord::FinderMethods#find.

+
collection.exists?(…) +
+

Checks whether an associated object with the given conditions exists. Uses the same rules as ActiveRecord::FinderMethods#exists?.

+
collection.build(attributes = {}) +
+

Returns a new object of the collection type that has been instantiated with attributes and linked to this object through the join table, but has not yet been saved.

+
collection.create(attributes = {}) +
+

Returns a new object of the collection type that has been instantiated with attributes, linked to this object through the join table, and that has already been saved (if it passed the validation).

+
collection.reload +
+

Returns a Relation of all of the associated objects, forcing a database read. An empty Relation is returned if none are found.

+
+ +

Example

+ +

A Developer class declares has_and_belongs_to_many :projects, which will add:

+
  • +

    Developer#projects

    +
  • +

    Developer#projects<<

    +
  • +

    Developer#projects.delete

    +
  • +

    Developer#projects.destroy

    +
  • +

    Developer#projects=

    +
  • +

    Developer#project_ids

    +
  • +

    Developer#project_ids=

    +
  • +

    Developer#projects.clear

    +
  • +

    Developer#projects.empty?

    +
  • +

    Developer#projects.size

    +
  • +

    Developer#projects.find(id)

    +
  • +

    Developer#projects.exists?(...)

    +
  • +

    Developer#projects.build (similar to Project.new(developer_id: id))

    +
  • +

    Developer#projects.create (similar to c = Project.new(developer_id: id); c.save; c)

    +
  • +

    Developer#projects.reload

    +
+ +

The declaration may include an options hash to specialize the behavior of the association.

+ +

Scopes

+ +

You can pass a second argument scope as a callable (i.e. proc or lambda) to retrieve a specific set of records or customize the generated query when you access the associated collection.

+ +

Scope examples:

+ +
has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
+has_and_belongs_to_many :categories, ->(post) {
+  where("default_category = ?", post.default_category)
+
+ +

Extensions

+ +

The extension argument allows you to pass a block into a has_and_belongs_to_many association. This is useful for adding new finders, creators and other factory-type methods to be used as part of the association.

+ +

Extension examples:

+ +
has_and_belongs_to_many :contractors do
+  def find_or_create_by_name(name)
+    first_name, last_name = name.split(" ", 2)
+    find_or_create_by(first_name: first_name, last_name: last_name)
+  end
+end
+
+ +

Options

+
:class_name +
+

Specify the class name of the association. Use it only if that name can't be inferred from the association name. So has_and_belongs_to_many :projects will by default be linked to the Project class, but if the real class name is SuperProject, you'll have to specify it with this option.

+
:join_table +
+

Specify the name of the join table if the default based on lexical order isn't what you want. WARNING: If you're overwriting the table name of either class, the table_name method MUST be declared underneath any has_and_belongs_to_many declaration in order to work.

+
:foreign_key +
+

Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and “_id” suffixed. So a Person class that makes a has_and_belongs_to_many association to Project will use “person_id” as the default :foreign_key.

+ +

If you are going to modify the association (rather than just read from it), then it is a good idea to set the :inverse_of option.

+
:association_foreign_key +
+

Specify the foreign key used for the association on the receiving side of the association. By default this is guessed to be the name of the associated class in lower-case and “_id” suffixed. So if a Person class makes a has_and_belongs_to_many association to Project, the association will use “project_id” as the default :association_foreign_key.

+
:validate +
+

When set to true, validates new objects added to association when saving the parent object. true by default. If you want to ensure associated objects are revalidated on every update, use validates_associated.

+
:autosave +
+

If true, always save the associated objects or destroy them if marked for destruction, when saving the parent object. If false, never save or destroy the associated objects. By default, only save associated objects that are new records.

+ +

Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets :autosave to true.

+
+ +

Option examples:

+ +
has_and_belongs_to_many :projects
+has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
+has_and_belongs_to_many :nations, class_name: "Country"
+has_and_belongs_to_many :categories, join_table: "prods_cats"
+has_and_belongs_to_many :categories, -> { readonly }
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations.rb, line 1821
+        def has_and_belongs_to_many(name, scope = nil, **options, &extension)
+          habtm_reflection = ActiveRecord::Reflection::HasAndBelongsToManyReflection.new(name, scope, options, self)
+
+          builder = Builder::HasAndBelongsToMany.new name, self, options
+
+          join_model = builder.through_model
+
+          const_set join_model.name, join_model
+          private_constant join_model.name
+
+          middle_reflection = builder.middle_reflection join_model
+
+          Builder::HasMany.define_callbacks self, middle_reflection
+          Reflection.add_reflection self, middle_reflection.name, middle_reflection
+          middle_reflection.parent_reflection = habtm_reflection
+
+          include Module.new {
+            class_eval <<-RUBY, __FILE__, __LINE__ + 1
+              def destroy_associations
+                association(:#{middle_reflection.name}).delete_all(:delete_all)
+                association(:#{name}).reset
+                super
+              end
+            RUBY
+          }
+
+          hm_options = {}
+          hm_options[:through] = middle_reflection.name
+          hm_options[:source] = join_model.right_reflection.name
+
+          [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
+            hm_options[k] = options[k] if options.key? k
+          end
+
+          has_many name, scope, hm_options, &extension
+          _reflections[name.to_s].parent_reflection = habtm_reflection
+        end
+
+
+ +
+ +
+

+ + has_many(name, scope = nil, **options, &extension) + +

+ + +
+

Specifies a one-to-many association. The following methods for retrieval and query of collections of associated objects will be added:

+ +

collection is a placeholder for the symbol passed as the name argument, so has_many :clients would add among others clients.empty?.

+
collection +
+

Returns a Relation of all the associated objects. An empty Relation is returned if none are found.

+
collection<<(object, …) +
+

Adds one or more objects to the collection by setting their foreign keys to the collection's primary key. Note that this operation instantly fires update SQL without waiting for the save or update call on the parent object, unless the parent object is a new record. This will also run validations and callbacks of associated object(s).

+
collection.delete(object, …) +
+

Removes one or more objects from the collection by setting their foreign keys to NULL. Objects will be in addition destroyed if they're associated with dependent: :destroy, and deleted if they're associated with dependent: :delete_all.

+ +

If the :through option is used, then the join records are deleted (rather than nullified) by default, but you can specify dependent: :destroy or dependent: :nullify to override this.

+
collection.destroy(object, …) +
+

Removes one or more objects from the collection by running destroy on each record, regardless of any dependent option, ensuring callbacks are run.

+ +

If the :through option is used, then the join records are destroyed instead, not the objects themselves.

+
collection=objects +
+

Replaces the collections content by deleting and adding objects as appropriate. If the :through option is true callbacks in the join models are triggered except destroy callbacks, since deletion is direct by default. You can specify dependent: :destroy or dependent: :nullify to override this.

+
collection_singular_ids +
+

Returns an array of the associated objects' ids

+
collection_singular_ids=ids +
+

Replace the collection with the objects identified by the primary keys in ids. This method loads the models and calls collection=. See above.

+
collection.clear +
+

Removes every object from the collection. This destroys the associated objects if they are associated with dependent: :destroy, deletes them directly from the database if dependent: :delete_all, otherwise sets their foreign keys to NULL. If the :through option is true no destroy callbacks are invoked on the join models. Join models are directly deleted.

+
collection.empty? +
+

Returns true if there are no associated objects.

+
collection.size +
+

Returns the number of associated objects.

+
collection.find(…) +
+

Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.

+
collection.exists?(…) +
+

Checks whether an associated object with the given conditions exists. Uses the same rules as ActiveRecord::FinderMethods#exists?.

+
collection.build(attributes = {}, …) +
+

Returns one or more new objects of the collection type that have been instantiated with attributes and linked to this object through a foreign key, but have not yet been saved.

+
collection.create(attributes = {}) +
+

Returns a new object of the collection type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation). Note: This only works if the base model already exists in the DB, not if it is a new (unsaved) record!

+
collection.create!(attributes = {}) +
+

Does the same as collection.create, but raises ActiveRecord::RecordInvalid if the record is invalid.

+
collection.reload +
+

Returns a Relation of all of the associated objects, forcing a database read. An empty Relation is returned if none are found.

+
+ +

Example

+ +

A Firm class declares has_many :clients, which will add:

+
  • +

    Firm#clients (similar to Client.where(firm_id: id))

    +
  • +

    Firm#clients<<

    +
  • +

    Firm#clients.delete

    +
  • +

    Firm#clients.destroy

    +
  • +

    Firm#clients=

    +
  • +

    Firm#client_ids

    +
  • +

    Firm#client_ids=

    +
  • +

    Firm#clients.clear

    +
  • +

    Firm#clients.empty? (similar to firm.clients.size == 0)

    +
  • +

    Firm#clients.size (similar to Client.count "firm_id = #{id}")

    +
  • +

    Firm#clients.find (similar to Client.where(firm_id: id).find(id))

    +
  • +

    Firm#clients.exists?(name: 'ACME') (similar to Client.exists?(name: 'ACME', firm_id: firm.id))

    +
  • +

    Firm#clients.build (similar to Client.new(firm_id: id))

    +
  • +

    Firm#clients.create (similar to c = Client.new(firm_id: id); c.save; c)

    +
  • +

    Firm#clients.create! (similar to c = Client.new(firm_id: id); c.save!)

    +
  • +

    Firm#clients.reload

    +
+ +

The declaration can also include an options hash to specialize the behavior of the association.

+ +

Scopes

+ +

You can pass a second argument scope as a callable (i.e. proc or lambda) to retrieve a specific set of records or customize the generated query when you access the associated collection.

+ +

Scope examples:

+ +
has_many :comments, -> { where(author_id: 1) }
+has_many :employees, -> { joins(:address) }
+has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
+
+ +

Extensions

+ +

The extension argument allows you to pass a block into a has_many association. This is useful for adding new finders, creators and other factory-type methods to be used as part of the association.

+ +

Extension examples:

+ +
has_many :employees do
+  def find_or_create_by_name(name)
+    first_name, last_name = name.split(" ", 2)
+    find_or_create_by(first_name: first_name, last_name: last_name)
+  end
+end
+
+ +

Options

+
:class_name +
+

Specify the class name of the association. Use it only if that name can't be inferred from the association name. So has_many :products will by default be linked to the Product class, but if the real class name is SpecialProduct, you'll have to specify it with this option.

+
:foreign_key +
+

Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and “_id” suffixed. So a Person class that makes a has_many association will use “person_id” as the default :foreign_key.

+ +

If you are going to modify the association (rather than just read from it), then it is a good idea to set the :inverse_of option.

+
:foreign_type +
+

Specify the column used to store the associated object's type, if this is a polymorphic association. By default this is guessed to be the name of the polymorphic association specified on “as” option with a “_type” suffix. So a class that defines a has_many :tags, as: :taggable association will use “taggable_type” as the default :foreign_type.

+
:primary_key +
+

Specify the name of the column to use as the primary key for the association. By default this is id.

+
:dependent +
+

Controls what happens to the associated objects when their owner is destroyed. Note that these are implemented as callbacks, and Rails executes callbacks in order. Therefore, other similar callbacks may affect the :dependent behavior, and the :dependent behavior may affect other callbacks.

+
  • +

    :destroy causes all the associated objects to also be destroyed.

    +
  • +

    :delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).

    +
  • +

    :nullify causes the foreign keys to be set to NULL. Callbacks are not executed.

    +
  • +

    :restrict_with_exception causes an exception to be raised if there are any associated records.

    +
  • +

    :restrict_with_error causes an error to be added to the owner if there are any associated objects.

    +
+ +

If using with the :through option, the association on the join model must be a belongs_to, and the records which get deleted are the join records, rather than the associated records.

+ +

If using dependent: :destroy on a scoped association, only the scoped objects are destroyed. For example, if a Post model defines has_many :comments, -> { where published: true }, dependent: :destroy and destroy is called on a post, only published comments are destroyed. This means that any unpublished comments in the database would still contain a foreign key pointing to the now deleted post.

+
:counter_cache +
+

This option can be used to configure a custom named :counter_cache. You only need this option, when you customized the name of your :counter_cache on the belongs_to association.

+
:as +
+

Specifies a polymorphic interface (See belongs_to).

+
:through +
+

Specifies an association through which to perform the query. This can be any other type of association, including other :through associations. Options for :class_name, :primary_key and :foreign_key are ignored, as the association uses the source reflection.

+ +

If the association on the join model is a belongs_to, the collection can be modified and the records on the :through model will be automatically created and removed as appropriate. Otherwise, the collection is read-only, so you should manipulate the :through association directly.

+ +

If you are going to modify the association (rather than just read from it), then it is a good idea to set the :inverse_of option on the source association on the join model. This allows associated records to be built which will automatically create the appropriate join model records when they are saved. (See the 'Association Join Models' section above.)

+
:source +
+

Specifies the source association name used by has_many :through queries. Only use it if the name cannot be inferred from the association. has_many :subscribers, through: :subscriptions will look for either :subscribers or :subscriber on Subscription, unless a :source is given.

+
:source_type +
+

Specifies type of the source association used by has_many :through queries where the source association is a polymorphic belongs_to.

+
:validate +
+

When set to true, validates new objects added to association when saving the parent object. true by default. If you want to ensure associated objects are revalidated on every update, use validates_associated.

+
:autosave +
+

If true, always save the associated objects or destroy them if marked for destruction, when saving the parent object. If false, never save or destroy the associated objects. By default, only save associated objects that are new records. This option is implemented as a before_save callback. Because callbacks are run in the order they are defined, associated objects may need to be explicitly saved in any user-defined before_save callbacks.

+ +

Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets :autosave to true.

+
:inverse_of +
+

Specifies the name of the belongs_to association on the associated object that is the inverse of this has_many association. See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.

+
:extend +
+

Specifies a module or array of modules that will be extended into the association object returned. Useful for defining methods on associations, especially when they should be shared between multiple association objects.

+
+ +

Option examples:

+ +
has_many :comments, -> { order("posted_on") }
+has_many :comments, -> { includes(:author) }
+has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person"
+has_many :tracks, -> { order("position") }, dependent: :destroy
+has_many :comments, dependent: :nullify
+has_many :tags, as: :taggable
+has_many :reports, -> { readonly }
+has_many :subscribers, through: :subscriptions, source: :user
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations.rb, line 1368
+def has_many(name, scope = nil, **options, &extension)
+  reflection = Builder::HasMany.build(self, name, scope, options, &extension)
+  Reflection.add_reflection self, name, reflection
+end
+
+
+ +
+ +
+

+ + has_one(name, scope = nil, **options) + +

+ + +
+

Specifies a one-to-one association with another class. This method should only be used if the other class contains the foreign key. If the current class contains the foreign key, then you should use belongs_to instead. See also ActiveRecord::Associations::ClassMethods's overview on when to use has_one and when to use belongs_to.

+ +

The following methods for retrieval and query of a single associated object will be added:

+ +

association is a placeholder for the symbol passed as the name argument, so has_one :manager would add among others manager.nil?.

+
association +
+

Returns the associated object. nil is returned if none is found.

+
association=(associate) +
+

Assigns the associate object, extracts the primary key, sets it as the foreign key, and saves the associate object. To avoid database inconsistencies, permanently deletes an existing associated object when assigning a new one, even if the new one isn't saved to database.

+
build_association(attributes = {}) +
+

Returns a new object of the associated type that has been instantiated with attributes and linked to this object through a foreign key, but has not yet been saved.

+
create_association(attributes = {}) +
+

Returns a new object of the associated type that has been instantiated with attributes, linked to this object through a foreign key, and that has already been saved (if it passed the validation).

+
create_association!(attributes = {}) +
+

Does the same as create_association, but raises ActiveRecord::RecordInvalid if the record is invalid.

+
reload_association +
+

Returns the associated object, forcing a database read.

+
+ +

Example

+ +

An Account class declares has_one :beneficiary, which will add:

+
  • +

    Account#beneficiary (similar to Beneficiary.where(account_id: id).first)

    +
  • +

    Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save)

    +
  • +

    Account#build_beneficiary (similar to Beneficiary.new(account_id: id))

    +
  • +

    Account#create_beneficiary (similar to b = Beneficiary.new(account_id: id); b.save; b)

    +
  • +

    Account#create_beneficiary! (similar to b = Beneficiary.new(account_id: id); b.save!; b)

    +
  • +

    Account#reload_beneficiary

    +
+ +

Scopes

+ +

You can pass a second argument scope as a callable (i.e. proc or lambda) to retrieve a specific record or customize the generated query when you access the associated object.

+ +

Scope examples:

+ +
has_one :author, -> { where(comment_id: 1) }
+has_one :employer, -> { joins(:company) }
+has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
+
+ +

Options

+ +

The declaration can also include an options hash to specialize the behavior of the association.

+ +

Options are:

+
:class_name +
+

Specify the class name of the association. Use it only if that name can't be inferred from the association name. So has_one :manager will by default be linked to the Manager class, but if the real class name is Person, you'll have to specify it with this option.

+
:dependent +
+

Controls what happens to the associated object when its owner is destroyed:

+
  • +

    :destroy causes the associated object to also be destroyed

    +
  • +

    :delete causes the associated object to be deleted directly from the database (so callbacks will not execute)

    +
  • +

    :nullify causes the foreign key to be set to NULL. Callbacks are not executed.

    +
  • +

    :restrict_with_exception causes an exception to be raised if there is an associated record

    +
  • +

    :restrict_with_error causes an error to be added to the owner if there is an associated object

    +
+ +

Note that :dependent option is ignored when using :through option.

+
:foreign_key +
+

Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and “_id” suffixed. So a Person class that makes a has_one association will use “person_id” as the default :foreign_key.

+ +

If you are going to modify the association (rather than just read from it), then it is a good idea to set the :inverse_of option.

+
:foreign_type +
+

Specify the column used to store the associated object's type, if this is a polymorphic association. By default this is guessed to be the name of the polymorphic association specified on “as” option with a “_type” suffix. So a class that defines a has_one :tag, as: :taggable association will use “taggable_type” as the default :foreign_type.

+
:primary_key +
+

Specify the method that returns the primary key used for the association. By default this is id.

+
:as +
+

Specifies a polymorphic interface (See belongs_to).

+
:through +
+

Specifies a Join Model through which to perform the query. Options for :class_name, :primary_key, and :foreign_key are ignored, as the association uses the source reflection. You can only use a :through query through a has_one or belongs_to association on the join model.

+ +

If you are going to modify the association (rather than just read from it), then it is a good idea to set the :inverse_of option.

+
:source +
+

Specifies the source association name used by has_one :through queries. Only use it if the name cannot be inferred from the association. has_one :favorite, through: :favorites will look for a :favorite on Favorite, unless a :source is given.

+
:source_type +
+

Specifies type of the source association used by has_one :through queries where the source association is a polymorphic belongs_to.

+
:validate +
+

When set to true, validates new objects added to association when saving the parent object. false by default. If you want to ensure associated objects are revalidated on every update, use validates_associated.

+
:autosave +
+

If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. If false, never save or destroy the associated object. By default, only save the associated object if it's a new record.

+ +

Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets :autosave to true.

+
:inverse_of +
+

Specifies the name of the belongs_to association on the associated object that is the inverse of this has_one association. See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.

+
:required +
+

When set to true, the association will also have its presence validated. This will validate the association itself, not the id. You can use :inverse_of to avoid an extra query during validation.

+
+ +

Option examples:

+ +
has_one :credit_card, dependent: :destroy  # destroys the associated credit card
+has_one :credit_card, dependent: :nullify  # updates the associated records foreign
+                                              # key value to NULL rather than destroying it
+has_one :last_comment, -> { order('posted_on') }, class_name: "Comment"
+has_one :project_manager, -> { where(role: 'project_manager') }, class_name: "Person"
+has_one :attachment, as: :attachable
+has_one :boss, -> { readonly }
+has_one :club, through: :membership
+has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
+has_one :credit_card, required: true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations.rb, line 1507
+def has_one(name, scope = nil, **options)
+  reflection = Builder::HasOne.build(self, name, scope, options)
+  Reflection.add_reflection self, name, reflection
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Associations/CollectionProxy.html b/src/5.2/classes/ActiveRecord/Associations/CollectionProxy.html new file mode 100644 index 0000000000..70b08c8a97 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Associations/CollectionProxy.html @@ -0,0 +1,2527 @@ +--- +title: ActiveRecord::Associations::CollectionProxy +layout: default +--- +
+ +
+
+ +
+ +

Association proxies in Active Record are middlemen between the object that holds the association, known as the @owner, and the actual associated object, known as the @target. The kind of association any proxy is about is available in @reflection. That's an instance of the class ActiveRecord::Reflection::AssociationReflection.

+ +

For example, given

+ +
class Blog < ActiveRecord::Base
+  has_many :posts
+end
+
+blog = Blog.first
+
+ +

the association proxy in blog.posts has the object in blog as @owner, the collection of its posts as @target, and the @reflection object represents a :has_many macro.

+ +

This class delegates unknown methods to @target via method_missing.

+ +

The @target object is not loaded until needed. For example,

+ +
blog.posts.count
+
+ +

is computed directly through SQL and does not trigger by itself the instantiation of the actual post records.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + <<(*records) + +

+ + +
+

Adds one or more records to the collection by setting their foreign keys to the association's primary key. Since +<<+ flattens its argument list and inserts each record, push and concat behave identically. Returns self so several appends may be chained together.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.size # => 0
+person.pets << Pet.new(name: 'Fancy-Fancy')
+person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')]
+person.pets.size # => 3
+
+person.id # => 1
+person.pets
+# => [
+#      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#      #<Pet id: 2, name: "Spook", person_id: 1>,
+#      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+
+ + + +
+ Also aliased as: push, append, concat +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1028
+def <<(*records)
+  proxy_association.concat(records) && self
+end
+
+
+ +
+ +
+

+ + ==(other) + +

+ + +
+

Equivalent to Array#==. Returns true if the two arrays contain the same number of elements and if each element is equal to the corresponding element in the other array, otherwise returns false.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets
+# => [
+#      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#      #<Pet id: 2, name: "Spook", person_id: 1>
+#    ]
+
+other = person.pets.to_ary
+
+person.pets == other
+# => true
+
+other = [Pet.new(id: 1), Pet.new(id: 2)]
+
+person.pets == other
+# => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 959
+def ==(other)
+  load_target == other
+end
+
+
+ +
+ +
+

+ + any?() + + +

+ + +
+

Returns true if the collection is not empty.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.count # => 0
+person.pets.any?  # => false
+
+person.pets << Pet.new(name: 'Snoop')
+person.pets.count # => 1
+person.pets.any?  # => true
+
+ +

You can also pass a block to define criteria. The behavior is the same, it returns true if the collection based on the criteria is not empty.

+ +
person.pets
+# => [#<Pet name: "Snoop", group: "dogs">]
+
+person.pets.any? do |pet|
+  pet.group == 'cats'
+end
+# => false
+
+person.pets.any? do |pet|
+  pet.group == 'dogs'
+end
+# => true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 836
+      
+
+
+ +
+ +
+

+ + append(*records) + +

+ + +
+ +
+ + + + + +
+ Alias for: << +
+ + + +
+ +
+

+ + build(attributes = {}, &block) + +

+ + +
+

Returns a new object of the collection type that has been instantiated with attributes and linked to this object, but have not yet been saved. You can pass an array of attributes hashes, this will return an array with the new objects.

+ +
class Person
+  has_many :pets
+end
+
+person.pets.build
+# => #<Pet id: nil, name: nil, person_id: 1>
+
+person.pets.build(name: 'Fancy-Fancy')
+# => #<Pet id: nil, name: "Fancy-Fancy", person_id: 1>
+
+person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])
+# => [
+#      #<Pet id: nil, name: "Spook", person_id: 1>,
+#      #<Pet id: nil, name: "Choo-Choo", person_id: 1>,
+#      #<Pet id: nil, name: "Brain", person_id: 1>
+#    ]
+
+person.pets.size  # => 5 # size of the collection
+person.pets.count # => 0 # count from database
+
+
+ + + +
+ Also aliased as: new +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 318
+def build(attributes = {}, &block)
+  @association.build(attributes, &block)
+end
+
+
+ +
+ +
+

+ + calculate(operation, column_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 724
+def calculate(operation, column_name)
+  null_scope? ? scope.calculate(operation, column_name) : super
+end
+
+
+ +
+ +
+

+ + clear() + +

+ + +
+

Equivalent to delete_all. The difference is that returns self, instead of an array with the deleted objects, so methods can be chained. See delete_all for more information. Note that because delete_all removes records by directly running an SQL query into the database, the updated_at column of the object is not changed.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1045
+def clear
+  delete_all
+  self
+end
+
+
+ +
+ +
+

+ + concat(*records) + +

+ + +
+ +
+ + + + + +
+ Alias for: << +
+ + + +
+ +
+

+ + count(column_name = nil, &block) + + +

+ + +
+

Count all records.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+# This will perform the count using SQL.
+person.pets.count # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+ +

Passing a block will select all of a person's pets in SQL and then perform the count using Ruby.

+ +
person.pets.count { |pet| pet.name.include?('-') } # => 2
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 733
+      
+
+
+ +
+ +
+

+ + create(attributes = {}, &block) + +

+ + +
+

Returns a new object of the collection type that has been instantiated with attributes, linked to this object and that has already been saved (if it passes the validations).

+ +
class Person
+  has_many :pets
+end
+
+person.pets.create(name: 'Fancy-Fancy')
+# => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
+
+person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])
+# => [
+#      #<Pet id: 2, name: "Spook", person_id: 1>,
+#      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.size  # => 3
+person.pets.count # => 3
+
+person.pets.find(1, 2, 3)
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 349
+def create(attributes = {}, &block)
+  @association.create(attributes, &block)
+end
+
+
+ +
+ +
+

+ + create!(attributes = {}, &block) + +

+ + +
+

Like create, except that if the record is invalid, raises an exception.

+ +
class Person
+  has_many :pets
+end
+
+class Pet
+  validates :name, presence: true
+end
+
+person.pets.create!(name: nil)
+# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 365
+def create!(attributes = {}, &block)
+  @association.create!(attributes, &block)
+end
+
+
+ +
+ +
+

+ + delete(*records) + +

+ + +
+

Deletes the records supplied from the collection according to the strategy specified by the :dependent option. If no :dependent option is given, then it will follow the default strategy. Returns an array with the deleted records.

+ +

For has_many :through associations, the default deletion strategy is :delete_all.

+ +

For has_many associations, the default deletion strategy is :nullify. This sets the foreign keys to NULL.

+ +
class Person < ActiveRecord::Base
+  has_many :pets # dependent: :nullify option by default
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.delete(Pet.find(1))
+# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
+
+person.pets.size # => 2
+person.pets
+# => [
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+Pet.find(1)
+# => #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>
+
+ +

If it is set to :destroy all the records are removed by calling their destroy method. See destroy for more information.

+ +
class Person < ActiveRecord::Base
+  has_many :pets, dependent: :destroy
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.delete(Pet.find(1), Pet.find(3))
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.size # => 1
+person.pets
+# => [#<Pet id: 2, name: "Spook", person_id: 1>]
+
+Pet.find(1, 3)
+# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
+
+ +

If it is set to :delete_all, all the records are deleted without calling their destroy method.

+ +
class Person < ActiveRecord::Base
+  has_many :pets, dependent: :delete_all
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.delete(Pet.find(1))
+# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
+
+person.pets.size # => 2
+person.pets
+# => [
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+Pet.find(1)
+# => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
+
+ +

You can pass Integer or String values, it finds the records responding to the id and executes delete on them.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.delete("1")
+# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
+
+person.pets.delete(2, 3)
+# => [
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 620
+def delete(*records)
+  @association.delete(*records).tap { reset_scope }
+end
+
+
+ +
+ +
+

+ + delete_all(dependent = nil) + +

+ + +
+

Deletes all the records from the collection according to the strategy specified by the :dependent option. If no :dependent option is given, then it will follow the default strategy.

+ +

For has_many :through associations, the default deletion strategy is :delete_all.

+ +

For has_many associations, the default deletion strategy is :nullify. This sets the foreign keys to NULL.

+ +
class Person < ActiveRecord::Base
+  has_many :pets # dependent: :nullify option by default
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.delete_all
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.size # => 0
+person.pets      # => []
+
+Pet.find(1, 2, 3)
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>,
+#       #<Pet id: 2, name: "Spook", person_id: nil>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: nil>
+#    ]
+
+ +

Both has_many and has_many :through dependencies default to the :delete_all strategy if the :dependent option is set to :destroy. Records are not instantiated and callbacks will not be fired.

+ +
class Person < ActiveRecord::Base
+  has_many :pets, dependent: :destroy
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.delete_all
+
+Pet.find(1, 2, 3)
+# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
+
+ +

If it is set to :delete_all, all the objects are deleted without calling their destroy method.

+ +
class Person < ActiveRecord::Base
+  has_many :pets, dependent: :delete_all
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.delete_all
+
+Pet.find(1, 2, 3)
+# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 474
+def delete_all(dependent = nil)
+  @association.delete_all(dependent).tap { reset_scope }
+end
+
+
+ +
+ +
+

+ + destroy(*records) + +

+ + +
+

Destroys the records supplied and removes them from the collection. This method will always remove record from the database ignoring the :dependent option. Returns an array with the removed records.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.destroy(Pet.find(1))
+# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
+
+person.pets.size # => 2
+person.pets
+# => [
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.destroy(Pet.find(2), Pet.find(3))
+# => [
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.size  # => 0
+person.pets       # => []
+
+Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
+
+ +

You can pass Integer or String values, it finds the records responding to the id and then deletes them from the database.

+ +
person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 4, name: "Benny", person_id: 1>,
+#       #<Pet id: 5, name: "Brain", person_id: 1>,
+#       #<Pet id: 6, name: "Boss",  person_id: 1>
+#    ]
+
+person.pets.destroy("4")
+# => #<Pet id: 4, name: "Benny", person_id: 1>
+
+person.pets.size # => 2
+person.pets
+# => [
+#       #<Pet id: 5, name: "Brain", person_id: 1>,
+#       #<Pet id: 6, name: "Boss",  person_id: 1>
+#    ]
+
+person.pets.destroy(5, 6)
+# => [
+#       #<Pet id: 5, name: "Brain", person_id: 1>,
+#       #<Pet id: 6, name: "Boss",  person_id: 1>
+#    ]
+
+person.pets.size  # => 0
+person.pets       # => []
+
+Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 692
+def destroy(*records)
+  @association.destroy(*records).tap { reset_scope }
+end
+
+
+ +
+ +
+

+ + destroy_all() + +

+ + +
+

Deletes the records of the collection directly from the database ignoring the :dependent option. Records are instantiated and it invokes before_remove, after_remove , before_destroy and after_destroy callbacks.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.size # => 3
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.destroy_all
+
+person.pets.size # => 0
+person.pets      # => []
+
+Pet.find(1) # => Couldn't find Pet with id=1
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 501
+def destroy_all
+  @association.destroy_all.tap { reset_scope }
+end
+
+
+ +
+ +
+

+ + distinct(value = true) + + +

+ + +
+

Specifies whether the records should be unique or not.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.select(:name)
+# => [
+#      #<Pet name: "Fancy-Fancy">,
+#      #<Pet name: "Fancy-Fancy">
+#    ]
+
+person.pets.select(:name).distinct
+# => [#<Pet name: "Fancy-Fancy">]
+
+person.pets.select(:name).distinct.distinct(false)
+# => [
+#      #<Pet name: "Fancy-Fancy">,
+#      #<Pet name: "Fancy-Fancy">
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 697
+      
+
+
+ +
+ +
+

+ + empty?() + +

+ + +
+

Returns true if the collection is empty. If the collection has been loaded it is equivalent to collection.size.zero?. If the collection has not been loaded, it is equivalent to !collection.exists?. If the collection has not already been loaded and you are going to fetch the records anyway it is better to check collection.length.zero?.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.count  # => 1
+person.pets.empty? # => false
+
+person.pets.delete_all
+
+person.pets.count  # => 0
+person.pets.empty? # => true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 831
+def empty?
+  @association.empty?
+end
+
+
+ +
+ +
+

+ + fifth() + + +

+ + +
+

Same as first except returns only the fifth record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 201
+      
+
+
+ +
+ +
+

+ + find(*args) + +

+ + +
+

Finds an object in the collection responding to the id. Uses the same rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound error if the object cannot be found.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
+person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
+
+person.pets.find(2) { |pet| pet.name.downcase! }
+# => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
+
+person.pets.find(2, 3)
+# => [
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 138
+def find(*args)
+  return super if block_given?
+  @association.find(*args)
+end
+
+
+ +
+ +
+

+ + first(limit = nil) + + +

+ + +
+

Returns the first record, or the first n records, from the collection. If the collection is empty, the first form returns nil, and the second form returns an empty array.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.first # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
+
+person.pets.first(2)
+# => [
+#      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#      #<Pet id: 2, name: "Spook", person_id: 1>
+#    ]
+
+another_person_without.pets          # => []
+another_person_without.pets.first    # => nil
+another_person_without.pets.first(3) # => []
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 144
+      
+
+
+ +
+ +
+

+ + forty_two() + + +

+ + +
+

Same as first except returns only the forty second record. Also known as accessing “the reddit”.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 209
+      
+
+
+ +
+ +
+

+ + fourth() + + +

+ + +
+

Same as first except returns only the fourth record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 193
+      
+
+
+ +
+ +
+

+ + include?(record) + +

+ + +
+

Returns true if the given record is present in the collection.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets # => [#<Pet id: 20, name: "Snoop">]
+
+person.pets.include?(Pet.find(20)) # => true
+person.pets.include?(Pet.find(21)) # => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 922
+def include?(record)
+  !!@association.include?(record)
+end
+
+
+ +
+ +
+

+ + last(limit = nil) + +

+ + +
+

Returns the last record, or the last n records, from the collection. If the collection is empty, the first form returns nil, and the second form returns an empty array.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.last # => #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+
+person.pets.last(2)
+# => [
+#      #<Pet id: 2, name: "Spook", person_id: 1>,
+#      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+another_person_without.pets         # => []
+another_person_without.pets.last    # => nil
+another_person_without.pets.last(3) # => []
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 259
+def last(limit = nil)
+  load_target if find_from_target?
+  super
+end
+
+
+ +
+ +
+

+ + length() + + +

+ + +
+

Returns the size of the collection calling size on the target. If the collection has been already loaded, length and size are equivalent. If not and you are going to need the records anyway this method will take one less query. Otherwise size is more efficient.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.length # => 3
+# executes something like SELECT "pets".* FROM "pets" WHERE "pets"."person_id" = 1
+
+# Because the collection is loaded, you can
+# call the collection with no additional queries:
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 787
+      
+
+
+ +
+ +
+

+ + load_target() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 45
+def load_target
+  @association.load_target
+end
+
+
+ +
+ +
+

+ + loaded?() + +

+ + +
+

Returns true if the association has been loaded, otherwise false.

+ +
person.pets.loaded? # => false
+person.pets
+person.pets.loaded? # => true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 54
+def loaded?
+  @association.loaded?
+end
+
+
+ +
+ +
+

+ + many?() + + +

+ + +
+

Returns true if the collection has more than one record. Equivalent to collection.size > 1.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.count # => 1
+person.pets.many? # => false
+
+person.pets << Pet.new(name: 'Snoopy')
+person.pets.count # => 2
+person.pets.many? # => true
+
+ +

You can also pass a block to define criteria. The behavior is the same, it returns true if the collection based on the criteria has more than one record.

+ +
person.pets
+# => [
+#      #<Pet name: "Gorby", group: "cats">,
+#      #<Pet name: "Puff", group: "cats">,
+#      #<Pet name: "Snoop", group: "dogs">
+#    ]
+
+person.pets.many? do |pet|
+  pet.group == 'dogs'
+end
+# => false
+
+person.pets.many? do |pet|
+  pet.group == 'cats'
+end
+# => true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 872
+      
+
+
+ +
+ +
+

+ + new(attributes = {}, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: build +
+ + + +
+ +
+

+ + pluck(*column_names) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 728
+def pluck(*column_names)
+  null_scope? ? scope.pluck(*column_names) : super
+end
+
+
+ +
+ +
+

+ + prepend(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1035
+def prepend(*args)
+  raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
+end
+
+
+ +
+ +
+

+ + proxy_association() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 926
+def proxy_association
+  @association
+end
+
+
+ +
+ +
+

+ + push(*records) + +

+ + +
+ +
+ + + + + +
+ Alias for: << +
+ + + +
+ +
+

+ + reload() + +

+ + +
+

Reloads the collection from the database. Returns self.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets # fetches pets from the database
+# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
+
+person.pets # uses the pets cache
+# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
+
+person.pets.reload # fetches pets from the database
+# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1064
+def reload
+  proxy_association.reload
+  reset_scope
+end
+
+
+ +
+ +
+

+ + replace(other_array) + +

+ + +
+

Replaces this collection with other_array. This will perform a diff and delete/add only records that have changed.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets
+# => [#<Pet id: 1, name: "Gorby", group: "cats", person_id: 1>]
+
+other_pets = [Pet.new(name: 'Puff', group: 'celebrities']
+
+person.pets.replace(other_pets)
+
+person.pets
+# => [#<Pet id: 2, name: "Puff", group: "celebrities", person_id: 1>]
+
+ +

If the supplied array has an incorrect association type, it raises an ActiveRecord::AssociationTypeMismatch error:

+ +
person.pets.replace(["doo", "ggie", "gaga"])
+# => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 391
+def replace(other_array)
+  @association.replace(other_array)
+end
+
+
+ +
+ +
+

+ + reset() + +

+ + +
+

Unloads the association. Returns self.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets # fetches pets from the database
+# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
+
+person.pets # uses the pets cache
+# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
+
+person.pets.reset # clears the pets cache
+
+person.pets  # fetches pets from the database
+# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1085
+def reset
+  proxy_association.reset
+  proxy_association.reset_scope
+  reset_scope
+end
+
+
+ +
+ +
+

+ + scope() + +

+ + +
+

Returns a Relation object for the records in this association

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 931
+def scope
+  @scope ||= @association.scope
+end
+
+
+ +
+ +
+

+ + second() + + +

+ + +
+

Same as first except returns only the second record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 177
+      
+
+
+ +
+ +
+

+ + second_to_last() + + +

+ + +
+

Same as first except returns only the second-to-last record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 226
+      
+
+
+ +
+ +
+

+ + select(*fields, &block) + + +

+ + +
+

Works in two ways.

+ +

First: Specify a subset of fields to be selected from the result set.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.select(:name)
+# => [
+#      #<Pet id: nil, name: "Fancy-Fancy">,
+#      #<Pet id: nil, name: "Spook">,
+#      #<Pet id: nil, name: "Choo-Choo">
+#    ]
+
+person.pets.select(:id, :name)
+# => [
+#      #<Pet id: 1, name: "Fancy-Fancy">,
+#      #<Pet id: 2, name: "Spook">,
+#      #<Pet id: 3, name: "Choo-Choo">
+#    ]
+
+ +

Be careful because this also means you're initializing a model object with only the fields that you've selected. If you attempt to access a field except id that is not in the initialized record you'll receive:

+ +
person.pets.select(:name).first.person_id
+# => ActiveModel::MissingAttributeError: missing attribute: person_id
+
+ +

Second: You can pass a block so it can be used just like Array#select. This builds an array of objects from the database for the scope, converting them into an array and iterating through them using Array#select.

+ +
person.pets.select { |pet| pet.name =~ /oo/ }
+# => [
+#      #<Pet id: 2, name: "Spook", person_id: 1>,
+#      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 59
+      
+
+
+ +
+ +
+

+ + size() + +

+ + +
+

Returns the size of the collection. If the collection hasn't been loaded, it executes a SELECT COUNT(*) query. Else it calls collection.size.

+ +

If the collection has been already loaded size and length are equivalent. If not and you are going to need the records anyway length will take one less query. Otherwise size is more efficient.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.size # => 3
+# executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1
+
+person.pets # This will execute a SELECT * FROM query
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.size # => 3
+# Because the collection is already loaded, this will behave like
+# collection.size and no SQL count query is executed.
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 782
+def size
+  @association.size
+end
+
+
+ +
+ +
+

+ + take(limit = nil) + +

+ + +
+

Gives a record (or N records if a parameter is supplied) from the collection using the same rules as ActiveRecord::Base.take.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets
+# => [
+#       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#       #<Pet id: 2, name: "Spook", person_id: 1>,
+#       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
+
+person.pets.take(2)
+# => [
+#      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
+#      #<Pet id: 2, name: "Spook", person_id: 1>
+#    ]
+
+another_person_without.pets         # => []
+another_person_without.pets.take    # => nil
+another_person_without.pets.take(2) # => []
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 289
+def take(limit = nil)
+  load_target if find_from_target?
+  super
+end
+
+
+ +
+ +
+

+ + target() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 41
+def target
+  @association.target
+end
+
+
+ +
+ +
+

+ + third() + + +

+ + +
+

Same as first except returns only the third record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 185
+      
+
+
+ +
+ +
+

+ + third_to_last() + + +

+ + +
+

Same as first except returns only the third-to-last record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 218
+      
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeAssignment.html b/src/5.2/classes/ActiveRecord/AttributeAssignment.html new file mode 100644 index 0000000000..022c7ba0d6 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeAssignment.html @@ -0,0 +1,68 @@ +--- +title: ActiveRecord::AttributeAssignment +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeAssignmentError.html b/src/5.2/classes/ActiveRecord/AttributeAssignmentError.html new file mode 100644 index 0000000000..3f5591a3e9 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeAssignmentError.html @@ -0,0 +1,137 @@ +--- +title: ActiveRecord::AttributeAssignmentError +layout: default +--- +
+ +
+
+ +
+ +

Raised when an error occurred while doing a mass assignment to an attribute through the ActiveRecord::Base#attributes= method. The exception has an attribute property that is the name of the offending attribute.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + attribute
+ [R] + exception
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, exception = nil, attribute = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 260
+def initialize(message = nil, exception = nil, attribute = nil)
+  super(message)
+  @exception = exception
+  @attribute = attribute
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods.html b/src/5.2/classes/ActiveRecord/AttributeMethods.html new file mode 100644 index 0000000000..414c6929fb --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods.html @@ -0,0 +1,723 @@ +--- +title: ActiveRecord::AttributeMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
AttrNames=Module.new { +def self.set_name_cache(name, value) +const_name = "ATTR_#{name}" +unless const_defined? const_name +const_set const_name, value.dup.freeze +end +end +}
 
BLACKLISTED_CLASS_METHODS=%w(private public protected allocate new name parent superclass)
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + [](attr_name) + +

+ + +
+

Returns the value of the attribute identified by attr_name after it has been typecast (for example, “2004-12-12” in a date column is cast to a date object, like Date.new(2004, 12, 12)). It raises ActiveModel::MissingAttributeError if the identified attribute is missing.

+ +

Note: :id is always present.

+ +
class Person < ActiveRecord::Base
+  belongs_to :organization
+end
+
+person = Person.new(name: 'Francesco', age: '22')
+person[:name] # => "Francesco"
+person[:age]  # => 22
+
+person = Person.select('id').first
+person[:name]            # => ActiveModel::MissingAttributeError: missing attribute: name
+person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute: organization_id
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 395
+def [](attr_name)
+  read_attribute(attr_name) { |n| missing_attribute(n, caller) }
+end
+
+
+ +
+ +
+

+ + []=(attr_name, value) + +

+ + +
+

Updates the attribute identified by attr_name with the specified value. (Alias for the protected write_attribute method).

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.new
+person[:age] = '22'
+person[:age] # => 22
+person[:age].class # => Integer
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 409
+def []=(attr_name, value)
+  write_attribute(attr_name, value)
+end
+
+
+ +
+ +
+

+ + accessed_fields() + +

+ + +
+

Returns the name of all database fields which have been read from this model. This can be useful in development mode to determine which fields need to be selected. For performance critical pages, selecting only the required fields can be an easy performance win (assuming you aren't using all of the fields on the model).

+ +

For example:

+ +
class PostsController < ActionController::Base
+  after_action :print_accessed_fields, only: :index
+
+  def index
+    @posts = Post.all
+  end
+
+  private
+
+  def print_accessed_fields
+    p @posts.first.accessed_fields
+  end
+end
+
+ +

Which allows you to quickly change your code to:

+ +
class PostsController < ActionController::Base
+  def index
+    @posts = Post.select(:id, :title, :author_id, :updated_at)
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 442
+def accessed_fields
+  @attributes.accessed
+end
+
+
+ +
+ +
+

+ + attribute_for_inspect(attr_name) + +

+ + +
+

Returns an #inspect-like string for the value of the attribute attr_name. String attributes are truncated up to 50 characters, Date and Time attributes are returned in the :db format. Other attributes return the value of #inspect without modification.

+ +
person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
+
+person.attribute_for_inspect(:name)
+# => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
+
+person.attribute_for_inspect(:created_at)
+# => "\"2012-10-22 00:15:07\""
+
+person.attribute_for_inspect(:tag_ids)
+# => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 346
+def attribute_for_inspect(attr_name)
+  value = read_attribute(attr_name)
+
+  if value.is_a?(String) && value.length > 50
+    "#{value[0, 50]}...".inspect
+  elsif value.is_a?(Date) || value.is_a?(Time)
+    %("#{value.to_s(:db)}")
+  else
+    value.inspect
+  end
+end
+
+
+ +
+ +
+

+ + attribute_names() + +

+ + +
+

Returns an array of names for the attributes available on this object.

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.new
+person.attribute_names
+# => ["id", "created_at", "updated_at", "name", "age"]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 314
+def attribute_names
+  @attributes.keys
+end
+
+
+ +
+ +
+

+ + attribute_present?(attribute) + +

+ + +
+

Returns true if the specified attribute has been set by the user or by a database load and is neither nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings). Otherwise, false. Note that it always returns true with boolean attributes.

+ +
class Task < ActiveRecord::Base
+end
+
+task = Task.new(title: '', is_done: false)
+task.attribute_present?(:title)   # => false
+task.attribute_present?(:is_done) # => true
+task.title = 'Buy milk'
+task.is_done = true
+task.attribute_present?(:title)   # => true
+task.attribute_present?(:is_done) # => true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 373
+def attribute_present?(attribute)
+  value = _read_attribute(attribute)
+  !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
+end
+
+
+ +
+ +
+

+ + attributes() + +

+ + +
+

Returns a hash of all the attributes with their names as keys and the values of the attributes as values.

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.create(name: 'Francesco', age: 22)
+person.attributes
+# => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 326
+def attributes
+  @attributes.to_hash
+end
+
+
+ +
+ +
+

+ + has_attribute?(attr_name) + +

+ + +
+

Returns true if the given attribute is in the attributes hash, otherwise false.

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.new
+person.has_attribute?(:name)    # => true
+person.has_attribute?('age')    # => true
+person.has_attribute?(:nothing) # => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 302
+def has_attribute?(attr_name)
+  @attributes.key?(attr_name.to_s)
+end
+
+
+ +
+ +
+

+ + respond_to?(name, include_private = false) + +

+ + +
+

A Person object with a name attribute can ask person.respond_to?(:name), person.respond_to?(:name=), and person.respond_to?(:name?) which will all return true. It also defines the attribute methods if they have not been generated.

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.new
+person.respond_to?(:name)    # => true
+person.respond_to?(:name=)   # => true
+person.respond_to?(:name?)   # => true
+person.respond_to?('age')    # => true
+person.respond_to?('age=')   # => true
+person.respond_to?('age?')   # => true
+person.respond_to?(:nothing) # => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 270
+def respond_to?(name, include_private = false)
+  return false unless super
+
+  case name
+  when :to_partial_path
+    name = "to_partial_path".freeze
+  when :to_model
+    name = "to_model".freeze
+  else
+    name = name.to_s
+  end
+
+  # If the result is true then check for the select case.
+  # For queries selecting a subset of columns, return false for unselected columns.
+  # We check defined?(@attributes) not to issue warnings if called on objects that
+  # have been allocated but not yet initialized.
+  if defined?(@attributes) && self.class.column_names.include?(name)
+    return has_attribute?(name)
+  end
+
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html b/src/5.2/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html new file mode 100644 index 0000000000..496bcf3009 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html @@ -0,0 +1,188 @@ +--- +title: ActiveRecord::AttributeMethods::BeforeTypeCast +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods Before Type Cast

+ +

ActiveRecord::AttributeMethods::BeforeTypeCast provides a way to read the value of the attributes before typecasting and deserialization.

+ +
class Task < ActiveRecord::Base
+end
+
+task = Task.new(id: '1', completed_on: '2012-10-21')
+task.id           # => 1
+task.completed_on # => Sun, 21 Oct 2012
+
+task.attributes_before_type_cast
+# => {"id"=>"1", "completed_on"=>"2012-10-21", ... }
+task.read_attribute_before_type_cast('id')           # => "1"
+task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
+
+ +

In addition to read_attribute_before_type_cast and attributes_before_type_cast, it declares a method for all attributes with the *_before_type_cast suffix.

+ +
task.id_before_type_cast           # => "1"
+task.completed_on_before_type_cast # => "2012-10-21"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attributes_before_type_cast() + +

+ + +
+

Returns a hash of attributes before typecasting and deserialization.

+ +
class Task < ActiveRecord::Base
+end
+
+task = Task.new(title: nil, is_done: true, completed_on: '2012-10-21')
+task.attributes
+# => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>Sun, 21 Oct 2012, "created_at"=>nil, "updated_at"=>nil}
+task.attributes_before_type_cast
+# => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/before_type_cast.rb, line 62
+def attributes_before_type_cast
+  @attributes.values_before_type_cast
+end
+
+
+ +
+ +
+

+ + read_attribute_before_type_cast(attr_name) + +

+ + +
+

Returns the value of the attribute identified by attr_name before typecasting and deserialization.

+ +
class Task < ActiveRecord::Base
+end
+
+task = Task.new(id: '1', completed_on: '2012-10-21')
+task.read_attribute('id')                            # => 1
+task.read_attribute_before_type_cast('id')           # => '1'
+task.read_attribute('completed_on')                  # => Sun, 21 Oct 2012
+task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
+task.read_attribute_before_type_cast(:completed_on)  # => "2012-10-21"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/before_type_cast.rb, line 48
+def read_attribute_before_type_cast(attr_name)
+  @attributes[attr_name.to_s].value_before_type_cast
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/ClassMethods.html b/src/5.2/classes/ActiveRecord/AttributeMethods/ClassMethods.html new file mode 100644 index 0000000000..b7c8fc4227 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/ClassMethods.html @@ -0,0 +1,417 @@ +--- +title: ActiveRecord::AttributeMethods::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
COLUMN_NAME_ORDER_WHITELIST=/ +\A +(?:\w+\.)? +\w+ +(?:\s+asc|\s+desc)? +(?:\s+nulls\s+(?:first|last))? +\z +/ix
 

Regexp whitelist. Matches the following:

+ +
"#{table_name}.#{column_name}"
+"#{table_name}.#{column_name} #{direction}"
+"#{table_name}.#{column_name} #{direction} NULLS FIRST"
+"#{table_name}.#{column_name} NULLS LAST"
+"#{column_name}"
+"#{column_name} #{direction}"
+"#{column_name} #{direction} NULLS FIRST"
+"#{column_name} NULLS LAST"
+
COLUMN_NAME_WHITELIST=/\A(?:\w+\.)?\w+\z/i
 

Regexp whitelist. Matches the following:

+ +
"#{table_name}.#{column_name}"
+"#{column_name}"
+
+ + + + + + + +

Instance Public methods

+ +
+

+ + attribute_method?(attribute) + +

+ + +
+

Returns true if attribute is an attribute method and table exists, false otherwise.

+ +
class Person < ActiveRecord::Base
+end
+
+Person.attribute_method?('name')   # => true
+Person.attribute_method?(:age=)    # => true
+Person.attribute_method?(:nothing) # => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 150
+def attribute_method?(attribute)
+  super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, "")))
+end
+
+
+ +
+ +
+

+ + attribute_names() + +

+ + +
+

Returns an array of column names as strings if it's not an abstract class and table exists. Otherwise it returns an empty array.

+ +
class Person < ActiveRecord::Base
+end
+
+Person.attribute_names
+# => ["id", "created_at", "updated_at", "name", "age"]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 162
+def attribute_names
+  @attribute_names ||= if !abstract_class? && table_exists?
+    attribute_types.keys
+  else
+    []
+  end
+end
+
+
+ +
+ +
+

+ + column_for_attribute(name) + +

+ + +
+

Returns the column object for the named attribute. Returns a ActiveRecord::ConnectionAdapters::NullColumn if the named attribute does not exist.

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.new
+person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
+# => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
+
+person.column_for_attribute(:nothing)
+# => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 246
+def column_for_attribute(name)
+  name = name.to_s
+  columns_hash.fetch(name) do
+    ConnectionAdapters::NullColumn.new(name)
+  end
+end
+
+
+ +
+ +
+

+ + dangerous_class_method?(method_name) + +

+ + +
+

A class method is 'dangerous' if it is already (re)defined by Active Record, but not by any ancestors. (So 'puts' is not dangerous but 'new' is.)

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 125
+def dangerous_class_method?(method_name)
+  BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
+end
+
+
+ +
+ +
+

+ + has_attribute?(attr_name) + +

+ + +
+

Returns true if the given attribute exists, otherwise false.

+ +
class Person < ActiveRecord::Base
+end
+
+Person.has_attribute?('name')   # => true
+Person.has_attribute?(:age)     # => true
+Person.has_attribute?(:nothing) # => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 229
+def has_attribute?(attr_name)
+  attribute_types.key?(attr_name.to_s)
+end
+
+
+ +
+ +
+

+ + instance_method_already_implemented?(method_name) + +

+ + +
+

Raises an ActiveRecord::DangerousAttributeError exception when an Active Record method is defined in the model, otherwise false.

+ +
class Person < ActiveRecord::Base
+  def save
+    'already defined by Active Record'
+  end
+end
+
+Person.instance_method_already_implemented?(:save)
+# => ActiveRecord::DangerousAttributeError: save is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
+
+Person.instance_method_already_implemented?(:name)
+# => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods.rb, line 89
+def instance_method_already_implemented?(method_name)
+  if dangerous_attribute_method?(method_name)
+    raise DangerousAttributeError, "#{method_name} is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name."
+  end
+
+  if superclass == Base
+    super
+  else
+    # If ThisClass < ... < SomeSuperClass < ... < Base and SomeSuperClass
+    # defines its own attribute method, then we don't want to overwrite that.
+    defined = method_defined_within?(method_name, superclass, Base) &&
+      ! superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods)
+    defined || super
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/Dirty.html b/src/5.2/classes/ActiveRecord/AttributeMethods/Dirty.html new file mode 100644 index 0000000000..b181c14ba5 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/Dirty.html @@ -0,0 +1,598 @@ +--- +title: ActiveRecord::AttributeMethods::Dirty +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attribute_before_last_save(attr_name) + +

+ + +
+

Returns the original value of an attribute before the last save. Behaves similarly to attribute_was. This method is useful in after callbacks to get the original value of an attribute before the save that just occurred

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 73
+def attribute_before_last_save(attr_name)
+  mutations_before_last_save.original_value(attr_name)
+end
+
+
+ +
+ +
+

+ + attribute_change_to_be_saved(attr_name) + +

+ + +
+

Alias for attribute_change

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 93
+def attribute_change_to_be_saved(attr_name)
+  mutations_from_database.change_to_attribute(attr_name)
+end
+
+
+ +
+ +
+

+ + attribute_in_database(attr_name) + +

+ + +
+

Alias for attribute_was

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 98
+def attribute_in_database(attr_name)
+  mutations_from_database.original_value(attr_name)
+end
+
+
+ +
+ +
+

+ + attributes_in_database() + +

+ + +
+

Alias for changed_attributes

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 118
+def attributes_in_database
+  mutations_from_database.changed_values
+end
+
+
+ +
+ +
+

+ + changed_attribute_names_to_save() + +

+ + +
+

Alias for changed

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 113
+def changed_attribute_names_to_save
+  mutations_from_database.changed_attribute_names
+end
+
+
+ +
+ +
+

+ + changes_to_save() + +

+ + +
+

Alias for changes

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 108
+def changes_to_save
+  mutations_from_database.changes
+end
+
+
+ +
+ +
+

+ + has_changes_to_save?() + +

+ + +
+

Alias for changed?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 103
+def has_changes_to_save?
+  mutations_from_database.any_changes?
+end
+
+
+ +
+ +
+

+ + reload(*) + +

+ + +
+

reload the record and clears changed attributes.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 30
+def reload(*)
+  super.tap do
+    @previously_changed = ActiveSupport::HashWithIndifferentAccess.new
+    @mutations_before_last_save = nil
+    @attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
+    @mutations_from_database = nil
+  end
+end
+
+
+ +
+ +
+

+ + saved_change_to_attribute(attr_name) + +

+ + +
+

Returns the change to an attribute during the last save. If the attribute was changed, the result will be an array containing the original value and the saved value.

+ +

Behaves similarly to attribute_change. This method is useful in after callbacks, to see the change in an attribute that just occurred

+ +

This method can be invoked as saved_change_to_name in instead of saved_change_to_attribute("name")

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 65
+def saved_change_to_attribute(attr_name)
+  mutations_before_last_save.change_to_attribute(attr_name)
+end
+
+
+ +
+ +
+

+ + saved_change_to_attribute?(attr_name, **options) + +

+ + +
+

Did this attribute change when we last saved? This method can be invoked as saved_change_to_name? instead of saved_change_to_attribute?("name"). Behaves similarly to attribute_changed?. This method is useful in after callbacks to determine if the call to save changed a certain attribute.

+ +

Options

+ +

from When passed, this method will return false unless the original value is equal to the given option

+ +

to When passed, this method will return false unless the value was changed to the given value

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 52
+def saved_change_to_attribute?(attr_name, **options)
+  mutations_before_last_save.changed?(attr_name, **options)
+end
+
+
+ +
+ +
+

+ + saved_changes() + +

+ + +
+

Returns a hash containing all the changes that were just saved.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 83
+def saved_changes
+  mutations_before_last_save.changes
+end
+
+
+ +
+ +
+

+ + saved_changes?() + +

+ + +
+

Did the last call to save have any changes to change?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 78
+def saved_changes?
+  mutations_before_last_save.any_changes?
+end
+
+
+ +
+ +
+

+ + will_save_change_to_attribute?(attr_name, **options) + +

+ + +
+

Alias for attribute_changed?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 88
+def will_save_change_to_attribute?(attr_name, **options)
+  mutations_from_database.changed?(attr_name, **options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey.html b/src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey.html new file mode 100644 index 0000000000..3a1ad9fad9 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey.html @@ -0,0 +1,357 @@ +--- +title: ActiveRecord::AttributeMethods::PrimaryKey +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + id() + +

+ + +
+

Returns the primary key value.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 18
+def id
+  sync_with_transaction_state
+  primary_key = self.class.primary_key
+  _read_attribute(primary_key) if primary_key
+end
+
+
+ +
+ +
+

+ + id=(value) + +

+ + +
+

Sets the primary key value.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 25
+def id=(value)
+  sync_with_transaction_state
+  primary_key = self.class.primary_key
+  _write_attribute(primary_key, value) if primary_key
+end
+
+
+ +
+ +
+

+ + id?() + +

+ + +
+

Queries the primary key value.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 32
+def id?
+  sync_with_transaction_state
+  query_attribute(self.class.primary_key)
+end
+
+
+ +
+ +
+

+ + id_before_type_cast() + +

+ + +
+

Returns the primary key value before type cast.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 38
+def id_before_type_cast
+  sync_with_transaction_state
+  read_attribute_before_type_cast(self.class.primary_key)
+end
+
+
+ +
+ +
+

+ + id_in_database() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 49
+def id_in_database
+  sync_with_transaction_state
+  attribute_in_database(self.class.primary_key)
+end
+
+
+ +
+ +
+

+ + id_was() + +

+ + +
+

Returns the primary key previous value.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 44
+def id_was
+  sync_with_transaction_state
+  attribute_was(self.class.primary_key)
+end
+
+
+ +
+ +
+

+ + to_key() + +

+ + +
+

Returns this record's primary key value wrapped in an array if one is available.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 12
+def to_key
+  key = id
+  [key] if key
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html b/src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html new file mode 100644 index 0000000000..fdc31bf6a9 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html @@ -0,0 +1,294 @@ +--- +title: ActiveRecord::AttributeMethods::PrimaryKey::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ID_ATTRIBUTE_METHODS=%w(id id= id? id_before_type_cast id_was id_in_database).to_set
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + dangerous_attribute_method?(method_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 67
+def dangerous_attribute_method?(method_name)
+  super && !ID_ATTRIBUTE_METHODS.include?(method_name)
+end
+
+
+ +
+ +
+

+ + instance_method_already_implemented?(method_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 63
+def instance_method_already_implemented?(method_name)
+  super || primary_key && ID_ATTRIBUTE_METHODS.include?(method_name)
+end
+
+
+ +
+ +
+

+ + primary_key() + +

+ + +
+

Defines the primary key field – can be overridden in subclasses. Overwriting will negate any effect of the primary_key_prefix_type setting, though.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 74
+def primary_key
+  @primary_key = reset_primary_key unless defined? @primary_key
+  @primary_key
+end
+
+
+ +
+ +
+

+ + primary_key=(value) + +

+ + +
+

Sets the name of the primary key column.

+ +
class Project < ActiveRecord::Base
+  self.primary_key = 'sysid'
+end
+
+ +

You can also define the primary_key method yourself:

+ +
class Project < ActiveRecord::Base
+  def self.primary_key
+    'foo_' + super
+  end
+end
+
+Project.primary_key # => "foo_id"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 123
+def primary_key=(value)
+  @primary_key        = value && value.to_s
+  @quoted_primary_key = nil
+  @attributes_builder = nil
+end
+
+
+ +
+ +
+

+ + quoted_primary_key() + +

+ + +
+

Returns a quoted version of the primary key name, used to construct SQL statements.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 81
+def quoted_primary_key
+  @quoted_primary_key ||= connection.quote_column_name(primary_key)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/Query.html b/src/5.2/classes/ActiveRecord/AttributeMethods/Query.html new file mode 100644 index 0000000000..63f348df0b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/Query.html @@ -0,0 +1,120 @@ +--- +title: ActiveRecord::AttributeMethods::Query +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + query_attribute(attr_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/query.rb, line 12
+def query_attribute(attr_name)
+  value = self[attr_name]
+
+  case value
+  when true        then true
+  when false, nil  then false
+  else
+    column = self.class.columns_hash[attr_name]
+    if column.nil?
+      if Numeric === value || value !~ /[^0-9]/
+        !value.to_i.zero?
+      else
+        return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
+        !value.blank?
+      end
+    elsif value.respond_to?(:zero?)
+      !value.zero?
+    else
+      !value.blank?
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/Read.html b/src/5.2/classes/ActiveRecord/AttributeMethods/Read.html new file mode 100644 index 0000000000..89db6e59fa --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/Read.html @@ -0,0 +1,110 @@ +--- +title: ActiveRecord::AttributeMethods::Read +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + read_attribute(attr_name, &block) + +

+ + +
+

Returns the value of the attribute identified by attr_name after it has been typecast (for example, “2004-12-12” in a date column is cast to a date object, like Date.new(2004, 12, 12)).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/read.rb, line 54
+def read_attribute(attr_name, &block)
+  name = if self.class.attribute_alias?(attr_name)
+    self.class.attribute_alias(attr_name).to_s
+  else
+    attr_name.to_s
+  end
+
+  primary_key = self.class.primary_key
+  name = primary_key if name == "id".freeze && primary_key
+  sync_with_transaction_state if name == primary_key
+  _read_attribute(name, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization.html b/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization.html new file mode 100644 index 0000000000..b949bd5f0f --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::AttributeMethods::Serialization +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html b/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html new file mode 100644 index 0000000000..7b8d548c89 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html @@ -0,0 +1,149 @@ +--- +title: ActiveRecord::AttributeMethods::Serialization::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + serialize(attr_name, class_name_or_coder = Object) + +

+ + +
+

If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object, then specify the name of that attribute using this method and it will be handled automatically. The serialization is done through YAML. If class_name is specified, the serialized object must be of that class on assignment and retrieval. Otherwise SerializationTypeMismatch will be raised.

+ +

Empty objects as {}, in the case of Hash, or [], in the case of Array, will always be persisted as null.

+ +

Keep in mind that database adapters handle certain serialization tasks for you. For instance: json and jsonb types in PostgreSQL will be converted between JSON object/array syntax and Ruby Hash or Array objects transparently. There is no need to use serialize in this case.

+ +

For more complex cases, such as conversion to or from your application domain objects, consider using the ActiveRecord::Attributes API.

+ +

Parameters

+
  • +

    attr_name - The field name that should be serialized.

    +
  • +

    class_name_or_coder - Optional, a coder object, which responds to .load and .dump or a class name that the object type should be equal to.

    +
+ +

Example

+ +
# Serialize a preferences attribute.
+class User < ActiveRecord::Base
+  serialize :preferences
+end
+
+# Serialize preferences using JSON as coder.
+class User < ActiveRecord::Base
+  serialize :preferences, JSON
+end
+
+# Serialize preferences as Hash using YAML coder.
+class User < ActiveRecord::Base
+  serialize :preferences, Hash
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/serialization.rb, line 60
+def serialize(attr_name, class_name_or_coder = Object)
+  # When ::JSON is used, force it to go through the Active Support JSON encoder
+  # to ensure special objects (e.g. Active Record models) are dumped correctly
+  # using the #as_json hook.
+  coder = if class_name_or_coder == ::JSON
+    Coders::JSON
+  elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
+    class_name_or_coder
+  else
+    Coders::YAMLColumn.new(attr_name, class_name_or_coder)
+  end
+
+  decorate_attribute_type(attr_name, :serialize) do |type|
+    if type_incompatible_with_serialize?(type, class_name_or_coder)
+      raise ColumnNotSerializableError.new(attr_name, type)
+    end
+
+    Type::Serialized.new(type, coder)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ColumnNotSerializableError.html b/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ColumnNotSerializableError.html new file mode 100644 index 0000000000..f5c3f1972e --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/Serialization/ColumnNotSerializableError.html @@ -0,0 +1,111 @@ +--- +title: ActiveRecord::AttributeMethods::Serialization::ColumnNotSerializableError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(name, type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/serialization.rb, line 9
+        def initialize(name, type)
+          super <<-EOS.strip_heredoc
+            Column `#{name}` of type #{type.class} does not support `serialize` feature.
+            Usually it means that you are trying to use `serialize`
+            on a column that already implements serialization natively.
+          EOS
+        end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/TimeZoneConversion.html b/src/5.2/classes/ActiveRecord/AttributeMethods/TimeZoneConversion.html new file mode 100644 index 0000000000..625e07ec14 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/TimeZoneConversion.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::AttributeMethods::TimeZoneConversion +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AttributeMethods/Write.html b/src/5.2/classes/ActiveRecord/AttributeMethods/Write.html new file mode 100644 index 0000000000..92e1b4ebd4 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AttributeMethods/Write.html @@ -0,0 +1,110 @@ +--- +title: ActiveRecord::AttributeMethods::Write +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + write_attribute(attr_name, value) + +

+ + +
+

Updates the attribute identified by attr_name with the specified value. Empty strings for Integer and Float columns are turned into nil.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attribute_methods/write.rb, line 35
+def write_attribute(attr_name, value)
+  name = if self.class.attribute_alias?(attr_name)
+    self.class.attribute_alias(attr_name).to_s
+  else
+    attr_name.to_s
+  end
+
+  primary_key = self.class.primary_key
+  name = primary_key if name == "id".freeze && primary_key
+  sync_with_transaction_state if name == primary_key
+  _write_attribute(name, value)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Attributes.html b/src/5.2/classes/ActiveRecord/Attributes.html new file mode 100644 index 0000000000..bbb2f32d02 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Attributes.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Attributes +layout: default +--- +
+ +
+
+ +
+ +

See ActiveRecord::Attributes::ClassMethods for documentation

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Attributes/ClassMethods.html b/src/5.2/classes/ActiveRecord/Attributes/ClassMethods.html new file mode 100644 index 0000000000..fe6b8ca19b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Attributes/ClassMethods.html @@ -0,0 +1,318 @@ +--- +title: ActiveRecord::Attributes::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attribute(name, cast_type = Type::Value.new, **options) + +

+ + +
+

Defines an attribute with a type on this model. It will override the type of existing attributes if needed. This allows control over how values are converted to and from SQL when assigned to a model. It also changes the behavior of values passed to ActiveRecord::Base.where. This will let you use your domain objects across much of Active Record, without having to rely on implementation details or monkey patching.

+ +

name The name of the methods to define attribute methods for, and the column which this will persist to.

+ +

cast_type A symbol such as :string or :integer, or a type object to be used for this attribute. See the examples below for more information about providing custom type objects.

+ +

Options

+ +

The following options are accepted:

+ +

default The default value to use when no value is provided. If this option is not passed, the previous default value (if any) will be used. Otherwise, the default will be nil.

+ +

array (PostgreSQL only) specifies that the type should be an array (see the examples below).

+ +

range (PostgreSQL only) specifies that the type should be a range (see the examples below).

+ +

Examples

+ +

The type detected by Active Record can be overridden.

+ +
# db/schema.rb
+create_table :store_listings, force: true do |t|
+  t.decimal :price_in_cents
+end
+
+# app/models/store_listing.rb
+class StoreListing < ActiveRecord::Base
+end
+
+store_listing = StoreListing.new(price_in_cents: '10.1')
+
+# before
+store_listing.price_in_cents # => BigDecimal(10.1)
+
+class StoreListing < ActiveRecord::Base
+  attribute :price_in_cents, :integer
+end
+
+# after
+store_listing.price_in_cents # => 10
+
+ +

A default can also be provided.

+ +
# db/schema.rb
+create_table :store_listings, force: true do |t|
+  t.string :my_string, default: "original default"
+end
+
+StoreListing.new.my_string # => "original default"
+
+# app/models/store_listing.rb
+class StoreListing < ActiveRecord::Base
+  attribute :my_string, :string, default: "new default"
+end
+
+StoreListing.new.my_string # => "new default"
+
+class Product < ActiveRecord::Base
+  attribute :my_default_proc, :datetime, default: -> { Time.now }
+end
+
+Product.new.my_default_proc # => 2015-05-30 11:04:48 -0600
+sleep 1
+Product.new.my_default_proc # => 2015-05-30 11:04:49 -0600
+
+ +

Attributes do not need to be backed by a database column.

+ +
# app/models/my_model.rb
+class MyModel < ActiveRecord::Base
+  attribute :my_string, :string
+  attribute :my_int_array, :integer, array: true
+  attribute :my_float_range, :float, range: true
+end
+
+model = MyModel.new(
+  my_string: "string",
+  my_int_array: ["1", "2", "3"],
+  my_float_range: "[1,3.5]",
+)
+model.attributes
+# =>
+  {
+    my_string: "string",
+    my_int_array: [1, 2, 3],
+    my_float_range: 1.0..3.5
+  }
+
+ +

Creating Custom Types

+ +

Users may also define their own custom types, as long as they respond to the methods defined on the value type. The method deserialize or cast will be called on your type object, with raw input from the database or from your controllers. See ActiveModel::Type::Value for the expected API. It is recommended that your type objects inherit from an existing type, or from ActiveRecord::Type::Value

+ +
class MoneyType < ActiveRecord::Type::Integer
+  def cast(value)
+    if !value.kind_of?(Numeric) && value.include?('$')
+      price_in_dollars = value.gsub(/\$/, '').to_f
+      super(price_in_dollars * 100)
+    else
+      super
+    end
+  end
+end
+
+# config/initializers/types.rb
+ActiveRecord::Type.register(:money, MoneyType)
+
+# app/models/store_listing.rb
+class StoreListing < ActiveRecord::Base
+  attribute :price_in_cents, :money
+end
+
+store_listing = StoreListing.new(price_in_cents: '$10.00')
+store_listing.price_in_cents # => 1000
+
+ +

For more details on creating custom types, see the documentation for ActiveModel::Type::Value. For more details on registering your types to be referenced by a symbol, see ActiveRecord::Type.register. You can also pass a type object directly, in place of a symbol.

+ +

Querying

+ +

When ActiveRecord::Base.where is called, it will use the type defined by the model class to convert the value to SQL, calling serialize on your type object. For example:

+ +
class Money < Struct.new(:amount, :currency)
+end
+
+class MoneyType < Type::Value
+  def initialize(currency_converter:)
+    @currency_converter = currency_converter
+  end
+
+  # value will be the result of +deserialize+ or
+  # +cast+. Assumed to be an instance of +Money+ in
+  # this case.
+  def serialize(value)
+    value_in_bitcoins = @currency_converter.convert_to_bitcoins(value)
+    value_in_bitcoins.amount
+  end
+end
+
+# config/initializers/types.rb
+ActiveRecord::Type.register(:money, MoneyType)
+
+# app/models/product.rb
+class Product < ActiveRecord::Base
+  currency_converter = ConversionRatesFromTheInternet.new
+  attribute :price_in_bitcoins, :money, currency_converter: currency_converter
+end
+
+Product.where(price_in_bitcoins: Money.new(5, "USD"))
+# => SELECT * FROM products WHERE price_in_bitcoins = 0.02230
+
+Product.where(price_in_bitcoins: Money.new(5, "GBP"))
+# => SELECT * FROM products WHERE price_in_bitcoins = 0.03412
+
+ +

Dirty Tracking

+ +

The type of an attribute is given the opportunity to change how dirty tracking is performed. The methods changed? and changed_in_place? will be called from ActiveModel::Dirty. See the documentation for those methods in ActiveModel::Type::Value for more details.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attributes.rb, line 195
+def attribute(name, cast_type = Type::Value.new, **options)
+  name = name.to_s
+  reload_schema_from_cache
+
+  self.attributes_to_define_after_schema_loads =
+    attributes_to_define_after_schema_loads.merge(
+      name => [cast_type, options]
+    )
+end
+
+
+ +
+ +
+

+ + define_attribute( name, cast_type, default: NO_DEFAULT_PROVIDED, user_provided_default: true ) + +

+ + +
+

This is the low level API which sits beneath attribute. It only accepts type objects, and will do its work immediately instead of waiting for the schema to load. Automatic schema detection and ClassMethods#attribute both call this under the hood. While this method is provided so it can be used by plugin authors, application code should probably use ClassMethods#attribute.

+ +

name The name of the attribute being defined. Expected to be a String.

+ +

cast_type The type object to use for this attribute.

+ +

default The default value to use when no value is provided. If this option is not passed, the previous default value (if any) will be used. Otherwise, the default will be nil. A proc can also be passed, and will be called once each time a new value is needed.

+ +

user_provided_default Whether the default value should be cast using cast or deserialize.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/attributes.rb, line 223
+def define_attribute(
+  name,
+  cast_type,
+  default: NO_DEFAULT_PROVIDED,
+  user_provided_default: true
+)
+  attribute_types[name] = cast_type
+  define_default_attribute(name, default, cast_type, from_user: user_provided_default)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/AutosaveAssociation.html b/src/5.2/classes/ActiveRecord/AutosaveAssociation.html new file mode 100644 index 0000000000..cddc2f0352 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/AutosaveAssociation.html @@ -0,0 +1,427 @@ +--- +title: ActiveRecord::AutosaveAssociation +layout: default +--- +
+ +
+
+ +
+ +

Active Record Autosave Association

+ +

AutosaveAssociation is a module that takes care of automatically saving associated records when their parent is saved. In addition to saving, it also destroys any associated records that were marked for destruction. (See mark_for_destruction and marked_for_destruction?).

+ +

Saving of the parent, its associations, and the destruction of marked associations, all happen inside a transaction. This should never leave the database in an inconsistent state.

+ +

If validations for any of the associations fail, their error messages will be applied to the parent.

+ +

Note that it also means that associations marked for destruction won't be destroyed directly. They will however still be marked for destruction.

+ +

Note that autosave: false is not same as not declaring :autosave. When the :autosave option is not present then new association records are saved but the updated association records are not saved.

+ +

Validation

+ +

Child records are validated unless :validate is false.

+ +

Callbacks

+ +

Association with autosave option defines several callbacks on your model (before_save, after_create, after_update). Please note that callbacks are executed in the order they were defined in model. You should avoid modifying the association content, before autosave callbacks are executed. Placing your callbacks after associations is usually a good practice.

+ +

One-to-one Example

+ +
class Post < ActiveRecord::Base
+  has_one :author, autosave: true
+end
+
+ +

Saving changes to the parent and its associated model can now be performed automatically and atomically:

+ +
post = Post.find(1)
+post.title       # => "The current global position of migrating ducks"
+post.author.name # => "alloy"
+
+post.title = "On the migration of ducks"
+post.author.name = "Eloy Duran"
+
+post.save
+post.reload
+post.title       # => "On the migration of ducks"
+post.author.name # => "Eloy Duran"
+
+ +

Destroying an associated model, as part of the parent's save action, is as simple as marking it for destruction:

+ +
post.author.mark_for_destruction
+post.author.marked_for_destruction? # => true
+
+ +

Note that the model is not yet removed from the database:

+ +
id = post.author.id
+Author.find_by(id: id).nil? # => false
+
+post.save
+post.reload.author # => nil
+
+ +

Now it is removed from the database:

+ +
Author.find_by(id: id).nil? # => true
+
+ +

One-to-many Example

+ +

When :autosave is not declared new children are saved when their parent is saved:

+ +
class Post < ActiveRecord::Base
+  has_many :comments # :autosave option is not declared
+end
+
+post = Post.new(title: 'ruby rocks')
+post.comments.build(body: 'hello world')
+post.save # => saves both post and comment
+
+post = Post.create(title: 'ruby rocks')
+post.comments.build(body: 'hello world')
+post.save # => saves both post and comment
+
+post = Post.create(title: 'ruby rocks')
+post.comments.create(body: 'hello world')
+post.save # => saves both post and comment
+
+ +

When :autosave is true all children are saved, no matter whether they are new records or not:

+ +
class Post < ActiveRecord::Base
+  has_many :comments, autosave: true
+end
+
+post = Post.create(title: 'ruby rocks')
+post.comments.create(body: 'hello world')
+post.comments[0].body = 'hi everyone'
+post.comments.build(body: "good morning.")
+post.title += "!"
+post.save # => saves both post and comments.
+
+ +

Destroying one of the associated models as part of the parent's save action is as simple as marking it for destruction:

+ +
post.comments # => [#<Comment id: 1, ...>, #<Comment id: 2, ...]>
+post.comments[1].mark_for_destruction
+post.comments[1].marked_for_destruction? # => true
+post.comments.length # => 2
+
+ +

Note that the model is not yet removed from the database:

+ +
id = post.comments.last.id
+Comment.find_by(id: id).nil? # => false
+
+post.save
+post.reload.comments.length # => 1
+
+ +

Now it is removed from the database:

+ +
Comment.find_by(id: id).nil? # => true
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + changed_for_autosave?() + +

+ + +
+

Returns whether or not this record has been changed in any way (including whether any of its nested autosave associations are likewise changed)

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/autosave_association.rb, line 265
+def changed_for_autosave?
+  new_record? || has_changes_to_save? || marked_for_destruction? || nested_records_changed_for_autosave?
+end
+
+
+ +
+ +
+

+ + destroyed_by_association() + +

+ + +
+

Returns the association for the parent being destroyed.

+ +

Used to avoid updating the counter cache unnecessarily.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/autosave_association.rb, line 259
+def destroyed_by_association
+  @destroyed_by_association
+end
+
+
+ +
+ +
+

+ + destroyed_by_association=(reflection) + +

+ + +
+

Records the association that is being destroyed and destroying this record in the process.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/autosave_association.rb, line 252
+def destroyed_by_association=(reflection)
+  @destroyed_by_association = reflection
+end
+
+
+ +
+ +
+

+ + mark_for_destruction() + +

+ + +
+

Marks this record to be destroyed as part of the parent's save transaction. This does not actually destroy the record instantly, rather child record will be destroyed when parent.save is called.

+ +

Only useful if the :autosave option on the parent is enabled for this associated model.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/autosave_association.rb, line 239
+def mark_for_destruction
+  @marked_for_destruction = true
+end
+
+
+ +
+ +
+

+ + marked_for_destruction?() + +

+ + +
+

Returns whether or not this record will be destroyed as part of the parent's save transaction.

+ +

Only useful if the :autosave option on the parent is enabled for this associated model.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/autosave_association.rb, line 246
+def marked_for_destruction?
+  @marked_for_destruction
+end
+
+
+ +
+ +
+

+ + reload(options = nil) + +

+ + +
+

Reloads the attributes of the object as usual and clears marked_for_destruction flag.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/autosave_association.rb, line 228
+def reload(options = nil)
+  @marked_for_destruction = false
+  @destroyed_by_association = nil
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Base.html b/src/5.2/classes/ActiveRecord/Base.html new file mode 100644 index 0000000000..140502167d --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Base.html @@ -0,0 +1,528 @@ +--- +title: ActiveRecord::Base +layout: default +--- +
+ +
+
+ +
+ +

Active Record

+ +

Active Record objects don't specify their attributes directly, but rather infer them from the table definition with which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.

+ +

See the mapping rules in table_name and the full example in files/activerecord/README_rdoc.html for more insight.

+ +

Creation

+ +

Active Records accept constructor parameters either in a hash or as a block. The hash method is especially useful when you're receiving the data from somewhere else, like an HTTP request. It works like this:

+ +
user = User.new(name: "David", occupation: "Code Artist")
+user.name # => "David"
+
+ +

You can also use block initialization:

+ +
user = User.new do |u|
+  u.name = "David"
+  u.occupation = "Code Artist"
+end
+
+ +

And of course you can just create a bare object and specify the attributes after the fact:

+ +
user = User.new
+user.name = "David"
+user.occupation = "Code Artist"
+
+ +

Conditions

+ +

Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement. The array form is to be used when the condition input is tainted and requires sanitization. The string form can be used for statements that don't involve tainted data. The hash form works much like the array form, except only equality and range is possible. Examples:

+ +
class User < ActiveRecord::Base
+  def self.authenticate_unsafely(user_name, password)
+    where("user_name = '#{user_name}' AND password = '#{password}'").first
+  end
+
+  def self.authenticate_safely(user_name, password)
+    where("user_name = ? AND password = ?", user_name, password).first
+  end
+
+  def self.authenticate_safely_simply(user_name, password)
+    where(user_name: user_name, password: password).first
+  end
+end
+
+ +

The authenticate_unsafely method inserts the parameters directly into the query and is thus susceptible to SQL-injection attacks if the user_name and password parameters come directly from an HTTP request. The authenticate_safely and authenticate_safely_simply both will sanitize the user_name and password before inserting them in the query, which will ensure that an attacker can't escape the query and fake the login (or worse).

+ +

When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing the question marks with symbols and supplying a hash with values for the matching symbol keys:

+ +
Company.where(
+  "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
+  { id: 3, name: "37signals", division: "First", accounting_date: '2005-01-01' }
+).first
+
+ +

Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND operator. For instance:

+ +
Student.where(first_name: "Harvey", status: 1)
+Student.where(params[:student])
+
+ +

A range may be used in the hash to use the SQL BETWEEN operator:

+ +
Student.where(grade: 9..12)
+
+ +

An array may be used in the hash to use the SQL IN operator:

+ +
Student.where(grade: [9,11,12])
+
+ +

When joining tables, nested hashes or keys written in the form 'table_name.column_name' can be used to qualify the table name of a particular condition. For instance:

+ +
Student.joins(:schools).where(schools: { category: 'public' })
+Student.joins(:schools).where('schools.category' => 'public' )
+
+ +

Overwriting default accessors

+ +

All column values are automatically available through basic accessors on the Active Record object, but sometimes you want to specialize this behavior. This can be done by overwriting the default accessors (using the same name as the attribute) and calling super to actually change things.

+ +
class Song < ActiveRecord::Base
+  # Uses an integer of seconds to hold the length of the song
+
+  def length=(minutes)
+    super(minutes.to_i * 60)
+  end
+
+  def length
+    super / 60
+  end
+end
+
+ +

Attribute query methods

+ +

In addition to the basic accessors, query methods are also automatically available on the Active Record object. Query methods allow you to test whether an attribute value is present. Additionally, when dealing with numeric values, a query method will return false if the value is zero.

+ +

For example, an Active Record User with the name attribute has a name? method that you can call to determine whether the user has a name:

+ +
user = User.new(name: "David")
+user.name? # => true
+
+anonymous = User.new(name: "")
+anonymous.name? # => false
+
+ +

Accessing attributes before they have been typecasted

+ +

Sometimes you want to be able to read the raw attribute data without having the column-determined typecast run its course first. That can be done by using the <attribute>_before_type_cast accessors that all attributes have. For example, if your Account model has a balance attribute, you can call account.balance_before_type_cast or account.id_before_type_cast.

+ +

This is especially useful in validation situations where the user might supply a string for an integer field and you want to display the original string back in an error message. Accessing the attribute normally would typecast the string to 0, which isn't what you want.

+ +

Dynamic attribute-based finders

+ +

Dynamic attribute-based finders are a mildly deprecated way of getting (and/or creating) objects by simple queries without turning to SQL. They work by appending the name of an attribute to find_by_ like Person.find_by_user_name. Instead of writing Person.find_by(user_name: user_name), you can use Person.find_by_user_name(user_name).

+ +

It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an ActiveRecord::RecordNotFound error if they do not return any records, like Person.find_by_last_name!.

+ +

It's also possible to use multiple attributes in the same find_by_ by separating them with “and”.

+ +
Person.find_by(user_name: user_name, password: password)
+Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
+
+ +

It's even possible to call these dynamic finder methods on relations and named scopes.

+ +
Payment.order("created_on").find_by_amount(50)
+
+ +

Saving arrays, hashes, and other non-mappable objects in text columns

+ +

Active Record can serialize any object in text columns using YAML. To do so, you must specify this with a call to the class method serialize. This makes it possible to store arrays, hashes, and other non-mappable objects without doing any additional work.

+ +
class User < ActiveRecord::Base
+  serialize :preferences
+end
+
+user = User.create(preferences: { "background" => "black", "display" => large })
+User.find(user.id).preferences # => { "background" => "black", "display" => large }
+
+ +

You can also specify a class option as the second parameter that'll raise an exception if a serialized object is retrieved as a descendant of a class not in the hierarchy.

+ +
class User < ActiveRecord::Base
+  serialize :preferences, Hash
+end
+
+user = User.create(preferences: %w( one two three ))
+User.find(user.id).preferences    # raises SerializationTypeMismatch
+
+ +

When you specify a class option, the default value for that attribute will be a new instance of that class.

+ +
class User < ActiveRecord::Base
+  serialize :preferences, OpenStruct
+end
+
+user = User.new
+user.preferences.theme_color = "red"
+
+ +

Single table inheritance

+ +

Active Record allows inheritance by storing the name of the class in a column that is named “type” by default. See ActiveRecord::Inheritance for more details.

+ +

Connection to multiple databases in different models

+ +

Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection. For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say Course.establish_connection and Course and all of its subclasses will use this connection instead.

+ +

This feature is implemented by keeping a connection pool in ActiveRecord::Base that is a hash indexed by the class. If a connection is requested, the ActiveRecord::Base.retrieve_connection method will go up the class-hierarchy until a connection is found in the connection pool.

+ +

Exceptions

+ + +

Note: The attributes listed are class-level attributes (accessible from both the class and instance level). So it's possible to assign a logger to the class through Base.logger= which will then be used by all instances in the current object space.

+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Batches.html b/src/5.2/classes/ActiveRecord/Batches.html new file mode 100644 index 0000000000..921a2a2e88 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Batches.html @@ -0,0 +1,436 @@ +--- +title: ActiveRecord::Batches +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ORDER_IGNORE_MESSAGE="Scoped order is ignored, it's forced to be batch order."
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + find_each(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil) + +

+ + +
+

Looping through a collection of records from the database (using the Scoping::Named::ClassMethods.all method, for example) is very inefficient since it will try to instantiate all the objects at once.

+ +

In that case, batch processing methods allow you to work with the records in batches, thereby greatly reducing memory consumption.

+ +

The find_each method uses find_in_batches with a batch size of 1000 (or as specified by the :batch_size option).

+ +
Person.find_each do |person|
+  person.do_awesome_stuff
+end
+
+Person.where("age > 21").find_each do |person|
+  person.party_all_night!
+end
+
+ +

If you do not provide a block to find_each, it will return an Enumerator for chaining with other methods:

+ +
Person.find_each.with_index do |person, index|
+  person.award_trophy(index + 1)
+end
+
+ +

Options

+
  • +

    :batch_size - Specifies the size of the batch. Defaults to 1000.

    +
  • +

    :start - Specifies the primary key value to start from, inclusive of the value.

    +
  • +

    :finish - Specifies the primary key value to end at, inclusive of the value.

    +
  • +

    :error_on_ignore - Overrides the application config to specify if an error should be raised when an order is present in the relation.

    +
+ +

Limits are honored, and if present there is no requirement for the batch size: it can be less than, equal to, or greater than the limit.

+ +

The options start and finish are especially useful if you want multiple workers dealing with the same processing queue. You can make worker 1 handle all the records between id 1 and 9999 and worker 2 handle from 10000 and beyond by setting the :start and :finish option on each worker.

+ +
# In worker 1, let's process until 9999 records.
+Person.find_each(finish: 9_999) do |person|
+  person.party_all_night!
+end
+
+# In worker 2, let's process from record 10_000 and onwards.
+Person.find_each(start: 10_000) do |person|
+  person.party_all_night!
+end
+
+ +

NOTE: It's not possible to set the order. That is automatically set to ascending on the primary key (“id ASC”) to make the batch ordering work. This also means that this method only works when the primary key is orderable (e.g. an integer or string).

+ +

NOTE: By its nature, batch processing is subject to race conditions if other processes are modifying the database.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/batches.rb, line 67
+def find_each(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)
+  if block_given?
+    find_in_batches(start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore) do |records|
+      records.each { |record| yield record }
+    end
+  else
+    enum_for(:find_each, start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore) do
+      relation = self
+      apply_limits(relation, start, finish).size
+    end
+  end
+end
+
+
+ +
+ +
+

+ + find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil) + +

+ + +
+

Yields each batch of records that was found by the find options as an array.

+ +
Person.where("age > 21").find_in_batches do |group|
+  sleep(50) # Make sure it doesn't get too crowded in there!
+  group.each { |person| person.party_all_night! }
+end
+
+ +

If you do not provide a block to find_in_batches, it will return an Enumerator for chaining with other methods:

+ +
Person.find_in_batches.with_index do |group, batch|
+  puts "Processing group ##{batch}"
+  group.each(&:recover_from_last_night!)
+end
+
+ +

To be yielded each record one by one, use find_each instead.

+ +

Options

+
  • +

    :batch_size - Specifies the size of the batch. Defaults to 1000.

    +
  • +

    :start - Specifies the primary key value to start from, inclusive of the value.

    +
  • +

    :finish - Specifies the primary key value to end at, inclusive of the value.

    +
  • +

    :error_on_ignore - Overrides the application config to specify if an error should be raised when an order is present in the relation.

    +
+ +

Limits are honored, and if present there is no requirement for the batch size: it can be less than, equal to, or greater than the limit.

+ +

The options start and finish are especially useful if you want multiple workers dealing with the same processing queue. You can make worker 1 handle all the records between id 1 and 9999 and worker 2 handle from 10000 and beyond by setting the :start and :finish option on each worker.

+ +
# Let's process from record 10_000 on.
+Person.find_in_batches(start: 10_000) do |group|
+  group.each { |person| person.party_all_night! }
+end
+
+ +

NOTE: It's not possible to set the order. That is automatically set to ascending on the primary key (“id ASC”) to make the batch ordering work. This also means that this method only works when the primary key is orderable (e.g. an integer or string).

+ +

NOTE: By its nature, batch processing is subject to race conditions if other processes are modifying the database.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/batches.rb, line 126
+def find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)
+  relation = self
+  unless block_given?
+    return to_enum(:find_in_batches, start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore) do
+      total = apply_limits(relation, start, finish).size
+      (total - 1).div(batch_size) + 1
+    end
+  end
+
+  in_batches(of: batch_size, start: start, finish: finish, load: true, error_on_ignore: error_on_ignore) do |batch|
+    yield batch.to_a
+  end
+end
+
+
+ +
+ +
+

+ + in_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil) + +

+ + +
+

Yields ActiveRecord::Relation objects to work with a batch of records.

+ +
Person.where("age > 21").in_batches do |relation|
+  relation.delete_all
+  sleep(10) # Throttle the delete queries
+end
+
+ +

If you do not provide a block to in_batches, it will return a BatchEnumerator which is enumerable.

+ +
Person.in_batches.each_with_index do |relation, batch_index|
+  puts "Processing relation ##{batch_index}"
+  relation.delete_all
+end
+
+ +

Examples of calling methods on the returned BatchEnumerator object:

+ +
Person.in_batches.delete_all
+Person.in_batches.update_all(awesome: true)
+Person.in_batches.each_record(&:party_all_night!)
+
+ +

Options

+
  • +

    :of - Specifies the size of the batch. Defaults to 1000.

    +
  • +

    :load - Specifies if the relation should be loaded. Defaults to false.

    +
  • +

    :start - Specifies the primary key value to start from, inclusive of the value.

    +
  • +

    :finish - Specifies the primary key value to end at, inclusive of the value.

    +
  • +

    :error_on_ignore - Overrides the application config to specify if an error should be raised when an order is present in the relation.

    +
+ +

Limits are honored, and if present there is no requirement for the batch size, it can be less than, equal, or greater than the limit.

+ +

The options start and finish are especially useful if you want multiple workers dealing with the same processing queue. You can make worker 1 handle all the records between id 1 and 9999 and worker 2 handle from 10000 and beyond by setting the :start and :finish option on each worker.

+ +
# Let's process from record 10_000 on.
+Person.in_batches(start: 10_000).update_all(awesome: true)
+
+ +

An example of calling where query method on the relation:

+ +
Person.in_batches.each do |relation|
+  relation.update_all('age = age + 1')
+  relation.where('age > 21').update_all(should_party: true)
+  relation.where('age <= 21').delete_all
+end
+
+ +

NOTE: If you are going to iterate through each record, you should call each_record on the yielded BatchEnumerator:

+ +
Person.in_batches.each_record(&:party_all_night!)
+
+ +

NOTE: It's not possible to set the order. That is automatically set to ascending on the primary key (“id ASC”) to make the batch ordering consistent. Therefore the primary key must be orderable, e.g. an integer or a string.

+ +

NOTE: By its nature, batch processing is subject to race conditions if other processes are modifying the database.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/batches.rb, line 201
+def in_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil)
+  relation = self
+  unless block_given?
+    return BatchEnumerator.new(of: of, start: start, finish: finish, relation: self)
+  end
+
+  if arel.orders.present?
+    act_on_ignored_order(error_on_ignore)
+  end
+
+  batch_limit = of
+  if limit_value
+    remaining   = limit_value
+    batch_limit = remaining if remaining < batch_limit
+  end
+
+  relation = relation.reorder(batch_order).limit(batch_limit)
+  relation = apply_limits(relation, start, finish)
+  relation.skip_query_cache! # Retaining the results in the query cache would undermine the point of batching
+  batch_relation = relation
+
+  loop do
+    if load
+      records = batch_relation.records
+      ids = records.map(&:id)
+      yielded_relation = where(primary_key => ids)
+      yielded_relation.load_records(records)
+    else
+      ids = batch_relation.pluck(primary_key)
+      yielded_relation = where(primary_key => ids)
+    end
+
+    break if ids.empty?
+
+    primary_key_offset = ids.last
+    raise ArgumentError.new("Primary key not included in the custom select clause") unless primary_key_offset
+
+    yield yielded_relation
+
+    break if ids.length < batch_limit
+
+    if limit_value
+      remaining -= ids.length
+
+      if remaining == 0
+        # Saves a useless iteration when the limit is a multiple of the
+        # batch size.
+        break
+      elsif remaining < batch_limit
+        relation = relation.limit(remaining)
+      end
+    end
+
+    attr = Relation::QueryAttribute.new(primary_key, primary_key_offset, klass.type_for_attribute(primary_key))
+    batch_relation = relation.where(arel_attribute(primary_key).gt(Arel::Nodes::BindParam.new(attr)))
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Batches/BatchEnumerator.html b/src/5.2/classes/ActiveRecord/Batches/BatchEnumerator.html new file mode 100644 index 0000000000..b55375cc99 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Batches/BatchEnumerator.html @@ -0,0 +1,189 @@ +--- +title: ActiveRecord::Batches::BatchEnumerator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + each() + +

+ + +
+

Yields an ActiveRecord::Relation object for each batch of records.

+ +
Person.in_batches.each do |relation|
+  relation.update_all(awesome: true)
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 62
+def each
+  enum = @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: false)
+  return enum.each { |relation| yield relation } if block_given?
+  enum
+end
+
+
+ +
+ +
+

+ + each_record() + +

+ + +
+

Looping through a collection of records from the database (using the all method, for example) is very inefficient since it will try to instantiate all the objects at once.

+ +

In that case, batch processing methods allow you to work with the records in batches, thereby greatly reducing memory consumption.

+ +
Person.in_batches.each_record do |person|
+  person.do_awesome_stuff
+end
+
+Person.where("age > 21").in_batches(of: 10).each_record do |person|
+  person.party_all_night!
+end
+
+ +

If you do not provide a block to each_record, it will return an Enumerator for chaining with other methods:

+ +
Person.in_batches.each_record.with_index do |person, index|
+  person.award_trophy(index + 1)
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 36
+def each_record
+  return to_enum(:each_record) unless block_given?
+
+  @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: true).each do |relation|
+    relation.records.each { |record| yield record }
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Calculations.html b/src/5.2/classes/ActiveRecord/Calculations.html new file mode 100644 index 0000000000..9aa163bb24 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Calculations.html @@ -0,0 +1,535 @@ +--- +title: ActiveRecord::Calculations +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + average(column_name) + +

+ + +
+

Calculates the average value on a given column. Returns nil if there's no row. See calculate for examples with options.

+ +
Person.average(:age) # => 35.8
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 59
+def average(column_name)
+  calculate(:average, column_name)
+end
+
+
+ +
+ +
+

+ + calculate(operation, column_name) + +

+ + +
+

This calculates aggregate values in the given column. Methods for count, sum, average, minimum, and maximum have been added as shortcuts.

+ +
Person.calculate(:count, :all) # The same as Person.count
+Person.average(:age) # SELECT AVG(age) FROM people...
+
+# Selects the minimum age for any family without any minors
+Person.group(:last_name).having("min(age) > 17").minimum(:age)
+
+Person.sum("2 * age")
+
+ +

There are two basic forms of output:

+
  • +

    Single aggregate value: The single value is type cast to Integer for COUNT, Float for AVG, and the given column's type for everything else.

    +
  • +

    Grouped values: This returns an ordered hash of the values and groups them. It takes either a column name, or the name of a belongs_to association.

    + +
    values = Person.group('last_name').maximum(:age)
    +puts values["Drake"]
    +# => 43
    +
    +drake  = Family.find_by(last_name: 'Drake')
    +values = Person.group(:family).maximum(:age) # Person belongs_to :family
    +puts values[drake]
    +# => 43
    +
    +values.each do |family, max_age|
    +  ...
    +end
    +
    +
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 131
+def calculate(operation, column_name)
+  if has_include?(column_name)
+    relation = apply_join_dependency
+
+    if operation.to_s.downcase == "count"
+      unless distinct_value || distinct_select?(column_name || select_for_count)
+        relation.distinct!
+        relation.select_values = [ klass.primary_key || table[Arel.star] ]
+      end
+      # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
+      relation.order_values = []
+    end
+
+    relation.calculate(operation, column_name)
+  else
+    perform_calculation(operation, column_name)
+  end
+end
+
+
+ +
+ +
+

+ + count(column_name = nil) + +

+ + +
+

Count the records.

+ +
Person.count
+# => the total count of all people
+
+Person.count(:age)
+# => returns the total count of all people whose age is present in database
+
+Person.count(:all)
+# => performs a COUNT(*) (:all is an alias for '*')
+
+Person.distinct.count(:age)
+# => counts the number of different age values
+
+ +

If count is used with Relation#group, it returns a Hash whose keys represent the aggregated column, and the values are the respective amounts:

+ +
Person.group(:city).count
+# => { 'Rome' => 5, 'Paris' => 3 }
+
+ +

If count is used with Relation#group for multiple columns, it returns a Hash whose keys are an array containing the individual values of each column and the value of each key would be the count.

+ +
Article.group(:status, :category).count
+# =>  {["draft", "business"]=>10, ["draft", "technology"]=>4,
+       ["published", "business"]=>0, ["published", "technology"]=>2}
+
+ +

If count is used with Relation#select, it will count the selected columns:

+ +
Person.select(:age).count
+# => counts the number of different age values
+
+ +

Note: not all valid Relation#select expressions are valid count expressions. The specifics differ between databases. In invalid cases, an error from the database is thrown.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 41
+def count(column_name = nil)
+  if block_given?
+    unless column_name.nil?
+      ActiveSupport::Deprecation.warn \
+        "When `count' is called with a block, it ignores other arguments. " \
+        "This behavior is now deprecated and will result in an ArgumentError in Rails 6.0."
+    end
+
+    return super()
+  end
+
+  calculate(:count, column_name)
+end
+
+
+ +
+ +
+

+ + ids() + +

+ + +
+

Pluck all the ID's for the relation using the table's primary key

+ +
Person.ids # SELECT people.id FROM people
+Person.joins(:companies).ids # SELECT people.id FROM people INNER JOIN companies ON companies.person_id = people.id
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 206
+def ids
+  pluck primary_key
+end
+
+
+ +
+ +
+

+ + maximum(column_name) + +

+ + +
+

Calculates the maximum value on a given column. The value is returned with the same data type of the column, or nil if there's no row. See calculate for examples with options.

+ +
Person.maximum(:age) # => 93
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 77
+def maximum(column_name)
+  calculate(:maximum, column_name)
+end
+
+
+ +
+ +
+

+ + minimum(column_name) + +

+ + +
+

Calculates the minimum value on a given column. The value is returned with the same data type of the column, or nil if there's no row. See calculate for examples with options.

+ +
Person.minimum(:age) # => 7
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 68
+def minimum(column_name)
+  calculate(:minimum, column_name)
+end
+
+
+ +
+ +
+

+ + pluck(*column_names) + +

+ + +
+

Use pluck as a shortcut to select one or more attributes without loading a bunch of records just to grab the attributes you want.

+ +
Person.pluck(:name)
+
+ +

instead of

+ +
Person.all.map(&:name)
+
+ +

Pluck returns an Array of attribute values type-casted to match the plucked column names, if they can be deduced. Plucking an SQL fragment returns String values by default.

+ +
Person.pluck(:name)
+# SELECT people.name FROM people
+# => ['David', 'Jeremy', 'Jose']
+
+Person.pluck(:id, :name)
+# SELECT people.id, people.name FROM people
+# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
+
+Person.distinct.pluck(:role)
+# SELECT DISTINCT role FROM people
+# => ['admin', 'member', 'guest']
+
+Person.where(age: 21).limit(5).pluck(:id)
+# SELECT people.id FROM people WHERE people.age = 21 LIMIT 5
+# => [2, 3]
+
+Person.pluck('DATEDIFF(updated_at, created_at)')
+# SELECT DATEDIFF(updated_at, created_at) FROM people
+# => ['0', '27761', '173']
+
+ +

See also ids.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 185
+def pluck(*column_names)
+  if loaded? && (column_names.map(&:to_s) - @klass.attribute_names - @klass.attribute_aliases.keys).empty?
+    return records.pluck(*column_names)
+  end
+
+  if has_include?(column_names.first)
+    relation = apply_join_dependency
+    relation.pluck(*column_names)
+  else
+    klass.enforce_raw_sql_whitelist(column_names)
+    relation = spawn
+    relation.select_values = column_names
+    result = skip_query_cache_if_necessary { klass.connection.select_all(relation.arel, nil) }
+    result.cast_values(klass.attribute_types)
+  end
+end
+
+
+ +
+ +
+

+ + sum(column_name = nil) + +

+ + +
+

Calculates the sum of values on a given column. The value is returned with the same data type of the column, 0 if there's no row. See calculate for examples with options.

+ +
Person.sum(:age) # => 4562
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/calculations.rb, line 86
+def sum(column_name = nil)
+  if block_given?
+    unless column_name.nil?
+      ActiveSupport::Deprecation.warn \
+        "When `sum' is called with a block, it ignores other arguments. " \
+        "This behavior is now deprecated and will result in an ArgumentError in Rails 6.0."
+    end
+
+    return super()
+  end
+
+  calculate(:sum, column_name)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Callbacks.html b/src/5.2/classes/ActiveRecord/Callbacks.html new file mode 100644 index 0000000000..06d8a38e50 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Callbacks.html @@ -0,0 +1,364 @@ +--- +title: ActiveRecord::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Active Record Callbacks

+ +

Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic before or after an alteration of the object state. This can be used to make sure that associated and dependent objects are deleted when ActiveRecord::Base#destroy is called (by overwriting before_destroy) or to massage attributes before they're validated (by overwriting before_validation). As an example of the callbacks initiated, consider the ActiveRecord::Base#save call for a new record:

+
  • +

    (-) save

    +
  • +

    (-) valid

    +
  • +

    (1) before_validation

    +
  • +

    (-) validate

    +
  • +

    (2) after_validation

    +
  • +

    (3) before_save

    +
  • +

    (4) before_create

    +
  • +

    (-) create

    +
  • +

    (5) after_create

    +
  • +

    (6) after_save

    +
  • +

    (7) after_commit

    +
+ +

Also, an after_rollback callback can be configured to be triggered whenever a rollback is issued. Check out ActiveRecord::Transactions for more details about after_commit and after_rollback.

+ +

Additionally, an after_touch callback is triggered whenever an object is touched.

+ +

Lastly an after_find and after_initialize callback is triggered for each object that is found and instantiated by a finder, with after_initialize being triggered after new objects are instantiated as well.

+ +

There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the Active Record life cycle. The sequence for calling ActiveRecord::Base#save for an existing record is similar, except that each _create callback is replaced by the corresponding _update callback.

+ +

Examples:

+ +
class CreditCard < ActiveRecord::Base
+  # Strip everything but digits, so the user can specify "555 234 34" or
+  # "5552-3434" and both will mean "55523434"
+  before_validation(on: :create) do
+    self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
+  end
+end
+
+class Subscription < ActiveRecord::Base
+  before_create :record_signup
+
+  private
+    def record_signup
+      self.signed_up_on = Date.today
+    end
+end
+
+class Firm < ActiveRecord::Base
+  # Disables access to the system, for associated clients and people when the firm is destroyed
+  before_destroy { |record| Person.where(firm_id: record.id).update_all(access: 'disabled')   }
+  before_destroy { |record| Client.where(client_of: record.id).update_all(access: 'disabled') }
+end
+
+ +

Inheritable callback queues

+ +

Besides the overwritable callback methods, it's also possible to register callbacks through the use of the callback macros. Their main advantage is that the macros add behavior into a callback queue that is kept intact down through an inheritance hierarchy.

+ +
class Topic < ActiveRecord::Base
+  before_destroy :destroy_author
+end
+
+class Reply < Topic
+  before_destroy :destroy_readers
+end
+
+ +

Now, when Topic#destroy is run only destroy_author is called. When Reply#destroy is run, both destroy_author and destroy_readers are called. Contrast this to the following situation where the before_destroy method is overridden:

+ +
class Topic < ActiveRecord::Base
+  def before_destroy() destroy_author end
+end
+
+class Reply < Topic
+  def before_destroy() destroy_readers end
+end
+
+ +

In that case, Reply#destroy would only run destroy_readers and not destroy_author. So, use the callback macros when you want to ensure that a certain callback is called for the entire hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant to decide whether they want to call super and trigger the inherited callbacks.

+ +

IMPORTANT: In order for inheritance to work for the callback queues, you must specify the callbacks before specifying the associations. Otherwise, you might trigger the loading of a child before the parent has registered the callbacks and they won't be inherited.

+ +

Types of callbacks

+ +

There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects, inline methods (using a proc). Method references and callback objects are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for creating mix-ins).

+ +

The method reference callbacks work by specifying a protected or private method available in the object, like this:

+ +
class Topic < ActiveRecord::Base
+  before_destroy :delete_parents
+
+  private
+    def delete_parents
+      self.class.delete_all "parent_id = #{id}"
+    end
+end
+
+ +

The callback objects have methods named after the callback called with the record as the only parameter, such as:

+ +
class BankAccount < ActiveRecord::Base
+  before_save      EncryptionWrapper.new
+  after_save       EncryptionWrapper.new
+  after_initialize EncryptionWrapper.new
+end
+
+class EncryptionWrapper
+  def before_save(record)
+    record.credit_card_number = encrypt(record.credit_card_number)
+  end
+
+  def after_save(record)
+    record.credit_card_number = decrypt(record.credit_card_number)
+  end
+
+  alias_method :after_initialize, :after_save
+
+  private
+    def encrypt(value)
+      # Secrecy is committed
+    end
+
+    def decrypt(value)
+      # Secrecy is unveiled
+    end
+end
+
+ +

So you specify the object you want messaged on a given callback. When that callback is triggered, the object has a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other initialization data such as the name of the attribute to work with:

+ +
class BankAccount < ActiveRecord::Base
+  before_save      EncryptionWrapper.new("credit_card_number")
+  after_save       EncryptionWrapper.new("credit_card_number")
+  after_initialize EncryptionWrapper.new("credit_card_number")
+end
+
+class EncryptionWrapper
+  def initialize(attribute)
+    @attribute = attribute
+  end
+
+  def before_save(record)
+    record.send("#{@attribute}=", encrypt(record.send("#{@attribute}")))
+  end
+
+  def after_save(record)
+    record.send("#{@attribute}=", decrypt(record.send("#{@attribute}")))
+  end
+
+  alias_method :after_initialize, :after_save
+
+  private
+    def encrypt(value)
+      # Secrecy is committed
+    end
+
+    def decrypt(value)
+      # Secrecy is unveiled
+    end
+end
+
+ +

before_validation* returning statements

+ +

If the before_validation callback throws :abort, the process will be aborted and ActiveRecord::Base#save will return false. If ActiveRecord::Base#save! is called it will raise an ActiveRecord::RecordInvalid exception. Nothing will be appended to the errors object.

+ +

Canceling callbacks

+ +

If a before_* callback throws :abort, all the later callbacks and the associated action are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last.

+ +

Ordering callbacks

+ +

Sometimes the code needs that the callbacks execute in a specific order. For example, a before_destroy callback (log_children in this case) should be executed before the children get destroyed by the dependent: :destroy option.

+ +

Let's look at the code below:

+ +
class Topic < ActiveRecord::Base
+  has_many :children, dependent: :destroy
+
+  before_destroy :log_children
+
+  private
+    def log_children
+      # Child processing
+    end
+end
+
+ +

In this case, the problem is that when the before_destroy callback is executed, the children are not available because the ActiveRecord::Base#destroy callback gets executed first. You can use the prepend option on the before_destroy callback to avoid this.

+ +
class Topic < ActiveRecord::Base
+  has_many :children, dependent: :destroy
+
+  before_destroy :log_children, prepend: true
+
+  private
+    def log_children
+      # Child processing
+    end
+end
+
+ +

This way, the before_destroy gets executed before the dependent: :destroy is called, and the data is still available.

+ +

Also, there are cases when you want several callbacks of the same type to be executed in order.

+ +

For example:

+ +
class Topic < ActiveRecord::Base
+  has_many :children
+
+  after_save :log_children
+  after_save :do_something_else
+
+  private
+
+  def log_children
+    # Child processing
+  end
+
+  def do_something_else
+    # Something else
+  end
+end
+
+ +

In this case the log_children gets executed before do_something_else. The same applies to all non-transactional callbacks.

+ +

In case there are multiple transactional callbacks as seen below, the order is reversed.

+ +

For example:

+ +
class Topic < ActiveRecord::Base
+  has_many :children
+
+  after_commit :log_children
+  after_commit :do_something_else
+
+  private
+
+  def log_children
+    # Child processing
+  end
+
+  def do_something_else
+    # Something else
+  end
+end
+
+ +

In this case the do_something_else gets executed before log_children.

+ +

Transactions

+ +

The entire callback chain of a #save, #save!, or #destroy call runs within a transaction. That includes after_* hooks. If everything goes fine a COMMIT is executed once the chain has been completed.

+ +

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks. Note, however, that in that case the client needs to be aware of it because an ordinary #save will raise such exception instead of quietly returning false.

+ +

Debugging callbacks

+ +

The callback chain is accessible via the _*_callbacks method on an object. Active Model Callbacks support :before, :after and :around as values for the kind property. The kind property defines what part of the chain the callback runs in.

+ +

To find all callbacks in the before_save callback chain:

+ +
Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
+
+ +

Returns an array of callback objects that form the before_save chain.

+ +

To further check if the before_save chain contains a proc defined as rest_when_dead use the filter property of the callback object:

+ +
Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
+
+ +

Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.

+ +
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
CALLBACKS=[ +:after_initialize, :after_find, :after_touch, :before_validation, :after_validation, +:before_save, :around_save, :after_save, :before_create, :around_create, +:after_create, :before_update, :around_update, :after_update, +:before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback +]
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/CollectionCacheKey.html b/src/5.2/classes/ActiveRecord/CollectionCacheKey.html new file mode 100644 index 0000000000..2d4d0dffd7 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/CollectionCacheKey.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::CollectionCacheKey +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConfigurationError.html b/src/5.2/classes/ActiveRecord/ConfigurationError.html new file mode 100644 index 0000000000..607f8fa904 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConfigurationError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ConfigurationError +layout: default +--- +
+ +
+
+ +
+ +

Raised when association is being configured improperly or user tries to use offset and limit together with ActiveRecord::Base.has_many or ActiveRecord::Base.has_and_belongs_to_many associations.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters.html new file mode 100644 index 0000000000..451f36c2b7 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters.html @@ -0,0 +1,274 @@ +--- +title: ActiveRecord::ConnectionAdapters +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html new file mode 100644 index 0000000000..a63017e4d4 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html @@ -0,0 +1,2090 @@ +--- +title: ActiveRecord::ConnectionAdapters::AbstractAdapter +layout: default +--- +
+ +
+
+ +
+ +

Active Record supports multiple database systems. AbstractAdapter and related classes form the abstraction layer which makes this possible. An AbstractAdapter represents a connection to a database, and provides an abstract interface for database-specific functionality such as establishing a connection, escaping values, building the right SQL fragments for :offset and :limit options, etc.

+ +

All the concrete database adapters follow the interface laid down in this class. ActiveRecord::Base.connection returns an AbstractAdapter object, which you can use.

+ +

Most of the methods in the adapter are useful during migrations. Most notably, the instance methods provided by SchemaStatements are very useful.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
ADAPTER_NAME="Abstract".freeze
 
SIMPLE_INT=/\A\d+\z/
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + in_use?
+ [R] + lock
+ [R] + logger
+ [R] + owner
+ [RW] + pool
+ [R] + prepared_statements
+ [R] + schema_cache
+ [RW] + visitor
+ + + + +

Class Public methods

+ +
+

+ + type_cast_config_to_boolean(config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 93
+def self.type_cast_config_to_boolean(config)
+  if config == "false"
+    false
+  else
+    config
+  end
+end
+
+
+ +
+ +
+

+ + type_cast_config_to_integer(config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 83
+def self.type_cast_config_to_integer(config)
+  if config.is_a?(Integer)
+    config
+  elsif config =~ SIMPLE_INT
+    config.to_i
+  else
+    config
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+

Checks whether the connection to the database is still active. This includes checking whether the database is actually capable of responding, i.e. whether the connection isn't stale.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 380
+def active?
+end
+
+
+ +
+ +
+

+ + adapter_name() + +

+ + +
+

Returns the human-readable name of the adapter. Use mixed case - one can always use downcase if needed.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 213
+def adapter_name
+  self.class::ADAPTER_NAME
+end
+
+
+ +
+ +
+

+ + clear_cache!() + +

+ + +
+

Clear any caching the database adapter may be doing, for example clearing the prepared statement cache. This is database specific.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 424
+def clear_cache!
+  # this should be overridden by concrete adapters
+end
+
+
+ +
+ +
+

+ + close() + +

+ + +
+

Check the connection back in to the connection pool

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 468
+def close
+  pool.checkin self
+end
+
+
+ +
+ +
+

+ + disable_extension(name) + +

+ + +
+

This is meant to be implemented by the adapters that support extensions

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 337
+def disable_extension(name)
+end
+
+
+ +
+ +
+

+ + disable_referential_integrity() + +

+ + +
+

Override to turn off referential integrity while executing &block.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 371
+def disable_referential_integrity
+  yield
+end
+
+
+ +
+ +
+

+ + discard!() + +

+ + +
+

Immediately forget this connection ever existed. Unlike disconnect!, this will not communicate with the server.

+ +

After calling this method, the behavior of all other methods becomes undefined. This is called internally just before a forked process gets rid of a connection that belonged to its parent.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 404
+def discard!
+  # This should be overridden by concrete adapters.
+  #
+  # Prevent @connection's finalizer from touching the socket, or
+  # otherwise communicating with its server, when it is collected.
+end
+
+
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 393
+def disconnect!
+  clear_cache!
+  reset_transaction
+end
+
+
+ +
+ +
+

+ + enable_extension(name) + +

+ + +
+

This is meant to be implemented by the adapters that support extensions

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 341
+def enable_extension(name)
+end
+
+
+ +
+ +
+

+ + expire() + +

+ + +
+

this method must only be called while holding connection pool's mutex

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 170
+def expire
+  if in_use?
+    if @owner != Thread.current
+      raise ActiveRecordError, "Cannot expire connection, " \
+        "it is owned by a different thread: #{@owner}. " \
+        "Current thread: #{Thread.current}."
+    end
+
+    @idle_since = Concurrent.monotonic_time
+    @owner = nil
+  else
+    raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
+  end
+end
+
+
+ +
+ +
+

+ + extensions() + +

+ + +
+

A list of extensions, to be filled in by adapters that support them.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 359
+def extensions
+  []
+end
+
+
+ +
+ +
+

+ + index_algorithms() + +

+ + +
+

A list of index algorithms, to be filled by adapters that support them.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 364
+def index_algorithms
+  {}
+end
+
+
+ +
+ +
+

+ + lease() + +

+ + +
+

this method must only be called while holding connection pool's mutex

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 149
+def lease
+  if in_use?
+    msg = "Cannot lease connection, ".dup
+    if @owner == Thread.current
+      msg << "it is already leased by the current thread."
+    else
+      msg << "it is already in use by a different thread: #{@owner}. " \
+             "Current thread: #{Thread.current}."
+    end
+    raise ActiveRecordError, msg
+  end
+
+  @owner = Thread.current
+end
+
+
+ +
+ +
+

+ + prefetch_primary_key?(table_name = nil) + +

+ + +
+

Should primary key values be selected from their corresponding sequence before the insert statement? If true, next_sequence_value is called before each insert to set the record's primary key.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 240
+def prefetch_primary_key?(table_name = nil)
+  false
+end
+
+
+ +
+ +
+

+ + raw_connection() + +

+ + +
+

Provides access to the underlying database driver for this adapter. For example, this method returns a Mysql2::Client object in case of Mysql2Adapter, and a PG::Connection object in case of PostgreSQLAdapter.

+ +

This is useful for when you need to call a proprietary method such as PostgreSQL's lo_* methods.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 446
+def raw_connection
+  @connection
+end
+
+
+ +
+ +
+

+ + reconnect!() + +

+ + +
+

Disconnects from the database if already connected, and establishes a new connection with the database. Implementors should call super if they override the default implementation.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 386
+def reconnect!
+  clear_cache!
+  reset_transaction
+end
+
+
+ +
+ +
+

+ + requires_reloading?() + +

+ + +
+

Returns true if its required to reload the connection between requests for development mode.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 429
+def requires_reloading?
+  false
+end
+
+
+ +
+ +
+

+ + reset!() + +

+ + +
+

Reset the state of this connection, directing the DBMS to clear transactions and other connection-related server-side state. Usually a database-dependent operation.

+ +

The default implementation does nothing; the implementation should be overridden by concrete adapters.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 417
+def reset!
+  # this should be overridden by concrete adapters
+end
+
+
+ +
+ +
+

+ + schema_cache=(cache) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 164
+def schema_cache=(cache)
+  cache.connection = self
+  @schema_cache = cache
+end
+
+
+ +
+ +
+

+ + supports_advisory_locks?() + +

+ + +
+

Does this adapter support application-enforced advisory locking?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 233
+def supports_advisory_locks?
+  false
+end
+
+
+ +
+ +
+

+ + supports_bulk_alter?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 223
+def supports_bulk_alter?
+  false
+end
+
+
+ +
+ +
+

+ + supports_comments?() + +

+ + +
+

Does this adapter support metadata comments on database objects (tables, columns, indexes)?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 312
+def supports_comments?
+  false
+end
+
+
+ +
+ +
+

+ + supports_comments_in_create?() + +

+ + +
+

Can comments for tables, columns, and indexes be specified in create/alter table statements?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 317
+def supports_comments_in_create?
+  false
+end
+
+
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+

Does this adapter support datetime with precision?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 302
+def supports_datetime_with_precision?
+  false
+end
+
+
+ +
+ +
+

+ + supports_ddl_transactions?() + +

+ + +
+

Does this adapter support DDL rollbacks in transactions? That is, would CREATE TABLE or ALTER TABLE get rolled back by a transaction?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 219
+def supports_ddl_transactions?
+  false
+end
+
+
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+

Does this adapter support explain?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 260
+def supports_explain?
+  false
+end
+
+
+ +
+ +
+

+ + supports_expression_index?() + +

+ + +
+

Does this adapter support expression indices?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 255
+def supports_expression_index?
+  false
+end
+
+
+ +
+ +
+

+ + supports_extensions?() + +

+ + +
+

Does this adapter support database extensions?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 270
+def supports_extensions?
+  false
+end
+
+
+ +
+ +
+

+ + supports_foreign_keys?() + +

+ + +
+

Does this adapter support creating foreign key constraints?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 281
+def supports_foreign_keys?
+  false
+end
+
+
+ +
+ +
+

+ + supports_foreign_keys_in_create?() + +

+ + +
+

Does this adapter support creating foreign key constraints in the same statement as creating the table?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 292
+def supports_foreign_keys_in_create?
+  supports_foreign_keys?
+end
+
+
+ +
+ +
+

+ + supports_foreign_tables?() + +

+ + +
+

Does this adapter support foreign/external tables?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 332
+def supports_foreign_tables?
+  false
+end
+
+
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+

Does this adapter support index sort order?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 245
+def supports_index_sort_order?
+  false
+end
+
+
+ +
+ +
+

+ + supports_indexes_in_create?() + +

+ + +
+

Does this adapter support creating indexes in the same statement as creating the table?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 276
+def supports_indexes_in_create?
+  false
+end
+
+
+ +
+ +
+

+ + supports_json?() + +

+ + +
+

Does this adapter support json data type?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 307
+def supports_json?
+  false
+end
+
+
+ +
+ +
+

+ + supports_multi_insert?() + +

+ + +
+

Does this adapter support multi-value insert?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 322
+def supports_multi_insert?
+  true
+end
+
+
+ +
+ +
+

+ + supports_partial_index?() + +

+ + +
+

Does this adapter support partial indices?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 250
+def supports_partial_index?
+  false
+end
+
+
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+

Does this adapter support savepoints?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 228
+def supports_savepoints?
+  false
+end
+
+
+ +
+ +
+

+ + supports_transaction_isolation?() + +

+ + +
+

Does this adapter support setting the isolation level for a transaction?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 265
+def supports_transaction_isolation?
+  false
+end
+
+
+ +
+ +
+

+ + supports_validate_constraints?() + +

+ + +
+

Does this adapter support creating invalid constraints?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 286
+def supports_validate_constraints?
+  false
+end
+
+
+ +
+ +
+

+ + supports_views?() + +

+ + +
+

Does this adapter support views?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 297
+def supports_views?
+  false
+end
+
+
+ +
+ +
+

+ + supports_virtual_columns?() + +

+ + +
+

Does this adapter support virtual columns?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 327
+def supports_virtual_columns?
+  false
+end
+
+
+ +
+ +
+

+ + unprepared_statement() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 204
+def unprepared_statement
+  old_prepared_statements, @prepared_statements = @prepared_statements, false
+  yield
+ensure
+  @prepared_statements = old_prepared_statements
+end
+
+
+ +
+ +
+

+ + verify!() + +

+ + +
+

Checks whether the connection to the database is still active (i.e. not stale). This is done under the hood by calling active?. If the connection is no longer active, then this method will reconnect to the database.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 436
+def verify!
+  reconnect! unless active?
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 570
+def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
+  @instrumenter.instrument(
+    "sql.active_record",
+    sql:               sql,
+    name:              name,
+    binds:             binds,
+    type_casted_binds: type_casted_binds,
+    statement_name:    statement_name,
+    connection_id:     object_id) do
+    begin
+      @lock.synchronize do
+        yield
+      end
+    rescue => e
+      raise translate_exception_class(e, sql)
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter/Version.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter/Version.html new file mode 100644 index 0000000000..4fcdd7285a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter/Version.html @@ -0,0 +1,161 @@ +--- +title: ActiveRecord::ConnectionAdapters::AbstractAdapter::Version +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Comparable + +
  • + +
+ + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(version_string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 135
+def initialize(version_string)
+  @version = version_string.split(".").map(&:to_i)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(version_string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 139
+def <=>(version_string)
+  @version <=> version_string.split(".").map(&:to_i)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html new file mode 100644 index 0000000000..0dd05cdbfe --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html @@ -0,0 +1,1596 @@ +--- +title: ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ER_CANNOT_ADD_FOREIGN=1215
 
ER_CANNOT_CREATE_TABLE=1005
 
ER_DATA_TOO_LONG=1406
 
ER_DO_NOT_HAVE_DEFAULT=1364
 
ER_DUP_ENTRY=1062
 

See dev.mysql.com/doc/refman/5.7/en/error-messages-server.html

ER_LOCK_DEADLOCK=1213
 
ER_LOCK_WAIT_TIMEOUT=1205
 
ER_NOT_NULL_VIOLATION=1048
 
ER_NO_REFERENCED_ROW_2=1452
 
ER_OUT_OF_RANGE=1264
 
ER_QUERY_INTERRUPTED=1317
 
ER_QUERY_TIMEOUT=3024
 
NATIVE_DATABASE_TYPES={ +primary_key: "bigint auto_increment PRIMARY KEY", +string: { name: "varchar", limit: 255 }, +text: { name: "text", limit: 65535 }, +integer: { name: "int", limit: 4 }, +float: { name: "float", limit: 24 }, +decimal: { name: "decimal" }, +datetime: { name: "datetime" }, +timestamp: { name: "timestamp" }, +time: { name: "time" }, +date: { name: "date" }, +binary: { name: "blob", limit: 65535 }, +boolean: { name: "tinyint", limit: 1 }, +json: { name: "json" }, +}
 
+ + + + + + +

Class Public methods

+ +
+

+ + emulate_booleans + +

+ + +
+

By default, the Mysql2Adapter will consider all columns of type tinyint(1) as boolean. If you wish to disable this emulation you can add the following line to your application.rb file:

+ +
ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 29
+class_attribute :emulate_booleans, default: true
+
+
+
+ +
+ +
+

+ + new(connection, logger, connection_options, config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 53
+def initialize(connection, logger, connection_options, config)
+  super(connection, logger, config)
+
+  @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
+
+  if version < "5.1.10"
+    raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.1.10."
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + begin_db_transaction() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 199
+def begin_db_transaction
+  execute "BEGIN"
+end
+
+
+ +
+ +
+

+ + begin_isolated_db_transaction(isolation) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 203
+def begin_isolated_db_transaction(isolation)
+  execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}"
+  begin_db_transaction
+end
+
+
+ +
+ +
+

+ + charset() + +

+ + +
+

Returns the database character set.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 271
+def charset
+  show_variable "character_set_database"
+end
+
+
+ +
+ +
+

+ + clear_cache!() + +

+ + +
+

Clears the prepared statements cache.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 165
+def clear_cache!
+  reload_type_map
+  @statements.clear
+end
+
+
+ +
+ +
+

+ + collation() + +

+ + +
+

Returns the database collation strategy.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 276
+def collation
+  show_variable "collation_database"
+end
+
+
+ +
+ +
+

+ + create_database(name, options = {}) + +

+ + +
+

Create a new MySQL database with optional :charset and :collation. Charset defaults to utf8.

+ +

Example:

+ +
create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin'
+create_database 'matt_development'
+create_database 'matt_development', charset: :big5
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 250
+def create_database(name, options = {})
+  if options[:collation]
+    execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT COLLATE #{quote_table_name(options[:collation])}"
+  else
+    execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset] || 'utf8')}"
+  end
+end
+
+
+ +
+ +
+

+ + current_database() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 266
+def current_database
+  query_value("SELECT database()", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + drop_table(table_name, options = {}) + +

+ + +
+

Drops a table from the database.

+
:force +
+

Set to :cascade to drop dependent objects as well. Defaults to false.

+
:if_exists +
+

Set to true to only drop the table if it exists. Defaults to false.

+
:temporary +
+

Set to true to drop temporary table. Defaults to false.

+
+ +

Although this command ignores most options and the block if one is given, it can be helpful to provide these in a migration's change method so it can be reverted. In that case, options and the block will be used by create_table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 339
+def drop_table(table_name, options = {})
+  execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
+end
+
+
+ +
+ +
+

+ + empty_insert_statement_value() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 228
+def empty_insert_statement_value
+  "VALUES ()"
+end
+
+
+ +
+ +
+

+ + execute(sql, name = nil) + +

+ + +
+

Executes the SQL statement in the context of this connection.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 184
+def execute(sql, name = nil)
+  log(sql, name) do
+    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
+      @connection.query(sql)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + explain(arel, binds = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 174
+def explain(arel, binds = [])
+  sql     = "EXPLAIN #{to_sql(arel, binds)}"
+  start   = Time.now
+  result  = exec_query(sql, "EXPLAIN", binds)
+  elapsed = Time.now - start
+
+  MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
+end
+
+
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 390
+      def foreign_keys(table_name)
+        raise ArgumentError unless table_name.present?
+
+        scope = quoted_scope(table_name)
+
+        fk_info = exec_query(<<-SQL.strip_heredoc, "SCHEMA")
+          SELECT fk.referenced_table_name AS 'to_table',
+                 fk.referenced_column_name AS 'primary_key',
+                 fk.column_name AS 'column',
+                 fk.constraint_name AS 'name',
+                 rc.update_rule AS 'on_update',
+                 rc.delete_rule AS 'on_delete'
+          FROM information_schema.referential_constraints rc
+          JOIN information_schema.key_column_usage fk
+          USING (constraint_schema, constraint_name)
+          WHERE fk.referenced_column_name IS NOT NULL
+            AND fk.table_schema = #{scope[:schema]}
+            AND fk.table_name = #{scope[:name]}
+            AND rc.constraint_schema = #{scope[:schema]}
+            AND rc.table_name = #{scope[:name]}
+        SQL
+
+        fk_info.map do |row|
+          options = {
+            column: row["column"],
+            name: row["name"],
+            primary_key: row["primary_key"]
+          }
+
+          options[:on_update] = extract_foreign_key_action(row["on_update"])
+          options[:on_delete] = extract_foreign_key_action(row["on_delete"])
+
+          ForeignKeyDefinition.new(table_name, row["to_table"], options)
+        end
+      end
+
+
+ +
+ +
+

+ + index_algorithms() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 131
+def index_algorithms
+  { default: "ALGORITHM = DEFAULT".dup, copy: "ALGORITHM = COPY".dup, inplace: "ALGORITHM = INPLACE".dup }
+end
+
+
+ +
+ +
+

+ + insert_fixtures_set(fixture_set, tables_to_delete = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 529
+def insert_fixtures_set(fixture_set, tables_to_delete = [])
+  with_multi_statements do
+    super { discard_remaining_results }
+  end
+end
+
+
+ +
+ +
+

+ + native_database_types() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 127
+def native_database_types
+  NATIVE_DATABASE_TYPES
+end
+
+
+ +
+ +
+

+ + recreate_database(name, options = {}) + +

+ + +
+

Drops the database specified on the name attribute and creates it again using the provided options.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 236
+def recreate_database(name, options = {})
+  drop_database(name)
+  sql = create_database(name, options)
+  reconnect!
+  sql
+end
+
+
+ +
+ +
+

+ + rename_index(table_name, old_name, new_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 343
+def rename_index(table_name, old_name, new_name)
+  if supports_rename_index?
+    validate_index_length!(table_name, new_name)
+
+    execute "ALTER TABLE #{quote_table_name(table_name)} RENAME INDEX #{quote_table_name(old_name)} TO #{quote_table_name(new_name)}"
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + rename_table(table_name, new_name) + +

+ + +
+

Renames a table.

+ +

Example:

+ +
rename_table('octopuses', 'octopi')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 319
+def rename_table(table_name, new_name)
+  execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
+  rename_table_indexes(table_name, new_name)
+end
+
+
+ +
+ +
+

+ + show_variable(name) + +

+ + +
+

SHOW VARIABLES LIKE 'name'

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 472
+def show_variable(name)
+  query_value("SELECT @@#{name}", "SCHEMA")
+rescue ActiveRecord::StatementInvalid
+  nil
+end
+
+
+ +
+ +
+

+ + strict_mode?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 521
+def strict_mode?
+  self.class.type_cast_config_to_boolean(@config.fetch(:strict, true))
+end
+
+
+ +
+ +
+

+ + supports_advisory_locks?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 115
+def supports_advisory_locks?
+  true
+end
+
+
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 99
+def supports_datetime_with_precision?
+  if mariadb?
+    version >= "5.3.0"
+  else
+    version >= "5.6.4"
+  end
+end
+
+
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 83
+def supports_explain?
+  true
+end
+
+
+ +
+ +
+

+ + supports_foreign_keys?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 91
+def supports_foreign_keys?
+  true
+end
+
+
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 75
+def supports_index_sort_order?
+  !mariadb? && version >= "8.0.1"
+end
+
+
+ +
+ +
+

+ + supports_indexes_in_create?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 87
+def supports_indexes_in_create?
+  true
+end
+
+
+ +
+ +
+

+ + supports_transaction_isolation?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 79
+def supports_transaction_isolation?
+  true
+end
+
+
+ +
+ +
+

+ + supports_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 95
+def supports_views?
+  true
+end
+
+
+ +
+ +
+

+ + supports_virtual_columns?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 107
+def supports_virtual_columns?
+  if mariadb?
+    version >= "5.2.0"
+  else
+    version >= "5.7.5"
+  end
+end
+
+
+ +
+ +
+

+ + truncate(table_name, name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 280
+def truncate(table_name, name = nil)
+  execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/Column.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Column.html new file mode 100644 index 0000000000..6afd166828 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Column.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::Column +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/ColumnMethods.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ColumnMethods.html new file mode 100644 index 0000000000..83582b3437 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ColumnMethods.html @@ -0,0 +1,101 @@ +--- +title: ActiveRecord::ConnectionAdapters::ColumnMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + primary_key(name, type = :primary_key, **options) + +

+ + +
+

Appends a primary key definition to the table definition. Can be called multiple times, but this is probably not a good idea.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 204
+def primary_key(name, type = :primary_key, **options)
+  column(name, type, options.merge(primary_key: true))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionHandler.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionHandler.html new file mode 100644 index 0000000000..c72561b510 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionHandler.html @@ -0,0 +1,621 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionHandler +layout: default +--- +
+ +
+
+ +
+ +

ConnectionHandler is a collection of ConnectionPool objects. It is used for keeping separate connection pools that connect to different databases.

+ +

For example, suppose that you have 5 models, with the following hierarchy:

+ +
class Author < ActiveRecord::Base
+end
+
+class BankAccount < ActiveRecord::Base
+end
+
+class Book < ActiveRecord::Base
+  establish_connection :library_db
+end
+
+class ScaryBook < Book
+end
+
+class GoodBook < Book
+end
+
+ +

And a database.yml that looked like this:

+ +
development:
+  database: my_application
+  host: localhost
+
+library_db:
+  database: library
+  host: some.library.org
+
+ +

Your primary database in the development environment is “my_application” but the Book model connects to a separate database called “library_db” (this can even be a database on a different machine).

+ +

Book, ScaryBook and GoodBook will all use the same connection pool to “library_db” while Author, BankAccount, and any other models you create will use the default connection pool to “my_application”.

+ +

The various connection pools are managed by a single instance of ConnectionHandler accessible via ActiveRecord::Base.connection_handler. All Active Record models use this handler to determine the connection pool that they should use.

+ +

The ConnectionHandler class is not coupled with the Active models, as it has no knowledge about the model. The model needs to pass a specification name to the handler, in order to look up the correct connection pool.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 959
+def initialize
+  # These caches are keyed by spec.name (ConnectionSpecification#name).
+  @owner_to_pool = ConnectionHandler.create_owner_to_pool
+
+  # Backup finalizer: if the forked child never needed a pool, the above
+  # early discard has not occurred
+  ObjectSpace.define_finalizer self, ConnectionHandler.unowned_pool_finalizer(@owner_to_pool)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + active_connections?() + +

+ + +
+

Returns true if there are any active connections among the connection pools that the ConnectionHandler is managing.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 997
+def active_connections?
+  connection_pool_list.any?(&:active_connection?)
+end
+
+
+ +
+ +
+

+ + clear_active_connections!() + +

+ + +
+

Returns any connections in use by the current thread back to the pool, and also returns connections to the pool cached by threads that are no longer alive.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1004
+def clear_active_connections!
+  connection_pool_list.each(&:release_connection)
+end
+
+
+ +
+ +
+

+ + clear_all_connections!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1015
+def clear_all_connections!
+  connection_pool_list.each(&:disconnect!)
+end
+
+
+ +
+ +
+

+ + clear_reloadable_connections!() + +

+ + +
+

Clears the cache which maps classes.

+ +

See ConnectionPool#clear_reloadable_connections! for details.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1011
+def clear_reloadable_connections!
+  connection_pool_list.each(&:clear_reloadable_connections!)
+end
+
+
+ +
+ +
+

+ + connected?(spec_name) + +

+ + +
+

Returns true if a connection that's accessible to this class has already been opened.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1038
+def connected?(spec_name)
+  conn = retrieve_connection_pool(spec_name)
+  conn && conn.connected?
+end
+
+
+ +
+ +
+

+ + connection_pool_list() + +

+ + +
+ +
+ + + +
+ Also aliased as: connection_pools +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 968
+def connection_pool_list
+  owner_to_pool.values.compact
+end
+
+
+ +
+ +
+

+ + connection_pools() + +

+ + +
+ +
+ + + + + +
+ Alias for: connection_pool_list +
+ + + +
+ +
+

+ + establish_connection(config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 973
+def establish_connection(config)
+  resolver = ConnectionSpecification::Resolver.new(Base.configurations)
+  spec = resolver.spec(config)
+
+  remove_connection(spec.name)
+
+  message_bus = ActiveSupport::Notifications.instrumenter
+  payload = {
+    connection_id: object_id
+  }
+  if spec
+    payload[:spec_name] = spec.name
+    payload[:config] = spec.config
+  end
+
+  message_bus.instrument("!connection.active_record", payload) do
+    owner_to_pool[spec.name] = ConnectionAdapters::ConnectionPool.new(spec)
+  end
+
+  owner_to_pool[spec.name]
+end
+
+
+ +
+ +
+

+ + flush_idle_connections!() + +

+ + +
+

Disconnects all currently idle connections.

+ +

See ConnectionPool#flush! for details.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1022
+def flush_idle_connections!
+  connection_pool_list.each(&:flush!)
+end
+
+
+ +
+ +
+

+ + remove_connection(spec_name) + +

+ + +
+

Remove the connection for this class. This will close the active connection and the defined connection (if they exist). The result can be used as an argument for establish_connection, for easily re-establishing the connection.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1047
+def remove_connection(spec_name)
+  if pool = owner_to_pool.delete(spec_name)
+    pool.automatic_reconnect = false
+    pool.disconnect!
+    pool.spec.config
+  end
+end
+
+
+ +
+ +
+

+ + retrieve_connection_pool(spec_name) + +

+ + +
+

Retrieving the connection pool happens a lot, so we cache it in @owner_to_pool. This makes retrieving the connection pool O(1) once the process is warm. When a connection is established or removed, we invalidate the cache.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 1058
+def retrieve_connection_pool(spec_name)
+  owner_to_pool.fetch(spec_name) do
+    # Check if a connection was previously established in an ancestor process,
+    # which may have been forked.
+    if ancestor_pool = pool_from_any_process_for(spec_name)
+      # A connection was established in an ancestor process that must have
+      # subsequently forked. We can't reuse the connection, but we can copy
+      # the specification and establish a new connection with it.
+      establish_connection(ancestor_pool.spec.to_hash).tap do |pool|
+        pool.schema_cache = ancestor_pool.schema_cache if ancestor_pool.schema_cache
+      end
+    else
+      owner_to_pool[spec_name] = nil
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html new file mode 100644 index 0000000000..ef1165bee2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html @@ -0,0 +1,1132 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionPool +layout: default +--- +
+ +
+
+ +
+ +

Connection pool base class for managing Active Record database connections.

+ +

Introduction

+ +

A connection pool synchronizes thread access to a limited number of database connections. The basic idea is that each thread checks out a database connection from the pool, uses that connection, and checks the connection back in. ConnectionPool is completely thread-safe, and will ensure that a connection cannot be used by two threads at the same time, as long as ConnectionPool's contract is correctly followed. It will also handle cases in which there are more threads than connections: if all connections have been checked out, and a thread tries to checkout a connection anyway, then ConnectionPool will wait until some other thread has checked in a connection.

+ +

Obtaining (checking out) a connection

+ +

Connections can be obtained and used from a connection pool in several ways:

+
  1. +

    Simply use ActiveRecord::Base.connection as with Active Record 2.1 and earlier (pre-connection-pooling). Eventually, when you're done with the connection(s) and wish it to be returned to the pool, you call ActiveRecord::Base.clear_active_connections!. This will be the default behavior for Active Record when used in conjunction with Action Pack's request handling cycle.

    +
  2. +

    Manually check out a connection from the pool with ActiveRecord::Base.connection_pool.checkout. You are responsible for returning this connection to the pool when finished by calling ActiveRecord::Base.connection_pool.checkin(connection).

    +
  3. +

    Use ActiveRecord::Base.connection_pool.with_connection(&block), which obtains a connection, yields it as the sole argument to the block, and returns it to the pool after the block completes.

    +
+ +

Connections in the pool are actually AbstractAdapter objects (or objects compatible with AbstractAdapter's interface).

+ +

Options

+ +

There are several connection-pooling-related options that you can add to your database connection configuration:

+
  • +

    pool: maximum number of connections the pool may manage (default 5).

    +
  • +

    idle_timeout: number of seconds that a connection will be kept unused in the pool before it is automatically disconnected (default 300 seconds). Set this to zero to keep connections forever.

    +
  • +

    checkout_timeout: number of seconds to wait for a connection to become available before giving up and raising a timeout error (default 5 seconds).

    +
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + automatic_reconnect
+ [RW] + checkout_timeout
+ [R] + reaper
+ [RW] + schema_cache
+ [R] + size
+ [R] + spec
+ + + + +

Class Public methods

+ +
+

+ + new(spec) + +

+ + +
+

Creates a new ConnectionPool object. spec is a ConnectionSpecification object which describes database connection information (e.g. adapter, host name, username, password, etc), as well as the maximum size for this ConnectionPool.

+ +

The default ConnectionPool maximum size is 5.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 321
+def initialize(spec)
+  super()
+
+  @spec = spec
+
+  @checkout_timeout = (spec.config[:checkout_timeout] && spec.config[:checkout_timeout].to_f) || 5
+  if @idle_timeout = spec.config.fetch(:idle_timeout, 300)
+    @idle_timeout = @idle_timeout.to_f
+    @idle_timeout = nil if @idle_timeout <= 0
+  end
+
+  # default max pool size to 5
+  @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
+
+  # This variable tracks the cache of threads mapped to reserved connections, with the
+  # sole purpose of speeding up the +connection+ method. It is not the authoritative
+  # registry of which thread owns which connection. Connection ownership is tracked by
+  # the +connection.owner+ attr on each +connection+ instance.
+  # The invariant works like this: if there is mapping of <tt>thread => conn</tt>,
+  # then that +thread+ does indeed own that +conn+. However, an absence of a such
+  # mapping does not mean that the +thread+ doesn't own the said connection. In
+  # that case +conn.owner+ attr should be consulted.
+  # Access and modification of <tt>@thread_cached_conns</tt> does not require
+  # synchronization.
+  @thread_cached_conns = Concurrent::Map.new(initial_capacity: @size)
+
+  @connections         = []
+  @automatic_reconnect = true
+
+  # Connection pool allows for concurrent (outside the main +synchronize+ section)
+  # establishment of new connections. This variable tracks the number of threads
+  # currently in the process of independently establishing connections to the DB.
+  @now_connecting = 0
+
+  @threads_blocking_new_connections = 0
+
+  @available = ConnectionLeasingQueue.new self
+
+  @lock_thread = false
+
+  # +reaping_frequency+ is configurable mostly for historical reasons, but it could
+  # also be useful if someone wants a very low +idle_timeout+.
+  reaping_frequency = spec.config.fetch(:reaping_frequency, 60)
+  @reaper = Reaper.new(self, reaping_frequency && reaping_frequency.to_f)
+  @reaper.run
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + active_connection?() + +

+ + +
+

Returns true if there is an open connection being used for the current thread.

+ +

This method only works for connections that have been obtained through connection or with_connection methods. Connections obtained through checkout will not be detected by active_connection?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 390
+def active_connection?
+  @thread_cached_conns[connection_cache_key(current_thread)]
+end
+
+
+ +
+ +
+

+ + checkin(conn) + +

+ + +
+

Check-in a database connection back into the pool, indicating that you no longer need this connection.

+ +

conn: an AbstractAdapter object, which was obtained by earlier by calling checkout on this pool.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 546
+def checkin(conn)
+  conn.lock.synchronize do
+    synchronize do
+      remove_connection_from_thread_cache conn
+
+      conn._run_checkin_callbacks do
+        conn.expire
+      end
+
+      @available.add conn
+    end
+  end
+end
+
+
+ +
+ +
+

+ + checkout(checkout_timeout = @checkout_timeout) + +

+ + +
+

Check-out a database connection from the pool, indicating that you want to use it. You should call checkin when you no longer need this.

+ +

This is done by either returning and leasing existing connection, or by creating a new connection and leasing it.

+ +

If all connections are leased and the pool is at capacity (meaning the number of currently leased connections is greater than or equal to the size limit set), an ActiveRecord::ConnectionTimeoutError exception will be raised.

+ +

Returns: an AbstractAdapter object.

+ +

Raises:

+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 537
+def checkout(checkout_timeout = @checkout_timeout)
+  checkout_and_verify(acquire_connection(checkout_timeout))
+end
+
+
+ +
+ +
+

+ + clear_reloadable_connections(raise_on_acquisition_timeout = true) + +

+ + +
+

Clears the cache which maps classes and re-connects connections that require reloading.

+ +

Raises:

+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 495
+def clear_reloadable_connections(raise_on_acquisition_timeout = true)
+  with_exclusively_acquired_all_connections(raise_on_acquisition_timeout) do
+    synchronize do
+      @connections.each do |conn|
+        if conn.in_use?
+          conn.steal!
+          checkin conn
+        end
+        conn.disconnect! if conn.requires_reloading?
+      end
+      @connections.delete_if(&:requires_reloading?)
+      @available.clear
+    end
+  end
+end
+
+
+ +
+ +
+

+ + clear_reloadable_connections!() + +

+ + +
+

Clears the cache which maps classes and re-connects connections that require reloading.

+ +

The pool first tries to gain ownership of all connections. If unable to do so within a timeout interval (default duration is spec.config[:checkout_timeout] * 2 seconds), then the pool forcefully clears the cache and reloads connections without any regard for other connection owning threads.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 519
+def clear_reloadable_connections!
+  clear_reloadable_connections(false)
+end
+
+
+ +
+ +
+

+ + connected?() + +

+ + +
+

Returns true if a connection has already been opened.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 422
+def connected?
+  synchronize { @connections.any? }
+end
+
+
+ +
+ +
+

+ + connection() + +

+ + +
+

Retrieve the connection associated with the current thread, or call checkout to obtain one if necessary.

+ +

connection can be called any number of times; the connection is held in a cache keyed by a thread.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 381
+def connection
+  @thread_cached_conns[connection_cache_key(current_thread)] ||= checkout
+end
+
+
+ +
+ +
+

+ + connections() + +

+ + +
+

Returns an array containing the connections currently in the pool. Access to the array does not require synchronization on the pool because the array is newly created and not retained by the pool.

+ +

However; this method bypasses the ConnectionPool's thread-safe connection access pattern. A returned connection may be owned by another thread, unowned, or by happen-stance owned by the calling thread.

+ +

Calling methods on a connection without ownership is subject to the thread-safety guarantees of the underlying method. Many of the methods on connection adapter classes are inherently multi-thread unsafe.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 437
+def connections
+  synchronize { @connections.dup }
+end
+
+
+ +
+ +
+

+ + disconnect(raise_on_acquisition_timeout = true) + +

+ + +
+

Disconnects all connections in the pool, and clears the pool.

+ +

Raises:

+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 447
+def disconnect(raise_on_acquisition_timeout = true)
+  with_exclusively_acquired_all_connections(raise_on_acquisition_timeout) do
+    synchronize do
+      @connections.each do |conn|
+        if conn.in_use?
+          conn.steal!
+          checkin conn
+        end
+        conn.disconnect!
+      end
+      @connections = []
+      @available.clear
+    end
+  end
+end
+
+
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects all connections in the pool, and clears the pool.

+ +

The pool first tries to gain ownership of all connections. If unable to do so within a timeout interval (default duration is spec.config[:checkout_timeout] * 2 seconds), then the pool is forcefully disconnected without any regard for other connection owning threads.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 469
+def disconnect!
+  disconnect(false)
+end
+
+
+ +
+ +
+

+ + flush(minimum_idle = @idle_timeout) + +

+ + +
+

Disconnect all connections that have been idle for at least minimum_idle seconds. Connections currently checked out, or that were checked in less than minimum_idle seconds ago, are unaffected.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 616
+def flush(minimum_idle = @idle_timeout)
+  return if minimum_idle.nil?
+
+  idle_connections = synchronize do
+    @connections.select do |conn|
+      !conn.in_use? && conn.seconds_idle >= minimum_idle
+    end.each do |conn|
+      conn.lease
+
+      @available.delete conn
+      @connections.delete conn
+    end
+  end
+
+  idle_connections.each do |conn|
+    conn.disconnect!
+  end
+end
+
+
+ +
+ +
+

+ + flush!() + +

+ + +
+

Disconnect all currently idle connections. Connections currently checked out are unaffected.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 637
+def flush!
+  reap
+  flush(-1)
+end
+
+
+ +
+ +
+

+ + lock_thread=(lock_thread) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 368
+def lock_thread=(lock_thread)
+  if lock_thread
+    @lock_thread = Thread.current
+  else
+    @lock_thread = nil
+  end
+end
+
+
+ +
+ +
+

+ + reap() + +

+ + +
+

Recover lost connections for the pool. A lost connection can occur if a programmer forgets to checkin a connection at the end of a thread or a thread dies unexpectedly.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 594
+def reap
+  stale_connections = synchronize do
+    @connections.select do |conn|
+      conn.in_use? && !conn.owner.alive?
+    end.each do |conn|
+      conn.steal!
+    end
+  end
+
+  stale_connections.each do |conn|
+    if conn.active?
+      conn.reset!
+      checkin conn
+    else
+      remove conn
+    end
+  end
+end
+
+
+ +
+ +
+

+ + release_connection(owner_thread = Thread.current) + +

+ + +
+

Signal that the thread is finished with the current connection. release_connection releases the connection-thread association and returns the connection to the pool.

+ +

This method only works for connections that have been obtained through connection or with_connection methods, connections obtained through checkout will not be automatically released.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 401
+def release_connection(owner_thread = Thread.current)
+  if conn = @thread_cached_conns.delete(connection_cache_key(owner_thread))
+    checkin conn
+  end
+end
+
+
+ +
+ +
+

+ + remove(conn) + +

+ + +
+

Remove a connection from the connection pool. The connection will remain open and active but will no longer be managed by this pool.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 562
+def remove(conn)
+  needs_new_connection = false
+
+  synchronize do
+    remove_connection_from_thread_cache conn
+
+    @connections.delete conn
+    @available.delete conn
+
+    # @available.any_waiting? => true means that prior to removing this
+    # conn, the pool was at its max size (@connections.size == @size).
+    # This would mean that any threads stuck waiting in the queue wouldn't
+    # know they could checkout_new_connection, so let's do it for them.
+    # Because condition-wait loop is encapsulated in the Queue class
+    # (that in turn is oblivious to ConnectionPool implementation), threads
+    # that are "stuck" there are helpless. They have no way of creating
+    # new connections and are completely reliant on us feeding available
+    # connections into the Queue.
+    needs_new_connection = @available.any_waiting?
+  end
+
+  # This is intentionally done outside of the synchronized section as we
+  # would like not to hold the main mutex while checking out new connections.
+  # Thus there is some chance that needs_new_connection information is now
+  # stale, we can live with that (bulk_make_new_connections will make
+  # sure not to exceed the pool's @size limit).
+  bulk_make_new_connections(1) if needs_new_connection
+end
+
+
+ +
+ +
+

+ + stat() + +

+ + +
+

Return connection pool's usage statistic Example:

+ +
ActiveRecord::Base.connection_pool.stat # => { size: 15, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 650
+def stat
+  synchronize do
+    {
+      size: size,
+      connections: @connections.size,
+      busy: @connections.count { |c| c.in_use? && c.owner.alive? },
+      dead: @connections.count { |c| c.in_use? && !c.owner.alive? },
+      idle: @connections.count { |c| !c.in_use? },
+      waiting: num_waiting_in_queue,
+      checkout_timeout: checkout_timeout
+    }
+  end
+end
+
+
+ +
+ +
+

+ + with_connection() + +

+ + +
+

If a connection obtained through connection or with_connection methods already exists yield it to the block. If no such connection exists checkout a connection, yield it to the block, and checkin the connection when finished.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 411
+def with_connection
+  unless conn = @thread_cached_conns[connection_cache_key(Thread.current)]
+    conn = connection
+    fresh_connection = true
+  end
+  yield conn
+ensure
+  release_connection if fresh_connection
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Queue.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Queue.html new file mode 100644 index 0000000000..28f2208f2b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Queue.html @@ -0,0 +1,375 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionPool::Queue +layout: default +--- +
+ +
+
+ +
+ +

Threadsafe, fair, LIFO queue. Meant to be used by ConnectionPool with which it shares a Monitor.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(lock = Monitor.new) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 86
+def initialize(lock = Monitor.new)
+  @lock = lock
+  @cond = @lock.new_cond
+  @num_waiting = 0
+  @queue = []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(element) + +

+ + +
+

Add element to the queue. Never blocks.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 109
+def add(element)
+  synchronize do
+    @queue.push element
+    @cond.signal
+  end
+end
+
+
+ +
+ +
+

+ + any_waiting?() + +

+ + +
+

Test if any threads are currently waiting on the queue.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 94
+def any_waiting?
+  synchronize do
+    @num_waiting > 0
+  end
+end
+
+
+ +
+ +
+

+ + clear() + +

+ + +
+

Remove all elements from the queue.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 124
+def clear
+  synchronize do
+    @queue.clear
+  end
+end
+
+
+ +
+ +
+

+ + delete(element) + +

+ + +
+

If element is in the queue, remove and return it, or nil.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 117
+def delete(element)
+  synchronize do
+    @queue.delete(element)
+  end
+end
+
+
+ +
+ +
+

+ + num_waiting() + +

+ + +
+

Returns the number of threads currently waiting on this queue.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 102
+def num_waiting
+  synchronize do
+    @num_waiting
+  end
+end
+
+
+ +
+ +
+

+ + poll(timeout = nil) + +

+ + +
+

Remove the head of the queue.

+ +

If timeout is not given, remove and return the head the queue if the number of available elements is strictly greater than the number of threads currently waiting (that is, don't jump ahead in line). Otherwise, return nil.

+ +

If timeout is given, block if there is no element available, waiting up to timeout seconds for an element to become available.

+ +

Raises:

+ + +

becomes available within timeout seconds,

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 144
+def poll(timeout = nil)
+  synchronize { internal_poll(timeout) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Reaper.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Reaper.html new file mode 100644 index 0000000000..a0b9256ae5 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Reaper.html @@ -0,0 +1,187 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionPool::Reaper +layout: default +--- +
+ +
+
+ +
+ +

Every frequency seconds, the reaper will call reap and flush on pool. A reaper instantiated with a zero frequency will never reap the connection pool.

+ +

Configure the frequency by setting reaping_frequency in your database yaml file (default 60 seconds).

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + frequency
+ [R] + pool
+ + + + +

Class Public methods

+ +
+

+ + new(pool, frequency) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 292
+def initialize(pool, frequency)
+  @pool      = pool
+  @frequency = frequency
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 297
+def run
+  return unless frequency && frequency > 0
+  Thread.new(frequency, pool) { |t, p|
+    loop do
+      sleep t
+      p.reap
+      p.flush
+    end
+  }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseLimits.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseLimits.html new file mode 100644 index 0000000000..b61119e9be --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseLimits.html @@ -0,0 +1,491 @@ +--- +title: ActiveRecord::ConnectionAdapters::DatabaseLimits +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + allowed_index_name_length() + +

+ + +
+

Returns the maximum allowed length for an index name. This limit is enforced by Rails and is less than or equal to index_name_length. The gap between index_name_length is to allow internal Rails operations to use prefixes in temporary operations.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 26
+def allowed_index_name_length
+  index_name_length
+end
+
+
+ +
+ +
+

+ + column_name_length() + +

+ + +
+

Returns the maximum length of a column name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 12
+def column_name_length
+  64
+end
+
+
+ +
+ +
+

+ + columns_per_multicolumn_index() + +

+ + +
+

Returns the maximum number of columns in a multicolumn index.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 46
+def columns_per_multicolumn_index
+  16
+end
+
+
+ +
+ +
+

+ + columns_per_table() + +

+ + +
+

Returns the maximum number of columns per table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 36
+def columns_per_table
+  1024
+end
+
+
+ +
+ +
+

+ + in_clause_length() + +

+ + +
+

Returns the maximum number of elements in an IN (x,y,z) clause. nil means no limit.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 52
+def in_clause_length
+  nil
+end
+
+
+ +
+ +
+

+ + index_name_length() + +

+ + +
+

Returns the maximum length of an index name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 31
+def index_name_length
+  64
+end
+
+
+ +
+ +
+

+ + indexes_per_table() + +

+ + +
+

Returns the maximum number of indexes per table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 41
+def indexes_per_table
+  16
+end
+
+
+ +
+ +
+

+ + joins_per_query() + +

+ + +
+

Returns maximum number of joins in a single query.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 62
+def joins_per_query
+  256
+end
+
+
+ +
+ +
+

+ + sql_query_length() + +

+ + +
+

Returns the maximum length of an SQL query.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 57
+def sql_query_length
+  1048575
+end
+
+
+ +
+ +
+

+ + table_alias_length() + +

+ + +
+

Returns the maximum length of a table alias.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 7
+def table_alias_length
+  255
+end
+
+
+ +
+ +
+

+ + table_name_length() + +

+ + +
+

Returns the maximum length of a table name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 17
+def table_name_length
+  64
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html new file mode 100644 index 0000000000..97f04d9a56 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html @@ -0,0 +1,1549 @@ +--- +title: ActiveRecord::ConnectionAdapters::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 6
+def initialize
+  super
+  reset_transaction
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_transaction_record(record) + +

+ + +
+

Register a record with the current transaction so that its after_commit and after_rollback callbacks can be called.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 287
+def add_transaction_record(record)
+  current_transaction.add_record(record)
+end
+
+
+ +
+ +
+

+ + begin_db_transaction() + +

+ + +
+

Begins the transaction (and turns off auto-committing).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 296
+def begin_db_transaction()    end
+
+
+ +
+ +
+

+ + begin_isolated_db_transaction(isolation) + +

+ + +
+

Begins the transaction with the isolation level set. Raises an error by default; adapters that support setting the isolation level should implement this method.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 310
+def begin_isolated_db_transaction(isolation)
+  raise ActiveRecord::TransactionIsolationError, "adapter does not support setting transaction isolation"
+end
+
+
+ +
+ +
+

+ + commit_db_transaction() + +

+ + +
+

Commits the transaction (and turns on auto-committing).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 315
+def commit_db_transaction()   end
+
+
+ +
+ +
+

+ + create(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) + +

+ + +
+ +
+ + + + + +
+ Alias for: insert +
+ + + +
+ +
+

+ + default_sequence_name(table, column) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 329
+def default_sequence_name(table, column)
+  nil
+end
+
+
+ +
+ +
+

+ + delete(arel, name = nil, binds = []) + +

+ + +
+

Executes the delete statement and returns the number of rows affected.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 174
+def delete(arel, name = nil, binds = [])
+  sql, binds = to_sql_and_binds(arel, binds)
+  exec_delete(sql, name, binds)
+end
+
+
+ +
+ +
+

+ + empty_insert_statement_value() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 401
+def empty_insert_statement_value
+  "DEFAULT VALUES"
+end
+
+
+ +
+ +
+

+ + exec_delete(sql, name = nil, binds = []) + +

+ + +
+

Executes delete sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 136
+def exec_delete(sql, name = nil, binds = [])
+  exec_query(sql, name, binds)
+end
+
+
+ +
+ +
+

+ + exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil) + +

+ + +
+

Executes insert sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 128
+def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
+  sql, binds = sql_for_insert(sql, pk, nil, sequence_name, binds)
+  exec_query(sql, name, binds)
+end
+
+
+ +
+ +
+

+ + exec_query(sql, name = "SQL", binds = [], prepare: false) + +

+ + +
+

Executes sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 121
+def exec_query(sql, name = "SQL", binds = [], prepare: false)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + exec_update(sql, name = nil, binds = []) + +

+ + +
+

Executes update sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 148
+def exec_update(sql, name = nil, binds = [])
+  exec_query(sql, name, binds)
+end
+
+
+ +
+ +
+

+ + execute(sql, name = nil) + +

+ + +
+

Executes the SQL statement in the context of this connection and returns the raw result from the connection adapter. Note: depending on your database connector, the result returned by this method may be manually memory managed. Consider using the exec_query wrapper instead.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 114
+def execute(sql, name = nil)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) + +

+ + +
+

Executes an INSERT query and returns the new record's ID

+ +

id_value will be returned unless the value is nil, in which case the database will attempt to calculate the last inserted id and return that value.

+ +

If the next id was calculated in advance (as in Oracle), it should be passed in as id_value.

+
+ + + +
+ Also aliased as: create +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 160
+def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
+  sql, binds = to_sql_and_binds(arel, binds)
+  value = exec_insert(sql, name, binds, pk, sequence_name)
+  id_value || last_inserted_id(value)
+end
+
+
+ +
+ +
+

+ + insert_fixture(fixture, table_name) + +

+ + +
+

Inserts the given fixture into the table. Overridden in adapters that require something beyond a simple insert (eg. Oracle). Most of adapters should implement `insert_fixtures` that leverages bulk SQL insert. We keep this method to provide fallback for databases like sqlite that do not support bulk inserts.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 343
+def insert_fixture(fixture, table_name)
+  fixture = fixture.stringify_keys
+
+  columns = schema_cache.columns_hash(table_name)
+  binds = fixture.map do |name, value|
+    if column = columns[name]
+      type = lookup_cast_type_from_column(column)
+      Relation::QueryAttribute.new(name, value, type)
+    else
+      raise Fixture::FixtureError, %(table "#{table_name}" has no column named #{name.inspect}.)
+    end
+  end
+
+  table = Arel::Table.new(table_name)
+
+  values = binds.map do |bind|
+    value = with_yaml_fallback(bind.value_for_database)
+    [table[bind.name], value]
+  end
+
+  manager = Arel::InsertManager.new
+  manager.into(table)
+  manager.insert(values)
+  execute manager.to_sql, "Fixture Insert"
+end
+
+
+ +
+ +
+

+ + insert_fixtures(fixtures, table_name) + +

+ + +
+

Inserts a set of fixtures into the table. Overridden in adapters that require something beyond a simple insert (eg. Oracle).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 371
+      def insert_fixtures(fixtures, table_name)
+        ActiveSupport::Deprecation.warn(<<-MSG.squish)
+          `insert_fixtures` is deprecated and will be removed in the next version of Rails.
+          Consider using `insert_fixtures_set` for performance improvement.
+        MSG
+        return if fixtures.empty?
+
+        execute(build_fixture_sql(fixtures, table_name), "Fixtures Insert")
+      end
+
+
+ +
+ +
+

+ + insert_fixtures_set(fixture_set, tables_to_delete = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 381
+def insert_fixtures_set(fixture_set, tables_to_delete = [])
+  fixture_inserts = fixture_set.map do |table_name, fixtures|
+    next if fixtures.empty?
+
+    build_fixture_sql(fixtures, table_name)
+  end.compact
+
+  table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name table}".dup }
+  total_sql = Array.wrap(combine_multi_statements(table_deletes + fixture_inserts))
+
+  disable_referential_integrity do
+    transaction(requires_new: true) do
+      total_sql.each do |sql|
+        execute sql, "Fixtures Load"
+        yield if block_given?
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + reset_sequence!(table, column, sequence = nil) + +

+ + +
+

Set the sequence to the max value of the table's column.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 334
+def reset_sequence!(table, column, sequence = nil)
+  # Do nothing by default. Implement for PostgreSQL, Oracle, ...
+end
+
+
+ +
+ +
+

+ + rollback_db_transaction() + +

+ + +
+

Rolls back the transaction (and turns on auto-committing). Must be done if the transaction block raises an exception or returns false.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 319
+def rollback_db_transaction
+  exec_rollback_db_transaction
+end
+
+
+ +
+ +
+

+ + rollback_to_savepoint(name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 325
+def rollback_to_savepoint(name = nil)
+  exec_rollback_to_savepoint(name)
+end
+
+
+ +
+ +
+

+ + sanitize_limit(limit) + +

+ + +
+

Sanitizes the given LIMIT parameter in order to prevent SQL injection.

+ +

The limit may be anything that can evaluate to a string via to_s. It should look like an integer, or an Arel SQL literal.

+ +

Returns Integer and Arel::Nodes::SqlLiteral limits as is.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 411
+def sanitize_limit(limit)
+  if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
+    limit
+  else
+    Integer(limit)
+  end
+end
+
+
+ +
+ +
+

+ + select_all(arel, name = nil, binds = [], preparable: nil) + +

+ + +
+

Returns an ActiveRecord::Result instance.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 59
+def select_all(arel, name = nil, binds = [], preparable: nil)
+  arel = arel_from_relation(arel)
+  sql, binds = to_sql_and_binds(arel, binds)
+
+  if preparable.nil?
+    preparable = prepared_statements ? visitor.preparable : false
+  end
+
+  if prepared_statements && preparable
+    select_prepared(sql, name, binds)
+  else
+    select(sql, name, binds)
+  end
+end
+
+
+ +
+ +
+

+ + select_one(arel, name = nil, binds = []) + +

+ + +
+

Returns a record hash with the column names as keys and column values as values.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 76
+def select_one(arel, name = nil, binds = [])
+  select_all(arel, name, binds).first
+end
+
+
+ +
+ +
+

+ + select_rows(arel, name = nil, binds = []) + +

+ + +
+

Returns an array of arrays containing the field values. Order is the same as that returned by columns.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 93
+def select_rows(arel, name = nil, binds = [])
+  select_all(arel, name, binds).rows
+end
+
+
+ +
+ +
+

+ + select_value(arel, name = nil, binds = []) + +

+ + +
+

Returns a single value from a record

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 81
+def select_value(arel, name = nil, binds = [])
+  single_value_from_rows(select_rows(arel, name, binds))
+end
+
+
+ +
+ +
+

+ + select_values(arel, name = nil, binds = []) + +

+ + +
+

Returns an array of the values of the first column in a select:

+ +
select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 87
+def select_values(arel, name = nil, binds = [])
+  select_rows(arel, name, binds).map(&:first)
+end
+
+
+ +
+ +
+

+ + to_sql(arel_or_sql_string, binds = []) + +

+ + +
+

Converts an arel AST to SQL

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 12
+def to_sql(arel_or_sql_string, binds = [])
+  sql, _ = to_sql_and_binds(arel_or_sql_string, binds)
+  sql
+end
+
+
+ +
+ +
+

+ + transaction(requires_new: nil, isolation: nil, joinable: true) + +

+ + +
+

Runs the given block in a database transaction, and returns the result of the block.

+ +

Nested transactions support

+ +

Most databases don't support true nested transactions. At the time of writing, the only database that supports true nested transactions that we're aware of, is MS-SQL.

+ +

In order to get around this problem, transaction will emulate the effect of nested transactions, by using savepoints: dev.mysql.com/doc/refman/5.7/en/savepoint.html Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8' supports savepoints.

+ +

It is safe to call this method if a database transaction is already open, i.e. if transaction is called within another transaction block. In case of a nested call, transaction will behave as follows:

+
  • +

    The block will be run without doing anything. All database statements that happen within the block are effectively appended to the already open database transaction.

    +
  • +

    However, if :requires_new is set, the block will be wrapped in a database savepoint acting as a sub-transaction.

    +
+ +

Caveats

+ +

MySQL doesn't support DDL transactions. If you perform a DDL operation, then any created savepoints will be automatically released. For example, if you've created a savepoint, then you execute a CREATE TABLE statement, then the savepoint that was created will be automatically released.

+ +

This means that, on MySQL, you shouldn't execute DDL operations inside a transaction call that you know might create a savepoint. Otherwise, transaction will raise exceptions when it tries to release the already-automatically-released savepoints:

+ +
Model.connection.transaction do  # BEGIN
+  Model.connection.transaction(requires_new: true) do  # CREATE SAVEPOINT active_record_1
+    Model.connection.create_table(...)
+    # active_record_1 now automatically released
+  end  # RELEASE SAVEPOINT active_record_1  <--- BOOM! database error!
+end
+
+ +

Transaction isolation

+ +

If your database supports setting the isolation level for a transaction, you can set it like so:

+ +
Post.transaction(isolation: :serializable) do
+  # ...
+end
+
+ +

Valid isolation levels are:

+
  • +

    :read_uncommitted

    +
  • +

    :read_committed

    +
  • +

    :repeatable_read

    +
  • +

    :serializable

    +
+ +

You should consult the documentation for your database to understand the semantics of these different levels:

+ + +

An ActiveRecord::TransactionIsolationError will be raised if:

+
  • +

    The adapter does not support setting the isolation level

    +
  • +

    You are joining an existing open transaction

    +
  • +

    You are creating a nested (savepoint) transaction

    +
+ +

The mysql2 and postgresql adapters support setting the transaction isolation level.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 260
+def transaction(requires_new: nil, isolation: nil, joinable: true)
+  if !requires_new && current_transaction.joinable?
+    if isolation
+      raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction"
+    end
+    yield
+  else
+    transaction_manager.within_new_transaction(isolation: isolation, joinable: joinable) { yield }
+  end
+rescue ActiveRecord::Rollback
+  # rollbacks are silently swallowed
+end
+
+
+ +
+ +
+

+ + transaction_isolation_levels() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 298
+def transaction_isolation_levels
+  {
+    read_uncommitted: "READ UNCOMMITTED",
+    read_committed:   "READ COMMITTED",
+    repeatable_read:  "REPEATABLE READ",
+    serializable:     "SERIALIZABLE"
+  }
+end
+
+
+ +
+ +
+

+ + transaction_open?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 277
+def transaction_open?
+  current_transaction.open?
+end
+
+
+ +
+ +
+

+ + transaction_state() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 291
+def transaction_state
+  current_transaction.state
+end
+
+
+ +
+ +
+

+ + truncate(table_name, name = nil) + +

+ + +
+

Executes the truncate statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 141
+def truncate(table_name, name = nil)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + update(arel, name = nil, binds = []) + +

+ + +
+

Executes the update statement and returns the number of rows affected.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 168
+def update(arel, name = nil, binds = [])
+  sql, binds = to_sql_and_binds(arel, binds)
+  exec_update(sql, name, binds)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements/PartialQueryCollector.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements/PartialQueryCollector.html new file mode 100644 index 0000000000..870c223b92 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements/PartialQueryCollector.html @@ -0,0 +1,231 @@ +--- +title: ActiveRecord::ConnectionAdapters::DatabaseStatements::PartialQueryCollector +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 518
+def initialize
+  @parts = []
+  @binds = []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(str) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 523
+def <<(str)
+  @parts << str
+  self
+end
+
+
+ +
+ +
+

+ + add_bind(obj) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 528
+def add_bind(obj)
+  @binds << obj
+  @parts << Arel::Nodes::BindParam.new(1)
+  self
+end
+
+
+ +
+ +
+

+ + value() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 534
+def value
+  [@parts, @binds]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/DetermineIfPreparableVisitor.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DetermineIfPreparableVisitor.html new file mode 100644 index 0000000000..fada6a0bc2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/DetermineIfPreparableVisitor.html @@ -0,0 +1,205 @@ +--- +title: ActiveRecord::ConnectionAdapters::DetermineIfPreparableVisitor +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + preparable
+ + + + + +

Instance Public methods

+ +
+

+ + accept(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb, line 8
+def accept(*)
+  @preparable = true
+  super
+end
+
+
+ +
+ +
+

+ + visit_Arel_Nodes_In(o, collector) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb, line 13
+def visit_Arel_Nodes_In(o, collector)
+  @preparable = false
+
+  if Array === o.right && !o.right.empty?
+    o.right.delete_if do |bind|
+      if Arel::Nodes::BindParam === bind && Relation::QueryAttribute === bind.value
+        !bind.value.boundable?
+      end
+    end
+  end
+
+  super
+end
+
+
+ +
+ +
+

+ + visit_Arel_Nodes_SqlLiteral(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb, line 27
+def visit_Arel_Nodes_SqlLiteral(*)
+  @preparable = false
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL.html new file mode 100644 index 0000000000..8d82866065 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL.html @@ -0,0 +1,94 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL +layout: default +--- + diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/ColumnMethods.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/ColumnMethods.html new file mode 100644 index 0000000000..98a360a0e0 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/ColumnMethods.html @@ -0,0 +1,491 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::ColumnMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blob(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 7
+def blob(*args, **options)
+  args.each { |name| column(name, :blob, options) }
+end
+
+
+ +
+ +
+

+ + longblob(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 19
+def longblob(*args, **options)
+  args.each { |name| column(name, :longblob, options) }
+end
+
+
+ +
+ +
+

+ + longtext(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 31
+def longtext(*args, **options)
+  args.each { |name| column(name, :longtext, options) }
+end
+
+
+ +
+ +
+

+ + mediumblob(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 15
+def mediumblob(*args, **options)
+  args.each { |name| column(name, :mediumblob, options) }
+end
+
+
+ +
+ +
+

+ + mediumtext(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 27
+def mediumtext(*args, **options)
+  args.each { |name| column(name, :mediumtext, options) }
+end
+
+
+ +
+ +
+

+ + tinyblob(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 11
+def tinyblob(*args, **options)
+  args.each { |name| column(name, :tinyblob, options) }
+end
+
+
+ +
+ +
+

+ + tinytext(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 23
+def tinytext(*args, **options)
+  args.each { |name| column(name, :tinytext, options) }
+end
+
+
+ +
+ +
+

+ + unsigned_bigint(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 39
+def unsigned_bigint(*args, **options)
+  args.each { |name| column(name, :unsigned_bigint, options) }
+end
+
+
+ +
+ +
+

+ + unsigned_decimal(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 47
+def unsigned_decimal(*args, **options)
+  args.each { |name| column(name, :unsigned_decimal, options) }
+end
+
+
+ +
+ +
+

+ + unsigned_float(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 43
+def unsigned_float(*args, **options)
+  args.each { |name| column(name, :unsigned_float, options) }
+end
+
+
+ +
+ +
+

+ + unsigned_integer(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 35
+def unsigned_integer(*args, **options)
+  args.each { |name| column(name, :unsigned_integer, options) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/DatabaseStatements.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/DatabaseStatements.html new file mode 100644 index 0000000000..88607bf87a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/DatabaseStatements.html @@ -0,0 +1,227 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + exec_delete(sql, name = nil, binds = []) + +

+ + +
+ +
+ + + +
+ Also aliased as: exec_update +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb, line 43
+def exec_delete(sql, name = nil, binds = [])
+  if without_prepared_statement?(binds)
+    execute_and_free(sql, name) { @connection.affected_rows }
+  else
+    exec_stmt_and_free(sql, name, binds) { |stmt| stmt.affected_rows }
+  end
+end
+
+
+ +
+ +
+

+ + exec_query(sql, name = "SQL", binds = [], prepare: false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb, line 31
+def exec_query(sql, name = "SQL", binds = [], prepare: false)
+  if without_prepared_statement?(binds)
+    execute_and_free(sql, name) do |result|
+      ActiveRecord::Result.new(result.fields, result.to_a) if result
+    end
+  else
+    exec_stmt_and_free(sql, name, binds, cache_stmt: prepare) do |_, result|
+      ActiveRecord::Result.new(result.fields, result.to_a) if result
+    end
+  end
+end
+
+
+ +
+ +
+

+ + exec_update(sql, name = nil, binds = []) + +

+ + +
+ +
+ + + + + +
+ Alias for: exec_delete +
+ + + +
+ +
+

+ + execute(sql, name = nil) + +

+ + +
+

Executes the SQL statement in the context of this connection.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb, line 23
+def execute(sql, name = nil)
+  # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
+  # made since we established the connection
+  @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
+
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/Table.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/Table.html new file mode 100644 index 0000000000..56a5766fdd --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/Table.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::Table +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/TableDefinition.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/TableDefinition.html new file mode 100644 index 0000000000..06a4442788 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/MySQL/TableDefinition.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html new file mode 100644 index 0000000000..a46e6997fc --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html @@ -0,0 +1,530 @@ +--- +title: ActiveRecord::ConnectionAdapters::Mysql2Adapter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ADAPTER_NAME="Mysql2".freeze
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(connection, logger, connection_options, config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 39
+def initialize(connection, logger, connection_options, config)
+  super
+  @prepared_statements = false unless config.key?(:prepared_statements)
+  configure_connection
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 89
+def active?
+  @connection.ping
+end
+
+
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 102
+def disconnect!
+  super
+  @connection.close
+end
+
+
+ +
+ +
+

+ + error_number(exception) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 73
+def error_number(exception)
+  exception.error_number if exception.respond_to?(:error_number)
+end
+
+
+ +
+ +
+

+ + quote_string(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 81
+def quote_string(string)
+  @connection.escape(string)
+end
+
+
+ +
+ +
+

+ + reconnect!() + +

+ + +
+ +
+ + + +
+ Also aliased as: reset! +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 93
+def reconnect!
+  super
+  disconnect!
+  connect
+end
+
+
+ +
+ +
+

+ + reset!() + +

+ + +
+ +
+ + + + + +
+ Alias for: reconnect! +
+ + + +
+ +
+

+ + supports_comments?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 49
+def supports_comments?
+  true
+end
+
+
+ +
+ +
+

+ + supports_comments_in_create?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 53
+def supports_comments_in_create?
+  true
+end
+
+
+ +
+ +
+

+ + supports_json?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 45
+def supports_json?
+  !mariadb? && version >= "5.7.8"
+end
+
+
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 57
+def supports_savepoints?
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/NullColumn.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/NullColumn.html new file mode 100644 index 0000000000..f330a5f288 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/NullColumn.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::NullColumn +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL.html new file mode 100644 index 0000000000..12834ddf1a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL.html @@ -0,0 +1,148 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL +layout: default +--- +
+ + +
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/AlterTable.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/AlterTable.html new file mode 100644 index 0000000000..1a75dc3863 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/AlterTable.html @@ -0,0 +1,164 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::AlterTable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + constraint_validations
+ + + + +

Class Public methods

+ +
+

+ + new(td) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 195
+def initialize(td)
+  super
+  @constraint_validations = []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + validate_constraint(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 200
+def validate_constraint(name)
+  @constraint_validations << name
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html new file mode 100644 index 0000000000..dc8171aa0f --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html @@ -0,0 +1,1305 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + bigserial(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 54
+def bigserial(*args, **options)
+  args.each { |name| column(name, :bigserial, options) }
+end
+
+
+ +
+ +
+

+ + bit(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 58
+def bit(*args, **options)
+  args.each { |name| column(name, :bit, options) }
+end
+
+
+ +
+ +
+

+ + bit_varying(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 62
+def bit_varying(*args, **options)
+  args.each { |name| column(name, :bit_varying, options) }
+end
+
+
+ +
+ +
+

+ + box(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 134
+def box(*args, **options)
+  args.each { |name| column(name, :box, options) }
+end
+
+
+ +
+ +
+

+ + cidr(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 66
+def cidr(*args, **options)
+  args.each { |name| column(name, :cidr, options) }
+end
+
+
+ +
+ +
+

+ + circle(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 146
+def circle(*args, **options)
+  args.each { |name| column(name, :circle, options) }
+end
+
+
+ +
+ +
+

+ + citext(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 70
+def citext(*args, **options)
+  args.each { |name| column(name, :citext, options) }
+end
+
+
+ +
+ +
+

+ + daterange(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 74
+def daterange(*args, **options)
+  args.each { |name| column(name, :daterange, options) }
+end
+
+
+ +
+ +
+

+ + hstore(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 78
+def hstore(*args, **options)
+  args.each { |name| column(name, :hstore, options) }
+end
+
+
+ +
+ +
+

+ + inet(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 82
+def inet(*args, **options)
+  args.each { |name| column(name, :inet, options) }
+end
+
+
+ +
+ +
+

+ + int4range(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 90
+def int4range(*args, **options)
+  args.each { |name| column(name, :int4range, options) }
+end
+
+
+ +
+ +
+

+ + int8range(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 94
+def int8range(*args, **options)
+  args.each { |name| column(name, :int8range, options) }
+end
+
+
+ +
+ +
+

+ + interval(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 86
+def interval(*args, **options)
+  args.each { |name| column(name, :interval, options) }
+end
+
+
+ +
+ +
+

+ + jsonb(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 98
+def jsonb(*args, **options)
+  args.each { |name| column(name, :jsonb, options) }
+end
+
+
+ +
+ +
+

+ + line(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 126
+def line(*args, **options)
+  args.each { |name| column(name, :line, options) }
+end
+
+
+ +
+ +
+

+ + lseg(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 130
+def lseg(*args, **options)
+  args.each { |name| column(name, :lseg, options) }
+end
+
+
+ +
+ +
+

+ + ltree(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 102
+def ltree(*args, **options)
+  args.each { |name| column(name, :ltree, options) }
+end
+
+
+ +
+ +
+

+ + macaddr(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 106
+def macaddr(*args, **options)
+  args.each { |name| column(name, :macaddr, options) }
+end
+
+
+ +
+ +
+

+ + money(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 110
+def money(*args, **options)
+  args.each { |name| column(name, :money, options) }
+end
+
+
+ +
+ +
+

+ + numrange(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 114
+def numrange(*args, **options)
+  args.each { |name| column(name, :numrange, options) }
+end
+
+
+ +
+ +
+

+ + oid(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 118
+def oid(*args, **options)
+  args.each { |name| column(name, :oid, options) }
+end
+
+
+ +
+ +
+

+ + path(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 138
+def path(*args, **options)
+  args.each { |name| column(name, :path, options) }
+end
+
+
+ +
+ +
+

+ + point(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 122
+def point(*args, **options)
+  args.each { |name| column(name, :point, options) }
+end
+
+
+ +
+ +
+

+ + polygon(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 142
+def polygon(*args, **options)
+  args.each { |name| column(name, :polygon, options) }
+end
+
+
+ +
+ +
+

+ + primary_key(name, type = :primary_key, **options) + +

+ + +
+

Defines the primary key field. Use of the native PostgreSQL UUID type is supported, and can be used by defining your tables as such:

+ +
create_table :stuffs, id: :uuid do |t|
+  t.string :content
+  t.timestamps
+end
+
+ +

By default, this will use the +gen_random_uuid()+ function from the pgcrypto extension. As that extension is only available in PostgreSQL 9.4+, for earlier versions an explicit default can be set to use +uuid_generate_v4()+ from the uuid-ossp extension instead:

+ +
create_table :stuffs, id: false do |t|
+  t.primary_key :id, :uuid, default: "uuid_generate_v4()"
+  t.uuid :foo_id
+  t.timestamps
+end
+
+ +

To enable the appropriate extension, which is a requirement, use the enable_extension method in your migrations.

+ +

To use a UUID primary key without any of the extensions, set the :default option to nil:

+ +
create_table :stuffs, id: false do |t|
+  t.primary_key :id, :uuid, default: nil
+  t.uuid :foo_id
+  t.timestamps
+end
+
+ +

You may also pass a custom stored procedure that returns a UUID or use a different UUID generation function from another library.

+ +

Note that setting the UUID primary key default value to nil will require you to assure that you always provide a UUID value before saving a record (as primary keys cannot be nil). This might be done via the SecureRandom.uuid method and a before_save callback, for instance.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 46
+def primary_key(name, type = :primary_key, **options)
+  if type == :uuid
+    options[:default] = options.fetch(:default, "gen_random_uuid()")
+  end
+
+  super
+end
+
+
+ +
+ +
+

+ + serial(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 150
+def serial(*args, **options)
+  args.each { |name| column(name, :serial, options) }
+end
+
+
+ +
+ +
+

+ + tsrange(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 154
+def tsrange(*args, **options)
+  args.each { |name| column(name, :tsrange, options) }
+end
+
+
+ +
+ +
+

+ + tstzrange(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 158
+def tstzrange(*args, **options)
+  args.each { |name| column(name, :tstzrange, options) }
+end
+
+
+ +
+ +
+

+ + tsvector(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 162
+def tsvector(*args, **options)
+  args.each { |name| column(name, :tsvector, options) }
+end
+
+
+ +
+ +
+

+ + uuid(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 166
+def uuid(*args, **options)
+  args.each { |name| column(name, :uuid, options) }
+end
+
+
+ +
+ +
+

+ + xml(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 170
+def xml(*args, **options)
+  args.each { |name| column(name, :xml, options) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/DatabaseStatements.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/DatabaseStatements.html new file mode 100644 index 0000000000..3959d5b2da --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/DatabaseStatements.html @@ -0,0 +1,474 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + begin_db_transaction() + +

+ + +
+

Begins a transaction.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 132
+def begin_db_transaction
+  execute "BEGIN"
+end
+
+
+ +
+ +
+

+ + begin_isolated_db_transaction(isolation) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 136
+def begin_isolated_db_transaction(isolation)
+  begin_db_transaction
+  execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}"
+end
+
+
+ +
+ +
+

+ + commit_db_transaction() + +

+ + +
+

Commits a transaction.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 142
+def commit_db_transaction
+  execute "COMMIT"
+end
+
+
+ +
+ +
+

+ + exec_delete(sql, name = nil, binds = []) + +

+ + +
+ +
+ + + +
+ Also aliased as: exec_update +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 93
+def exec_delete(sql, name = nil, binds = [])
+  execute_and_clear(sql, name, binds) { |result| result.cmd_tuples }
+end
+
+
+ +
+ +
+

+ + exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 113
+def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
+  if use_insert_returning? || pk == false
+    super
+  else
+    result = exec_query(sql, name, binds)
+    unless sequence_name
+      table_ref = extract_table_ref_from_insert_sql(sql)
+      if table_ref
+        pk = primary_key(table_ref) if pk.nil?
+        pk = suppress_composite_primary_key(pk)
+        sequence_name = default_sequence_name(table_ref, pk)
+      end
+      return result unless sequence_name
+    end
+    last_insert_id_result(sequence_name)
+  end
+end
+
+
+ +
+ +
+

+ + exec_query(sql, name = "SQL", binds = [], prepare: false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 80
+def exec_query(sql, name = "SQL", binds = [], prepare: false)
+  execute_and_clear(sql, name, binds, prepare: prepare) do |result|
+    types = {}
+    fields = result.fields
+    fields.each_with_index do |fname, i|
+      ftype = result.ftype i
+      fmod  = result.fmod i
+      types[fname] = get_oid_type(ftype, fmod, fname)
+    end
+    ActiveRecord::Result.new(fields, result.values, types)
+  end
+end
+
+
+ +
+ +
+

+ + exec_rollback_db_transaction() + +

+ + +
+

Aborts a transaction.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 147
+def exec_rollback_db_transaction
+  execute "ROLLBACK"
+end
+
+
+ +
+ +
+

+ + exec_update(sql, name = nil, binds = []) + +

+ + +
+ +
+ + + + + +
+ Alias for: exec_delete +
+ + + +
+ +
+

+ + execute(sql, name = nil) + +

+ + +
+

Executes an SQL statement, returning a PG::Result object on success or raising a PG::Error exception otherwise. Note: the PG::Result object is manually memory managed; if you don't need it specifically, you may want consider the exec_query wrapper.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 72
+def execute(sql, name = nil)
+  log(sql, name) do
+    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
+      @connection.async_exec(sql)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + explain(arel, binds = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 7
+def explain(arel, binds = [])
+  sql = "EXPLAIN #{to_sql(arel, binds)}"
+  PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID.html new file mode 100644 index 0000000000..2704abb60d --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID.html @@ -0,0 +1,113 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::OID +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit.html new file mode 100644 index 0000000000..2a248617d1 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit.html @@ -0,0 +1,75 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Bit +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit/Data.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit/Data.html new file mode 100644 index 0000000000..ed2b79b456 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit/Data.html @@ -0,0 +1,241 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Bit::Data +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + value

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ + + + +

Class Public methods

+ +
+

+ + new(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 30
+def initialize(value)
+  @value = value
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 38
+def binary?
+  /\A[01]*\Z/.match?(value)
+end
+
+
+ +
+ +
+

+ + hex?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 42
+def hex?
+  /\A[0-9A-F]*\Z/i.match?(value)
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 34
+def to_s
+  value
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting.html new file mode 100644 index 0000000000..bdf0046fc0 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting.html @@ -0,0 +1,218 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + escape_bytea(value) + +

+ + +
+

Escapes binary strings for bytea input to the database.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 8
+def escape_bytea(value)
+  @connection.escape_bytea(value) if value
+end
+
+
+ +
+ +
+

+ + quote_schema_name(name) + +

+ + +
+

Quotes schema names for use in SQL queries.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 37
+def quote_schema_name(name)
+  PG::Connection.quote_ident(name)
+end
+
+
+ +
+ +
+

+ + quote_table_name_for_assignment(table, attr) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 41
+def quote_table_name_for_assignment(table, attr)
+  quote_column_name(attr)
+end
+
+
+ +
+ +
+

+ + unescape_bytea(value) + +

+ + +
+

Unescapes bytea output from a database to the binary string it represents. NOTE: This is NOT an inverse of escape_bytea! This is only to be used on escaped binary output from database drive.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 15
+def unescape_bytea(value)
+  @connection.unescape_bytea(value) if value
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html new file mode 100644 index 0000000000..660f9bb226 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html @@ -0,0 +1,1149 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + bulk_change_table(table_name, operations) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 371
+def bulk_change_table(table_name, operations)
+  sql_fragments = []
+  non_combinable_operations = []
+
+  operations.each do |command, args|
+    table, arguments = args.shift, args
+    method = :"#{command}_for_alter"
+
+    if respond_to?(method, true)
+      sqls, procs = Array(send(method, table, *arguments)).partition { |v| v.is_a?(String) }
+      sql_fragments << sqls
+      non_combinable_operations.concat(procs)
+    else
+      execute "ALTER TABLE #{quote_table_name(table_name)} #{sql_fragments.join(", ")}" unless sql_fragments.empty?
+      non_combinable_operations.each(&:call)
+      sql_fragments = []
+      non_combinable_operations = []
+      send(command, table, *arguments)
+    end
+  end
+
+  execute "ALTER TABLE #{quote_table_name(table_name)} #{sql_fragments.join(", ")}" unless sql_fragments.empty?
+  non_combinable_operations.each(&:call)
+end
+
+
+ +
+ +
+

+ + client_min_messages() + +

+ + +
+

Returns the current client message level.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 236
+def client_min_messages
+  query_value("SHOW client_min_messages", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + client_min_messages=(level) + +

+ + +
+

Set the client message level.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 241
+def client_min_messages=(level)
+  execute("SET client_min_messages TO '#{level}'", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + collation() + +

+ + +
+

Returns the current database collation.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 188
+def collation
+  query_value("SELECT datcollate FROM pg_database WHERE datname = current_database()", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + create_database(name, options = {}) + +

+ + +
+

Create a new PostgreSQL database. Options include :owner, :template, :encoding (defaults to utf8), :collation, :ctype, :tablespace, and :connection_limit (note that MySQL uses :charset while PostgreSQL uses :encoding).

+ +

Example:

+ +
create_database config[:database], config
+create_database 'foo_development', encoding: 'unicode'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 22
+def create_database(name, options = {})
+  options = { encoding: "utf8" }.merge!(options.symbolize_keys)
+
+  option_string = options.inject("") do |memo, (key, value)|
+    memo += case key
+            when :owner
+              " OWNER = \"#{value}\""
+            when :template
+              " TEMPLATE = \"#{value}\""
+            when :encoding
+              " ENCODING = '#{value}'"
+            when :collation
+              " LC_COLLATE = '#{value}'"
+            when :ctype
+              " LC_CTYPE = '#{value}'"
+            when :tablespace
+              " TABLESPACE = \"#{value}\""
+            when :connection_limit
+              " CONNECTION LIMIT = #{value}"
+            else
+              ""
+    end
+  end
+
+  execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
+end
+
+
+ +
+ +
+

+ + create_schema(schema_name) + +

+ + +
+

Creates a schema for the given schema name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 209
+def create_schema(schema_name)
+  execute "CREATE SCHEMA #{quote_schema_name(schema_name)}"
+end
+
+
+ +
+ +
+

+ + ctype() + +

+ + +
+

Returns the current database ctype.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 193
+def ctype
+  query_value("SELECT datctype FROM pg_database WHERE datname = current_database()", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + current_database() + +

+ + +
+

Returns the current database name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 173
+def current_database
+  query_value("SELECT current_database()", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + current_schema() + +

+ + +
+

Returns the current schema name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 178
+def current_schema
+  query_value("SELECT current_schema", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + drop_schema(schema_name, options = {}) + +

+ + +
+

Drops the schema for the given schema name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 214
+def drop_schema(schema_name, options = {})
+  execute "DROP SCHEMA#{' IF EXISTS' if options[:if_exists]} #{quote_schema_name(schema_name)} CASCADE"
+end
+
+
+ +
+ +
+

+ + encoding() + +

+ + +
+

Returns the current database encoding format.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 183
+def encoding
+  query_value("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = current_database()", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 503
+        def foreign_keys(table_name)
+          scope = quoted_scope(table_name)
+          fk_info = exec_query(<<-SQL.strip_heredoc, "SCHEMA")
+            SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete, c.convalidated AS valid
+            FROM pg_constraint c
+            JOIN pg_class t1 ON c.conrelid = t1.oid
+            JOIN pg_class t2 ON c.confrelid = t2.oid
+            JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
+            JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
+            JOIN pg_namespace t3 ON c.connamespace = t3.oid
+            WHERE c.contype = 'f'
+              AND t1.relname = #{scope[:name]}
+              AND t3.nspname = #{scope[:schema]}
+            ORDER BY c.conname
+          SQL
+
+          fk_info.map do |row|
+            options = {
+              column: row["column"],
+              name: row["name"],
+              primary_key: row["primary_key"]
+            }
+
+            options[:on_delete] = extract_foreign_key_action(row["on_delete"])
+            options[:on_update] = extract_foreign_key_action(row["on_update"])
+            options[:validate] = row["valid"]
+
+            ForeignKeyDefinition.new(table_name, row["to_table"], options)
+          end
+        end
+
+
+ +
+ +
+

+ + foreign_table_exists?(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 538
+def foreign_table_exists?(table_name)
+  query_values(data_source_sql(table_name, type: "FOREIGN TABLE"), "SCHEMA").any? if table_name.present?
+end
+
+
+ +
+ +
+

+ + foreign_tables() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 534
+def foreign_tables
+  query_values(data_source_sql(type: "FOREIGN TABLE"), "SCHEMA")
+end
+
+
+ +
+ +
+

+ + index_name_exists?(table_name, index_name) + +

+ + +
+

Verifies existence of an index with a given name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 67
+        def index_name_exists?(table_name, index_name)
+          table = quoted_scope(table_name)
+          index = quoted_scope(index_name)
+
+          query_value(<<-SQL, "SCHEMA").to_i > 0
+            SELECT COUNT(*)
+            FROM pg_class t
+            INNER JOIN pg_index d ON t.oid = d.indrelid
+            INNER JOIN pg_class i ON d.indexrelid = i.oid
+            LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
+            WHERE i.relkind = 'i'
+              AND i.relname = #{index[:name]}
+              AND t.relname = #{table[:name]}
+              AND n.nspname = #{index[:schema]}
+          SQL
+        end
+
+
+ +
+ +
+

+ + rename_index(table_name, old_name, new_name) + +

+ + +
+

Renames an index of a table. Raises error if length of new index name is greater than allowed limit.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 497
+def rename_index(table_name, old_name, new_name)
+  validate_index_length!(table_name, new_name)
+
+  execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
+end
+
+
+ +
+ +
+

+ + rename_table(table_name, new_name) + +

+ + +
+

Renames a table. Also renames a table's primary key sequence if the sequence name exists and matches the Active Record default.

+ +

Example:

+ +
rename_table('octopuses', 'octopi')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 402
+def rename_table(table_name, new_name)
+  clear_cache!
+  execute "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
+  pk, seq = pk_and_sequence_for(new_name)
+  if pk
+    idx = "#{table_name}_pkey"
+    new_idx = "#{new_name}_pkey"
+    execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
+    if seq && seq.identifier == "#{table_name}_#{pk}_seq"
+      new_seq = "#{new_name}_#{pk}_seq"
+      execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
+    end
+  end
+  rename_table_indexes(table_name, new_name)
+end
+
+
+ +
+ +
+

+ + schema_exists?(name) + +

+ + +
+

Returns true if schema exists.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 62
+def schema_exists?(name)
+  query_value("SELECT COUNT(*) FROM pg_namespace WHERE nspname = #{quote(name)}", "SCHEMA").to_i > 0
+end
+
+
+ +
+ +
+

+ + schema_names() + +

+ + +
+

Returns an array of schema names.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 198
+        def schema_names
+          query_values(<<-SQL, "SCHEMA")
+            SELECT nspname
+              FROM pg_namespace
+             WHERE nspname !~ '^pg_.*'
+               AND nspname NOT IN ('information_schema')
+             ORDER by nspname;
+          SQL
+        end
+
+
+ +
+ +
+

+ + schema_search_path() + +

+ + +
+

Returns the active schema search path.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 231
+def schema_search_path
+  @schema_search_path ||= query_value("SHOW search_path", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + schema_search_path=(schema_csv) + +

+ + +
+

Sets the schema search path to a string of comma-separated schema names. Names beginning with $ have to be quoted (e.g. $user => '$user'). See: www.postgresql.org/docs/current/static/ddl-schemas.html

+ +

This should be not be called manually but set in database.yml.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 223
+def schema_search_path=(schema_csv)
+  if schema_csv
+    execute("SET search_path TO #{schema_csv}", "SCHEMA")
+    @schema_search_path = schema_csv
+  end
+end
+
+
+ +
+ +
+

+ + serial_sequence(table, column) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 254
+def serial_sequence(table, column)
+  query_value("SELECT pg_get_serial_sequence(#{quote(table)}, #{quote(column)})", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + validate_constraint(table_name, constraint_name) + +

+ + +
+

Validates the given constraint.

+ +

Validates the constraint named constraint_name on accounts.

+ +
validate_constraint :accounts, :constraint_name
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 602
+def validate_constraint(table_name, constraint_name)
+  return unless supports_validate_constraints?
+
+  at = create_alter_table table_name
+  at.validate_constraint constraint_name
+
+  execute schema_creation.accept(at)
+end
+
+
+ +
+ +
+

+ + validate_foreign_key(from_table, options_or_to_table = {}) + +

+ + +
+

Validates the given foreign key.

+ +

Validates the foreign key on accounts.branch_id.

+ +
validate_foreign_key :accounts, :branches
+
+ +

Validates the foreign key on accounts.owner_id.

+ +
validate_foreign_key :accounts, column: :owner_id
+
+ +

Validates the foreign key named special_fk_name on the accounts table.

+ +
validate_foreign_key :accounts, name: :special_fk_name
+
+ +

The options hash accepts the same keys as SchemaStatements#add_foreign_key.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 626
+def validate_foreign_key(from_table, options_or_to_table = {})
+  return unless supports_validate_constraints?
+
+  fk_name_to_validate = foreign_key_for!(from_table, options_or_to_table).name
+
+  validate_constraint from_table, fk_name_to_validate
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Table.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Table.html new file mode 100644 index 0000000000..7141154a47 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Table.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::Table +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TableDefinition.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TableDefinition.html new file mode 100644 index 0000000000..752a9f206e --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TableDefinition.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html new file mode 100644 index 0000000000..6b51c5ae86 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html @@ -0,0 +1,1883 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter +layout: default +--- +
+ +
+
+ +
+ +

The PostgreSQL adapter works with the native C (bitbucket.org/ged/ruby-pg) driver.

+ +

Options:

+
  • +

    :host - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets, the default is to connect to localhost.

    +
  • +

    :port - Defaults to 5432.

    +
  • +

    :username - Defaults to be the same as the operating system name of the user running the application.

    +
  • +

    :password - Password to be used if the server demands password authentication.

    +
  • +

    :database - Defaults to be the same as the user name.

    +
  • +

    :schema_search_path - An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the :schema_order option.

    +
  • +

    :encoding - An optional client encoding that is used in a SET client_encoding TO <encoding> call on the connection.

    +
  • +

    :min_messages - An optional client min messages that is used in a SET client_min_messages TO <min_messages> call on the connection.

    +
  • +

    :variables - An optional hash of additional parameters that will be used in SET SESSION key = val calls on the connection.

    +
  • +

    :insert_returning - An optional boolean to control the use of RETURNING for INSERT statements defaults to true.

    +
+ +

Any further options are used as connection parameters to libpq. See www.postgresql.org/docs/current/static/libpq-connect.html for the list of parameters.

+ +

In addition, default connection parameters of libpq can be set per environment variables. See www.postgresql.org/docs/current/static/libpq-envars.html .

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ADAPTER_NAME="PostgreSQL".freeze
 
CACHED_PLAN_HEURISTIC="cached plan must not change result type".freeze
 

Annoyingly, the code for prepared statements whose return value may have changed is FEATURE_NOT_SUPPORTED.

+ +

This covers various different error types so we need to do additional work to classify the exception definitively as a ActiveRecord::PreparedStatementCacheExpired

+ +

Check here for more details: git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573

DEADLOCK_DETECTED="40P01"
 
FOREIGN_KEY_VIOLATION="23503"
 
LOCK_NOT_AVAILABLE="55P03"
 
NATIVE_DATABASE_TYPES={ +primary_key: "bigserial primary key", +string: { name: "character varying" }, +text: { name: "text" }, +integer: { name: "integer", limit: 4 }, +float: { name: "float" }, +decimal: { name: "decimal" }, +datetime: { name: "timestamp" }, +time: { name: "time" }, +date: { name: "date" }, +daterange: { name: "daterange" }, +numrange: { name: "numrange" }, +tsrange: { name: "tsrange" }, +tstzrange: { name: "tstzrange" }, +int4range: { name: "int4range" }, +int8range: { name: "int8range" }, +binary: { name: "bytea" }, +boolean: { name: "boolean" }, +xml: { name: "xml" }, +tsvector: { name: "tsvector" }, +hstore: { name: "hstore" }, +inet: { name: "inet" }, +cidr: { name: "cidr" }, +macaddr: { name: "macaddr" }, +uuid: { name: "uuid" }, +json: { name: "json" }, +jsonb: { name: "jsonb" }, +ltree: { name: "ltree" }, +citext: { name: "citext" }, +point: { name: "point" }, +line: { name: "line" }, +lseg: { name: "lseg" }, +box: { name: "box" }, +path: { name: "path" }, +polygon: { name: "polygon" }, +circle: { name: "circle" }, +bit: { name: "bit" }, +bit_varying: { name: "bit varying" }, +money: { name: "money" }, +interval: { name: "interval" }, +oid: { name: "oid" }, +}
 
NOT_NULL_VIOLATION="23502"
 
NUMERIC_VALUE_OUT_OF_RANGE="22003"
 
QUERY_CANCELED="57014"
 
SERIALIZATION_FAILURE="40001"
 
UNIQUE_VIOLATION="23505"
 
VALUE_LIMIT_VIOLATION="22001"
 

See www.postgresql.org/docs/current/static/errcodes-appendix.html

+ + + + + + +

Class Public methods

+ +
+

+ + new(connection, logger, connection_parameters, config) + +

+ + +
+

Initializes and connects a PostgreSQL adapter.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 214
+def initialize(connection, logger, connection_parameters, config)
+  super(connection, logger, config)
+
+  @connection_parameters = connection_parameters
+
+  # @local_tz is initialized as nil to avoid warnings when connect tries to use it
+  @local_tz = nil
+  @max_identifier_length = nil
+
+  connect
+  add_pg_encoders
+  @statements = StatementPool.new @connection,
+                                  self.class.type_cast_config_to_integer(config[:statement_limit])
+
+  if postgresql_version < 90100
+    raise "Your version of PostgreSQL (#{postgresql_version}) is too old. Active Record supports PostgreSQL >= 9.1."
+  end
+
+  add_pg_decoders
+
+  @type_map = Type::HashLookupTypeMap.new
+  initialize_type_map
+  @local_tz = execute("SHOW TIME ZONE", "SCHEMA").first["TimeZone"]
+  @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+

Is this connection alive and ready for queries?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 252
+def active?
+  @lock.synchronize do
+    @connection.query "SELECT 1"
+  end
+  true
+rescue PG::Error
+  false
+end
+
+
+ +
+ +
+

+ + clear_cache!() + +

+ + +
+

Clears the prepared statements cache.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 241
+def clear_cache!
+  @lock.synchronize do
+    @statements.clear
+  end
+end
+
+
+ +
+ +
+

+ + disable_extension(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 357
+def disable_extension(name)
+  exec_query("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE").tap {
+    reload_type_map
+  }
+end
+
+
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 284
+def disconnect!
+  @lock.synchronize do
+    super
+    @connection.close rescue nil
+  end
+end
+
+
+ +
+ +
+

+ + enable_extension(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 351
+def enable_extension(name)
+  exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap {
+    reload_type_map
+  }
+end
+
+
+ +
+ +
+

+ + extension_enabled?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 363
+def extension_enabled?(name)
+  res = exec_query("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled", "SCHEMA")
+  res.cast_values.first
+end
+
+
+ +
+ +
+

+ + extensions() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 368
+def extensions
+  exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
+end
+
+
+ +
+ +
+

+ + index_algorithms() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 181
+def index_algorithms
+  { concurrently: "CONCURRENTLY" }
+end
+
+
+ +
+ +
+

+ + index_name_length() + +

+ + +
+ +
+ + + + + +
+ Alias for: max_identifier_length +
+ + + +
+ +
+

+ + max_identifier_length() + +

+ + +
+

Returns the configured supported identifier length supported by PostgreSQL

+
+ + + +
+ Also aliased as: table_alias_length, index_name_length +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 373
+def max_identifier_length
+  @max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
+end
+
+
+ +
+ +
+

+ + postgresql_version() + +

+ + +
+

Returns the version of the connected PostgreSQL server.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 400
+def postgresql_version
+  @connection.server_version
+end
+
+
+ +
+ +
+

+ + reconnect!() + +

+ + +
+

Close then reopen the connection.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 262
+def reconnect!
+  @lock.synchronize do
+    super
+    @connection.reset
+    configure_connection
+  end
+end
+
+
+ +
+ +
+

+ + reset!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 270
+def reset!
+  @lock.synchronize do
+    clear_cache!
+    reset_transaction
+    unless @connection.transaction_status == ::PG::PQTRANS_IDLE
+      @connection.query "ROLLBACK"
+    end
+    @connection.query "DISCARD ALL"
+    configure_connection
+  end
+end
+
+
+ +
+ +
+

+ + session_auth=(user) + +

+ + +
+

Set the authorized user for this session

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 380
+def session_auth=(user)
+  clear_cache!
+  execute("SET SESSION AUTHORIZATION #{user}")
+end
+
+
+ +
+ +
+

+ + set_standard_conforming_strings() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 300
+def set_standard_conforming_strings
+  execute("SET standard_conforming_strings = on", "SCHEMA")
+end
+
+
+ +
+ +
+

+ + supports_advisory_locks?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 308
+def supports_advisory_locks?
+  true
+end
+
+
+ +
+ +
+

+ + supports_bulk_alter?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 133
+def supports_bulk_alter?
+  true
+end
+
+
+ +
+ +
+

+ + supports_comments?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 173
+def supports_comments?
+  true
+end
+
+
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 165
+def supports_datetime_with_precision?
+  true
+end
+
+
+ +
+ +
+

+ + supports_ddl_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 304
+def supports_ddl_transactions?
+  true
+end
+
+
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 312
+def supports_explain?
+  true
+end
+
+
+ +
+ +
+

+ + supports_expression_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 145
+def supports_expression_index?
+  true
+end
+
+
+ +
+ +
+

+ + supports_extensions?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 316
+def supports_extensions?
+  true
+end
+
+
+ +
+ +
+

+ + supports_foreign_keys?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 153
+def supports_foreign_keys?
+  true
+end
+
+
+ +
+ +
+

+ + supports_foreign_tables?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 329
+def supports_foreign_tables?
+  postgresql_version >= 90300
+end
+
+
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 137
+def supports_index_sort_order?
+  true
+end
+
+
+ +
+ +
+

+ + supports_json?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 169
+def supports_json?
+  postgresql_version >= 90200
+end
+
+
+ +
+ +
+

+ + supports_materialized_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 325
+def supports_materialized_views?
+  postgresql_version >= 90300
+end
+
+
+ +
+ +
+

+ + supports_partial_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 141
+def supports_partial_index?
+  true
+end
+
+
+ +
+ +
+

+ + supports_pgcrypto_uuid?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 333
+def supports_pgcrypto_uuid?
+  postgresql_version >= 90400
+end
+
+
+ +
+ +
+

+ + supports_ranges?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 320
+def supports_ranges?
+  # Range datatypes weren't introduced until PostgreSQL 9.2
+  postgresql_version >= 90200
+end
+
+
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 177
+def supports_savepoints?
+  true
+end
+
+
+ +
+ +
+

+ + supports_transaction_isolation?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 149
+def supports_transaction_isolation?
+  true
+end
+
+
+ +
+ +
+

+ + supports_validate_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 157
+def supports_validate_constraints?
+  true
+end
+
+
+ +
+ +
+

+ + supports_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 161
+def supports_views?
+  true
+end
+
+
+ +
+ +
+

+ + table_alias_length() + +

+ + +
+ +
+ + + + + +
+ Alias for: max_identifier_length +
+ + + +
+ +
+

+ + truncate(table_name, name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 247
+def truncate(table_name, name = nil)
+  exec_query "TRUNCATE TABLE #{quote_table_name(table_name)}", name, []
+end
+
+
+ +
+ +
+

+ + use_insert_returning?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 385
+def use_insert_returning?
+  @use_insert_returning
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLTypeMetadata.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLTypeMetadata.html new file mode 100644 index 0000000000..dac2938acc --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLTypeMetadata.html @@ -0,0 +1,336 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQLTypeMetadata +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + array
+ [R] + fmod
+ [R] + oid
+ + + + +

Class Public methods

+ +
+

+ + new(type_metadata, oid: nil, fmod: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb, line 10
+def initialize(type_metadata, oid: nil, fmod: nil)
+  super(type_metadata)
+  @type_metadata = type_metadata
+  @oid = oid
+  @fmod = fmod
+  @array = /\[\]$/.match?(type_metadata.sql_type)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+ +
+ + + +
+ Also aliased as: eql? +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb, line 22
+def ==(other)
+  other.is_a?(PostgreSQLTypeMetadata) &&
+    attributes_for_hash == other.attributes_for_hash
+end
+
+
+ +
+ +
+

+ + eql?(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: == +
+ + + +
+ +
+

+ + hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb, line 28
+def hash
+  attributes_for_hash.hash
+end
+
+
+ +
+ +
+

+ + sql_type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb, line 18
+def sql_type
+  super.gsub(/\[\]$/, "".freeze)
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + attributes_for_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb, line 34
+def attributes_for_hash
+  [self.class, @type_metadata, oid, fmod]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache.html new file mode 100644 index 0000000000..613689fccd --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache.html @@ -0,0 +1,444 @@ +--- +title: ActiveRecord::ConnectionAdapters::QueryCache +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + query_cache
+ [R] + query_cache_enabled
+ + + + +

Class Public methods

+ +
+

+ + dirties_query_cache(base, *method_names) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 16
+        def dirties_query_cache(base, *method_names)
+          method_names.each do |method_name|
+            base.class_eval <<-end_code, __FILE__, __LINE__ + 1
+              def #{method_name}(*)
+                clear_query_cache if @query_cache_enabled
+                super
+              end
+            end_code
+          end
+        end
+
+
+ +
+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 51
+def initialize(*)
+  super
+  @query_cache         = Hash.new { |h, sql| h[sql] = {} }
+  @query_cache_enabled = false
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + cache() + +

+ + +
+

Enable the query cache within the block.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 58
+def cache
+  old, @query_cache_enabled = @query_cache_enabled, true
+  yield
+ensure
+  @query_cache_enabled = old
+  clear_query_cache unless @query_cache_enabled
+end
+
+
+ +
+ +
+

+ + clear_query_cache() + +

+ + +
+

Clears the query cache.

+ +

One reason you may wish to call this method explicitly is between queries that ask the database to randomize results. Otherwise the cache would see the same SQL query and repeatedly return the same result each time, silently undermining the randomness you were expecting.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 89
+def clear_query_cache
+  @lock.synchronize do
+    @query_cache.clear
+  end
+end
+
+
+ +
+ +
+

+ + disable_query_cache!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 70
+def disable_query_cache!
+  @query_cache_enabled = false
+  clear_query_cache
+end
+
+
+ +
+ +
+

+ + enable_query_cache!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 66
+def enable_query_cache!
+  @query_cache_enabled = true
+end
+
+
+ +
+ +
+

+ + select_all(arel, name = nil, binds = [], preparable: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 95
+def select_all(arel, name = nil, binds = [], preparable: nil)
+  if @query_cache_enabled && !locked?(arel)
+    arel = arel_from_relation(arel)
+    sql, binds = to_sql_and_binds(arel, binds)
+
+    if preparable.nil?
+      preparable = prepared_statements ? visitor.preparable : false
+    end
+
+    cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + uncached() + +

+ + +
+

Disable the query cache within the block.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 76
+def uncached
+  old, @query_cache_enabled = @query_cache_enabled, false
+  yield
+ensure
+  @query_cache_enabled = old
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache/ConnectionPoolConfiguration.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache/ConnectionPoolConfiguration.html new file mode 100644 index 0000000000..99261d5446 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/QueryCache/ConnectionPoolConfiguration.html @@ -0,0 +1,224 @@ +--- +title: ActiveRecord::ConnectionAdapters::QueryCache::ConnectionPoolConfiguration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 29
+def initialize(*)
+  super
+  @query_cache_enabled = Concurrent::Map.new { false }
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + disable_query_cache!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 39
+def disable_query_cache!
+  @query_cache_enabled.delete connection_cache_key(current_thread)
+  connection.disable_query_cache! if active_connection?
+end
+
+
+ +
+ +
+

+ + enable_query_cache!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 34
+def enable_query_cache!
+  @query_cache_enabled[connection_cache_key(current_thread)] = true
+  connection.enable_query_cache! if active_connection?
+end
+
+
+ +
+ +
+

+ + query_cache_enabled() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 44
+def query_cache_enabled
+  @query_cache_enabled[connection_cache_key(current_thread)]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html new file mode 100644 index 0000000000..dfc2598a8d --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html @@ -0,0 +1,523 @@ +--- +title: ActiveRecord::ConnectionAdapters::Quoting +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + quote(value) + +

+ + +
+

Quotes the column value to help prevent SQL injection attacks.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 11
+def quote(value)
+  value = id_value_for_database(value) if value.is_a?(Base)
+
+  if value.respond_to?(:value_for_database)
+    value = value.value_for_database
+  end
+
+  _quote(value)
+end
+
+
+ +
+ +
+

+ + quote_column_name(column_name) + +

+ + +
+

Quotes the column name. Defaults to no quoting.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 67
+def quote_column_name(column_name)
+  column_name.to_s
+end
+
+
+ +
+ +
+

+ + quote_string(s) + +

+ + +
+

Quotes a string, escaping any ' (single quote) and \ (backslash) characters.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 62
+def quote_string(s)
+  s.gsub('\\'.freeze, '\&\&'.freeze).gsub("'".freeze, "''".freeze) # ' (for ruby-mode)
+end
+
+
+ +
+ +
+

+ + quote_table_name(table_name) + +

+ + +
+

Quotes the table name. Defaults to column name quoting.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 72
+def quote_table_name(table_name)
+  quote_column_name(table_name)
+end
+
+
+ +
+ +
+

+ + quote_table_name_for_assignment(table, attr) + +

+ + +
+

Override to return the quoted table name for assignment. Defaults to table quoting.

+ +

This works for mysql2 where table.column can be used to resolve ambiguity.

+ +

We override this in the sqlite3 and postgresql adapters to use only the column name (as per syntax requirements).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 84
+def quote_table_name_for_assignment(table, attr)
+  quote_table_name("#{table}.#{attr}")
+end
+
+
+ +
+ +
+

+ + quoted_date(value) + +

+ + +
+

Quote date/time values for use in SQL input. Includes microseconds if the value is a Time responding to usec.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 115
+def quoted_date(value)
+  if value.acts_like?(:time)
+    zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
+
+    if value.respond_to?(zone_conversion_method)
+      value = value.send(zone_conversion_method)
+    end
+  end
+
+  result = value.to_s(:db)
+  if value.respond_to?(:usec) && value.usec > 0
+    "#{result}.#{sprintf("%06d", value.usec)}"
+  else
+    result
+  end
+end
+
+
+ +
+ +
+

+ + quoted_false() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 105
+def quoted_false
+  "FALSE".freeze
+end
+
+
+ +
+ +
+

+ + quoted_true() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 97
+def quoted_true
+  "TRUE".freeze
+end
+
+
+ +
+ +
+

+ + type_cast(value, column = nil) + +

+ + +
+

Cast a value to a type that the database understands. For example, SQLite does not understand dates, so this method will convert a Date to a String.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 24
+def type_cast(value, column = nil)
+  value = id_value_for_database(value) if value.is_a?(Base)
+
+  if column
+    value = type_cast_from_column(column, value)
+  end
+
+  _type_cast(value)
+rescue TypeError
+  to_type = column ? " to #{column.type}" : ""
+  raise TypeError, "can't cast #{value.class}#{to_type}"
+end
+
+
+ +
+ +
+

+ + unquoted_false() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 109
+def unquoted_false
+  false
+end
+
+
+ +
+ +
+

+ + unquoted_true() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 101
+def unquoted_true
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/RealTransaction.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/RealTransaction.html new file mode 100644 index 0000000000..bdd6d120fa --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/RealTransaction.html @@ -0,0 +1,195 @@ +--- +title: ActiveRecord::ConnectionAdapters::RealTransaction +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(connection, options, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 170
+def initialize(connection, options, *args)
+  super
+  if options[:isolation]
+    connection.begin_isolated_db_transaction(options[:isolation])
+  else
+    connection.begin_db_transaction
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + commit() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 184
+def commit
+  connection.commit_db_transaction
+  @state.full_commit!
+end
+
+
+ +
+ +
+

+ + rollback() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 179
+def rollback
+  connection.rollback_db_transaction
+  @state.full_rollback!
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3.html new file mode 100644 index 0000000000..55533eb481 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3.html @@ -0,0 +1,79 @@ +--- +title: ActiveRecord::ConnectionAdapters::SQLite3 +layout: default +--- + diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/TableDefinition.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/TableDefinition.html new file mode 100644 index 0000000000..731f75ebc2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/TableDefinition.html @@ -0,0 +1,139 @@ +--- +title: ActiveRecord::ConnectionAdapters::SQLite3::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + belongs_to(*args, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: references +
+ + + +
+ +
+

+ + references(*args, **options) + +

+ + +
+ +
+ + + +
+ Also aliased as: belongs_to +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb, line 7
+def references(*args, **options)
+  super(*args, type: :integer, **options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html new file mode 100644 index 0000000000..b59edbdd76 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html @@ -0,0 +1,1295 @@ +--- +title: ActiveRecord::ConnectionAdapters::SQLite3Adapter +layout: default +--- +
+ +
+
+ +
+ +

The SQLite3 adapter works SQLite 3.6.16 or newer with the sqlite3-ruby drivers (available as gem from rubygems.org/gems/sqlite3).

+ +

Options:

+
  • +

    :database - Path to the database file.

    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ADAPTER_NAME="SQLite".freeze
 
COLLATE_REGEX=/.*\"(\w+)\".*collate\s+\"(\w+)\".*/i.freeze
 
NATIVE_DATABASE_TYPES={ +primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL", +string: { name: "varchar" }, +text: { name: "text" }, +integer: { name: "integer" }, +float: { name: "float" }, +decimal: { name: "decimal" }, +datetime: { name: "datetime" }, +time: { name: "time" }, +date: { name: "date" }, +binary: { name: "blob" }, +boolean: { name: "boolean" }, +json: { name: "json" }, +}
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(connection, logger, connection_options, config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 101
+def initialize(connection, logger, connection_options, config)
+  super(connection, logger, config)
+
+  @active     = true
+  @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
+
+  configure_connection
+end
+
+
+ +
+ +
+

+ + represent_boolean_as_integer + +

+ + +
+

Indicates whether boolean values are stored in sqlite3 databases as 1 and 0 or 't' and 'f'. Leaving ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer set to false is deprecated. SQLite databases have used 't' and 'f' to serialize boolean values and must have old data converted to 1 and 0 (its native boolean serialization) before setting this flag to true. Conversion can be accomplished by setting up a rake task which runs

+ +
ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
+ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
+
+ +

for all models and all boolean columns, after which the flag must be set to true by adding the following to your application.rb file:

+ +
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 92
+class_attribute :represent_boolean_as_integer, default: false
+
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 146
+def active?
+  @active
+end
+
+
+ +
+ +
+

+ + allowed_index_name_length() + +

+ + +
+

Returns 62. SQLite supports index names up to 64 characters. The rest is used by Rails internally to perform temporary rename operations

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 170
+def allowed_index_name_length
+  index_name_length - 2
+end
+
+
+ +
+ +
+

+ + clear_cache!() + +

+ + +
+

Clears the prepared statements cache.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 159
+def clear_cache!
+  @statements.clear
+end
+
+
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 152
+def disconnect!
+  super
+  @active = false
+  @connection.close rescue nil
+end
+
+
+ +
+ +
+

+ + encoding() + +

+ + +
+

Returns the current database encoding format as a string, eg: 'UTF-8'

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 179
+def encoding
+  @connection.encoding.to_s
+end
+
+
+ +
+ +
+

+ + exec_delete(sql, name = "SQL", binds = []) + +

+ + +
+ +
+ + + +
+ Also aliased as: exec_update +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 242
+def exec_delete(sql, name = "SQL", binds = [])
+  exec_query(sql, name, binds)
+  @connection.changes
+end
+
+
+ +
+ +
+

+ + exec_query(sql, name = nil, binds = [], prepare: false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 209
+def exec_query(sql, name = nil, binds = [], prepare: false)
+  type_casted_binds = type_casted_binds(binds)
+
+  log(sql, name, binds, type_casted_binds) do
+    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
+      # Don't cache statements if they are not prepared
+      unless prepare
+        stmt = @connection.prepare(sql)
+        begin
+          cols = stmt.columns
+          unless without_prepared_statement?(binds)
+            stmt.bind_params(type_casted_binds)
+          end
+          records = stmt.to_a
+        ensure
+          stmt.close
+        end
+      else
+        cache = @statements[sql] ||= {
+          stmt: @connection.prepare(sql)
+        }
+        stmt = cache[:stmt]
+        cols = cache[:cols] ||= stmt.columns
+        stmt.reset!
+        stmt.bind_params(type_casted_binds)
+        records = stmt.to_a
+      end
+
+      ActiveRecord::Result.new(cols, records)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + exec_update(sql, name = "SQL", binds = []) + +

+ + +
+ +
+ + + + + +
+ Alias for: exec_delete +
+ + + +
+ +
+

+ + explain(arel, binds = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 204
+def explain(arel, binds = [])
+  sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
+  SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
+end
+
+
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 356
+def foreign_keys(table_name)
+  fk_info = exec_query("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA")
+  fk_info.map do |row|
+    options = {
+      column: row["from"],
+      primary_key: row["to"],
+      on_delete: extract_foreign_key_action(row["on_delete"]),
+      on_update: extract_foreign_key_action(row["on_update"])
+    }
+    ForeignKeyDefinition.new(table_name, row["table"], options)
+  end
+end
+
+
+ +
+ +
+

+ + insert_fixtures(rows, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 369
+      def insert_fixtures(rows, table_name)
+        ActiveSupport::Deprecation.warn(<<-MSG.squish)
+          `insert_fixtures` is deprecated and will be removed in the next version of Rails.
+          Consider using `insert_fixtures_set` for performance improvement.
+        MSG
+        insert_fixtures_set(table_name => rows)
+      end
+
+
+ +
+ +
+

+ + insert_fixtures_set(fixture_set, tables_to_delete = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 377
+def insert_fixtures_set(fixture_set, tables_to_delete = [])
+  disable_referential_integrity do
+    transaction(requires_new: true) do
+      tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }
+
+      fixture_set.each do |table_name, rows|
+        rows.each { |row| insert_fixture(row, table_name) }
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + last_inserted_id(result) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 248
+def last_inserted_id(result)
+  @connection.last_insert_row_id
+end
+
+
+ +
+ +
+

+ + rename_table(table_name, new_name) + +

+ + +
+

Renames a table.

+ +

Example:

+ +
rename_table('octopuses', 'octopi')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 288
+def rename_table(table_name, new_name)
+  exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
+  rename_table_indexes(table_name, new_name)
+end
+
+
+ +
+ +
+

+ + requires_reloading?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 122
+def requires_reloading?
+  true
+end
+
+
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 134
+def supports_datetime_with_precision?
+  true
+end
+
+
+ +
+ +
+

+ + supports_ddl_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 110
+def supports_ddl_transactions?
+  true
+end
+
+
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 183
+def supports_explain?
+  true
+end
+
+
+ +
+ +
+

+ + supports_foreign_keys_in_create?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 126
+def supports_foreign_keys_in_create?
+  sqlite_version >= "3.6.19"
+end
+
+
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 163
+def supports_index_sort_order?
+  true
+end
+
+
+ +
+ +
+

+ + supports_json?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 138
+def supports_json?
+  true
+end
+
+
+ +
+ +
+

+ + supports_multi_insert?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 142
+def supports_multi_insert?
+  sqlite_version >= "3.7.11"
+end
+
+
+ +
+ +
+

+ + supports_partial_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 118
+def supports_partial_index?
+  sqlite_version >= "3.8.0"
+end
+
+
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 114
+def supports_savepoints?
+  true
+end
+
+
+ +
+ +
+

+ + supports_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 130
+def supports_views?
+  true
+end
+
+
+ +
+ +
+

+ + valid_alter_table_type?(type, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 293
+def valid_alter_table_type?(type, options = {})
+  !invalid_alter_table_type?(type, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/SavepointTransaction.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SavepointTransaction.html new file mode 100644 index 0000000000..e46398b2e2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SavepointTransaction.html @@ -0,0 +1,234 @@ +--- +title: ActiveRecord::ConnectionAdapters::SavepointTransaction +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(connection, savepoint_name, parent_transaction, options, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 145
+def initialize(connection, savepoint_name, parent_transaction, options, *args)
+  super(connection, options, *args)
+
+  parent_transaction.state.add_child(@state)
+
+  if options[:isolation]
+    raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
+  end
+  connection.create_savepoint(@savepoint_name = savepoint_name)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + commit() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 161
+def commit
+  connection.release_savepoint(savepoint_name)
+  @state.commit!
+end
+
+
+ +
+ +
+

+ + full_rollback?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 166
+def full_rollback?; false; end
+
+
+ +
+ +
+

+ + rollback() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 156
+def rollback
+  connection.rollback_to_savepoint(savepoint_name)
+  @state.rollback!
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/Savepoints.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Savepoints.html new file mode 100644 index 0000000000..72dfd78d86 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Savepoints.html @@ -0,0 +1,218 @@ +--- +title: ActiveRecord::ConnectionAdapters::Savepoints +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + create_savepoint(name = current_savepoint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 10
+def create_savepoint(name = current_savepoint_name)
+  execute("SAVEPOINT #{name}")
+end
+
+
+ +
+ +
+

+ + current_savepoint_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 6
+def current_savepoint_name
+  current_transaction.savepoint_name
+end
+
+
+ +
+ +
+

+ + exec_rollback_to_savepoint(name = current_savepoint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 14
+def exec_rollback_to_savepoint(name = current_savepoint_name)
+  execute("ROLLBACK TO SAVEPOINT #{name}")
+end
+
+
+ +
+ +
+

+ + release_savepoint(name = current_savepoint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 18
+def release_savepoint(name = current_savepoint_name)
+  execute("RELEASE SAVEPOINT #{name}")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html new file mode 100644 index 0000000000..75748df724 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html @@ -0,0 +1,713 @@ +--- +title: ActiveRecord::ConnectionAdapters::SchemaCache +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + connection
+ [R] + version
+ + + + +

Class Public methods

+ +
+

+ + new(conn) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 9
+def initialize(conn)
+  @connection = conn
+
+  @columns      = {}
+  @columns_hash = {}
+  @primary_keys = {}
+  @data_sources = {}
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(table_name) + +

+ + +
+

Add internal cache for table with table_name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 55
+def add(table_name)
+  if data_source_exists?(table_name)
+    primary_keys(table_name)
+    columns(table_name)
+    columns_hash(table_name)
+  end
+end
+
+
+ +
+ +
+

+ + clear!() + +

+ + +
+

Clears out internal caches

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 81
+def clear!
+  @columns.clear
+  @columns_hash.clear
+  @primary_keys.clear
+  @data_sources.clear
+  @version = nil
+end
+
+
+ +
+ +
+

+ + clear_data_source_cache!(name) + +

+ + +
+

Clear out internal caches for the data source name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 94
+def clear_data_source_cache!(name)
+  @columns.delete name
+  @columns_hash.delete name
+  @primary_keys.delete name
+  @data_sources.delete name
+end
+
+
+ +
+ +
+

+ + columns(table_name) + +

+ + +
+

Get the columns for a table

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 68
+def columns(table_name)
+  @columns[table_name] ||= connection.columns(table_name)
+end
+
+
+ +
+ +
+

+ + columns_hash(table_name) + +

+ + +
+

Get the columns for a table as a hash, key is the column name value is the column object.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 74
+def columns_hash(table_name)
+  @columns_hash[table_name] ||= Hash[columns(table_name).map { |col|
+    [col.name, col]
+  }]
+end
+
+
+ +
+ +
+

+ + data_source_exists?(name) + +

+ + +
+

A cached lookup for table existence.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 47
+def data_source_exists?(name)
+  prepare_data_sources if @data_sources.empty?
+  return @data_sources[name] if @data_sources.key? name
+
+  @data_sources[name] = connection.data_source_exists?(name)
+end
+
+
+ +
+ +
+

+ + data_sources(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 63
+def data_sources(name)
+  @data_sources[name]
+end
+
+
+ +
+ +
+

+ + encode_with(coder) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 26
+def encode_with(coder)
+  coder["columns"] = @columns
+  coder["columns_hash"] = @columns_hash
+  coder["primary_keys"] = @primary_keys
+  coder["data_sources"] = @data_sources
+  coder["version"] = connection.migration_context.current_version
+end
+
+
+ +
+ +
+

+ + init_with(coder) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 34
+def init_with(coder)
+  @columns = coder["columns"]
+  @columns_hash = coder["columns_hash"]
+  @primary_keys = coder["primary_keys"]
+  @data_sources = coder["data_sources"]
+  @version = coder["version"]
+end
+
+
+ +
+ +
+

+ + initialize_dup(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 18
+def initialize_dup(other)
+  super
+  @columns      = @columns.dup
+  @columns_hash = @columns_hash.dup
+  @primary_keys = @primary_keys.dup
+  @data_sources = @data_sources.dup
+end
+
+
+ +
+ +
+

+ + marshal_dump() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 101
+def marshal_dump
+  # if we get current version during initialization, it happens stack over flow.
+  @version = connection.migration_context.current_version
+  [@version, @columns, @columns_hash, @primary_keys, @data_sources]
+end
+
+
+ +
+ +
+

+ + marshal_load(array) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 107
+def marshal_load(array)
+  @version, @columns, @columns_hash, @primary_keys, @data_sources = array
+end
+
+
+ +
+ +
+

+ + primary_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 42
+def primary_keys(table_name)
+  @primary_keys[table_name] ||= data_source_exists?(table_name) ? connection.primary_key(table_name) : nil
+end
+
+
+ +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 89
+def size
+  [@columns, @columns_hash, @primary_keys, @data_sources].map(&:size).inject :+
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html new file mode 100644 index 0000000000..5f484a0a5b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html @@ -0,0 +1,2719 @@ +--- +title: ActiveRecord::ConnectionAdapters::SchemaStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + add_belongs_to(table_name, ref_name, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: add_reference +
+ + + +
+ +
+

+ + add_column(table_name, column_name, type, options = {}) + +

+ + +
+

Add a new type column named column_name to table_name.

+ +

The type parameter is normally one of the migrations native types, which is one of the following: :primary_key, :string, :text, :integer, :bigint, :float, :decimal, :numeric, :datetime, :time, :date, :binary, :boolean.

+ +

You may use a type not in this list as long as it is supported by your database (for example, “polygon” in MySQL), but this will not be database agnostic and should usually be avoided.

+ +

Available options are (none of these exists by default):

+
  • +

    :limit - Requests a maximum column length. This is the number of characters for a :string column and number of bytes for :text, :binary and :integer columns. This option is ignored by some backends.

    +
  • +

    :default - The column's default value. Use nil for NULL.

    +
  • +

    :null - Allows or disallows NULL values in the column.

    +
  • +

    :precision - Specifies the precision for the :decimal and :numeric columns.

    +
  • +

    :scale - Specifies the scale for the :decimal and :numeric columns.

    +
  • +

    :comment - Specifies the comment for the column. This option is ignored by some backends.

    +
+ +

Note: The precision is the total number of significant digits, and the scale is the number of digits that can be stored following the decimal point. For example, the number 123.45 has a precision of 5 and a scale of 2. A decimal with a precision of 5 and a scale of 2 can range from -999.99 to 999.99.

+ +

Please be aware of different RDBMS implementations behavior with :decimal columns:

+
  • +

    The SQL standard says the default scale should be 0, :scale <= :precision, and makes no comments about the requirements of :precision.

    +
  • +

    MySQL: :precision [1..63], :scale [0..30]. Default is (10,0).

    +
  • +

    PostgreSQL: :precision [1..infinity], :scale [0..infinity]. No default.

    +
  • +

    SQLite3: No restrictions on :precision and :scale, but the maximum supported :precision is 16. No default.

    +
  • +

    Oracle: :precision [1..38], :scale [-84..127]. Default is (38,0).

    +
  • +

    DB2: :precision [1..63], :scale [0..62]. Default unknown.

    +
  • +

    SqlServer: :precision [1..38], :scale [0..38]. Default (38,0).

    +
+ +

Examples

+ +
add_column(:users, :picture, :binary, limit: 2.megabytes)
+# ALTER TABLE "users" ADD "picture" blob(2097152)
+
+add_column(:articles, :status, :string, limit: 20, default: 'draft', null: false)
+# ALTER TABLE "articles" ADD "status" varchar(20) DEFAULT 'draft' NOT NULL
+
+add_column(:answers, :bill_gates_money, :decimal, precision: 15, scale: 2)
+# ALTER TABLE "answers" ADD "bill_gates_money" decimal(15,2)
+
+add_column(:measurements, :sensor_reading, :decimal, precision: 30, scale: 20)
+# ALTER TABLE "measurements" ADD "sensor_reading" decimal(30,20)
+
+# While :scale defaults to zero on most databases, it
+# probably wouldn't hurt to include it.
+add_column(:measurements, :huge_integer, :decimal, precision: 30)
+# ALTER TABLE "measurements" ADD "huge_integer" decimal(30)
+
+# Defines a column that stores an array of a type.
+add_column(:users, :skills, :text, array: true)
+# ALTER TABLE "users" ADD "skills" text[]
+
+# Defines a column with a database-specific type.
+add_column(:shapes, :triangle, 'polygon')
+# ALTER TABLE "shapes" ADD "triangle" polygon
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 578
+def add_column(table_name, column_name, type, options = {})
+  at = create_alter_table table_name
+  at.add_column(column_name, type, options)
+  execute schema_creation.accept at
+end
+
+
+ +
+ +
+

+ + add_foreign_key(from_table, to_table, options = {}) + +

+ + +
+

Adds a new foreign key. from_table is the table with the key column, to_table contains the referenced primary key.

+ +

The foreign key will be named after the following pattern: fk_rails_<identifier>. identifier is a 10 character long string which is deterministically generated from the from_table and column. A custom name can be specified with the :name option.

+ +
Creating a simple foreign key
+ +
add_foreign_key :articles, :authors
+
+ +

generates:

+ +
ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id")
+
+ +
Creating a foreign key on a specific column
+ +
add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"
+
+ +

generates:

+ +
ALTER TABLE "articles" ADD CONSTRAINT fk_rails_58ca3d3a82 FOREIGN KEY ("author_id") REFERENCES "users" ("lng_id")
+
+ +
Creating a cascading foreign key
+ +
add_foreign_key :articles, :authors, on_delete: :cascade
+
+ +

generates:

+ +
ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id") ON DELETE CASCADE
+
+ +

The options hash can include the following keys:

+
:column +
+

The foreign key column name on from_table. Defaults to to_table.singularize + "_id"

+
:primary_key +
+

The primary key column name on to_table. Defaults to id.

+
:name +
+

The constraint name. Defaults to fk_rails_<identifier>.

+
:on_delete +
+

Action that happens ON DELETE. Valid values are :nullify, :cascade and :restrict

+
:on_update +
+

Action that happens ON UPDATE. Valid values are :nullify, :cascade and :restrict

+
:validate +
+

(Postgres only) Specify whether or not the constraint should be validated. Defaults to true.

+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 960
+def add_foreign_key(from_table, to_table, options = {})
+  return unless supports_foreign_keys?
+
+  options = foreign_key_options(from_table, to_table, options)
+  at = create_alter_table from_table
+  at.add_foreign_key to_table, options
+
+  execute schema_creation.accept(at)
+end
+
+
+ +
+ +
+

+ + add_index(table_name, column_name, options = {}) + +

+ + +
+

Adds a new index to the table. column_name can be a single Symbol, or an Array of Symbols.

+ +

The index will be named after the table and the column name(s), unless you pass :name as an option.

+ +
Creating a simple index
+ +
add_index(:suppliers, :name)
+
+ +

generates:

+ +
CREATE INDEX suppliers_name_index ON suppliers(name)
+
+ +
Creating a unique index
+ +
add_index(:accounts, [:branch_id, :party_id], unique: true)
+
+ +

generates:

+ +
CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
+
+ +
Creating a named index
+ +
add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
+
+ +

generates:

+ +
CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
+
+ +
Creating an index with specific key length
+ +
add_index(:accounts, :name, name: 'by_name', length: 10)
+
+ +

generates:

+ +
CREATE INDEX by_name ON accounts(name(10))
+
+ +
Creating an index with specific key lengths for multiple keys
+ +
add_index(:accounts, [:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
+
+ +

generates:

+ +
CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
+
+ +

Note: SQLite doesn't support index length.

+ +
Creating an index with a sort order (desc or asc, asc is the default)
+ +
add_index(:accounts, [:branch_id, :party_id, :surname], order: {branch_id: :desc, party_id: :asc})
+
+ +

generates:

+ +
CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
+
+ +

Note: MySQL only supports index order from 8.0.1 onwards (earlier versions accepted the syntax but ignored it).

+ +
Creating a partial index
+ +
add_index(:accounts, [:branch_id, :party_id], unique: true, where: "active")
+
+ +

generates:

+ +
CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
+
+ +

Note: Partial indexes are only supported for PostgreSQL and SQLite 3.8.0+.

+ +
Creating an index with a specific method
+ +
add_index(:developers, :name, using: 'btree')
+
+ +

generates:

+ +
CREATE INDEX index_developers_on_name ON developers USING btree (name) -- PostgreSQL
+CREATE INDEX index_developers_on_name USING btree ON developers (name) -- MySQL
+
+ +

Note: only supported by PostgreSQL and MySQL

+ +
Creating an index with a specific operator class
+ +
add_index(:developers, :name, using: 'gist', opclass: :gist_trgm_ops)
+# CREATE INDEX developers_on_name ON developers USING gist (name gist_trgm_ops) -- PostgreSQL
+
+add_index(:developers, [:name, :city], using: 'gist', opclass: { city: :gist_trgm_ops })
+# CREATE INDEX developers_on_name_and_city ON developers USING gist (name, city gist_trgm_ops) -- PostgreSQL
+
+add_index(:developers, [:name, :city], using: 'gist', opclass: :gist_trgm_ops)
+# CREATE INDEX developers_on_name_and_city ON developers USING gist (name gist_trgm_ops, city gist_trgm_ops) -- PostgreSQL
+
+ +

Note: only supported by PostgreSQL

+ +
Creating an index with a specific type
+ +
add_index(:developers, :name, type: :fulltext)
+
+ +

generates:

+ +
CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL
+
+ +

Note: only supported by MySQL.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 763
+def add_index(table_name, column_name, options = {})
+  index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
+  execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}"
+end
+
+
+ +
+ +
+

+ + add_reference(table_name, ref_name, **options) + +

+ + +
+

Adds a reference. The reference column is a bigint by default, the :type option can be used to specify a different type. Optionally adds a _type column, if :polymorphic option is provided. add_reference and add_belongs_to are acceptable.

+ +

The options hash can include the following keys:

+
:type +
+

The reference column type. Defaults to :bigint.

+
:index +
+

Add an appropriate index. Defaults to true. See add_index for usage of this option.

+
:foreign_key +
+

Add an appropriate foreign key constraint. Defaults to false.

+
:polymorphic +
+

Whether an additional _type column should be added. Defaults to false.

+
:null +
+

Whether the column allows nulls. Defaults to true.

+
+ +
Create a user_id bigint column
+ +
add_reference(:products, :user)
+
+ +
Create a user_id string column
+ +
add_reference(:products, :user, type: :string)
+
+ +
Create supplier_id, supplier_type columns and appropriate index
+ +
add_reference(:products, :supplier, polymorphic: true, index: true)
+
+ +
Create a supplier_id column with a unique index
+ +
add_reference(:products, :supplier, index: { unique: true })
+
+ +
Create a supplier_id column with a named index
+ +
add_reference(:products, :supplier, index: { name: "my_supplier_index" })
+
+ +
Create a supplier_id column and appropriate foreign key
+ +
add_reference(:products, :supplier, foreign_key: true)
+
+ +
Create a supplier_id column and a foreign key to the firms table
+ +
add_reference(:products, :supplier, foreign_key: {to_table: :firms})
+
+
+ + + +
+ Also aliased as: add_belongs_to +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 873
+def add_reference(table_name, ref_name, **options)
+  ReferenceDefinition.new(ref_name, options).add_to(update_table_definition(table_name, self))
+end
+
+
+ +
+ +
+

+ + add_timestamps(table_name, options = {}) + +

+ + +
+

Adds timestamps (created_at and updated_at) columns to table_name. Additional options (like :null) are forwarded to add_column.

+ +
add_timestamps(:suppliers, null: true)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1115
+def add_timestamps(table_name, options = {})
+  options[:null] = false if options[:null].nil?
+
+  add_column table_name, :created_at, :datetime, options
+  add_column table_name, :updated_at, :datetime, options
+end
+
+
+ +
+ +
+

+ + assume_migrated_upto_version(version, migrations_paths) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1037
+def assume_migrated_upto_version(version, migrations_paths)
+  migrations_paths = Array(migrations_paths)
+  version = version.to_i
+  sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
+
+  migrated = ActiveRecord::SchemaMigration.all_versions.map(&:to_i)
+  versions = migration_context.migration_files.map do |file|
+    migration_context.parse_migration_filename(file).first.to_i
+  end
+
+  unless migrated.include?(version)
+    execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version)})"
+  end
+
+  inserting = (versions - migrated).select { |v| v < version }
+  if inserting.any?
+    if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
+      raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
+    end
+    if supports_multi_insert?
+      execute insert_versions_sql(inserting)
+    else
+      inserting.each do |v|
+        execute insert_versions_sql(v)
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + change_column(table_name, column_name, type, options = {}) + +

+ + +
+

Changes the column's definition according to the new options. See TableDefinition#column for details of the options you can use.

+ +
change_column(:suppliers, :name, :string, limit: 80)
+change_column(:accounts, :description, :text)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 612
+def change_column(table_name, column_name, type, options = {})
+  raise NotImplementedError, "change_column is not implemented"
+end
+
+
+ +
+ +
+

+ + change_column_comment(table_name, column_name, comment) + +

+ + +
+

Changes the comment for a column or removes it if nil.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1177
+def change_column_comment(table_name, column_name, comment)
+  raise NotImplementedError, "#{self.class} does not support changing column comments"
+end
+
+
+ +
+ +
+

+ + change_column_default(table_name, column_name, default_or_changes) + +

+ + +
+

Sets a new default value for a column:

+ +
change_column_default(:suppliers, :qualification, 'new')
+change_column_default(:accounts, :authorized, 1)
+
+ +

Setting the default to nil effectively drops the default:

+ +
change_column_default(:users, :email, nil)
+
+ +

Passing a hash containing :from and :to will make this change reversible in migration:

+ +
change_column_default(:posts, :state, from: nil, to: "draft")
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 630
+def change_column_default(table_name, column_name, default_or_changes)
+  raise NotImplementedError, "change_column_default is not implemented"
+end
+
+
+ +
+ +
+

+ + change_column_null(table_name, column_name, null, default = nil) + +

+ + +
+

Sets or removes a NOT NULL constraint on a column. The null flag indicates whether the value can be NULL. For example

+ +
change_column_null(:users, :nickname, false)
+
+ +

says nicknames cannot be NULL (adds the constraint), whereas

+ +
change_column_null(:users, :nickname, true)
+
+ +

allows them to be NULL (drops the constraint).

+ +

The method accepts an optional fourth argument to replace existing NULLs with some other value. Use that one when enabling the constraint if needed, since otherwise those rows would not be valid.

+ +

Please note the fourth argument does not set a column's default.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 650
+def change_column_null(table_name, column_name, null, default = nil)
+  raise NotImplementedError, "change_column_null is not implemented"
+end
+
+
+ +
+ +
+

+ + change_table(table_name, options = {}) + +

+ + +
+

A block for changing columns in table.

+ +
# change_table() yields a Table instance
+change_table(:suppliers) do |t|
+  t.column :name, :string, limit: 60
+  # Other column alterations here
+end
+
+ +

The options hash can include the following keys:

+
:bulk +
+

Set this to true to make this a bulk alter query, such as

+ +
ALTER TABLE `users` ADD COLUMN age INT, ADD COLUMN birthdate DATETIME ...
+
+ +

Defaults to false.

+ +

Only supported on the MySQL and PostgreSQL adapter, ignored elsewhere.

+
+ +
Add a column
+ +
change_table(:suppliers) do |t|
+  t.column :name, :string, limit: 60
+end
+
+ +
Add 2 integer columns
+ +
change_table(:suppliers) do |t|
+  t.integer :width, :height, null: false, default: 0
+end
+
+ +
Add created_at/updated_at columns
+ +
change_table(:suppliers) do |t|
+  t.timestamps
+end
+
+ +
Add a foreign key column
+ +
change_table(:suppliers) do |t|
+  t.references :company
+end
+
+ +

Creates a company_id(bigint) column.

+ +
Add a polymorphic foreign key column
+ +
change_table(:suppliers) do |t|
+  t.belongs_to :company, polymorphic: true
+end
+
+ +

Creates company_type(varchar) and company_id(bigint) columns.

+ +
Remove a column
+ +
change_table(:suppliers) do |t|
+  t.remove :company
+end
+
+ +
Remove several columns
+ +
change_table(:suppliers) do |t|
+  t.remove :company_id
+  t.remove :width, :height
+end
+
+ +
Remove an index
+ +
change_table(:suppliers) do |t|
+  t.remove_index :company_id
+end
+
+ +

See also Table for details on all of the various column transformations.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 465
+def change_table(table_name, options = {})
+  if supports_bulk_alter? && options[:bulk]
+    recorder = ActiveRecord::Migration::CommandRecorder.new(self)
+    yield update_table_definition(table_name, recorder)
+    bulk_change_table(table_name, recorder.commands)
+  else
+    yield update_table_definition(table_name, self)
+  end
+end
+
+
+ +
+ +
+

+ + change_table_comment(table_name, comment) + +

+ + +
+

Changes the comment for a table or removes it if nil.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1172
+def change_table_comment(table_name, comment)
+  raise NotImplementedError, "#{self.class} does not support changing table comments"
+end
+
+
+ +
+ +
+

+ + column_exists?(table_name, column_name, type = nil, options = {}) + +

+ + +
+

Checks to see if a column exists in a given table.

+ +
# Check a column exists
+column_exists?(:suppliers, :name)
+
+# Check a column exists of a particular type
+column_exists?(:suppliers, :name, :string)
+
+# Check a column exists with a specific definition
+column_exists?(:suppliers, :name, :string, limit: 100)
+column_exists?(:suppliers, :name, :string, default: 'default')
+column_exists?(:suppliers, :name, :string, null: false)
+column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 132
+def column_exists?(table_name, column_name, type = nil, options = {})
+  column_name = column_name.to_s
+  checks = []
+  checks << lambda { |c| c.name == column_name }
+  checks << lambda { |c| c.type == type } if type
+  column_options_keys.each do |attr|
+    checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
+  end
+
+  columns(table_name).any? { |c| checks.all? { |check| check[c] } }
+end
+
+
+ +
+ +
+

+ + columns(table_name) + +

+ + +
+

Returns an array of Column objects for the table specified by table_name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 111
+def columns(table_name)
+  table_name = table_name.to_s
+  column_definitions(table_name).map do |field|
+    new_column_from_field(table_name, field)
+  end
+end
+
+
+ +
+ +
+

+ + create_join_table(table_1, table_2, column_options: {}, **options) + +

+ + +
+

Creates a new join table with the name created using the lexical order of the first two arguments. These arguments can be a String or a Symbol.

+ +
# Creates a table called 'assemblies_parts' with no id.
+create_join_table(:assemblies, :parts)
+
+ +

You can pass an options hash which can include the following keys:

+
:table_name +
+

Sets the table name, overriding the default.

+
:column_options +
+

Any extra options you want appended to the columns definition.

+
:options +
+

Any extra options you want appended to the table definition.

+
:temporary +
+

Make a temporary table.

+
:force +
+

Set to true to drop the table before creating it. Defaults to false.

+
+ +

Note that create_join_table does not create any indices by default; you can use its block form to do so yourself:

+ +
create_join_table :products, :categories do |t|
+  t.index :product_id
+  t.index :category_id
+end
+
+ +
Add a backend specific option to the generated SQL (MySQL)
+ +
create_join_table(:assemblies, :parts, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
+
+ +

generates:

+ +
CREATE TABLE assemblies_parts (
+  assembly_id bigint NOT NULL,
+  part_id bigint NOT NULL,
+) ENGINE=InnoDB DEFAULT CHARSET=utf8
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 368
+def create_join_table(table_1, table_2, column_options: {}, **options)
+  join_table_name = find_join_table_name(table_1, table_2, options)
+
+  column_options.reverse_merge!(null: false, index: false)
+
+  t1_ref, t2_ref = [table_1, table_2].map { |t| t.to_s.singularize }
+
+  create_table(join_table_name, options.merge!(id: false)) do |td|
+    td.references t1_ref, column_options
+    td.references t2_ref, column_options
+    yield td if block_given?
+  end
+end
+
+
+ +
+ +
+

+ + create_table(table_name, comment: nil, **options) + +

+ + +
+

Creates a new table with the name table_name. table_name may either be a String or a Symbol.

+ +

There are two ways to work with create_table. You can use the block form or the regular form, like this:

+ +

Block form

+ +
# create_table() passes a TableDefinition object to the block.
+# This form will not only create the table, but also columns for the
+# table.
+
+create_table(:suppliers) do |t|
+  t.column :name, :string, limit: 60
+  # Other fields here
+end
+
+ +

Block form, with shorthand

+ +
# You can also use the column types as method calls, rather than calling the column method.
+create_table(:suppliers) do |t|
+  t.string :name, limit: 60
+  # Other fields here
+end
+
+ +

Regular form

+ +
# Creates a table called 'suppliers' with no columns.
+create_table(:suppliers)
+# Add a column to 'suppliers'.
+add_column(:suppliers, :name, :string, {limit: 60})
+
+ +

The options hash can include the following keys:

+
:id +
+

Whether to automatically add a primary key column. Defaults to true. Join tables for ActiveRecord::Base.has_and_belongs_to_many should set it to false.

+ +

A Symbol can be used to specify the type of the generated primary key column.

+
:primary_key +
+

The name of the primary key, if one is to be added automatically. Defaults to id. If :id is false, then this option is ignored.

+ +

If an array is passed, a composite primary key will be created.

+ +

Note that Active Record models will automatically detect their primary key. This can be avoided by using self.primary_key= on the model to define the key explicitly.

+
:options +
+

Any extra options you want appended to the table definition.

+
:temporary +
+

Make a temporary table.

+
:force +
+

Set to true to drop the table before creating it. Set to :cascade to drop dependent objects as well. Defaults to false.

+
:as +
+

SQL to use to generate the table. When this option is used, the block is ignored, as are the :id and :primary_key options.

+
+ +
Add a backend specific option to the generated SQL (MySQL)
+ +
create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
+
+ +

generates:

+ +
CREATE TABLE suppliers (
+  id bigint auto_increment PRIMARY KEY
+) ENGINE=InnoDB DEFAULT CHARSET=utf8
+
+ +
Rename the primary key column
+ +
create_table(:objects, primary_key: 'guid') do |t|
+  t.column :name, :string, limit: 80
+end
+
+ +

generates:

+ +
CREATE TABLE objects (
+  guid bigint auto_increment PRIMARY KEY,
+  name varchar(80)
+)
+
+ +
Change the primary key column type
+ +
create_table(:tags, id: :string) do |t|
+  t.column :label, :string
+end
+
+ +

generates:

+ +
CREATE TABLE tags (
+  id varchar PRIMARY KEY,
+  label varchar
+)
+
+ +
Create a composite primary key
+ +
create_table(:orders, primary_key: [:product_id, :client_id]) do |t|
+  t.belongs_to :product
+  t.belongs_to :client
+end
+
+ +

generates:

+ +
CREATE TABLE order (
+    product_id bigint NOT NULL,
+    client_id bigint NOT NULL
+);
+
+ALTER TABLE ONLY "orders"
+  ADD CONSTRAINT orders_pkey PRIMARY KEY (product_id, client_id);
+
+ +
Do not add a primary key column
+ +
create_table(:categories_suppliers, id: false) do |t|
+  t.column :category_id, :bigint
+  t.column :supplier_id, :bigint
+end
+
+ +

generates:

+ +
CREATE TABLE categories_suppliers (
+  category_id bigint,
+  supplier_id bigint
+)
+
+ +
Create a temporary table based on a query
+ +
create_table(:long_query, temporary: true,
+  as: "SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id")
+
+ +

generates:

+ +
CREATE TEMPORARY TABLE long_query AS
+  SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id
+
+ +

See also TableDefinition#column for details on how to create columns.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 290
+def create_table(table_name, comment: nil, **options)
+  td = create_table_definition table_name, options[:temporary], options[:options], options[:as], comment: comment
+
+  if options[:id] != false && !options[:as]
+    pk = options.fetch(:primary_key) do
+      Base.get_primary_key table_name.to_s.singularize
+    end
+
+    if pk.is_a?(Array)
+      td.primary_keys pk
+    else
+      td.primary_key pk, options.fetch(:id, :primary_key), options
+    end
+  end
+
+  yield td if block_given?
+
+  if options[:force]
+    drop_table(table_name, options.merge(if_exists: true))
+  end
+
+  result = execute schema_creation.accept td
+
+  unless supports_indexes_in_create?
+    td.indexes.each do |column_name, index_options|
+      add_index(table_name, column_name, index_options)
+    end
+  end
+
+  if supports_comments? && !supports_comments_in_create?
+    change_table_comment(table_name, comment) if comment.present?
+
+    td.columns.each do |column|
+      change_column_comment(table_name, column.name, column.comment) if column.comment.present?
+    end
+  end
+
+  result
+end
+
+
+ +
+ +
+

+ + data_source_exists?(name) + +

+ + +
+

Checks to see if the data source name exists on the database.

+ +
data_source_exists?(:ebooks)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 45
+def data_source_exists?(name)
+  query_values(data_source_sql(name), "SCHEMA").any? if name.present?
+rescue NotImplementedError
+  data_sources.include?(name.to_s)
+end
+
+
+ +
+ +
+

+ + data_sources() + +

+ + +
+

Returns the relation names useable to back Active Record models. For most adapters this means all tables and views.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 35
+def data_sources
+  query_values(data_source_sql, "SCHEMA")
+rescue NotImplementedError
+  tables | views
+end
+
+
+ +
+ +
+

+ + drop_join_table(table_1, table_2, options = {}) + +

+ + +
+

Drops the join table specified by the given arguments. See create_join_table for details.

+ +

Although this command ignores the block if one is given, it can be helpful to provide one in a migration's change method so it can be reverted. In that case, the block will be used by create_join_table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 388
+def drop_join_table(table_1, table_2, options = {})
+  join_table_name = find_join_table_name(table_1, table_2, options)
+  drop_table(join_table_name)
+end
+
+
+ +
+ +
+

+ + drop_table(table_name, options = {}) + +

+ + +
+

Drops a table from the database.

+
:force +
+

Set to :cascade to drop dependent objects as well. Defaults to false.

+
:if_exists +
+

Set to true to only drop the table if it exists. Defaults to false.

+
+ +

Although this command ignores most options and the block if one is given, it can be helpful to provide these in a migration's change method so it can be reverted. In that case, options and the block will be used by create_table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 495
+def drop_table(table_name, options = {})
+  execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
+end
+
+
+ +
+ +
+

+ + foreign_key_exists?(from_table, options_or_to_table = {}) + +

+ + +
+

Checks to see if a foreign key exists on a table for a given foreign key definition.

+ +
# Checks to see if a foreign key exists.
+foreign_key_exists?(:accounts, :branches)
+
+# Checks to see if a foreign key on a specified column exists.
+foreign_key_exists?(:accounts, column: :owner_id)
+
+# Checks to see if a foreign key with a custom name exists.
+foreign_key_exists?(:accounts, name: "special_fk_name")
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1010
+def foreign_key_exists?(from_table, options_or_to_table = {})
+  foreign_key_for(from_table, options_or_to_table).present?
+end
+
+
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+

Returns an array of foreign keys for the given table. The foreign keys are represented as ForeignKeyDefinition objects.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 912
+def foreign_keys(table_name)
+  raise NotImplementedError, "foreign_keys is not implemented"
+end
+
+
+ +
+ +
+

+ + index_exists?(table_name, column_name, options = {}) + +

+ + +
+

Checks to see if an index exists on a table for a given index definition.

+ +
# Check an index exists
+index_exists?(:suppliers, :company_id)
+
+# Check an index on multiple columns exists
+index_exists?(:suppliers, [:company_id, :company_type])
+
+# Check a unique index exists
+index_exists?(:suppliers, :company_id, unique: true)
+
+# Check an index with a custom name exists
+index_exists?(:suppliers, :company_id, name: "idx_company_id")
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 100
+def index_exists?(table_name, column_name, options = {})
+  column_names = Array(column_name).map(&:to_s)
+  checks = []
+  checks << lambda { |i| Array(i.columns) == column_names }
+  checks << lambda { |i| i.unique } if options[:unique]
+  checks << lambda { |i| i.name == options[:name].to_s } if options[:name]
+
+  indexes(table_name).any? { |i| checks.all? { |check| check[i] } }
+end
+
+
+ +
+ +
+

+ + index_name_exists?(table_name, index_name) + +

+ + +
+

Verifies the existence of an index with a given name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 822
+def index_name_exists?(table_name, index_name)
+  index_name = index_name.to_s
+  indexes(table_name).detect { |i| i.name == index_name }
+end
+
+
+ +
+ +
+

+ + indexes(table_name) + +

+ + +
+

Returns an array of indexes for the given table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 82
+def indexes(table_name)
+  raise NotImplementedError, "#indexes is not implemented"
+end
+
+
+ +
+ +
+

+ + native_database_types() + +

+ + +
+

Returns a hash of mappings from the abstract data types to the native database types. See TableDefinition#column for details on the recognized abstract data types.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 15
+def native_database_types
+  {}
+end
+
+
+ +
+ +
+

+ + options_include_default?(options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1167
+def options_include_default?(options)
+  options.include?(:default) && !(options[:null] == false && options[:default].nil?)
+end
+
+
+ +
+ +
+

+ + primary_key(table_name) + +

+ + +
+

Returns just a table's primary key

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 145
+def primary_key(table_name)
+  pk = primary_keys(table_name)
+  pk = pk.first unless pk.size > 1
+  pk
+end
+
+
+ +
+ +
+

+ + remove_belongs_to(table_name, ref_name, foreign_key: false, polymorphic: false, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: remove_reference +
+ + + +
+ +
+

+ + remove_column(table_name, column_name, type = nil, options = {}) + +

+ + +
+

Removes the column from the table definition.

+ +
remove_column(:suppliers, :qualification)
+
+ +

The type and options parameters will be ignored if present. It can be helpful to provide these in a migration's change method so it can be reverted. In that case, type and options will be used by add_column.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 602
+def remove_column(table_name, column_name, type = nil, options = {})
+  execute "ALTER TABLE #{quote_table_name(table_name)} #{remove_column_for_alter(table_name, column_name, type, options)}"
+end
+
+
+ +
+ +
+

+ + remove_columns(table_name, *column_names) + +

+ + +
+

Removes the given columns from the table definition.

+ +
remove_columns(:suppliers, :qualification, :experience)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 588
+def remove_columns(table_name, *column_names)
+  raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)") if column_names.empty?
+  column_names.each do |column_name|
+    remove_column(table_name, column_name)
+  end
+end
+
+
+ +
+ +
+

+ + remove_foreign_key(from_table, options_or_to_table = {}) + +

+ + +
+

Removes the given foreign key from the table. Any option parameters provided will be used to re-add the foreign key in case of a migration rollback. It is recommended that you provide any options used when creating the foreign key so that the migration can be reverted properly.

+ +

Removes the foreign key on accounts.branch_id.

+ +
remove_foreign_key :accounts, :branches
+
+ +

Removes the foreign key on accounts.owner_id.

+ +
remove_foreign_key :accounts, column: :owner_id
+
+ +

Removes the foreign key named special_fk_name on the accounts table.

+ +
remove_foreign_key :accounts, name: :special_fk_name
+
+ +

The options hash accepts the same keys as SchemaStatements#add_foreign_key.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 988
+def remove_foreign_key(from_table, options_or_to_table = {})
+  return unless supports_foreign_keys?
+
+  fk_name_to_delete = foreign_key_for!(from_table, options_or_to_table).name
+
+  at = create_alter_table from_table
+  at.drop_foreign_key fk_name_to_delete
+
+  execute schema_creation.accept(at)
+end
+
+
+ +
+ +
+

+ + remove_index(table_name, options = {}) + +

+ + +
+

Removes the given index from the table.

+ +

Removes the index on branch_id in the accounts table if exactly one such index exists.

+ +
remove_index :accounts, :branch_id
+
+ +

Removes the index on branch_id in the accounts table if exactly one such index exists.

+ +
remove_index :accounts, column: :branch_id
+
+ +

Removes the index on branch_id and party_id in the accounts table if exactly one such index exists.

+ +
remove_index :accounts, column: [:branch_id, :party_id]
+
+ +

Removes the index named by_branch_party in the accounts table.

+ +
remove_index :accounts, name: :by_branch_party
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 786
+def remove_index(table_name, options = {})
+  index_name = index_name_for_remove(table_name, options)
+  execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
+end
+
+
+ +
+ +
+

+ + remove_reference(table_name, ref_name, foreign_key: false, polymorphic: false, **options) + +

+ + +
+

Removes the reference(s). Also removes a type column if one exists. remove_reference and remove_belongs_to are acceptable.

+ +
Remove the reference
+ +
remove_reference(:products, :user, index: true)
+
+ +
Remove polymorphic reference
+ +
remove_reference(:products, :supplier, polymorphic: true)
+
+ +
Remove the reference with a foreign key
+ +
remove_reference(:products, :user, index: true, foreign_key: true)
+
+
+ + + +
+ Also aliased as: remove_belongs_to +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 893
+def remove_reference(table_name, ref_name, foreign_key: false, polymorphic: false, **options)
+  if foreign_key
+    reference_name = Base.pluralize_table_names ? ref_name.to_s.pluralize : ref_name
+    if foreign_key.is_a?(Hash)
+      foreign_key_options = foreign_key
+    else
+      foreign_key_options = { to_table: reference_name }
+    end
+    foreign_key_options[:column] ||= "#{ref_name}_id"
+    remove_foreign_key(table_name, foreign_key_options)
+  end
+
+  remove_column(table_name, "#{ref_name}_id")
+  remove_column(table_name, "#{ref_name}_type") if polymorphic
+end
+
+
+ +
+ +
+

+ + remove_timestamps(table_name, options = {}) + +

+ + +
+

Removes the timestamp columns (created_at and updated_at) from the table definition.

+ +
remove_timestamps(:suppliers)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1126
+def remove_timestamps(table_name, options = {})
+  remove_column table_name, :updated_at
+  remove_column table_name, :created_at
+end
+
+
+ +
+ +
+

+ + rename_column(table_name, column_name, new_column_name) + +

+ + +
+

Renames a column.

+ +
rename_column(:suppliers, :description, :name)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 658
+def rename_column(table_name, column_name, new_column_name)
+  raise NotImplementedError, "rename_column is not implemented"
+end
+
+
+ +
+ +
+

+ + rename_index(table_name, old_name, new_name) + +

+ + +
+

Renames an index.

+ +

Rename the index_people_on_last_name index to index_users_on_last_name:

+ +
rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 797
+def rename_index(table_name, old_name, new_name)
+  validate_index_length!(table_name, new_name)
+
+  # this is a naive implementation; some DBs may support this more efficiently (PostgreSQL, for instance)
+  old_index_def = indexes(table_name).detect { |i| i.name == old_name }
+  return unless old_index_def
+  add_index(table_name, old_index_def.columns, name: new_name, unique: old_index_def.unique)
+  remove_index(table_name, name: old_name)
+end
+
+
+ +
+ +
+

+ + rename_table(table_name, new_name) + +

+ + +
+

Renames a table.

+ +
rename_table('octopuses', 'octopi')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 479
+def rename_table(table_name, new_name)
+  raise NotImplementedError, "rename_table is not implemented"
+end
+
+
+ +
+ +
+

+ + table_alias_for(table_name) + +

+ + +
+

Truncates a table alias according to the limits of the current adapter.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 29
+def table_alias_for(table_name)
+  table_name[0...table_alias_length].tr(".", "_")
+end
+
+
+ +
+ +
+

+ + table_comment(table_name) + +

+ + +
+

Returns the table comment that's stored in database metadata.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 24
+def table_comment(table_name)
+  nil
+end
+
+
+ +
+ +
+

+ + table_exists?(table_name) + +

+ + +
+

Checks to see if the table table_name exists on the database.

+ +
table_exists?(:developers)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 60
+def table_exists?(table_name)
+  query_values(data_source_sql(table_name, type: "BASE TABLE"), "SCHEMA").any? if table_name.present?
+rescue NotImplementedError
+  tables.include?(table_name.to_s)
+end
+
+
+ +
+ +
+

+ + table_options(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 19
+def table_options(table_name)
+  nil
+end
+
+
+ +
+ +
+

+ + tables() + +

+ + +
+

Returns an array of table names defined in the database.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 52
+def tables
+  query_values(data_source_sql(type: "BASE TABLE"), "SCHEMA")
+end
+
+
+ +
+ +
+

+ + view_exists?(view_name) + +

+ + +
+

Checks to see if the view view_name exists on the database.

+ +
view_exists?(:ebooks)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 75
+def view_exists?(view_name)
+  query_values(data_source_sql(view_name, type: "VIEW"), "SCHEMA").any? if view_name.present?
+rescue NotImplementedError
+  views.include?(view_name.to_s)
+end
+
+
+ +
+ +
+

+ + views() + +

+ + +
+

Returns an array of view names defined in the database.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 67
+def views
+  query_values(data_source_sql(type: "VIEW"), "SCHEMA")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/SqlTypeMetadata.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SqlTypeMetadata.html new file mode 100644 index 0000000000..048c54142b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/SqlTypeMetadata.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::SqlTypeMetadata +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/Table.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Table.html new file mode 100644 index 0000000000..3686d664ed --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/Table.html @@ -0,0 +1,966 @@ +--- +title: ActiveRecord::ConnectionAdapters::Table +layout: default +--- +
+ +
+
+ +
+ +

Represents an SQL table in an abstract way for updating a table. Also see TableDefinition and connection.create_table

+ +

Available transformations are:

+ +
change_table :table do |t|
+  t.primary_key
+  t.column
+  t.index
+  t.rename_index
+  t.timestamps
+  t.change
+  t.change_default
+  t.rename
+  t.references
+  t.belongs_to
+  t.string
+  t.text
+  t.integer
+  t.bigint
+  t.float
+  t.decimal
+  t.numeric
+  t.datetime
+  t.timestamp
+  t.time
+  t.date
+  t.binary
+  t.boolean
+  t.foreign_key
+  t.json
+  t.virtual
+  t.remove
+  t.remove_references
+  t.remove_belongs_to
+  t.remove_index
+  t.remove_timestamps
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + name
+ + + + +

Class Public methods

+ +
+

+ + new(table_name, base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 516
+def initialize(table_name, base)
+  @name = table_name
+  @base = base
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + belongs_to(*args, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: references +
+ + + +
+ +
+

+ + change(column_name, type, options = {}) + +

+ + +
+

Changes the column's definition according to the new options.

+ +
t.change(:name, :string, limit: 80)
+t.change(:description, :text)
+
+ +

See TableDefinition#column for details of the options you can use.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 586
+def change(column_name, type, options = {})
+  @base.change_column(name, column_name, type, options)
+end
+
+
+ +
+ +
+

+ + change_default(column_name, default_or_changes) + +

+ + +
+

Sets a new default value for a column.

+ +
t.change_default(:qualification, 'new')
+t.change_default(:authorized, 1)
+t.change_default(:status, from: nil, to: "draft")
+
+ +

See connection.change_column_default

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 597
+def change_default(column_name, default_or_changes)
+  @base.change_column_default(name, column_name, default_or_changes)
+end
+
+
+ +
+ +
+

+ + column(column_name, type, options = {}) + +

+ + +
+

Adds a new column to the named table.

+ +
t.column(:name, :string)
+
+ +

See TableDefinition#column for details of the options you can use.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 526
+def column(column_name, type, options = {})
+  @base.add_column(name, column_name, type, options)
+end
+
+
+ +
+ +
+

+ + column_exists?(column_name, type = nil, options = {}) + +

+ + +
+

Checks to see if a column exists.

+ +
t.string(:name) unless t.column_exists?(:name, :string)
+
+ +

See connection.column_exists?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 535
+def column_exists?(column_name, type = nil, options = {})
+  @base.column_exists?(name, column_name, type, options)
+end
+
+
+ +
+ +
+

+ + foreign_key(*args) + +

+ + +
+

Adds a foreign key.

+ +
t.foreign_key(:authors)
+
+ +

See connection.add_foreign_key

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 671
+def foreign_key(*args)
+  @base.add_foreign_key(name, *args)
+end
+
+
+ +
+ +
+

+ + foreign_key_exists?(*args) + +

+ + +
+

Checks to see if a foreign key exists.

+ +
t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
+
+ +

See connection.foreign_key_exists?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 680
+def foreign_key_exists?(*args)
+  @base.foreign_key_exists?(name, *args)
+end
+
+
+ +
+ +
+

+ + index(column_name, options = {}) + +

+ + +
+

Adds a new index to the table. column_name can be a single Symbol, or an Array of Symbols.

+ +
t.index(:name)
+t.index([:branch_id, :party_id], unique: true)
+t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
+
+ +

See connection.add_index for details of the options you can use.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 547
+def index(column_name, options = {})
+  @base.add_index(name, column_name, options)
+end
+
+
+ +
+ +
+

+ + index_exists?(column_name, options = {}) + +

+ + +
+

Checks to see if an index exists.

+ +
unless t.index_exists?(:branch_id)
+  t.index(:branch_id)
+end
+
+ +

See connection.index_exists?

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 558
+def index_exists?(column_name, options = {})
+  @base.index_exists?(name, column_name, options)
+end
+
+
+ +
+ +
+

+ + references(*args, **options) + +

+ + +
+

Adds a reference.

+ +
t.references(:user)
+t.belongs_to(:supplier, foreign_key: true)
+
+ +

See connection.add_reference for details of the options you can use.

+
+ + + +
+ Also aliased as: belongs_to +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 646
+def references(*args, **options)
+  args.each do |ref_name|
+    @base.add_reference(name, ref_name, options)
+  end
+end
+
+
+ +
+ +
+

+ + remove(*column_names) + +

+ + +
+

Removes the column(s) from the table definition.

+ +
t.remove(:qualification)
+t.remove(:qualification, :experience)
+
+ +

See connection.remove_columns

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 607
+def remove(*column_names)
+  @base.remove_columns(name, *column_names)
+end
+
+
+ +
+ +
+

+ + remove_belongs_to(*args, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: remove_references +
+ + + +
+ +
+

+ + remove_index(options = {}) + +

+ + +
+

Removes the given index from the table.

+ +
t.remove_index(:branch_id)
+t.remove_index(column: [:branch_id, :party_id])
+t.remove_index(name: :by_branch_party)
+
+ +

See connection.remove_index

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 618
+def remove_index(options = {})
+  @base.remove_index(name, options)
+end
+
+
+ +
+ +
+

+ + remove_references(*args, **options) + +

+ + +
+

Removes a reference. Optionally removes a type column.

+ +
t.remove_references(:user)
+t.remove_belongs_to(:supplier, polymorphic: true)
+
+ +

See connection.remove_reference

+
+ + + +
+ Also aliased as: remove_belongs_to +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 659
+def remove_references(*args, **options)
+  args.each do |ref_name|
+    @base.remove_reference(name, ref_name, options)
+  end
+end
+
+
+ +
+ +
+

+ + remove_timestamps(options = {}) + +

+ + +
+

Removes the timestamp columns (created_at and updated_at) from the table.

+ +
t.remove_timestamps
+
+ +

See connection.remove_timestamps

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 627
+def remove_timestamps(options = {})
+  @base.remove_timestamps(name, options)
+end
+
+
+ +
+ +
+

+ + rename(column_name, new_column_name) + +

+ + +
+

Renames a column.

+ +
t.rename(:description, :name)
+
+ +

See connection.rename_column

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 636
+def rename(column_name, new_column_name)
+  @base.rename_column(name, column_name, new_column_name)
+end
+
+
+ +
+ +
+

+ + rename_index(index_name, new_index_name) + +

+ + +
+

Renames the given index on the table.

+ +
t.rename_index(:user_id, :account_id)
+
+ +

See connection.rename_index

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 567
+def rename_index(index_name, new_index_name)
+  @base.rename_index(name, index_name, new_index_name)
+end
+
+
+ +
+ +
+

+ + timestamps(options = {}) + +

+ + +
+

Adds timestamps (created_at and updated_at) columns to the table.

+ +
t.timestamps(null: false)
+
+ +

See connection.add_timestamps

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 576
+def timestamps(options = {})
+  @base.add_timestamps(name, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html new file mode 100644 index 0000000000..43f25cefc4 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html @@ -0,0 +1,612 @@ +--- +title: ActiveRecord::ConnectionAdapters::TableDefinition +layout: default +--- +
+ +
+
+ +
+ +

Represents the schema of an SQL table in an abstract way. This class provides methods for manipulating the schema representation.

+ +

Inside migration files, the t object in create_table is actually of this type:

+ +
class SomeMigration < ActiveRecord::Migration[5.0]
+  def up
+    create_table :foo do |t|
+      puts t.class  # => "ActiveRecord::ConnectionAdapters::TableDefinition"
+    end
+  end
+
+  def down
+    ...
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + as
+ [R] + comment
+ [R] + foreign_keys
+ [RW] + indexes
+ [R] + name
+ [R] + options
+ [R] + temporary
+ + + + +

Class Public methods

+ +
+

+ + new(name, temporary = false, options = nil, as = nil, comment: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 263
+def initialize(name, temporary = false, options = nil, as = nil, comment: nil)
+  @columns_hash = {}
+  @indexes = []
+  @foreign_keys = []
+  @primary_keys = nil
+  @temporary = temporary
+  @options = options
+  @as = as
+  @name = name
+  @comment = comment
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](name) + +

+ + +
+

Returns a ColumnDefinition for the column with name name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 284
+def [](name)
+  @columns_hash[name.to_s]
+end
+
+
+ +
+ +
+

+ + belongs_to(*args, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: references +
+ + + +
+ +
+

+ + column(name, type, options = {}) + +

+ + +
+

Instantiates a new column for the table. See connection.add_column for available options.

+ +

Additional options are:

+
  • +

    :index - Create an index for the column. Can be either true or an options hash.

    +
+ +

This method returns self.

+ +

Examples

+ +
# Assuming +td+ is an instance of TableDefinition
+td.column(:granted, :boolean, index: true)
+
+ +

Short-hand examples

+ +

Instead of calling column directly, you can also work with the short-hand definitions for the default types. They use the type as the method name instead of as a parameter and allow for multiple columns to be defined in a single statement.

+ +

What can be written like this with the regular calls to column:

+ +
create_table :products do |t|
+  t.column :shop_id,     :integer
+  t.column :creator_id,  :integer
+  t.column :item_number, :string
+  t.column :name,        :string, default: "Untitled"
+  t.column :value,       :string, default: "Untitled"
+  t.column :created_at,  :datetime
+  t.column :updated_at,  :datetime
+end
+add_index :products, :item_number
+
+ +

can also be written as follows using the short-hand:

+ +
create_table :products do |t|
+  t.integer :shop_id, :creator_id
+  t.string  :item_number, index: true
+  t.string  :name, :value, default: "Untitled"
+  t.timestamps null: false
+end
+
+ +

There's a short-hand method for each of the type values declared at the top. And then there's TableDefinition#timestamps that'll add created_at and updated_at as datetimes.

+ +

TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type column if the :polymorphic option is supplied. If :polymorphic is a hash of options, these will be used when creating the _type column. The :index option will also create an index, similar to calling add_index. So what can be written like this:

+ +
create_table :taggings do |t|
+  t.integer :tag_id, :tagger_id, :taggable_id
+  t.string  :tagger_type
+  t.string  :taggable_type, default: 'Photo'
+end
+add_index :taggings, :tag_id, name: 'index_taggings_on_tag_id'
+add_index :taggings, [:tagger_id, :tagger_type]
+
+ +

Can also be written as follows using references:

+ +
create_table :taggings do |t|
+  t.references :tag, index: { name: 'index_taggings_on_tag_id' }
+  t.references :tagger, polymorphic: true, index: true
+  t.references :taggable, polymorphic: { default: 'Photo' }
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 355
+def column(name, type, options = {})
+  name = name.to_s
+  type = type.to_sym if type
+  options = options.dup
+
+  if @columns_hash[name] && @columns_hash[name].primary_key?
+    raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
+  end
+
+  index_options = options.delete(:index)
+  index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
+  @columns_hash[name] = new_column_definition(name, type, options)
+  self
+end
+
+
+ +
+ +
+

+ + columns() + +

+ + +
+

Returns an array of ColumnDefinition objects for the columns of the table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 281
+def columns; @columns_hash.values; end
+
+
+ +
+ +
+

+ + index(column_name, options = {}) + +

+ + +
+

Adds index options to the indexes hash, keyed by column name This is primarily used to track indexes that need to be created after the table

+ +
index(:account_id, name: 'index_projects_on_account_id')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 380
+def index(column_name, options = {})
+  indexes << [column_name, options]
+end
+
+
+ +
+ +
+

+ + references(*args, **options) + +

+ + +
+

Adds a reference.

+ +
t.references(:user)
+t.belongs_to(:supplier, foreign_key: true)
+
+ +

See connection.add_reference for details of the options you can use.

+
+ + + +
+ Also aliased as: belongs_to +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 408
+def references(*args, **options)
+  args.each do |ref_name|
+    ReferenceDefinition.new(ref_name, options).add_to(self)
+  end
+end
+
+
+ +
+ +
+

+ + remove_column(name) + +

+ + +
+

remove the column name from the table.

+ +
remove_column(:account_id)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 372
+def remove_column(name)
+  @columns_hash.delete name.to_s
+end
+
+
+ +
+ +
+

+ + timestamps(**options) + +

+ + +
+

Appends :datetime columns :created_at and :updated_at to the table. See connection.add_timestamps

+ +
t.timestamps null: false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 395
+def timestamps(**options)
+  options[:null] = false if options[:null].nil?
+
+  column(:created_at, :datetime, options)
+  column(:updated_at, :datetime, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionAdapters/TransactionState.html b/src/5.2/classes/ActiveRecord/ConnectionAdapters/TransactionState.html new file mode 100644 index 0000000000..bd0488709a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionAdapters/TransactionState.html @@ -0,0 +1,673 @@ +--- +title: ActiveRecord::ConnectionAdapters::TransactionState +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(state = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 6
+def initialize(state = nil)
+  @state = state
+  @children = []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_child(state) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 11
+def add_child(state)
+  @children << state
+end
+
+
+ +
+ +
+

+ + commit!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 71
+def commit!
+  @state = :committed
+end
+
+
+ +
+ +
+

+ + committed?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 19
+def committed?
+  @state == :committed || @state == :fully_committed
+end
+
+
+ +
+ +
+

+ + completed?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 39
+def completed?
+  committed? || rolledback?
+end
+
+
+ +
+ +
+

+ + finalized?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 15
+def finalized?
+  @state
+end
+
+
+ +
+ +
+

+ + full_commit!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 75
+def full_commit!
+  @state = :fully_committed
+end
+
+
+ +
+ +
+

+ + full_rollback!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 66
+def full_rollback!
+  @children.each { |c| c.rollback! }
+  @state = :fully_rolledback
+end
+
+
+ +
+ +
+

+ + fully_committed?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 23
+def fully_committed?
+  @state == :fully_committed
+end
+
+
+ +
+ +
+

+ + fully_completed?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 35
+def fully_completed?
+  completed?
+end
+
+
+ +
+ +
+

+ + fully_rolledback?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 31
+def fully_rolledback?
+  @state == :fully_rolledback
+end
+
+
+ +
+ +
+

+ + nullify!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 79
+def nullify!
+  @state = nil
+end
+
+
+ +
+ +
+

+ + rollback!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 61
+def rollback!
+  @children.each { |c| c.rollback! }
+  @state = :rolledback
+end
+
+
+ +
+ +
+

+ + rolledback?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 27
+def rolledback?
+  @state == :rolledback || @state == :fully_rolledback
+end
+
+
+ +
+ +
+

+ + set_state(state) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 43
+      def set_state(state)
+        ActiveSupport::Deprecation.warn(<<-MSG.squish)
+          The set_state method is deprecated and will be removed in
+          Rails 6.0. Please use rollback! or commit! to set transaction
+          state directly.
+        MSG
+        case state
+        when :rolledback
+          rollback!
+        when :committed
+          commit!
+        when nil
+          nullify!
+        else
+          raise ArgumentError, "Invalid transaction state: #{state}"
+        end
+      end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionHandling.html b/src/5.2/classes/ActiveRecord/ConnectionHandling.html new file mode 100644 index 0000000000..3b5901e51d --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionHandling.html @@ -0,0 +1,494 @@ +--- +title: ActiveRecord::ConnectionHandling +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_ENV=-> { RAILS_ENV.call || "default_env" }
 
RAILS_ENV=-> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence }
 
+ + + + +

Attributes

+ + + + + + + + +
+ [W] + connection_specification_name
+ + + + + +

Instance Public methods

+ +
+

+ + connected?() + +

+ + +
+

Returns true if Active Record is connected.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 122
+def connected?
+  connection_handler.connected?(connection_specification_name)
+end
+
+
+ +
+ +
+

+ + connection() + +

+ + +
+

Returns the connection currently associated with the class. This can also be used to “borrow” the connection to do database work unrelated to any of the specific Active Records.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 89
+def connection
+  retrieve_connection
+end
+
+
+ +
+ +
+

+ + connection_config() + +

+ + +
+

Returns the configuration of the associated connection as a hash:

+ +
ActiveRecord::Base.connection_config
+# => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"}
+
+ +

Please use only for reading.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 109
+def connection_config
+  connection_pool.spec.config
+end
+
+
+ +
+ +
+

+ + connection_pool() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 113
+def connection_pool
+  connection_handler.retrieve_connection_pool(connection_specification_name) || raise(ConnectionNotEstablished)
+end
+
+
+ +
+ +
+

+ + connection_specification_name() + +

+ + +
+

Return the specification name from the current class or its parent.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 96
+def connection_specification_name
+  if !defined?(@connection_specification_name) || @connection_specification_name.nil?
+    return self == Base ? "primary" : superclass.connection_specification_name
+  end
+  @connection_specification_name
+end
+
+
+ +
+ +
+

+ + establish_connection(config = nil) + +

+ + +
+

Establishes the connection to the database. Accepts a hash as input where the :adapter key must be specified with the name of a database adapter (in lower-case) example for regular databases (MySQL, PostgreSQL, etc):

+ +
ActiveRecord::Base.establish_connection(
+  adapter:  "mysql2",
+  host:     "localhost",
+  username: "myuser",
+  password: "mypass",
+  database: "somedatabase"
+)
+
+ +

Example for SQLite database:

+ +
ActiveRecord::Base.establish_connection(
+  adapter:  "sqlite3",
+  database: "path/to/dbfile"
+)
+
+ +

Also accepts keys as strings (for parsing from YAML for example):

+ +
ActiveRecord::Base.establish_connection(
+  "adapter"  => "sqlite3",
+  "database" => "path/to/dbfile"
+)
+
+ +

Or a URL:

+ +
ActiveRecord::Base.establish_connection(
+  "postgres://myuser:mypass@localhost/somedatabase"
+)
+
+ +

In case ActiveRecord::Base.configurations is set (Rails automatically loads the contents of config/database.yml into it), a symbol can also be given as argument, representing a key in the configuration hash:

+ +
ActiveRecord::Base.establish_connection(:production)
+
+ +

The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError may be returned on an error.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 49
+def establish_connection(config = nil)
+  raise "Anonymous class is not allowed." unless name
+
+  config ||= DEFAULT_ENV.call.to_sym
+  spec_name = self == Base ? "primary" : name
+  self.connection_specification_name = spec_name
+
+  resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(Base.configurations)
+  spec = resolver.resolve(config).symbolize_keys
+  spec[:name] = spec_name
+
+  connection_handler.establish_connection(spec)
+end
+
+
+ +
+ +
+

+ + remove_connection(name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 126
+def remove_connection(name = nil)
+  name ||= @connection_specification_name if defined?(@connection_specification_name)
+  # if removing a connection that has a pool, we reset the
+  # connection_specification_name so it will use the parent
+  # pool.
+  if connection_handler.retrieve_connection_pool(name)
+    self.connection_specification_name = nil
+  end
+
+  connection_handler.remove_connection(name)
+end
+
+
+ +
+ +
+

+ + retrieve_connection() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/connection_handling.rb, line 117
+def retrieve_connection
+  connection_handler.retrieve_connection(connection_specification_name)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionNotEstablished.html b/src/5.2/classes/ActiveRecord/ConnectionNotEstablished.html new file mode 100644 index 0000000000..0c68cc7b9b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionNotEstablished.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ConnectionNotEstablished +layout: default +--- +
+ +
+
+ +
+ +

Raised when connection to the database could not been established (for example when ActiveRecord::Base.connection= is given a nil object).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ConnectionTimeoutError.html b/src/5.2/classes/ActiveRecord/ConnectionTimeoutError.html new file mode 100644 index 0000000000..28936ea6ce --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ConnectionTimeoutError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ConnectionTimeoutError +layout: default +--- +
+ +
+
+ +
+ +

Raised when a connection could not be obtained within the connection acquisition timeout period: because max connections in pool are in use.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Core.html b/src/5.2/classes/ActiveRecord/Core.html new file mode 100644 index 0000000000..557317ef78 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Core.html @@ -0,0 +1,1011 @@ +--- +title: ActiveRecord::Core +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + configurations() + +

+ + +
+

Returns fully resolved configurations hash

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 59
+def self.configurations
+  @@configurations
+end
+
+
+ +
+ +
+

+ + configurations=(config) + +

+ + +
+

Contains the database configuration - as is typically stored in config/database.yml - as a Hash.

+ +

For example, the following database.yml…

+ +
development:
+  adapter: sqlite3
+  database: db/development.sqlite3
+
+production:
+  adapter: sqlite3
+  database: db/production.sqlite3
+
+ +

…would result in ActiveRecord::Base.configurations to look like this:

+ +
{
+   'development' => {
+      'adapter'  => 'sqlite3',
+      'database' => 'db/development.sqlite3'
+   },
+   'production' => {
+      'adapter'  => 'sqlite3',
+      'database' => 'db/production.sqlite3'
+   }
+}
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 53
+def self.configurations=(config)
+  @@configurations = ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve
+end
+
+
+ +
+ +
+

+ + connection_handler() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 130
+def self.connection_handler
+  ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
+end
+
+
+ +
+ +
+

+ + connection_handler=(handler) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 134
+def self.connection_handler=(handler)
+  ActiveRecord::RuntimeRegistry.connection_handler = handler
+end
+
+
+ +
+ +
+

+ + new(attributes = nil) + +

+ + +
+

New objects can be instantiated as either empty (pass no construction parameter) or pre-set with attributes but not yet saved (pass a hash with key names matching the associated table column names). In both instances, valid attribute keys are determined by the column names of the associated table – hence you can't have attributes that aren't part of the table columns.

+ +

Example:

+ +
# Instantiates a single new object
+User.new(first_name: 'Jamie')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 308
+def initialize(attributes = nil)
+  self.class.define_attribute_methods
+  @attributes = self.class._default_attributes.deep_dup
+
+  init_internals
+  initialize_internals_callback
+
+  assign_attributes(attributes) if attributes
+
+  yield self if block_given?
+  _run_initialize_callbacks
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(other_object) + +

+ + +
+

Allows sort on objects

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 453
+def <=>(other_object)
+  if other_object.is_a?(self.class)
+    to_key <=> other_object.to_key
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + ==(comparison_object) + +

+ + +
+

Returns true if comparison_object is the same exact object, or comparison_object is of the same type and self has an ID and it is equal to comparison_object.id.

+ +

Note that new records are different from any other record by definition, unless the other record is the receiver itself. Besides, if you fetch existing records with select and leave the ID out, you're on your own, this predicate will return false.

+ +

Note also that destroying a record preserves its ID in the model instance, so deleted models are still comparable.

+
+ + + +
+ Also aliased as: eql? +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 421
+def ==(comparison_object)
+  super ||
+    comparison_object.instance_of?(self.class) &&
+    !id.nil? &&
+    comparison_object.id == id
+end
+
+
+ +
+ +
+

+ + clone + +

+ + +
+

Identical to Ruby's clone method. This is a “shallow” copy. Be warned that your attributes are not copied. That means that modifying attributes of the clone will modify the original, since they will both point to the same attributes hash. If you need a copy of your attributes hash, please use the dup method.

+ +
user = User.first
+new_user = user.clone
+user.name               # => "Bob"
+new_user.name = "Joe"
+user.name               # => "Joe"
+
+user.object_id == new_user.object_id            # => false
+user.name.object_id == new_user.name.object_id  # => true
+
+user.name.object_id == user.dup.name.object_id  # => false
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 354
+    
+
+
+ +
+ +
+

+ + connection_handler() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 472
+def connection_handler
+  self.class.connection_handler
+end
+
+
+ +
+ +
+

+ + dup + +

+ + +
+

Duped objects have no id assigned and are treated as new records. Note that this is a “shallow” copy as it copies the object's attributes only, not its associations. The extent of a “deep” copy is application specific and is therefore left to the application to implement according to its need. The dup method does not preserve the timestamps (created|updated)_(at|on).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 371
+    
+
+
+ +
+ +
+

+ + encode_with(coder) + +

+ + +
+

Populate coder with attributes about this record that should be serialized. The structure of coder defined in this method is guaranteed to match the structure of coder passed to the init_with method.

+ +

Example:

+ +
class Post < ActiveRecord::Base
+end
+coder = {}
+Post.new.encode_with(coder)
+coder # => {"attributes" => {"id" => nil, ... }}
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 406
+def encode_with(coder)
+  self.class.yaml_encoder.encode(@attributes, coder)
+  coder["new_record"] = new_record?
+  coder["active_record_yaml_version"] = 2
+end
+
+
+ +
+ +
+

+ + eql?(comparison_object) + +

+ + +
+ +
+ + + + + +
+ Alias for: == +
+ + + +
+ +
+

+ + freeze() + +

+ + +
+

Clone and freeze the attributes hash such that associations are still accessible, even on destroyed records, but cloned models will not be frozen.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 442
+def freeze
+  @attributes = @attributes.clone.freeze
+  self
+end
+
+
+ +
+ +
+

+ + frozen?() + +

+ + +
+

Returns true if the attributes hash has been frozen.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 448
+def frozen?
+  @attributes.frozen?
+end
+
+
+ +
+ +
+

+ + hash() + +

+ + +
+

Delegates to id in order to allow two records of the same type and id to work with something like:

+ +
[ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 431
+def hash
+  if id
+    self.class.hash ^ id.hash
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + init_with(coder) + +

+ + +
+

Initialize an empty model object from coder. coder should be the result of previously encoding an Active Record model, using encode_with.

+ +
class Post < ActiveRecord::Base
+end
+
+old_post = Post.new(title: "hello world")
+coder = {}
+old_post.encode_with(coder)
+
+post = Post.allocate
+post.init_with(coder)
+post.title # => 'hello world'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 335
+def init_with(coder)
+  coder = LegacyYamlAdapter.convert(self.class, coder)
+  @attributes = self.class.yaml_encoder.decode(coder)
+
+  init_internals
+
+  @new_record = coder["new_record"]
+
+  self.class.define_attribute_methods
+
+  yield self if block_given?
+
+  _run_find_callbacks
+  _run_initialize_callbacks
+
+  self
+end
+
+
+ +
+ +
+

+ + inspect() + +

+ + +
+

Returns the contents of the record as a nicely formatted string.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 477
+def inspect
+  # We check defined?(@attributes) not to issue warnings if the object is
+  # allocated but not initialized.
+  inspection = if defined?(@attributes) && @attributes
+    self.class.attribute_names.collect do |name|
+      if has_attribute?(name)
+        "#{name}: #{attribute_for_inspect(name)}"
+      end
+    end.compact.join(", ")
+  else
+    "not initialized"
+  end
+
+  "#<#{self.class} #{inspection}>"
+end
+
+
+ +
+ +
+

+ + pretty_print(pp) + +

+ + +
+

Takes a PP and prettily prints this record to it, allowing you to get a nice result from pp record when pp is required.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 495
+def pretty_print(pp)
+  return super if custom_inspect_method_defined?
+  pp.object_address_group(self) do
+    if defined?(@attributes) && @attributes
+      column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
+      pp.seplist(column_names, proc { pp.text "," }) do |column_name|
+        column_value = read_attribute(column_name)
+        pp.breakable " "
+        pp.group(1) do
+          pp.text column_name
+          pp.text ":"
+          pp.breakable
+          pp.pp column_value
+        end
+      end
+    else
+      pp.breakable " "
+      pp.text "not initialized"
+    end
+  end
+end
+
+
+ +
+ +
+

+ + readonly!() + +

+ + +
+

Marks this record as read only.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 468
+def readonly!
+  @readonly = true
+end
+
+
+ +
+ +
+

+ + readonly?() + +

+ + +
+

Returns true if the record is read only. Records loaded through joins with piggy-back attributes will be marked as read only since they cannot be saved.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 463
+def readonly?
+  @readonly
+end
+
+
+ +
+ +
+

+ + slice(*methods) + +

+ + +
+

Returns a hash of the given methods with their names as keys and returned values as values.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/core.rb, line 518
+def slice(*methods)
+  Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/CounterCache.html b/src/5.2/classes/ActiveRecord/CounterCache.html new file mode 100644 index 0000000000..7f4a7ac079 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/CounterCache.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::CounterCache +layout: default +--- +
+ +
+
+ +
+ +

Active Record Counter Cache

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/CounterCache/ClassMethods.html b/src/5.2/classes/ActiveRecord/CounterCache/ClassMethods.html new file mode 100644 index 0000000000..575deeda15 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/CounterCache/ClassMethods.html @@ -0,0 +1,366 @@ +--- +title: ActiveRecord::CounterCache::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + decrement_counter(counter_name, id, touch: nil) + +

+ + +
+

Decrement a numeric field by one, via a direct SQL update.

+ +

This works the same as increment_counter but reduces the column value by 1 instead of increasing it.

+ +

Parameters

+
  • +

    counter_name - The name of the field that should be decremented.

    +
  • +

    id - The id of the object that should be decremented or an array of ids.

    +
  • +

    :touch - Touch timestamp columns when updating. Pass true to touch updated_at and/or updated_on. Pass a symbol to touch that column or an array of symbols to touch just those ones.

    +
+ +

Examples

+ +
# Decrement the posts_count column for the record with an id of 5
+DiscussionBoard.decrement_counter(:posts_count, 5)
+
+# Decrement the posts_count column for the record with an id of 5
+# and update the updated_at value.
+DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/counter_cache.rb, line 176
+def decrement_counter(counter_name, id, touch: nil)
+  update_counters(id, counter_name => -1, touch: touch)
+end
+
+
+ +
+ +
+

+ + increment_counter(counter_name, id, touch: nil) + +

+ + +
+

Increment a numeric field by one, via a direct SQL update.

+ +

This method is used primarily for maintaining counter_cache columns that are used to store aggregate values. For example, a DiscussionBoard may cache posts_count and comments_count to avoid running an SQL query to calculate the number of posts and comments there are, each time it is displayed.

+ +

Parameters

+
  • +

    counter_name - The name of the field that should be incremented.

    +
  • +

    id - The id of the object that should be incremented or an array of ids.

    +
  • +

    :touch - Touch timestamp columns when updating. Pass true to touch updated_at and/or updated_on. Pass a symbol to touch that column or an array of symbols to touch just those ones.

    +
+ +

Examples

+ +
# Increment the posts_count column for the record with an id of 5
+DiscussionBoard.increment_counter(:posts_count, 5)
+
+# Increment the posts_count column for the record with an id of 5
+# and update the updated_at value.
+DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/counter_cache.rb, line 151
+def increment_counter(counter_name, id, touch: nil)
+  update_counters(id, counter_name => 1, touch: touch)
+end
+
+
+ +
+ +
+

+ + reset_counters(id, *counters, touch: nil) + +

+ + +
+

Resets one or more counter caches to their correct value using an SQL count query. This is useful when adding new counter caches, or if the counter has been corrupted or modified directly by SQL.

+ +

Parameters

+
  • +

    id - The id of the object you wish to reset a counter on.

    +
  • +

    counters - One or more association counters to reset. Association name or counter name can be given.

    +
  • +

    :touch - Touch timestamp columns when updating. Pass true to touch updated_at and/or updated_on. Pass a symbol to touch that column or an array of symbols to touch just those ones.

    +
+ +

Examples

+ +
# For the Post with id #1, reset the comments_count
+Post.reset_counters(1, :comments)
+
+# Like above, but also touch the +updated_at+ and/or +updated_on+
+# attributes.
+Post.reset_counters(1, :comments, touch: true)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/counter_cache.rb, line 29
+def reset_counters(id, *counters, touch: nil)
+  object = find(id)
+
+  counters.each do |counter_association|
+    has_many_association = _reflect_on_association(counter_association)
+    unless has_many_association
+      has_many = reflect_on_all_associations(:has_many)
+      has_many_association = has_many.find { |association| association.counter_cache_column && association.counter_cache_column.to_sym == counter_association.to_sym }
+      counter_association = has_many_association.plural_name if has_many_association
+    end
+    raise ArgumentError, "'#{name}' has no association called '#{counter_association}'" unless has_many_association
+
+    if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection
+      has_many_association = has_many_association.through_reflection
+    end
+
+    foreign_key  = has_many_association.foreign_key.to_s
+    child_class  = has_many_association.klass
+    reflection   = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
+    counter_name = reflection.counter_cache_column
+
+    updates = { counter_name => object.send(counter_association).count(:all) }
+
+    if touch
+      names = touch if touch != true
+      updates.merge!(touch_attributes_with_time(*names))
+    end
+
+    unscoped.where(primary_key => object.id).update_all(updates)
+  end
+
+  true
+end
+
+
+ +
+ +
+

+ + update_counters(id, counters) + +

+ + +
+

A generic “counter updater” implementation, intended primarily to be used by increment_counter and decrement_counter, but which may also be useful on its own. It simply does a direct SQL update for the record with the given ID, altering the given hash of counters by the amount given by the corresponding value:

+ +

Parameters

+
  • +

    id - The id of the object you wish to update a counter on or an array of ids.

    +
  • +

    counters - A Hash containing the names of the fields to update as keys and the amount to update the field by as values.

    +
  • +

    :touch option - Touch timestamp columns when updating. If attribute names are passed, they are updated along with updated_at/on attributes.

    +
+ +

Examples

+ +
# For the Post with id of 5, decrement the comment_count by 1, and
+# increment the action_count by 1
+Post.update_counters 5, comment_count: -1, action_count: 1
+# Executes the following SQL:
+# UPDATE posts
+#    SET comment_count = COALESCE(comment_count, 0) - 1,
+#        action_count = COALESCE(action_count, 0) + 1
+#  WHERE id = 5
+
+# For the Posts with id of 10 and 15, increment the comment_count by 1
+Post.update_counters [10, 15], comment_count: 1
+# Executes the following SQL:
+# UPDATE posts
+#    SET comment_count = COALESCE(comment_count, 0) + 1
+#  WHERE id IN (10, 15)
+
+# For the Posts with id of 10 and 15, increment the comment_count by 1
+# and update the updated_at value for each counter.
+Post.update_counters [10, 15], comment_count: 1, touch: true
+# Executes the following SQL:
+# UPDATE posts
+#    SET comment_count = COALESCE(comment_count, 0) + 1,
+#    `updated_at` = '2016-10-13T09:59:23-05:00'
+#  WHERE id IN (10, 15)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/counter_cache.rb, line 104
+def update_counters(id, counters)
+  touch = counters.delete(:touch)
+
+  updates = counters.map do |counter_name, value|
+    operator = value < 0 ? "-" : "+"
+    quoted_column = connection.quote_column_name(counter_name)
+    "#{quoted_column} = COALESCE(#{quoted_column}, 0) #{operator} #{value.abs}"
+  end
+
+  if touch
+    names = touch if touch != true
+    touch_updates = touch_attributes_with_time(*names)
+    updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
+  end
+
+  if id.is_a?(Relation) && self == id.klass
+    relation = id
+  else
+    relation = unscoped.where!(primary_key => id)
+  end
+
+  relation.update_all updates.join(", ")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/DangerousAttributeError.html b/src/5.2/classes/ActiveRecord/DangerousAttributeError.html new file mode 100644 index 0000000000..9dc2e6e501 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/DangerousAttributeError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::DangerousAttributeError +layout: default +--- +
+ +
+
+ +
+ +

Raised when attribute has a name reserved by Active Record (when attribute has name of one of Active Record instance methods).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Deadlocked.html b/src/5.2/classes/ActiveRecord/Deadlocked.html new file mode 100644 index 0000000000..10e7571f25 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Deadlocked.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::Deadlocked +layout: default +--- +
+ +
+
+ +
+ +

Deadlocked will be raised when a transaction is rolled back by the database when a deadlock is encountered.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/DefineCallbacks.html b/src/5.2/classes/ActiveRecord/DefineCallbacks.html new file mode 100644 index 0000000000..8a6bc3a87a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/DefineCallbacks.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::DefineCallbacks +layout: default +--- +
+ +
+
+ +
+ +

This module exists because ActiveRecord::AttributeMethods::Dirty needs to define callbacks, but continue to have its version of save be the super method of ActiveRecord::Callbacks. This will be removed when the removal of deprecated code removes this need.

+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/DynamicMatchers.html b/src/5.2/classes/ActiveRecord/DynamicMatchers.html new file mode 100644 index 0000000000..7ae2b3c4f5 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/DynamicMatchers.html @@ -0,0 +1,71 @@ +--- +title: ActiveRecord::DynamicMatchers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/DynamicMatchers/FindBy.html b/src/5.2/classes/ActiveRecord/DynamicMatchers/FindBy.html new file mode 100644 index 0000000000..357add901b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/DynamicMatchers/FindBy.html @@ -0,0 +1,149 @@ +--- +title: ActiveRecord::DynamicMatchers::FindBy +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 97
+def self.prefix
+  "find_by"
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + finder() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 101
+def finder
+  "find_by"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/DynamicMatchers/FindByBang.html b/src/5.2/classes/ActiveRecord/DynamicMatchers/FindByBang.html new file mode 100644 index 0000000000..ad75186476 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/DynamicMatchers/FindByBang.html @@ -0,0 +1,188 @@ +--- +title: ActiveRecord::DynamicMatchers::FindByBang +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 109
+def self.prefix
+  "find_by"
+end
+
+
+ +
+ +
+

+ + suffix() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 113
+def self.suffix
+  "!"
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + finder() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 117
+def finder
+  "find_by!"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/DynamicMatchers/Method.html b/src/5.2/classes/ActiveRecord/DynamicMatchers/Method.html new file mode 100644 index 0000000000..840238b8c7 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/DynamicMatchers/Method.html @@ -0,0 +1,390 @@ +--- +title: ActiveRecord::DynamicMatchers::Method +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + matchers
+ [R] + attribute_names
+ [R] + model
+ [R] + name
+ + + + +

Class Public methods

+ +
+

+ + match(model, name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 32
+def match(model, name)
+  klass = matchers.find { |k| k.pattern.match?(name) }
+  klass.new(model, name) if klass
+end
+
+
+ +
+ +
+

+ + new(model, name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 52
+def initialize(model, name)
+  @model           = model
+  @name            = name.to_s
+  @attribute_names = @name.match(self.class.pattern)[1].split("_and_")
+  @attribute_names.map! { |n| @model.attribute_aliases[n] || n }
+end
+
+
+ +
+ +
+

+ + pattern() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 37
+def pattern
+  @pattern ||= /\A#{prefix}_([_a-zA-Z]\w*)#{suffix}\Z/
+end
+
+
+ +
+ +
+

+ + prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 41
+def prefix
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + suffix() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 45
+def suffix
+  ""
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + define() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 63
+        def define
+          model.class_eval <<-CODE, __FILE__, __LINE__ + 1
+            def self.#{name}(#{signature})
+              #{body}
+            end
+          CODE
+        end
+
+
+ +
+ +
+

+ + valid?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/dynamic_matchers.rb, line 59
+def valid?
+  attribute_names.all? { |name| model.columns_hash[name] || model.reflect_on_aggregation(name.to_sym) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/EagerLoadPolymorphicError.html b/src/5.2/classes/ActiveRecord/EagerLoadPolymorphicError.html new file mode 100644 index 0000000000..29fb7daae9 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/EagerLoadPolymorphicError.html @@ -0,0 +1,117 @@ +--- +title: ActiveRecord::EagerLoadPolymorphicError +layout: default +--- +
+ +
+
+ +
+ +

This error is raised when trying to eager load a polymorphic association using a JOIN. Eager loading polymorphic associations is only possible with ActiveRecord::Relation#preload.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(reflection = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/associations.rb, line 163
+def initialize(reflection = nil)
+  if reflection
+    super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
+  else
+    super("Eager load polymorphic error.")
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Enum.html b/src/5.2/classes/ActiveRecord/Enum.html new file mode 100644 index 0000000000..497922c728 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Enum.html @@ -0,0 +1,263 @@ +--- +title: ActiveRecord::Enum +layout: default +--- +
+ +
+
+ +
+ +

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

+ +
class Conversation < ActiveRecord::Base
+  enum status: [ :active, :archived ]
+end
+
+# conversation.update! status: 0
+conversation.active!
+conversation.active? # => true
+conversation.status  # => "active"
+
+# conversation.update! status: 1
+conversation.archived!
+conversation.archived? # => true
+conversation.status    # => "archived"
+
+# conversation.status = 1
+conversation.status = "archived"
+
+conversation.status = nil
+conversation.status.nil? # => true
+conversation.status      # => nil
+
+ +

Scopes based on the allowed values of the enum field will be provided as well. With the above example:

+ +
Conversation.active
+Conversation.archived
+
+ +

Of course, you can also query them directly if the scopes don't fit your needs:

+ +
Conversation.where(status: [:active, :archived])
+Conversation.where.not(status: :active)
+
+ +

You can set the default value from the database declaration, like:

+ +
create_table :conversations do |t|
+  t.column :status, :integer, default: 0
+end
+
+ +

Good practice is to let the first declared status be the default.

+ +

Finally, it's also possible to explicitly map the relation between attribute and database integer with a hash:

+ +
class Conversation < ActiveRecord::Base
+  enum status: { active: 0, archived: 1 }
+end
+
+ +

Note that when an array is used, the implicit mapping from the values to database integers is derived from the order the values appear in the array. In the example, :active is mapped to 0 as it's the first element, and :archived is mapped to 1. In general, the i-th element is mapped to i-1 in the database.

+ +

Therefore, once a value is added to the enum array, its position in the array must be maintained, and new values should only be added to the end of the array. To remove unused values, the explicit hash syntax should be used.

+ +

In rare circumstances you might need to access the mapping directly. The mappings are exposed through a class method with the pluralized attribute name, which return the mapping in a HashWithIndifferentAccess:

+ +
Conversation.statuses[:active]    # => 0
+Conversation.statuses["archived"] # => 1
+
+ +

Use that class method when you need to know the ordinal value of an enum. For example, you can use that when manually building SQL strings:

+ +
Conversation.where("status <> ?", Conversation.statuses[:archived])
+
+ +

You can use the :_prefix or :_suffix options when you need to define multiple enums with same values. If the passed value is true, the methods are prefixed/suffixed with the name of the enum. It is also possible to supply a custom value:

+ +
class Conversation < ActiveRecord::Base
+  enum status: [:active, :archived], _suffix: true
+  enum comments_status: [:active, :inactive], _prefix: :comments
+end
+
+ +

With the above example, the bang and predicate methods along with the associated scopes are now prefixed and/or suffixed accordingly:

+ +
conversation.active_status!
+conversation.archived_status? # => false
+
+conversation.comments_inactive!
+conversation.comments_active? # => false
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ENUM_CONFLICT_MESSAGE=\ +"You tried to define an enum named \"%{enum}\" on the model \"%{klass}\", but " \ +"this will generate a %{type} method \"%{method}\", which is already defined " \ +"by %{source}."
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + enum(definitions) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/enum.rb, line 151
+def enum(definitions)
+  klass = self
+  enum_prefix = definitions.delete(:_prefix)
+  enum_suffix = definitions.delete(:_suffix)
+  definitions.each do |name, values|
+    # statuses = { }
+    enum_values = ActiveSupport::HashWithIndifferentAccess.new
+    name = name.to_s
+
+    # def self.statuses() statuses end
+    detect_enum_conflict!(name, name.pluralize, true)
+    singleton_class.send(:define_method, name.pluralize) { enum_values }
+    defined_enums[name] = enum_values
+
+    detect_enum_conflict!(name, name)
+    detect_enum_conflict!(name, "#{name}=")
+
+    attr = attribute_alias?(name) ? attribute_alias(name) : name
+    decorate_attribute_type(attr, :enum) do |subtype|
+      EnumType.new(attr, enum_values, subtype)
+    end
+
+    _enum_methods_module.module_eval do
+      pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
+      pairs.each do |label, value|
+        if enum_prefix == true
+          prefix = "#{name}_"
+        elsif enum_prefix
+          prefix = "#{enum_prefix}_"
+        end
+        if enum_suffix == true
+          suffix = "_#{name}"
+        elsif enum_suffix
+          suffix = "_#{enum_suffix}"
+        end
+
+        value_method_name = "#{prefix}#{label}#{suffix}"
+        enum_values[label] = value
+        label = label.to_s
+
+        # def active?() status == "active" end
+        klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
+        define_method("#{value_method_name}?") { self[attr] == label }
+
+        # def active!() update!(status: 0) end
+        klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
+        define_method("#{value_method_name}!") { update!(attr => value) }
+
+        # scope :active, -> { where(status: 0) }
+        klass.send(:detect_enum_conflict!, name, value_method_name, true)
+        klass.scope value_method_name, -> { where(attr => value) }
+      end
+    end
+    enum_values.freeze
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/EnvironmentMismatchError.html b/src/5.2/classes/ActiveRecord/EnvironmentMismatchError.html new file mode 100644 index 0000000000..c62efd355a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/EnvironmentMismatchError.html @@ -0,0 +1,115 @@ +--- +title: ActiveRecord::EnvironmentMismatchError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(current: nil, stored: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 171
+def initialize(current: nil, stored: nil)
+  msg =  "You are attempting to modify a database that was last run in `#{ stored }` environment.\n".dup
+  msg << "You are running in `#{ current }` environment. "
+  msg << "If you are sure you want to continue, first set the environment using:\n\n"
+  msg << "        bin/rails db:environment:set"
+  if defined?(Rails.env)
+    super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
+  else
+    super("#{msg}\n\n")
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ExclusiveConnectionTimeoutError.html b/src/5.2/classes/ActiveRecord/ExclusiveConnectionTimeoutError.html new file mode 100644 index 0000000000..2a2c121fd1 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ExclusiveConnectionTimeoutError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ExclusiveConnectionTimeoutError +layout: default +--- +
+ +
+
+ +
+ +

Raised when a pool was unable to get ahold of all its connections to perform a “group” action such as ActiveRecord::Base.connection_pool.disconnect! or ActiveRecord::Base.clear_reloadable_connections!.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Explain.html b/src/5.2/classes/ActiveRecord/Explain.html new file mode 100644 index 0000000000..a69df143b8 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Explain.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Explain +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/FinderMethods.html b/src/5.2/classes/ActiveRecord/FinderMethods.html new file mode 100644 index 0000000000..a7c8102e7a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/FinderMethods.html @@ -0,0 +1,1197 @@ +--- +title: ActiveRecord::FinderMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ONE_AS_ONE="1 AS one"
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + exists?(conditions = :none) + +

+ + +
+

Returns true if a record exists in the table that matches the id or conditions given, or false otherwise. The argument can take six forms:

+
  • +

    Integer - Finds the record with this primary key.

    +
  • +

    String - Finds the record with a primary key corresponding to this string (such as '5').

    +
  • +

    Array - Finds the record that matches these find-style conditions (such as ['name LIKE ?', "%#{query}%"]).

    +
  • +

    Hash - Finds the record that matches these find-style conditions (such as {name: 'David'}).

    +
  • +

    false - Returns always false.

    +
  • +

    No args - Returns false if the relation is empty, true otherwise.

    +
+ +

For more information about specifying conditions as a hash or array, see the Conditions section in the introduction to ActiveRecord::Base.

+ +

Note: You can't pass in a condition as a string (like name = 'Jamie'), since it would be sanitized and then queried against the primary key column, like id = 'name = \'Jamie\''.

+ +
Person.exists?(5)
+Person.exists?('5')
+Person.exists?(['name LIKE ?', "%#{query}%"])
+Person.exists?(id: [1, 4, 8])
+Person.exists?(name: 'David')
+Person.exists?(false)
+Person.exists?
+Person.where(name: 'Spartacus', rating: 4).exists?
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 305
+    def exists?(conditions = :none)
+      if Base === conditions
+        raise ArgumentError, <<-MSG.squish
+          You are passing an instance of ActiveRecord::Base to `exists?`.
+          Please pass the id of the object by calling `.id`.
+        MSG
+      end
+
+      return false if !conditions || limit_value == 0
+
+      if eager_loading?
+        relation = apply_join_dependency(eager_loading: false)
+        return relation.exists?(conditions)
+      end
+
+      relation = construct_relation_for_exists(conditions)
+
+      skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists") } ? true : false
+    rescue ::RangeError
+      false
+    end
+
+
+ +
+ +
+

+ + fifth() + +

+ + +
+

Find the fifth record. If no order is defined it will order by primary key.

+ +
Person.fifth # returns the fifth object fetched by SELECT * FROM people
+Person.offset(3).fifth # returns the fifth object from OFFSET 3 (which is OFFSET 7)
+Person.where(["user_name = :u", { u: user_name }]).fifth
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 219
+def fifth
+  find_nth 4
+end
+
+
+ +
+ +
+

+ + fifth!() + +

+ + +
+

Same as fifth but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 225
+def fifth!
+  fifth || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + find(*args) + +

+ + +
+

Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). If one or more records can not be found for the requested ids, then RecordNotFound will be raised. If the primary key is an integer, find by id coerces its arguments using to_i.

+ +
Person.find(1)          # returns the object for ID = 1
+Person.find("1")        # returns the object for ID = 1
+Person.find("31-sarah") # returns the object for ID = 31
+Person.find(1, 2, 6)    # returns an array for objects with IDs in (1, 2, 6)
+Person.find([7, 17])    # returns an array for objects with IDs in (7, 17)
+Person.find([1])        # returns an array for the object with ID = 1
+Person.where("administrator = 1").order("created_on DESC").find(1)
+
+ +

NOTE: The returned records are in the same order as the ids you provide. If you want the results to be sorted by database, you can use ActiveRecord::QueryMethods#where method and provide an explicit ActiveRecord::QueryMethods#order option. But ActiveRecord::QueryMethods#where method doesn't raise ActiveRecord::RecordNotFound.

+ +

Find with lock

+ +

Example for find with a lock: Imagine two concurrent transactions: each will read person.visits == 2, add 1 to it, and save, resulting in two saves of person.visits = 3. By locking the row, the second transaction has to wait until the first is finished; we get the expected person.visits == 4.

+ +
Person.transaction do
+  person = Person.lock(true).find(1)
+  person.visits += 1
+  person.save!
+end
+
+ +

Variations of find

+ +
Person.where(name: 'Spartacus', rating: 4)
+# returns a chainable list (which can be empty).
+
+Person.find_by(name: 'Spartacus', rating: 4)
+# returns the first item or nil.
+
+Person.find_or_initialize_by(name: 'Spartacus', rating: 4)
+# returns the first item or returns a new instance (requires you call .save to persist against the database).
+
+Person.find_or_create_by(name: 'Spartacus', rating: 4)
+# returns the first item or creates it and returns it.
+
+ +

Alternatives for find

+ +
Person.where(name: 'Spartacus', rating: 4).exists?(conditions = :none)
+# returns a boolean indicating if any record with the given conditions exist.
+
+Person.where(name: 'Spartacus', rating: 4).select("field1, field2, field3")
+# returns a chainable list of instances with only the mentioned fields.
+
+Person.where(name: 'Spartacus', rating: 4).ids
+# returns an Array of ids.
+
+Person.where(name: 'Spartacus', rating: 4).pluck(:field1, :field2)
+# returns an Array of the required fields.
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 67
+def find(*args)
+  return super if block_given?
+  find_with_ids(*args)
+end
+
+
+ +
+ +
+

+ + find_by(arg, *args) + +

+ + +
+

Finds the first record matching the specified conditions. There is no implied ordering so if order matters, you should specify it yourself.

+ +

If no record is found, returns nil.

+ +
Post.find_by name: 'Spartacus', rating: 4
+Post.find_by "published_at < ?", 2.weeks.ago
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 80
+def find_by(arg, *args)
+  where(arg, *args).take
+rescue ::RangeError
+  nil
+end
+
+
+ +
+ +
+

+ + find_by!(arg, *args) + +

+ + +
+

Like find_by, except that if no record is found, raises an ActiveRecord::RecordNotFound error.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 88
+def find_by!(arg, *args)
+  where(arg, *args).take!
+rescue ::RangeError
+  raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
+                           @klass.name, @klass.primary_key)
+end
+
+
+ +
+ +
+

+ + first(limit = nil) + +

+ + +
+

Find the first record (or first N records if a parameter is supplied). If no order is defined it will order by primary key.

+ +
Person.first # returns the first object fetched by SELECT * FROM people ORDER BY people.id LIMIT 1
+Person.where(["user_name = ?", user_name]).first
+Person.where(["user_name = :u", { u: user_name }]).first
+Person.order("created_on DESC").offset(5).first
+Person.first(3) # returns the first three objects fetched by SELECT * FROM people ORDER BY people.id LIMIT 3
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 121
+def first(limit = nil)
+  if limit
+    find_nth_with_limit(0, limit)
+  else
+    find_nth 0
+  end
+end
+
+
+ +
+ +
+

+ + first!() + +

+ + +
+

Same as first but raises ActiveRecord::RecordNotFound if no record is found. Note that first! accepts no arguments.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 131
+def first!
+  first || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + forty_two() + +

+ + +
+

Find the forty-second record. Also known as accessing “the reddit”. If no order is defined it will order by primary key.

+ +
Person.forty_two # returns the forty-second object fetched by SELECT * FROM people
+Person.offset(3).forty_two # returns the forty-second object from OFFSET 3 (which is OFFSET 44)
+Person.where(["user_name = :u", { u: user_name }]).forty_two
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 235
+def forty_two
+  find_nth 41
+end
+
+
+ +
+ +
+

+ + forty_two!() + +

+ + +
+

Same as forty_two but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 241
+def forty_two!
+  forty_two || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + fourth() + +

+ + +
+

Find the fourth record. If no order is defined it will order by primary key.

+ +
Person.fourth # returns the fourth object fetched by SELECT * FROM people
+Person.offset(3).fourth # returns the fourth object from OFFSET 3 (which is OFFSET 6)
+Person.where(["user_name = :u", { u: user_name }]).fourth
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 203
+def fourth
+  find_nth 3
+end
+
+
+ +
+ +
+

+ + fourth!() + +

+ + +
+

Same as fourth but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 209
+def fourth!
+  fourth || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + last(limit = nil) + +

+ + +
+

Find the last record (or last N records if a parameter is supplied). If no order is defined it will order by primary key.

+ +
Person.last # returns the last object fetched by SELECT * FROM people
+Person.where(["user_name = ?", user_name]).last
+Person.order("created_on DESC").offset(5).last
+Person.last(3) # returns the last three objects fetched by SELECT * FROM people.
+
+ +

Take note that in that last case, the results are sorted in ascending order:

+ +
[#<Person id:2>, #<Person id:3>, #<Person id:4>]
+
+ +

and not:

+ +
[#<Person id:4>, #<Person id:3>, #<Person id:2>]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 150
+def last(limit = nil)
+  return find_last(limit) if loaded? || has_limit_or_offset?
+
+  result = ordered_relation.limit(limit)
+  result = result.reverse_order!
+
+  limit ? result.reverse : result.first
+end
+
+
+ +
+ +
+

+ + last!() + +

+ + +
+

Same as last but raises ActiveRecord::RecordNotFound if no record is found. Note that last! accepts no arguments.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 161
+def last!
+  last || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + second() + +

+ + +
+

Find the second record. If no order is defined it will order by primary key.

+ +
Person.second # returns the second object fetched by SELECT * FROM people
+Person.offset(3).second # returns the second object from OFFSET 3 (which is OFFSET 4)
+Person.where(["user_name = :u", { u: user_name }]).second
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 171
+def second
+  find_nth 1
+end
+
+
+ +
+ +
+

+ + second!() + +

+ + +
+

Same as second but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 177
+def second!
+  second || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + second_to_last() + +

+ + +
+

Find the second-to-last record. If no order is defined it will order by primary key.

+ +
Person.second_to_last # returns the second-to-last object fetched by SELECT * FROM people
+Person.offset(3).second_to_last # returns the second-to-last object from OFFSET 3
+Person.where(["user_name = :u", { u: user_name }]).second_to_last
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 267
+def second_to_last
+  find_nth_from_last 2
+end
+
+
+ +
+ +
+

+ + second_to_last!() + +

+ + +
+

Same as second_to_last but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 273
+def second_to_last!
+  second_to_last || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + take(limit = nil) + +

+ + +
+

Gives a record (or N records if a parameter is supplied) without any implied order. The order will depend on the database implementation. If an order is supplied it will be respected.

+ +
Person.take # returns an object fetched by SELECT * FROM people LIMIT 1
+Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5
+Person.where(["name LIKE '%?'", name]).take
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 102
+def take(limit = nil)
+  limit ? find_take_with_limit(limit) : find_take
+end
+
+
+ +
+ +
+

+ + take!() + +

+ + +
+

Same as take but raises ActiveRecord::RecordNotFound if no record is found. Note that take! accepts no arguments.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 108
+def take!
+  take || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + third() + +

+ + +
+

Find the third record. If no order is defined it will order by primary key.

+ +
Person.third # returns the third object fetched by SELECT * FROM people
+Person.offset(3).third # returns the third object from OFFSET 3 (which is OFFSET 5)
+Person.where(["user_name = :u", { u: user_name }]).third
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 187
+def third
+  find_nth 2
+end
+
+
+ +
+ +
+

+ + third!() + +

+ + +
+

Same as third but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 193
+def third!
+  third || raise_record_not_found_exception!
+end
+
+
+ +
+ +
+

+ + third_to_last() + +

+ + +
+

Find the third-to-last record. If no order is defined it will order by primary key.

+ +
Person.third_to_last # returns the third-to-last object fetched by SELECT * FROM people
+Person.offset(3).third_to_last # returns the third-to-last object from OFFSET 3
+Person.where(["user_name = :u", { u: user_name }]).third_to_last
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 251
+def third_to_last
+  find_nth_from_last 3
+end
+
+
+ +
+ +
+

+ + third_to_last!() + +

+ + +
+

Same as third_to_last but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/finder_methods.rb, line 257
+def third_to_last!
+  third_to_last || raise_record_not_found_exception!
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/FixtureSet.html b/src/5.2/classes/ActiveRecord/FixtureSet.html new file mode 100644 index 0000000000..7b01808eaa --- /dev/null +++ b/src/5.2/classes/ActiveRecord/FixtureSet.html @@ -0,0 +1,1317 @@ +--- +title: ActiveRecord::FixtureSet +layout: default +--- +
+ +
+
+ +
+ +

Fixtures are a way of organizing data that you want to test against; in short, sample data.

+ +

They are stored in YAML files, one file per model, which are placed in the directory appointed by ActiveSupport::TestCase.fixture_path=(path) (this is automatically configured for Rails, so you can just put your files in <your-rails-app>/test/fixtures/). The fixture file ends with the .yml file extension, for example: <your-rails-app>/test/fixtures/web_sites.yml).

+ +

The format of a fixture file looks like this:

+ +
rubyonrails:
+  id: 1
+  name: Ruby on Rails
+  url: http://www.rubyonrails.org
+
+google:
+  id: 2
+  name: Google
+  url: http://www.google.com
+
+ +

This fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and is followed by an indented list of key/value pairs in the “key: value” format. Records are separated by a blank line for your viewing pleasure.

+ +

Note: Fixtures are unordered. If you want ordered fixtures, use the omap YAML type. See yaml.org/type/omap.html for the specification. You will need ordered fixtures when you have foreign key constraints on keys in the same table. This is commonly needed for tree structures. Example:

+ +
--- !omap
+- parent:
+    id:         1
+    parent_id:  NULL
+    title:      Parent
+- child:
+    id:         2
+    parent_id:  1
+    title:      Child
+
+ +

Using Fixtures in Test Cases

+ +

Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the fixtures, but first let's take a look at a sample unit test:

+ +
require 'test_helper'
+
+class WebSiteTest < ActiveSupport::TestCase
+  test "web_site_count" do
+    assert_equal 2, WebSite.count
+  end
+end
+
+ +

By default, test_helper.rb will load all of your fixtures into your test database, so this test will succeed.

+ +

The testing environment will automatically load all the fixtures into the database before each test. To ensure consistent data, the environment deletes the fixtures before running the load.

+ +

In addition to being available in the database, the fixture's data may also be accessed by using a special dynamic method, which has the same name as the model.

+ +

Passing in a fixture name to this dynamic method returns the fixture matching this name:

+ +
test "find one" do
+  assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
+end
+
+ +

Passing in multiple fixture names returns all fixtures matching these names:

+ +
test "find all by name" do
+  assert_equal 2, web_sites(:rubyonrails, :google).length
+end
+
+ +

Passing in no arguments returns all fixtures:

+ +
test "find all" do
+  assert_equal 2, web_sites.length
+end
+
+ +

Passing in any fixture name that does not exist will raise StandardError:

+ +
test "find by name that does not exist" do
+  assert_raise(StandardError) { web_sites(:reddit) }
+end
+
+ +

Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the following tests:

+ +
test "find_alt_method_1" do
+  assert_equal "Ruby on Rails", @web_sites['rubyonrails']['name']
+end
+
+test "find_alt_method_2" do
+  assert_equal "Ruby on Rails", @rubyonrails.name
+end
+
+ +

In order to use these methods to access fixtured data within your test cases, you must specify one of the following in your ActiveSupport::TestCase-derived class:

+
  • +

    to fully enable instantiated fixtures (enable alternate methods #1 and #2 above)

    + +
    self.use_instantiated_fixtures = true
    +
    +
  • +

    create only the hash for the fixtures, do not 'find' each instance (enable alternate method #1 only)

    + +
    self.use_instantiated_fixtures = :no_instances
    +
    +
+ +

Using either of these alternate methods incurs a performance hit, as the fixtured data must be fully traversed in the database to create the fixture hash and/or instance variables. This is expensive for large sets of fixtured data.

+ +

Dynamic fixtures with ERB

+ +

Sometimes you don't care about the content of the fixtures as much as you care about the volume. In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load testing, like:

+ +
<% 1.upto(1000) do |i| %>
+fix_<%= i %>:
+  id: <%= i %>
+  name: guy_<%= i %>
+<% end %>
+
+ +

This will create 1000 very simple fixtures.

+ +

Using ERB, you can also inject dynamic values into your fixtures with inserts like <%= Date.today.strftime("%Y-%m-%d") %>. This is however a feature to be used with some caution. The point of fixtures are that they're stable units of predictable sample data. If you feel that you need to inject dynamic values, then perhaps you should reexamine whether your application is properly testable. Hence, dynamic values in fixtures are to be considered a code smell.

+ +

Helper methods defined in a fixture will not be available in other fixtures, to prevent against unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module that is included in ActiveRecord::FixtureSet.context_class.

+
  • +

    define a helper method in test_helper.rb

    + +
    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
    +
    +
  • +

    use the helper method in a fixture

    + +
    photo:
    +  name: kitten.png
    +  sha: <%= file_sha 'files/kitten.png' %>
    +
    +
+ +

Transactional Tests

+ +

Test cases can use begin+rollback to isolate their changes to the database instead of having to delete+insert for every test case.

+ +
class FooTest < ActiveSupport::TestCase
+  self.use_transactional_tests = true
+
+  test "godzilla" do
+    assert_not_empty Foo.all
+    Foo.destroy_all
+    assert_empty Foo.all
+  end
+
+  test "godzilla aftermath" do
+    assert_not_empty Foo.all
+  end
+end
+
+ +

If you preload your test database with all fixture data (probably in the rake task) and use transactional tests, then you may omit all fixtures declarations in your test cases since all the data's already there and every case rolls back its changes.

+ +

In order to use instantiated fixtures with preloaded data, set self.pre_loaded_fixtures to true. This will provide access to fixture data for every table that has been loaded through fixtures (depending on the value of use_instantiated_fixtures).

+ +

When not to use transactional tests:

+
  1. +

    You're testing whether a transaction works correctly. Nested transactions don't commit until all parent transactions commit, particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won't be able to verify the results of your transaction until Active Record supports nested transactions or savepoints (in progress).

    +
  2. +

    Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM. Use InnoDB, MaxDB, or NDB instead.

    +
+ +

Advanced Fixtures

+ +

Fixtures that don't specify an ID get some extra features:

+
  • +

    Stable, autogenerated IDs

    +
  • +

    Label references for associations (belongs_to, has_one, has_many)

    +
  • +

    HABTM associations as inline lists

    +
+ +

There are some more advanced features available even if the id is specified:

+
  • +

    Autofilled timestamp columns

    +
  • +

    Fixture label interpolation

    +
  • +

    Support for YAML defaults

    +
+ +

Stable, Autogenerated IDs

+ +

Here, have a monkey fixture:

+ +
george:
+  id: 1
+  name: George the Monkey
+
+reginald:
+  id: 2
+  name: Reginald the Pirate
+
+ +

Each of these fixtures has two unique identifiers: one for the database and one for the humans. Why don't we generate the primary key instead? Hashing each fixture's label yields a consistent ID:

+ +
george: # generated id: 503576764
+  name: George the Monkey
+
+reginald: # generated id: 324201669
+  name: Reginald the Pirate
+
+ +

Active Record looks at the fixture's model class, discovers the correct primary key, and generates it right before inserting the fixture into the database.

+ +

The generated ID for a given label is constant, so we can discover any fixture's ID without loading anything, as long as we know the label.

+ +

Label references for associations (belongs_to, has_one, has_many)

+ +

Specifying foreign keys in fixtures can be very fragile, not to mention difficult to read. Since Active Record can figure out the ID of any fixture from its label, you can specify FK's by label instead of ID.

+ +

belongs_to

+ +

Let's break out some more monkeys and pirates.

+ +
### in pirates.yml
+
+reginald:
+  id: 1
+  name: Reginald the Pirate
+  monkey_id: 1
+
+### in monkeys.yml
+
+george:
+  id: 1
+  name: George the Monkey
+  pirate_id: 1
+
+ +

Add a few more monkeys and pirates and break this into multiple files, and it gets pretty hard to keep track of what's going on. Let's use labels instead of IDs:

+ +
### in pirates.yml
+
+reginald:
+  name: Reginald the Pirate
+  monkey: george
+
+### in monkeys.yml
+
+george:
+  name: George the Monkey
+  pirate: reginald
+
+ +

Pow! All is made clear. Active Record reflects on the fixture's model class, finds all the belongs_to associations, and allows you to specify a target label for the association (monkey: george) rather than a target id for the FK (monkey_id: 1).

+ +

Polymorphic belongs_to

+ +

Supporting polymorphic relationships is a little bit more complicated, since Active Record needs to know what type your association is pointing at. Something like this should look familiar:

+ +
### in fruit.rb
+
+belongs_to :eater, polymorphic: true
+
+### in fruits.yml
+
+apple:
+  id: 1
+  name: apple
+  eater_id: 1
+  eater_type: Monkey
+
+ +

Can we do better? You bet!

+ +
apple:
+  eater: george (Monkey)
+
+ +

Just provide the polymorphic target type and Active Record will take care of the rest.

+ +

has_and_belongs_to_many

+ +

Time to give our monkey some fruit.

+ +
### in monkeys.yml
+
+george:
+  id: 1
+  name: George the Monkey
+
+### in fruits.yml
+
+apple:
+  id: 1
+  name: apple
+
+orange:
+  id: 2
+  name: orange
+
+grape:
+  id: 3
+  name: grape
+
+### in fruits_monkeys.yml
+
+apple_george:
+  fruit_id: 1
+  monkey_id: 1
+
+orange_george:
+  fruit_id: 2
+  monkey_id: 1
+
+grape_george:
+  fruit_id: 3
+  monkey_id: 1
+
+ +

Let's make the HABTM fixture go away.

+ +
### in monkeys.yml
+
+george:
+  id: 1
+  name: George the Monkey
+  fruits: apple, orange, grape
+
+### in fruits.yml
+
+apple:
+  name: apple
+
+orange:
+  name: orange
+
+grape:
+  name: grape
+
+ +

Zap! No more fruits_monkeys.yml file. We've specified the list of fruits on George's fixture, but we could've just as easily specified a list of monkeys on each fruit. As with belongs_to, Active Record reflects on the fixture's model class and discovers the has_and_belongs_to_many associations.

+ +

Autofilled Timestamp Columns

+ +

If your table/model specifies any of Active Record's standard timestamp columns (created_at, created_on, updated_at, updated_on), they will automatically be set to Time.now.

+ +

If you've set specific values, they'll be left alone.

+ +

Fixture label interpolation

+ +

The label of the current fixture is always available as a column value:

+ +
geeksomnia:
+  name: Geeksomnia's Account
+  subdomain: $LABEL
+  email: $LABEL@email.com
+
+ +

Also, sometimes (like when porting older join table fixtures) you'll need to be able to get a hold of the identifier for a given label. ERB to the rescue:

+ +
george_reginald:
+  monkey_id: <%= ActiveRecord::FixtureSet.identify(:reginald) %>
+  pirate_id: <%= ActiveRecord::FixtureSet.identify(:george) %>
+
+ +

Support for YAML defaults

+ +

You can set and reuse defaults in your fixtures YAML file. This is the same technique used in the database.yml file to specify defaults:

+ +
DEFAULTS: &DEFAULTS
+  created_on: <%= 3.weeks.ago.to_s(:db) %>
+
+first:
+  name: Smurf
+  <<: *DEFAULTS
+
+second:
+  name: Fraggle
+  <<: *DEFAULTS
+
+ +

Any fixture labeled “DEFAULTS” is safely ignored.

+ +

Configure the fixture model class

+ +

It's possible to set the fixture's model class directly in the YAML file. This is helpful when fixtures are loaded outside tests and set_fixture_class is not available (e.g. when running rails db:fixtures:load).

+ +
_fixture:
+  model_class: User
+david:
+  name: David
+
+ +

Any fixtures labeled “_fixture” are safely ignored.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
MAX_ID=2**30 - 1
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + config
+ [R] + fixtures
+ [R] + model_class
+ [R] + name
+ [R] + table_name
+ + + + +

Class Public methods

+ +
+

+ + cache_fixtures(connection, fixtures_map) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 475
+def self.cache_fixtures(connection, fixtures_map)
+  cache_for_connection(connection).update(fixtures_map)
+end
+
+
+ +
+ +
+

+ + cache_for_connection(connection) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 459
+def self.cache_for_connection(connection)
+  @@all_cached_fixtures[connection]
+end
+
+
+ +
+ +
+

+ + cached_fixtures(connection, keys_to_fetch = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 467
+def self.cached_fixtures(connection, keys_to_fetch = nil)
+  if keys_to_fetch
+    cache_for_connection(connection).values_at(*keys_to_fetch)
+  else
+    cache_for_connection(connection).values
+  end
+end
+
+
+ +
+ +
+

+ + context_class() + +

+ + +
+

Superclass for the evaluation contexts used by ERB fixtures.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 590
+def self.context_class
+  @context_class ||= Class.new
+end
+
+
+ +
+ +
+

+ + create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 531
+def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
+  fixture_set_names = Array(fixture_set_names).map(&:to_s)
+  class_names = ClassCache.new class_names, config
+
+  # FIXME: Apparently JK uses this.
+  connection = block_given? ? yield : ActiveRecord::Base.connection
+
+  files_to_read = fixture_set_names.reject { |fs_name|
+    fixture_is_cached?(connection, fs_name)
+  }
+
+  unless files_to_read.empty?
+    fixtures_map = {}
+
+    fixture_sets = files_to_read.map do |fs_name|
+      klass = class_names[fs_name]
+      conn = klass ? klass.connection : connection
+      fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
+        conn,
+        fs_name,
+        klass,
+        ::File.join(fixtures_directory, fs_name))
+    end
+
+    update_all_loaded_fixtures fixtures_map
+    fixture_sets_by_connection = fixture_sets.group_by { |fs| fs.model_class ? fs.model_class.connection : connection }
+
+    fixture_sets_by_connection.each do |conn, set|
+      table_rows_for_connection = Hash.new { |h, k| h[k] = [] }
+
+      set.each do |fs|
+        fs.table_rows.each do |table, rows|
+          table_rows_for_connection[table].unshift(*rows)
+        end
+      end
+      conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
+
+      # Cap primary key sequences to max(pk).
+      if conn.respond_to?(:reset_pk_sequence!)
+        set.each { |fs| conn.reset_pk_sequence!(fs.table_name) }
+      end
+    end
+
+    cache_fixtures(connection, fixtures_map)
+  end
+  cached_fixtures(connection, fixture_set_names)
+end
+
+
+ +
+ +
+

+ + fixture_is_cached?(connection, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 463
+def self.fixture_is_cached?(connection, table_name)
+  cache_for_connection(connection)[table_name]
+end
+
+
+ +
+ +
+

+ + identify(label, column_type = :integer) + +

+ + +
+

Returns a consistent, platform-independent identifier for label. Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 581
+def self.identify(label, column_type = :integer)
+  if column_type == :uuid
+    Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, label.to_s)
+  else
+    Zlib.crc32(label.to_s) % MAX_ID
+  end
+end
+
+
+ +
+ +
+

+ + instantiate_all_loaded_fixtures(object, load_instances = true) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 491
+def self.instantiate_all_loaded_fixtures(object, load_instances = true)
+  all_loaded_fixtures.each_value do |fixture_set|
+    instantiate_fixtures(object, fixture_set, load_instances)
+  end
+end
+
+
+ +
+ +
+

+ + instantiate_fixtures(object, fixture_set, load_instances = true) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 479
+def self.instantiate_fixtures(object, fixture_set, load_instances = true)
+  if load_instances
+    fixture_set.each do |fixture_name, fixture|
+      begin
+        object.instance_variable_set "@#{fixture_name}", fixture.find
+      rescue FixtureClassNotFound
+        nil
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + new(connection, name, class_name, path, config = ActiveRecord::Base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 600
+def initialize(connection, name, class_name, path, config = ActiveRecord::Base)
+  @name     = name
+  @path     = path
+  @config   = config
+
+  self.model_class = class_name
+
+  @fixtures = read_fixture_files(path)
+
+  @connection = connection
+
+  @table_name = (model_class.respond_to?(:table_name) ?
+                  model_class.table_name :
+                  self.class.default_fixture_table_name(name, config))
+end
+
+
+ +
+ +
+

+ + reset_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 455
+def self.reset_cache
+  @@all_cached_fixtures.clear
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](x) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 616
+def [](x)
+  fixtures[x]
+end
+
+
+ +
+ +
+

+ + []=(k, v) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 620
+def []=(k, v)
+  fixtures[k] = v
+end
+
+
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 624
+def each(&block)
+  fixtures.each(&block)
+end
+
+
+ +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 628
+def size
+  fixtures.size
+end
+
+
+ +
+ +
+

+ + table_rows() + +

+ + +
+

Returns a hash of rows to be inserted. The key is the table, the value is a list of rows to insert to that table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 634
+def table_rows
+  now = config.default_timezone == :utc ? Time.now.utc : Time.now
+
+  # allow a standard key to be used for doing defaults in YAML
+  fixtures.delete("DEFAULTS")
+
+  # track any join tables we need to insert later
+  rows = Hash.new { |h, table| h[table] = [] }
+
+  rows[table_name] = fixtures.map do |label, fixture|
+    row = fixture.to_hash
+
+    if model_class
+      # fill in timestamp columns if they aren't specified and the model is set to record_timestamps
+      if model_class.record_timestamps
+        timestamp_column_names.each do |c_name|
+          row[c_name] = now unless row.key?(c_name)
+        end
+      end
+
+      # interpolate the fixture label
+      row.each do |key, value|
+        row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String)
+      end
+
+      # generate a primary key if necessary
+      if has_primary_key_column? && !row.include?(primary_key_name)
+        row[primary_key_name] = ActiveRecord::FixtureSet.identify(label, primary_key_type)
+      end
+
+      # Resolve enums
+      model_class.defined_enums.each do |name, values|
+        if row.include?(name)
+          row[name] = values.fetch(row[name], row[name])
+        end
+      end
+
+      # If STI is used, find the correct subclass for association reflection
+      reflection_class =
+        if row.include?(inheritance_column_name)
+          row[inheritance_column_name].constantize rescue model_class
+        else
+          model_class
+        end
+
+      reflection_class._reflections.each_value do |association|
+        case association.macro
+        when :belongs_to
+          # Do not replace association name with association foreign key if they are named the same
+          fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s
+
+          if association.name.to_s != fk_name && value = row.delete(association.name.to_s)
+            if association.polymorphic? && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
+              # support polymorphic belongs_to as "label (Type)"
+              row[association.foreign_type] = $1
+            end
+
+            fk_type = reflection_class.type_for_attribute(fk_name).type
+            row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
+          end
+        when :has_many
+          if association.options[:through]
+            add_join_records(rows, row, HasManyThroughProxy.new(association))
+          end
+        end
+      end
+    end
+
+    row
+  end
+  rows
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/FixtureSet/ClassCache.html b/src/5.2/classes/ActiveRecord/FixtureSet/ClassCache.html new file mode 100644 index 0000000000..97c84f6193 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/FixtureSet/ClassCache.html @@ -0,0 +1,156 @@ +--- +title: ActiveRecord::FixtureSet::ClassCache +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + [] +
  • + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(class_names, config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 500
+def initialize(class_names, config)
+  @class_names = class_names.stringify_keys
+  @config      = config
+
+  # Remove string values that aren't constants or subclasses of AR
+  @class_names.delete_if { |klass_name, klass| !insert_class(@class_names, klass_name, klass) }
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](fs_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 508
+def [](fs_name)
+  @class_names.fetch(fs_name) {
+    klass = default_fixture_model(fs_name, @config).safe_constantize
+    insert_class(@class_names, fs_name, klass)
+  }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ImmutableRelation.html b/src/5.2/classes/ActiveRecord/ImmutableRelation.html new file mode 100644 index 0000000000..c599b23891 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ImmutableRelation.html @@ -0,0 +1,77 @@ +--- +title: ActiveRecord::ImmutableRelation +layout: default +--- +
+ +
+
+ +
+ +

Raised when a relation cannot be mutated because it's already loaded.

+ +
class Task < ActiveRecord::Base
+end
+
+relation = Task.all
+relation.loaded? # => true
+
+# Methods which try to mutate a loaded relation fail.
+relation.where!(title: 'TODO')  # => ActiveRecord::ImmutableRelation
+relation.limit!(5)              # => ActiveRecord::ImmutableRelation
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Inheritance.html b/src/5.2/classes/ActiveRecord/Inheritance.html new file mode 100644 index 0000000000..6d139662cd --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Inheritance.html @@ -0,0 +1,142 @@ +--- +title: ActiveRecord::Inheritance +layout: default +--- +
+ +
+
+ +
+ +

Single table inheritance

+ +

Active Record allows inheritance by storing the name of the class in a column that by default is named “type” (can be changed by overwriting Base.inheritance_column). This means that an inheritance looking like this:

+ +
class Company < ActiveRecord::Base; end
+class Firm < Company; end
+class Client < Company; end
+class PriorityClient < Client; end
+
+ +

When you do Firm.create(name: "37signals"), this record will be saved in the companies table with type = “Firm”. You can then fetch this row again using Company.where(name: '37signals').first and it will return a Firm object.

+ +

Be aware that because the type column is an attribute on the record every new subclass will instantly be marked as dirty and the type column will be included in the list of changed attributes on the record. This is different from non Single Table Inheritance(STI) classes:

+ +
Company.new.changed? # => false
+Firm.new.changed?    # => true
+Firm.new.changes     # => {"type"=>["","Firm"]}
+
+ +

If you don't have a type column defined in your table, single-table inheritance won't be triggered. In that case, it'll work just like normal subclasses with no special magic for differentiating between them or reloading the right type with find.

+ +

Note, all the attributes for all the cases are kept in the same table. Read more: www.martinfowler.com/eaaCatalog/singleTableInheritance.html

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + initialize_dup(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 259
+def initialize_dup(other)
+  super
+  ensure_proper_type
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Inheritance/ClassMethods.html b/src/5.2/classes/ActiveRecord/Inheritance/ClassMethods.html new file mode 100644 index 0000000000..2b48bbd03a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Inheritance/ClassMethods.html @@ -0,0 +1,482 @@ +--- +title: ActiveRecord::Inheritance::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + abstract_class

Set this to true if this is an abstract class (see abstract_class?). If you are using inheritance with Active Record and don't want a class to be considered as part of the STI hierarchy, you must set this to true. ApplicationRecord, for example, is generated as an abstract class.

+ +

Consider the following default behaviour:

+ +
Shape = Class.new(ActiveRecord::Base)
+Polygon = Class.new(Shape)
+Square = Class.new(Polygon)
+
+Shape.table_name   # => "shapes"
+Polygon.table_name # => "shapes"
+Square.table_name  # => "shapes"
+Shape.create!      # => #<Shape id: 1, type: nil>
+Polygon.create!    # => #<Polygon id: 2, type: "Polygon">
+Square.create!     # => #<Square id: 3, type: "Square">
+
+ +

However, when using abstract_class, Shape is omitted from the hierarchy:

+ +
class Shape < ActiveRecord::Base
+  self.abstract_class = true
+end
+Polygon = Class.new(Shape)
+Square = Class.new(Polygon)
+
+Shape.table_name   # => nil
+Polygon.table_name # => "polygons"
+Square.table_name  # => "polygons"
+Shape.create!      # => NotImplementedError: Shape is an abstract class and cannot be instantiated.
+Polygon.create!    # => #<Polygon id: 1, type: nil>
+Square.create!     # => #<Square id: 2, type: "Square">
+
+ +

Note that in the above example, to disallow the creation of a plain Polygon, you should use validates :type, presence: true, instead of setting it as an abstract class. This way, Polygon will stay in the hierarchy, and Active Record will continue to correctly derive the table name.

+ + + + + +

Instance Public methods

+ +
+

+ + abstract_class?() + +

+ + +
+

Returns whether this class is an abstract class or not.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 151
+def abstract_class?
+  defined?(@abstract_class) && @abstract_class == true
+end
+
+
+ +
+ +
+

+ + base_class() + +

+ + +
+

Returns the class descending directly from ActiveRecord::Base, or an abstract class, if any, in the inheritance hierarchy.

+ +

If A extends ActiveRecord::Base, A.base_class will return A. If B descends from A through some arbitrarily deep hierarchy, B.base_class will return A.

+ +

If B < A and C < B and if A is an abstract_class then both B.base_class and C.base_class would return B as the answer since A is an abstract_class.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 95
+def base_class
+  unless self < Base
+    raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
+  end
+
+  if superclass == Base || superclass.abstract_class?
+    self
+  else
+    superclass.base_class
+  end
+end
+
+
+ +
+ +
+

+ + descends_from_active_record?() + +

+ + +
+

Returns true if this does not need STI type condition. Returns false if STI type condition needs to be applied.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 72
+def descends_from_active_record?
+  if self == Base
+    false
+  elsif superclass.abstract_class?
+    superclass.descends_from_active_record?
+  else
+    superclass == Base || !columns_hash.include?(inheritance_column)
+  end
+end
+
+
+ +
+ +
+

+ + inherited(subclass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 163
+def inherited(subclass)
+  subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
+  super
+end
+
+
+ +
+ +
+

+ + new(attributes = nil, &block) + +

+ + +
+

Determines if one of the attributes passed in is the inheritance column, and if the inheritance column is attr accessible, it initializes an instance of the given subclass instead of the base class.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 50
+def new(attributes = nil, &block)
+  if abstract_class? || self == Base
+    raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
+  end
+
+  if has_attribute?(inheritance_column)
+    subclass = subclass_from_attributes(attributes)
+
+    if subclass.nil? && base_class == self
+      subclass = subclass_from_attributes(column_defaults)
+    end
+  end
+
+  if subclass && subclass != self
+    subclass.new(attributes, &block)
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + polymorphic_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 159
+def polymorphic_name
+  base_class.name
+end
+
+
+ +
+ +
+

+ + sti_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 155
+def sti_name
+  store_full_sti_class ? name : name.demodulize
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + compute_type(type_name) + +

+ + +
+

Returns the class type of the record using the current module as a prefix. So descendants of MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/inheritance.rb, line 172
+def compute_type(type_name)
+  if type_name.start_with?("::".freeze)
+    # If the type is prefixed with a scope operator then we assume that
+    # the type_name is an absolute reference.
+    ActiveSupport::Dependencies.constantize(type_name)
+  else
+    type_candidate = @_type_candidates_cache[type_name]
+    if type_candidate && type_constant = ActiveSupport::Dependencies.safe_constantize(type_candidate)
+      return type_constant
+    end
+
+    # Build a list of candidates to search for
+    candidates = []
+    name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
+    candidates << type_name
+
+    candidates.each do |candidate|
+      constant = ActiveSupport::Dependencies.safe_constantize(candidate)
+      if candidate == constant.to_s
+        @_type_candidates_cache[type_name] = candidate
+        return constant
+      end
+    end
+
+    raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Integration.html b/src/5.2/classes/ActiveRecord/Integration.html new file mode 100644 index 0000000000..1d1f5813c9 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Integration.html @@ -0,0 +1,292 @@ +--- +title: ActiveRecord::Integration +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + cache_key(*timestamp_names) + +

+ + +
+

Returns a stable cache key that can be used to identify this record.

+ +
Product.new.cache_key     # => "products/new"
+Product.find(5).cache_key # => "products/5"
+
+ +

If ActiveRecord::Base.cache_versioning is turned off, as it was in Rails 5.1 and earlier, the cache key will also include a version.

+ +
Product.cache_versioning = false
+Person.find(5).cache_key  # => "people/5-20071224150000" (updated_at available)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/integration.rb, line 64
+    def cache_key(*timestamp_names)
+      if new_record?
+        "#{model_name.cache_key}/new"
+      else
+        if cache_version && timestamp_names.none?
+          "#{model_name.cache_key}/#{id}"
+        else
+          timestamp = if timestamp_names.any?
+            ActiveSupport::Deprecation.warn(<<-MSG.squish)
+              Specifying a timestamp name for #cache_key has been deprecated in favor of
+              the explicit #cache_version method that can be overwritten.
+            MSG
+
+            max_updated_column_timestamp(timestamp_names)
+          else
+            max_updated_column_timestamp
+          end
+
+          if timestamp
+            timestamp = timestamp.utc.to_s(cache_timestamp_format)
+            "#{model_name.cache_key}/#{id}-#{timestamp}"
+          else
+            "#{model_name.cache_key}/#{id}"
+          end
+        end
+      end
+    end
+
+
+ +
+ +
+

+ + cache_key_with_version() + +

+ + +
+

Returns a cache key along with the version.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/integration.rb, line 105
+def cache_key_with_version
+  if version = cache_version
+    "#{cache_key}-#{version}"
+  else
+    cache_key
+  end
+end
+
+
+ +
+ +
+

+ + cache_version() + +

+ + +
+

Returns a cache version that can be used together with the cache key to form a recyclable caching scheme. By default, the updated_at column is used for the cache_version, but this method can be overwritten to return something else.

+ +

Note, this method will return nil if ActiveRecord::Base.cache_versioning is set to false (which it is by default until Rails 6.0).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/integration.rb, line 98
+def cache_version
+  if cache_versioning && timestamp = try(:updated_at)
+    timestamp.utc.to_s(:usec)
+  end
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns a String, which Action Pack uses for constructing a URL to this object. The default implementation returns this record's id as a String, or nil if this record's unsaved.

+ +

For example, suppose that you have a User model, and that you have a resources :users route. Normally, user_path will construct a path with the user object's 'id' in it:

+ +
user = User.find_by(name: 'Phusion')
+user_path(user)  # => "/users/1"
+
+ +

You can override to_param in your model to make user_path construct a path using the user's name instead of the user's id:

+ +
class User < ActiveRecord::Base
+  def to_param  # overridden
+    name
+  end
+end
+
+user = User.find_by(name: 'Phusion')
+user_path(user)  # => "/users/Phusion"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/integration.rb, line 49
+def to_param
+  # We can't use alias_method here, because method 'id' optimizes itself on the fly.
+  id && id.to_s # Be sure to stringify the id for routes
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Integration/ClassMethods.html b/src/5.2/classes/ActiveRecord/Integration/ClassMethods.html new file mode 100644 index 0000000000..99917f4dc5 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Integration/ClassMethods.html @@ -0,0 +1,135 @@ +--- +title: ActiveRecord::Integration::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + to_param(method_name = nil) + +

+ + +
+

Defines your model's to_param method to generate “pretty” URLs using method_name, which can be any attribute or method that responds to to_s.

+ +
class User < ActiveRecord::Base
+  to_param :name
+end
+
+user = User.find_by(name: 'Fancy Pants')
+user.id         # => 123
+user_path(user) # => "/users/123-fancy-pants"
+
+ +

Values longer than 20 characters will be truncated. The value is truncated word by word.

+ +
user = User.find_by(name: 'David Heinemeier Hansson')
+user.id         # => 125
+user_path(user) # => "/users/125-david-heinemeier"
+
+ +

Because the generated param begins with the record's id, it is suitable for passing to find. In a controller, for example:

+ +
params[:id]               # => "123-fancy-pants"
+User.find(params[:id]).id # => 123
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/integration.rb, line 138
+def to_param(method_name = nil)
+  if method_name.nil?
+    super()
+  else
+    define_method :to_param do
+      if (default = super()) &&
+           (result = send(method_name).to_s).present? &&
+             (param = result.squish.parameterize.truncate(20, separator: /-/, omission: "")).present?
+        "#{default}-#{param}"
+      else
+        default
+      end
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/InvalidForeignKey.html b/src/5.2/classes/ActiveRecord/InvalidForeignKey.html new file mode 100644 index 0000000000..1d70b8d782 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/InvalidForeignKey.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::InvalidForeignKey +layout: default +--- +
+ +
+
+ +
+ +

Raised when a record cannot be inserted or updated because it references a non-existent record.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/IrreversibleMigration.html b/src/5.2/classes/ActiveRecord/IrreversibleMigration.html new file mode 100644 index 0000000000..268915f573 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/IrreversibleMigration.html @@ -0,0 +1,139 @@ +--- +title: ActiveRecord::IrreversibleMigration +layout: default +--- +
+ +
+
+ +
+ +

Exception that can be raised to stop migrations from being rolled back. For example the following migration is not reversible. Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.

+ +
class IrreversibleMigrationExample < ActiveRecord::Migration[5.0]
+  def change
+    create_table :distributors do |t|
+      t.string :zipcode
+    end
+
+    execute <<-SQL
+      ALTER TABLE distributors
+        ADD CONSTRAINT zipchk
+          CHECK (char_length(zipcode) = 5) NO INHERIT;
+    SQL
+  end
+end
+
+ +

There are two ways to mitigate this problem.

+
  1. +

    Define #up and #down methods instead of #change:

    +
+ +
class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
+  def up
+    create_table :distributors do |t|
+      t.string :zipcode
+    end
+
+    execute <<-SQL
+      ALTER TABLE distributors
+        ADD CONSTRAINT zipchk
+          CHECK (char_length(zipcode) = 5) NO INHERIT;
+    SQL
+  end
+
+  def down
+    execute <<-SQL
+      ALTER TABLE distributors
+        DROP CONSTRAINT zipchk
+    SQL
+
+    drop_table :distributors
+  end
+end
+
+
  1. +

    Use the reversible method in #change method:

    +
+ +
class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
+  def change
+    create_table :distributors do |t|
+      t.string :zipcode
+    end
+
+    reversible do |dir|
+      dir.up do
+        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
+  end
+end
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/IrreversibleOrderError.html b/src/5.2/classes/ActiveRecord/IrreversibleOrderError.html new file mode 100644 index 0000000000..2acd5c9733 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/IrreversibleOrderError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::IrreversibleOrderError +layout: default +--- +
+ +
+
+ +
+ +

IrreversibleOrderError is raised when a relation's order is too complex for reverse_order to automatically reverse.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/LegacyYamlAdapter.html b/src/5.2/classes/ActiveRecord/LegacyYamlAdapter.html new file mode 100644 index 0000000000..a2aef2f8d0 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/LegacyYamlAdapter.html @@ -0,0 +1,126 @@ +--- +title: ActiveRecord::LegacyYamlAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + convert(klass, coder) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/legacy_yaml_adapter.rb, line 5
+def self.convert(klass, coder)
+  return coder unless coder.is_a?(Psych::Coder)
+
+  case coder["active_record_yaml_version"]
+  when 1, 2 then coder
+  else
+    if coder["attributes"].is_a?(ActiveModel::AttributeSet)
+      Rails420.convert(klass, coder)
+    else
+      Rails41.convert(klass, coder)
+    end
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails41.html b/src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails41.html new file mode 100644 index 0000000000..eeabd1afc7 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails41.html @@ -0,0 +1,108 @@ +--- +title: ActiveRecord::LegacyYamlAdapter::Rails41 +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + convert(klass, coder) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/legacy_yaml_adapter.rb, line 36
+def self.convert(klass, coder)
+  attributes = klass.attributes_builder
+    .build_from_database(coder["attributes"])
+  new_record = coder["attributes"][klass.primary_key].blank?
+
+  {
+    "attributes" => attributes,
+    "new_record" => new_record,
+  }
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails420.html b/src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails420.html new file mode 100644 index 0000000000..d9499197a2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/LegacyYamlAdapter/Rails420.html @@ -0,0 +1,111 @@ +--- +title: ActiveRecord::LegacyYamlAdapter::Rails420 +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + convert(klass, coder) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/legacy_yaml_adapter.rb, line 20
+def self.convert(klass, coder)
+  attribute_set = coder["attributes"]
+
+  klass.attribute_names.each do |attr_name|
+    attribute = attribute_set[attr_name]
+    if attribute.type.is_a?(Delegator)
+      type_from_klass = klass.type_for_attribute(attr_name)
+      attribute_set[attr_name] = attribute.with_type(type_from_klass)
+    end
+  end
+
+  coder
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/LockWaitTimeout.html b/src/5.2/classes/ActiveRecord/LockWaitTimeout.html new file mode 100644 index 0000000000..770b9db825 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/LockWaitTimeout.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::LockWaitTimeout +layout: default +--- +
+ +
+
+ +
+ +

LockWaitTimeout will be raised when lock wait timeout exceeded.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Locking.html b/src/5.2/classes/ActiveRecord/Locking.html new file mode 100644 index 0000000000..08c735f3fa --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Locking.html @@ -0,0 +1,71 @@ +--- +title: ActiveRecord::Locking +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Locking/Optimistic.html b/src/5.2/classes/ActiveRecord/Locking/Optimistic.html new file mode 100644 index 0000000000..8b7ddc0249 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Locking/Optimistic.html @@ -0,0 +1,113 @@ +--- +title: ActiveRecord::Locking::Optimistic +layout: default +--- +
+ +
+
+ +
+ +

What is Optimistic Locking

+ +

Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of conflicts with the data. It does this by checking whether another process has made changes to a record since it was opened, an ActiveRecord::StaleObjectError exception is thrown if that has occurred and the update is ignored.

+ +

Check out ActiveRecord::Locking::Pessimistic for an alternative.

+ +

Usage

+ +

Active Record supports optimistic locking if the lock_version field is present. Each update to the record increments the lock_version column and the locking facilities ensure that records instantiated twice will let the last one saved raise a StaleObjectError if the first was also updated. Example:

+ +
p1 = Person.find(1)
+p2 = Person.find(1)
+
+p1.first_name = "Michael"
+p1.save
+
+p2.first_name = "should fail"
+p2.save # Raises an ActiveRecord::StaleObjectError
+
+ +

Optimistic locking will also check for stale data when objects are destroyed. Example:

+ +
p1 = Person.find(1)
+p2 = Person.find(1)
+
+p1.first_name = "Michael"
+p1.save
+
+p2.destroy # Raises an ActiveRecord::StaleObjectError
+
+ +

You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging, or otherwise apply the business logic needed to resolve the conflict.

+ +

This locking mechanism will function inside a single Ruby process. To make it work across all web requests, the recommended approach is to add lock_version as a hidden field to your form.

+ +

This behavior can be turned off by setting ActiveRecord::Base.lock_optimistically = false. To override the name of the lock_version column, set the locking_column class attribute:

+ +
class Person < ActiveRecord::Base
+  self.locking_column = :lock_person
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Locking/Optimistic/ClassMethods.html b/src/5.2/classes/ActiveRecord/Locking/Optimistic/ClassMethods.html new file mode 100644 index 0000000000..245ff8c296 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Locking/Optimistic/ClassMethods.html @@ -0,0 +1,278 @@ +--- +title: ActiveRecord::Locking::Optimistic::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_LOCKING_COLUMN="lock_version"
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + locking_column() + +

+ + +
+

The version column used for optimistic locking. Defaults to lock_version.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/locking/optimistic.rb, line 142
+def locking_column
+  @locking_column = DEFAULT_LOCKING_COLUMN unless defined?(@locking_column)
+  @locking_column
+end
+
+
+ +
+ +
+

+ + locking_column=(value) + +

+ + +
+

Set the column to use for optimistic locking. Defaults to lock_version.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/locking/optimistic.rb, line 136
+def locking_column=(value)
+  reload_schema_from_cache
+  @locking_column = value.to_s
+end
+
+
+ +
+ +
+

+ + locking_enabled?() + +

+ + +
+

Returns true if the lock_optimistically flag is set to true (which it is, by default) and the table includes the locking_column column (defaults to lock_version).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/locking/optimistic.rb, line 131
+def locking_enabled?
+  lock_optimistically && columns_hash[locking_column]
+end
+
+
+ +
+ +
+

+ + reset_locking_column() + +

+ + +
+

Reset the column used for optimistic locking back to the lock_version default.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/locking/optimistic.rb, line 148
+def reset_locking_column
+  self.locking_column = DEFAULT_LOCKING_COLUMN
+end
+
+
+ +
+ +
+

+ + update_counters(id, counters) + +

+ + +
+

Make sure the lock version column gets updated when counters are updated.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/locking/optimistic.rb, line 154
+def update_counters(id, counters)
+  counters = counters.merge(locking_column => 1) if locking_enabled?
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Locking/Pessimistic.html b/src/5.2/classes/ActiveRecord/Locking/Pessimistic.html new file mode 100644 index 0000000000..731308aa40 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Locking/Pessimistic.html @@ -0,0 +1,213 @@ +--- +title: ActiveRecord::Locking::Pessimistic +layout: default +--- +
+ +
+
+ +
+ +

Locking::Pessimistic provides support for row-level locking using SELECT … FOR UPDATE and other lock types.

+ +

Chain ActiveRecord::Base#find to ActiveRecord::QueryMethods#lock to obtain an exclusive lock on the selected rows:

+ +
# select * from accounts where id=1 for update
+Account.lock.find(1)
+
+ +

Call lock('some locking clause') to use a database-specific locking clause of your own such as 'LOCK IN SHARE MODE' or 'FOR UPDATE NOWAIT'. Example:

+ +
Account.transaction do
+  # select * from accounts where name = 'shugo' limit 1 for update
+  shugo = Account.where("name = 'shugo'").lock(true).first
+  yuko = Account.where("name = 'yuko'").lock(true).first
+  shugo.balance -= 100
+  shugo.save!
+  yuko.balance += 100
+  yuko.save!
+end
+
+ +

You can also use ActiveRecord::Base#lock! method to lock one record by id. This may be better if you don't need to lock every row. Example:

+ +
Account.transaction do
+  # select * from accounts where ...
+  accounts = Account.where(...)
+  account1 = accounts.detect { |account| ... }
+  account2 = accounts.detect { |account| ... }
+  # select * from accounts where id=? for update
+  account1.lock!
+  account2.lock!
+  account1.balance -= 100
+  account1.save!
+  account2.balance += 100
+  account2.save!
+end
+
+ +

You can start a transaction and acquire the lock in one go by calling with_lock with a block. The block is called from within a transaction, the object is already locked. Example:

+ +
account = Account.first
+account.with_lock do
+  # This block is called within a transaction,
+  # account is already locked.
+  account.balance -= 100
+  account.save!
+end
+
+ +

Database-specific information on row locking:

+ +
MySQL: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
+PostgreSQL: https://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + lock!(lock = true) + +

+ + +
+

Obtain a row lock on this record. Reloads the record to obtain the requested lock. Pass an SQL locking clause to append the end of the SELECT statement or pass true for “FOR UPDATE” (the default, an exclusive row lock). Returns the locked record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/locking/pessimistic.rb, line 63
+      def lock!(lock = true)
+        if persisted?
+          if has_changes_to_save?
+            raise(<<-MSG.squish)
+              Locking a record with unpersisted changes is not supported. Use
+              `save` to persist the changes, or `reload` to discard them
+              explicitly.
+            MSG
+          end
+
+          reload(lock: lock)
+        end
+        self
+      end
+
+
+ +
+ +
+

+ + with_lock(lock = true) + +

+ + +
+

Wraps the passed block in a transaction, locking the object before yielding. You can pass the SQL locking clause as argument (see lock!).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/locking/pessimistic.rb, line 81
+def with_lock(lock = true)
+  transaction do
+    lock!(lock)
+    yield
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/LogSubscriber.html b/src/5.2/classes/ActiveRecord/LogSubscriber.html new file mode 100644 index 0000000000..170b5428ee --- /dev/null +++ b/src/5.2/classes/ActiveRecord/LogSubscriber.html @@ -0,0 +1,280 @@ +--- +title: ActiveRecord::LogSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
IGNORE_PAYLOAD_NAMES=["SCHEMA", "EXPLAIN"]
 
RAILS_GEM_ROOT=File.expand_path("../../..", __dir__) + "/"
 
+ + + + + + +

Class Public methods

+ +
+

+ + reset_runtime() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/log_subscriber.rb, line 15
+def self.reset_runtime
+  rt, self.runtime = runtime, 0
+  rt
+end
+
+
+ +
+ +
+

+ + runtime() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/log_subscriber.rb, line 11
+def self.runtime
+  ActiveRecord::RuntimeRegistry.sql_runtime ||= 0
+end
+
+
+ +
+ +
+

+ + runtime=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/log_subscriber.rb, line 7
+def self.runtime=(value)
+  ActiveRecord::RuntimeRegistry.sql_runtime = value
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + sql(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/log_subscriber.rb, line 20
+def sql(event)
+  self.class.runtime += event.duration
+  return unless logger.debug?
+
+  payload = event.payload
+
+  return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
+
+  name  = "#{payload[:name]} (#{event.duration.round(1)}ms)"
+  name  = "CACHE #{name}" if payload[:cached]
+  sql   = payload[:sql]
+  binds = nil
+
+  unless (payload[:binds] || []).empty?
+    casted_params = type_casted_binds(payload[:type_casted_binds])
+    binds = "  " + payload[:binds].zip(casted_params).map { |attr, value|
+      render_bind(attr, value)
+    }.inspect
+  end
+
+  name = colorize_payload_name(name, payload[:name])
+  sql  = color(sql, sql_color(sql), true)
+
+  debug "  #{name}  #{sql}#{binds}"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration.html b/src/5.2/classes/ActiveRecord/Migration.html new file mode 100644 index 0000000000..e446c6fc14 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration.html @@ -0,0 +1,1638 @@ +--- +title: ActiveRecord::Migration +layout: default +--- +
+ +
+
+ +
+ +

Active Record Migrations

+ +

Migrations can manage the evolution of a schema used by several physical databases. It's a solution to the common problem of adding a field to make a new feature work in your local database, but being unsure of how to push that change to other developers and to the production server. With migrations, you can describe the transformations in self-contained classes that can be checked into version control systems and executed against another database that might be one, two, or five versions behind.

+ +

Example of a simple migration:

+ +
class AddSsl < ActiveRecord::Migration[5.0]
+  def up
+    add_column :accounts, :ssl_enabled, :boolean, default: true
+  end
+
+  def down
+    remove_column :accounts, :ssl_enabled
+  end
+end
+
+ +

This migration will add a boolean flag to the accounts table and remove it if you're backing out of the migration. It shows how all migrations have two methods up and down that describes the transformations required to implement or remove the migration. These methods can consist of both the migration specific methods like add_column and remove_column, but may also contain regular Ruby code for generating data needed for the transformations.

+ +

Example of a more complex migration that also needs to initialize data:

+ +
class AddSystemSettings < ActiveRecord::Migration[5.0]
+  def up
+    create_table :system_settings do |t|
+      t.string  :name
+      t.string  :label
+      t.text    :value
+      t.string  :type
+      t.integer :position
+    end
+
+    SystemSetting.create  name:  'notice',
+                          label: 'Use notice?',
+                          value: 1
+  end
+
+  def down
+    drop_table :system_settings
+  end
+end
+
+ +

This migration first adds the system_settings table, then creates the very first row in it using the Active Record model that relies on the table. It also uses the more advanced create_table syntax where you can specify a complete table schema in one block call.

+ +

Available transformations

+ +

Creation

+
  • +

    create_join_table(table_1, table_2, options): Creates a join table having its name as the lexical order of the first two arguments. See ActiveRecord::ConnectionAdapters::SchemaStatements#create_join_table for details.

    +
  • +

    create_table(name, options): Creates a table called name and makes the table object available to a block that can then add columns to it, following the same format as add_column. See example above. The options hash is for fragments like “DEFAULT CHARSET=UTF-8” that are appended to the create table definition.

    +
  • +

    add_column(table_name, column_name, type, options): Adds a new column to the table called table_name named column_name specified to be one of the following types: :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean. A default value can be specified by passing an options hash like { default: 11 }. Other options include :limit and :null (e.g. { limit: 50, null: false }) – see ActiveRecord::ConnectionAdapters::TableDefinition#column for details.

    +
  • +

    add_foreign_key(from_table, to_table, options): Adds a new foreign key. from_table is the table with the key column, to_table contains the referenced primary key.

    +
  • +

    add_index(table_name, column_names, options): Adds a new index with the name of the column. Other options include :name, :unique (e.g. { name: 'users_name_index', unique: true }) and :order (e.g. { order: { name: :desc } }).

    +
  • +

    add_reference(:table_name, :reference_name): Adds a new column reference_name_id by default an integer. See ActiveRecord::ConnectionAdapters::SchemaStatements#add_reference for details.

    +
  • +

    add_timestamps(table_name, options): Adds timestamps (created_at and updated_at) columns to table_name.

    +
+ +

Modification

+
  • +

    change_column(table_name, column_name, type, options): Changes the column to a different type using the same parameters as add_column.

    +
  • +

    change_column_default(table_name, column_name, default_or_changes): Sets a default value for column_name defined by default_or_changes on table_name. Passing a hash containing :from and :to as default_or_changes will make this change reversible in the migration.

    +
  • +

    change_column_null(table_name, column_name, null, default = nil): Sets or removes a +NOT NULL+ constraint on column_name. The null flag indicates whether the value can be NULL. See ActiveRecord::ConnectionAdapters::SchemaStatements#change_column_null for details.

    +
  • +

    change_table(name, options): Allows to make column alterations to the table called name. It makes the table object available to a block that can then add/remove columns, indexes or foreign keys to it.

    +
  • +

    rename_column(table_name, column_name, new_column_name): Renames a column but keeps the type and content.

    +
  • +

    rename_index(table_name, old_name, new_name): Renames an index.

    +
  • +

    rename_table(old_name, new_name): Renames the table called old_name to new_name.

    +
+ +

Deletion

+
  • +

    drop_table(name): Drops the table called name.

    +
  • +

    drop_join_table(table_1, table_2, options): Drops the join table specified by the given arguments.

    +
  • +

    remove_column(table_name, column_name, type, options): Removes the column named column_name from the table called table_name.

    +
  • +

    remove_columns(table_name, *column_names): Removes the given columns from the table definition.

    +
  • +

    remove_foreign_key(from_table, options_or_to_table): Removes the given foreign key from the table called table_name.

    +
  • +

    remove_index(table_name, column: column_names): Removes the index specified by column_names.

    +
  • +

    remove_index(table_name, name: index_name): Removes the index specified by index_name.

    +
  • +

    remove_reference(table_name, ref_name, options): Removes the reference(s) on table_name specified by ref_name.

    +
  • +

    remove_timestamps(table_name, options): Removes the timestamp columns (created_at and updated_at) from the table definition.

    +
+ +

Irreversible transformations

+ +

Some transformations are destructive in a manner that cannot be reversed. Migrations of that kind should raise an ActiveRecord::IrreversibleMigration exception in their down method.

+ +

Running migrations from within Rails

+ +

The Rails package has several tools to help create and apply migrations.

+ +

To generate a new migration, you can use

+ +
rails generate migration MyNewMigration
+
+ +

where MyNewMigration is the name of your migration. The generator will create an empty migration file timestamp_my_new_migration.rb in the db/migrate/ directory where timestamp is the UTC formatted date and time that the migration was generated.

+ +

There is a special syntactic shortcut to generate migrations that add fields to a table.

+ +
rails generate migration add_fieldname_to_tablename fieldname:string
+
+ +

This will generate the file timestamp_add_fieldname_to_tablename.rb, which will look like this:

+ +
class AddFieldnameToTablename < ActiveRecord::Migration[5.0]
+  def change
+    add_column :tablenames, :fieldname, :string
+  end
+end
+
+ +

To run migrations against the currently configured database, use rails db:migrate. This will update the database by running all of the pending migrations, creating the schema_migrations table (see “About the schema_migrations table” section below) if missing. It will also invoke the db:schema:dump task, which will update your db/schema.rb file to match the structure of your database.

+ +

To roll the database back to a previous migration version, use rails db:rollback VERSION=X where X is the version to which you wish to downgrade. Alternatively, you can also use the STEP option if you wish to rollback last few migrations. rails db:rollback STEP=2 will rollback the latest two migrations.

+ +

If any of the migrations throw an ActiveRecord::IrreversibleMigration exception, that step will fail and you'll have some manual work to do.

+ +

Database support

+ +

Migrations are currently supported in MySQL, PostgreSQL, SQLite, SQL Server, and Oracle (all supported databases except DB2).

+ +

More examples

+ +

Not all migrations change the schema. Some just fix the data:

+ +
class RemoveEmptyTags < ActiveRecord::Migration[5.0]
+  def up
+    Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
+  end
+
+  def down
+    # not much we can do to restore deleted data
+    raise ActiveRecord::IrreversibleMigration, "Can't recover the deleted tags"
+  end
+end
+
+ +

Others remove columns when they migrate up instead of down:

+ +
class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[5.0]
+  def up
+    remove_column :items, :incomplete_items_count
+    remove_column :items, :completed_items_count
+  end
+
+  def down
+    add_column :items, :incomplete_items_count
+    add_column :items, :completed_items_count
+  end
+end
+
+ +

And sometimes you need to do something in SQL not abstracted directly by migrations:

+ +
class MakeJoinUnique < ActiveRecord::Migration[5.0]
+  def up
+    execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
+  end
+
+  def down
+    execute "ALTER TABLE `pages_linked_pages` DROP INDEX `page_id_linked_page_id`"
+  end
+end
+
+ +

Using a model after changing its table

+ +

Sometimes you'll want to add a column in a migration and populate it immediately after. In that case, you'll need to make a call to Base#reset_column_information in order to ensure that the model has the latest column data from after the new column was added. Example:

+ +
class AddPeopleSalary < ActiveRecord::Migration[5.0]
+  def up
+    add_column :people, :salary, :integer
+    Person.reset_column_information
+    Person.all.each do |p|
+      p.update_attribute :salary, SalaryCalculator.compute(p)
+    end
+  end
+end
+
+ +

Controlling verbosity

+ +

By default, migrations will describe the actions they are taking, writing them to the console as they happen, along with benchmarks describing how long each step took.

+ +

You can quiet them down by setting ActiveRecord::Migration.verbose = false.

+ +

You can also insert your own messages and benchmarks by using the say_with_time method:

+ +
def up
+  ...
+  say_with_time "Updating salaries..." do
+    Person.all.each do |p|
+      p.update_attribute :salary, SalaryCalculator.compute(p)
+    end
+  end
+  ...
+end
+
+ +

The phrase “Updating salaries…” would then be printed, along with the benchmark for the block when the block completes.

+ +

Timestamped Migrations

+ +

By default, Rails generates migrations that look like:

+ +
20080717013526_your_migration_name.rb
+
+ +

The prefix is a generation timestamp (in UTC).

+ +

If you'd prefer to use numeric prefixes, you can turn timestamped migrations off by setting:

+ +
config.active_record.timestamped_migrations = false
+
+ +

In application.rb.

+ +

Reversible Migrations

+ +

Reversible migrations are migrations that know how to go down for you. You simply supply the up logic, and the Migration system figures out how to execute the down commands for you.

+ +

To define a reversible migration, define the change method in your migration like this:

+ +
class TenderloveMigration < ActiveRecord::Migration[5.0]
+  def change
+    create_table(:horses) do |t|
+      t.column :content, :text
+      t.column :remind_at, :datetime
+    end
+  end
+end
+
+ +

This migration will create the horses table for you on the way up, and automatically figure out how to drop the table on the way down.

+ +

Some commands like remove_column cannot be reversed. If you care to define how to move up and down in these cases, you should define the up and down methods as before.

+ +

If a command cannot be reversed, an ActiveRecord::IrreversibleMigration exception will be raised when the migration is moving down.

+ +

For a list of commands that are reversible, please see ActiveRecord::Migration::CommandRecorder.

+ +

Transactional Migrations

+ +

If the database adapter supports DDL transactions, all migrations will automatically be wrapped in a transaction. There are queries that you can't execute inside a transaction though, and for these situations you can turn the automatic transactions off.

+ +
class ChangeEnum < ActiveRecord::Migration[5.0]
+  disable_ddl_transaction!
+
+  def up
+    execute "ALTER TYPE model_size ADD VALUE 'new_value'"
+  end
+end
+
+ +

Remember that you can still open your own transactions, even if you are in a Migration with self.disable_ddl_transaction!.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + name
+ [RW] + version
+ + + + +

Class Public methods

+ +
+

+ + [](version) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 535
+def self.[](version)
+  Compatibility.find(version)
+end
+
+
+ +
+ +
+

+ + check_pending!(connection = Base.connection) + +

+ + +
+

Raises ActiveRecord::PendingMigrationError error if any migrations are pending.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 578
+def check_pending!(connection = Base.connection)
+  raise ActiveRecord::PendingMigrationError if connection.migration_context.needs_migration?
+end
+
+
+ +
+ +
+

+ + current_version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 539
+def self.current_version
+  ActiveRecord::VERSION::STRING.to_f
+end
+
+
+ +
+ +
+

+ + disable_ddl_transaction!() + +

+ + +
+

Disable the transaction wrapping this migration. You can still create your own transactions even after calling disable_ddl_transaction!

+ +

For more details read the “Transactional Migrations” section above.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 615
+def disable_ddl_transaction!
+  @disable_ddl_transaction = true
+end
+
+
+ +
+ +
+

+ + load_schema_if_pending!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 582
+def load_schema_if_pending!
+  if Base.connection.migration_context.needs_migration? || !Base.connection.migration_context.any_migrations?
+    # Roundtrip to Rake to allow plugins to hook into database initialization.
+    root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
+    FileUtils.cd(root) do
+      current_config = Base.connection_config
+      Base.clear_all_connections!
+      system("bin/rails db:test:prepare")
+      # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
+      Base.establish_connection(current_config)
+    end
+    check_pending!
+  end
+end
+
+
+ +
+ +
+

+ + migrate(direction) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 607
+def migrate(direction)
+  new.migrate direction
+end
+
+
+ +
+ +
+

+ + new(name = self.class.name, version = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 627
+def initialize(name = self.class.name, version = nil)
+  @name       = name
+  @version    = version
+  @connection = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + announce(message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 827
+def announce(message)
+  text = "#{version} #{name}: #{message}"
+  length = [0, 75 - text.length].max
+  write "== %s %s" % [text, "=" * length]
+end
+
+
+ +
+ +
+

+ + connection() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 853
+def connection
+  @connection || ActiveRecord::Base.connection
+end
+
+
+ +
+ +
+

+ + copy(destination, sources, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 875
+def copy(destination, sources, options = {})
+  copied = []
+
+  FileUtils.mkdir_p(destination) unless File.exist?(destination)
+
+  destination_migrations = ActiveRecord::MigrationContext.new(destination).migrations
+  last = destination_migrations.last
+  sources.each do |scope, path|
+    source_migrations = ActiveRecord::MigrationContext.new(path).migrations
+
+    source_migrations.each do |migration|
+      source = File.binread(migration.filename)
+      inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
+      magic_comments = "".dup
+      loop do
+        # If we have a magic comment in the original migration,
+        # insert our comment after the first newline(end of the magic comment line)
+        # so the magic keep working.
+        # Note that magic comments must be at the first line(except sh-bang).
+        source.sub!(/\A(?:#.*\b(?:en)?coding:\s*\S+|#\s*frozen_string_literal:\s*(?:true|false)).*\n/) do |magic_comment|
+          magic_comments << magic_comment; ""
+        end || break
+      end
+      source = "#{magic_comments}#{inserted_comment}#{source}"
+
+      if duplicate = destination_migrations.detect { |m| m.name == migration.name }
+        if options[:on_skip] && duplicate.scope != scope.to_s
+          options[:on_skip].call(scope, migration)
+        end
+        next
+      end
+
+      migration.version = next_migration_number(last ? last.version + 1 : 0).to_i
+      new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.#{scope}.rb")
+      old_path, migration.filename = migration.filename, new_path
+      last = migration
+
+      File.binwrite(migration.filename, source)
+      copied << migration
+      options[:on_copy].call(scope, migration, old_path) if options[:on_copy]
+      destination_migrations << migration
+    end
+  end
+
+  copied
+end
+
+
+ +
+ +
+

+ + down() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 780
+def down
+  self.class.delegate = self
+  return unless self.class.respond_to?(:down)
+  self.class.down
+end
+
+
+ +
+ +
+

+ + exec_migration(conn, direction) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 808
+def exec_migration(conn, direction)
+  @connection = conn
+  if respond_to?(:change)
+    if direction == :down
+      revert { change }
+    else
+      change
+    end
+  else
+    send(direction)
+  end
+ensure
+  @connection = nil
+end
+
+
+ +
+ +
+

+ + method_missing(method, *arguments, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 857
+def method_missing(method, *arguments, &block)
+  arg_list = arguments.map(&:inspect) * ", "
+
+  say_with_time "#{method}(#{arg_list})" do
+    unless connection.respond_to? :revert
+      unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
+        arguments[0] = proper_table_name(arguments.first, table_name_options)
+        if [:rename_table, :add_foreign_key].include?(method) ||
+          (method == :remove_foreign_key && !arguments.second.is_a?(Hash))
+          arguments[1] = proper_table_name(arguments.second, table_name_options)
+        end
+      end
+    end
+    return super unless connection.respond_to?(method)
+    connection.send(method, *arguments, &block)
+  end
+end
+
+
+ +
+ +
+

+ + migrate(direction) + +

+ + +
+

Execute this migration in the named direction

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 787
+def migrate(direction)
+  return unless respond_to?(direction)
+
+  case direction
+  when :up   then announce "migrating"
+  when :down then announce "reverting"
+  end
+
+  time = nil
+  ActiveRecord::Base.connection_pool.with_connection do |conn|
+    time = Benchmark.measure do
+      exec_migration(conn, direction)
+    end
+  end
+
+  case direction
+  when :up   then announce "migrated (%.4fs)" % time.real; write
+  when :down then announce "reverted (%.4fs)" % time.real; write
+  end
+end
+
+
+ +
+ +
+

+ + next_migration_number(number) + +

+ + +
+

Determines the version number of the next migration.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 934
+def next_migration_number(number)
+  if ActiveRecord::Base.timestamped_migrations
+    [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
+  else
+    SchemaMigration.normalize_migration_number(number)
+  end
+end
+
+
+ +
+ +
+

+ + proper_table_name(name, options = {}) + +

+ + +
+

Finds the correct table name given an Active Record object. Uses the Active Record object's own table_name, or pre/suffix from the options passed in.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 925
+def proper_table_name(name, options = {})
+  if name.respond_to? :table_name
+    name.table_name
+  else
+    "#{options[:table_name_prefix]}#{name}#{options[:table_name_suffix]}"
+  end
+end
+
+
+ +
+ +
+

+ + reversible() + +

+ + +
+

Used to specify an operation that can be run in one direction or another. Call the methods up and down of the yielded object to run a block only in one given direction. The whole block will be called in the right order within the migration.

+ +

In the following example, the looping on users will always be done when the three columns 'first_name', 'last_name' and 'full_name' exist, even when migrating down:

+ +
class SplitNameMigration < ActiveRecord::Migration[5.0]
+  def change
+    add_column :users, :first_name, :string
+    add_column :users, :last_name, :string
+
+    reversible do |dir|
+      User.reset_column_information
+      User.all.each do |u|
+        dir.up   { u.first_name, u.last_name = u.full_name.split(' ') }
+        dir.down { u.full_name = "#{u.first_name} #{u.last_name}" }
+        u.save
+      end
+    end
+
+    revert { add_column :users, :full_name, :string }
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 733
+def reversible
+  helper = ReversibleBlockHelper.new(reverting?)
+  execute_block { yield helper }
+end
+
+
+ +
+ +
+

+ + revert(*migration_classes) + +

+ + +
+

Reverses the migration commands for the given block and the given migrations.

+ +

The following migration will remove the table 'horses' and create the table 'apples' on the way up, and the reverse on the way down.

+ +
class FixTLMigration < ActiveRecord::Migration[5.0]
+  def change
+    revert do
+      create_table(:horses) do |t|
+        t.text :content
+        t.datetime :remind_at
+      end
+    end
+    create_table(:apples) do |t|
+      t.string :variety
+    end
+  end
+end
+
+ +

Or equivalently, if TenderloveMigration is defined as in the documentation for Migration:

+ +
require_relative '20121212123456_tenderlove_migration'
+
+class FixupTLMigration < ActiveRecord::Migration[5.0]
+  def change
+    revert TenderloveMigration
+
+    create_table(:apples) do |t|
+      t.string :variety
+    end
+  end
+end
+
+ +

This command can be nested.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 674
+def revert(*migration_classes)
+  run(*migration_classes.reverse, revert: true) unless migration_classes.empty?
+  if block_given?
+    if connection.respond_to? :revert
+      connection.revert { yield }
+    else
+      recorder = CommandRecorder.new(connection)
+      @connection = recorder
+      suppress_messages do
+        connection.revert { yield }
+      end
+      @connection = recorder.delegate
+      recorder.commands.each do |cmd, args, block|
+        send(cmd, *args, &block)
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + reverting?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 693
+def reverting?
+  connection.respond_to?(:reverting) && connection.reverting
+end
+
+
+ +
+ +
+

+ + run(*migration_classes) + +

+ + +
+

Runs the given migration classes. Last argument can specify options:

+
  • +

    :direction (default is :up)

    +
  • +

    :revert (default is false)

    +
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 760
+def run(*migration_classes)
+  opts = migration_classes.extract_options!
+  dir = opts[:direction] || :up
+  dir = (dir == :down ? :up : :down) if opts[:revert]
+  if reverting?
+    # If in revert and going :up, say, we want to execute :down without reverting, so
+    revert { run(*migration_classes, direction: dir, revert: true) }
+  else
+    migration_classes.each do |migration_class|
+      migration_class.new.exec_migration(connection, dir)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + say(message, subitem = false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 833
+def say(message, subitem = false)
+  write "#{subitem ? "   ->" : "--"} #{message}"
+end
+
+
+ +
+ +
+

+ + say_with_time(message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 837
+def say_with_time(message)
+  say(message)
+  result = nil
+  time = Benchmark.measure { result = yield }
+  say "%.4fs" % time.real, :subitem
+  say("#{result} rows", :subitem) if result.is_a?(Integer)
+  result
+end
+
+
+ +
+ +
+

+ + suppress_messages() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 846
+def suppress_messages
+  save, self.verbose = verbose, false
+  yield
+ensure
+  self.verbose = save
+end
+
+
+ +
+ +
+

+ + up() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 774
+def up
+  self.class.delegate = self
+  return unless self.class.respond_to?(:up)
+  self.class.up
+end
+
+
+ +
+ +
+

+ + up_only() + +

+ + +
+

Used to specify an operation that is only run when migrating up (for example, populating a new column with its initial values).

+ +

In the following example, the new column published will be given the value true for all existing records.

+ +
class AddPublishedToPosts < ActiveRecord::Migration[5.2]
+  def change
+    add_column :posts, :published, :boolean, default: false
+    up_only do
+      execute "update posts set published = 'true'"
+    end
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 752
+def up_only
+  execute_block { yield } unless reverting?
+end
+
+
+ +
+ +
+

+ + write(text = "") + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 823
+def write(text = "")
+  puts(text) if verbose
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/CheckPending.html b/src/5.2/classes/ActiveRecord/Migration/CheckPending.html new file mode 100644 index 0000000000..676ef076d7 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/CheckPending.html @@ -0,0 +1,161 @@ +--- +title: ActiveRecord::Migration::CheckPending +layout: default +--- +
+ +
+
+ +
+ +

This class is used to verify that all migrations have been run before loading a web page if config.active_record.migration_error is set to :page_load

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 548
+def initialize(app)
+  @app = app
+  @last_check = 0
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration.rb, line 553
+def call(env)
+  mtime = ActiveRecord::Base.connection.migration_context.last_migration.mtime.to_i
+  if @last_check < mtime
+    ActiveRecord::Migration.check_pending!(connection)
+    @last_check = mtime
+  end
+  @app.call(env)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/CommandRecorder.html b/src/5.2/classes/ActiveRecord/Migration/CommandRecorder.html new file mode 100644 index 0000000000..e59c769571 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/CommandRecorder.html @@ -0,0 +1,366 @@ +--- +title: ActiveRecord::Migration::CommandRecorder +layout: default +--- +
+ +
+
+ +
+ +

ActiveRecord::Migration::CommandRecorder records commands done during a migration and knows how to reverse those commands. The CommandRecorder knows how to invert the following commands:

+
  • +

    add_column

    +
  • +

    add_foreign_key

    +
  • +

    add_index

    +
  • +

    add_reference

    +
  • +

    add_timestamps

    +
  • +

    change_column

    +
  • +

    change_column_default (must supply a :from and :to option)

    +
  • +

    change_column_null

    +
  • +

    create_join_table

    +
  • +

    create_table

    +
  • +

    disable_extension

    +
  • +

    drop_join_table

    +
  • +

    drop_table (must supply a block)

    +
  • +

    enable_extension

    +
  • +

    remove_column (must supply a type)

    +
  • +

    remove_columns (must specify at least one column name or more)

    +
  • +

    remove_foreign_key (must supply a second table)

    +
  • +

    remove_index

    +
  • +

    remove_reference

    +
  • +

    remove_timestamps

    +
  • +

    rename_column

    +
  • +

    rename_index

    +
  • +

    rename_table

    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ReversibleAndIrreversibleMethods=[:create_table, :create_join_table, :rename_table, :add_column, :remove_column, +:rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps, +:change_column_default, :add_reference, :remove_reference, :transaction, +:drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension, +:change_column, :execute, :remove_columns, :change_column_null, +:add_foreign_key, :remove_foreign_key +]
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [RW] + commands
+ [RW] + delegate
+ [RW] + reverting
+ + + + +

Class Public methods

+ +
+

+ + new(delegate = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration/command_recorder.rb, line 44
+def initialize(delegate = nil)
+  @commands = []
+  @delegate = delegate
+  @reverting = false
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + inverse_of(command, args, &block) + +

+ + +
+

Returns the inverse of the given command. For example:

+ +
recorder.inverse_of(:rename_table, [:old, :new])
+# => [:rename_table, [:new, :old]]
+
+ +

This method will raise an IrreversibleMigration exception if it cannot invert the command.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration/command_recorder.rb, line 86
+      def inverse_of(command, args, &block)
+        method = :"invert_#{command}"
+        raise IrreversibleMigration, <<-MSG.strip_heredoc unless respond_to?(method, true)
+          This migration uses #{command}, which is not automatically reversible.
+          To make the migration reversible you can either:
+          1. Define #up and #down methods in place of the #change method.
+          2. Use the #reversible method to define reversible behavior.
+        MSG
+        send(method, args, &block)
+      end
+
+
+ +
+ +
+

+ + record(*command, &block) + +

+ + +
+

Record command. command should be a method name and arguments. For example:

+ +
recorder.record(:method_name, [:arg1, :arg2])
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration/command_recorder.rb, line 71
+def record(*command, &block)
+  if @reverting
+    @commands << inverse_of(*command, &block)
+  else
+    @commands << (command << block)
+  end
+end
+
+
+ +
+ +
+

+ + revert() + +

+ + +
+

While executing the given block, the recorded will be in reverting mode. All commands recorded will end up being recorded reverted and in reverse order. For example:

+ +
recorder.revert{ recorder.record(:rename_table, [:old, :new]) }
+# same effect as recorder.record(:rename_table, [:new, :old])
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/migration/command_recorder.rb, line 57
+def revert
+  @reverting = !@reverting
+  previous = @commands
+  @commands = []
+  yield
+ensure
+  @commands = previous.concat(@commands.reverse)
+  @reverting = !@reverting
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/Compatibility.html b/src/5.2/classes/ActiveRecord/Migration/Compatibility.html new file mode 100644 index 0000000000..c77dc0444b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/Compatibility.html @@ -0,0 +1,71 @@ +--- +title: ActiveRecord::Migration::Compatibility +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2.html b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2.html new file mode 100644 index 0000000000..2aeefaad40 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Migration::Compatibility::V4_2 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2/TableDefinition.html b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2/TableDefinition.html new file mode 100644 index 0000000000..4628f011e2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V4_2/TableDefinition.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V4_2::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0.html b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0.html new file mode 100644 index 0000000000..42e6cffdf5 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Migration::Compatibility::V5_0 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0/TableDefinition.html b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0/TableDefinition.html new file mode 100644 index 0000000000..9221a72d65 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_0/TableDefinition.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V5_0::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_1.html b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_1.html new file mode 100644 index 0000000000..9896a77380 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Migration/Compatibility/V5_1.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Migration::Compatibility::V5_1 +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/MismatchedForeignKey.html b/src/5.2/classes/ActiveRecord/MismatchedForeignKey.html new file mode 100644 index 0000000000..48767f6457 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/MismatchedForeignKey.html @@ -0,0 +1,140 @@ +--- +title: ActiveRecord::MismatchedForeignKey +layout: default +--- +
+ +
+
+ +
+ +

Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new( adapter = nil, message: nil, sql: nil, binds: nil, table: nil, foreign_key: nil, target_table: nil, primary_key: nil, primary_key_column: nil ) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 120
+    def initialize(
+      adapter = nil,
+      message: nil,
+      sql: nil,
+      binds: nil,
+      table: nil,
+      foreign_key: nil,
+      target_table: nil,
+      primary_key: nil,
+      primary_key_column: nil
+    )
+      if table
+        type = primary_key_column.bigint? ? :bigint : primary_key_column.type
+        msg = <<-EOM.squish
+          Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
+          which has type `#{primary_key_column.sql_type}`.
+          To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
+          (For example `t.#{type} :#{foreign_key}`).
+        EOM
+      else
+        msg = <<-EOM.squish
+          There is a mismatch between the foreign key and primary key column types.
+          Verify that the foreign key column type and the primary key of the associated table match types.
+        EOM
+      end
+      if message
+        msg << "\nOriginal message: #{message}"
+      end
+      super(msg)
+    end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ModelSchema.html b/src/5.2/classes/ActiveRecord/ModelSchema.html new file mode 100644 index 0000000000..6b3d7ca467 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ModelSchema.html @@ -0,0 +1,551 @@ +--- +title: ActiveRecord::ModelSchema +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + internal_metadata_table_name + + +

+ + +
+

The name of the internal metadata table. By default, the value is "ar_internal_metadata".

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 78
+    
+
+
+ +
+ +
+

+ + internal_metadata_table_name=(table_name) + + +

+ + +
+

Sets the name of the internal metadata table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 84
+    
+
+
+ +
+ +
+

+ + pluralize_table_names + + +

+ + +
+

Indicates whether table names should be the pluralized versions of the corresponding class names. If true, the default table name for a Product class will be “products”. If false, it would just be “product”. See table_name for the full rules on table/class naming. This is true, by default.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 90
+    
+
+
+ +
+ +
+

+ + pluralize_table_names=(value) + + +

+ + +
+

Set whether table names should be the pluralized versions of the corresponding class names. If true, the default table name for a Product class will be “products”. If false, it would just be “product”. See table_name for the full rules on table/class naming. This is true, by default.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 105
+included do
+  mattr_accessor :primary_key_prefix_type, instance_writer: false
+
+  class_attribute :table_name_prefix, instance_writer: false, default: ""
+  class_attribute :table_name_suffix, instance_writer: false, default: ""
+  class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
+  class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
+  class_attribute :pluralize_table_names, instance_writer: false, default: true
+
+  self.protected_environments = ["production"]
+  self.inheritance_column = "type"
+  self.ignored_columns = [].freeze
+
+  delegate :type_for_attribute, to: :class
+
+  initialize_load_schema_monitor
+end
+
+
+ +
+ +
+

+ + primary_key_prefix_type + + +

+ + +
+

The prefix type that will be prepended to every primary key column name. The options are :table_name and :table_name_with_underscore. If the first is specified, the Product class will look for “productid” instead of “id” as the primary column. If the latter is specified, the Product class will look for “product_id” instead of “id”. Remember that this is a global setting for all Active Records.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 10
+    
+
+
+ +
+ +
+

+ + primary_key_prefix_type=(prefix_type) + + +

+ + +
+

Sets the prefix type that will be prepended to every primary key column name. The options are :table_name and :table_name_with_underscore. If the first is specified, the Product class will look for “productid” instead of “id” as the primary column. If the latter is specified, the Product class will look for “product_id” instead of “id”. Remember that this is a global setting for all Active Records.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 20
+    
+
+
+ +
+ +
+

+ + schema_migrations_table_name + + +

+ + +
+

The name of the schema migrations table. By default, the value is "schema_migrations".

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 66
+    
+
+
+ +
+ +
+

+ + schema_migrations_table_name=(table_name) + + +

+ + +
+

Sets the name of the schema migrations table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 72
+    
+
+
+ +
+ +
+

+ + table_name_prefix + + +

+ + +
+

The prefix string to prepend to every table name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 30
+    
+
+
+ +
+ +
+

+ + table_name_prefix=(prefix) + + +

+ + +
+

Sets the prefix string to prepend to every table name. So if set to “basecamp_”, all table names will be named like “basecamp_projects”, “basecamp_people”, etc. This is a convenient way of creating a namespace for tables in a shared database. By default, the prefix is the empty string.

+ +

If you are organising your models within modules you can add a prefix to the models within a namespace by defining a singleton method in the parent module called table_name_prefix which returns your chosen prefix.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 36
+    
+
+
+ +
+ +
+

+ + table_name_suffix + + +

+ + +
+

The suffix string to append to every table name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 49
+    
+
+
+ +
+ +
+

+ + table_name_suffix=(suffix) + + +

+ + +
+

Works like table_name_prefix=, but appends instead of prepends (set to “_basecamp” gives “projects_basecamp”, “people_basecamp”). By default, the suffix is the empty string.

+ +

If you are organising your models within modules, you can add a suffix to the models within a namespace by defining a singleton method in the parent module called table_name_suffix which returns your chosen suffix.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 55
+    
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ModelSchema/ClassMethods.html b/src/5.2/classes/ActiveRecord/ModelSchema/ClassMethods.html new file mode 100644 index 0000000000..ac45d9612c --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ModelSchema/ClassMethods.html @@ -0,0 +1,1009 @@ +--- +title: ActiveRecord::ModelSchema::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + column_defaults() + +

+ + +
+

Returns a hash where the keys are column names and the values are default values when instantiating the Active Record object for this table.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 376
+def column_defaults
+  load_schema
+  @column_defaults ||= _default_attributes.deep_dup.to_hash
+end
+
+
+ +
+ +
+

+ + column_names() + +

+ + +
+

Returns an array of column names as strings.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 387
+def column_names
+  @column_names ||= columns.map(&:name)
+end
+
+
+ +
+ +
+

+ + columns() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 340
+def columns
+  load_schema
+  @columns ||= columns_hash.values
+end
+
+
+ +
+ +
+

+ + content_columns() + +

+ + +
+

Returns an array of column objects where the primary id, all columns ending in “_id” or “_count”, and columns used for single table inheritance have been removed.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 393
+def content_columns
+  @content_columns ||= columns.reject do |c|
+    c.name == primary_key ||
+    c.name == inheritance_column ||
+    c.name.end_with?("_id") ||
+    c.name.end_with?("_count")
+  end
+end
+
+
+ +
+ +
+

+ + ignored_columns() + +

+ + +
+

The list of columns names the model should ignore. Ignored columns won't have attribute accessors defined, and won't be referenced in SQL queries.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 264
+def ignored_columns
+  if defined?(@ignored_columns)
+    @ignored_columns
+  else
+    superclass.ignored_columns
+  end
+end
+
+
+ +
+ +
+

+ + ignored_columns=(columns) + +

+ + +
+

Sets the columns names the model should ignore. Ignored columns won't have attribute accessors defined, and won't be referenced in SQL queries.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 274
+def ignored_columns=(columns)
+  @ignored_columns = columns.map(&:to_s)
+end
+
+
+ +
+ +
+

+ + inheritance_column() + +

+ + +
+

Defines the name of the table column which will store the class name on single-table inheritance situations.

+ +

The default inheritance column name is type, which means it's a reserved word inside Active Record. To be able to use single-table inheritance with another column name, or to use the column type in your own model for something else, you can set inheritance_column:

+ +
self.inheritance_column = 'zoink'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 252
+def inheritance_column
+  (@inheritance_column ||= nil) || superclass.inheritance_column
+end
+
+
+ +
+ +
+

+ + inheritance_column=(value) + +

+ + +
+

Sets the value of inheritance_column

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 257
+def inheritance_column=(value)
+  @inheritance_column = value.to_s
+  @explicit_inheritance_column = true
+end
+
+
+ +
+ +
+

+ + next_sequence_value() + +

+ + +
+

Returns the next value that will be used as the primary key on an insert statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 318
+def next_sequence_value
+  connection.next_sequence_value(sequence_name)
+end
+
+
+ +
+ +
+

+ + prefetch_primary_key?() + +

+ + +
+

Determines if the primary key values should be selected from their corresponding sequence before the insert statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 312
+def prefetch_primary_key?
+  connection.prefetch_primary_key?(table_name)
+end
+
+
+ +
+ +
+

+ + protected_environments() + +

+ + +
+

The array of names of environments where destructive actions should be prohibited. By default, the value is ["production"].

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 230
+def protected_environments
+  if defined?(@protected_environments)
+    @protected_environments
+  else
+    superclass.protected_environments
+  end
+end
+
+
+ +
+ +
+

+ + protected_environments=(environments) + +

+ + +
+

Sets an array of names of environments where destructive actions should be prohibited.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 239
+def protected_environments=(environments)
+  @protected_environments = environments.map(&:to_s)
+end
+
+
+ +
+ +
+

+ + quoted_table_name() + +

+ + +
+

Returns a quoted version of the table name, used to construct SQL statements.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 205
+def quoted_table_name
+  @quoted_table_name ||= connection.quote_table_name(table_name)
+end
+
+
+ +
+ +
+

+ + reset_column_information() + +

+ + +
+

Resets all the cached information about columns, which will cause them to be reloaded on the next request.

+ +

The most common usage pattern for this method is probably in a migration, when just after creating a table you want to populate it with some default values, eg:

+ +
class CreateJobLevels < ActiveRecord::Migration[5.0]
+  def up
+    create_table :job_levels do |t|
+      t.integer :id
+      t.string :name
+
+      t.timestamps
+    end
+
+    JobLevel.reset_column_information
+    %w{assistant executive manager director}.each do |type|
+      JobLevel.create(name: type)
+    end
+  end
+
+  def down
+    drop_table :job_levels
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 428
+def reset_column_information
+  connection.clear_cache!
+  ([self] + descendants).each(&:undefine_attribute_methods)
+  connection.schema_cache.clear_data_source_cache!(table_name)
+
+  reload_schema_from_cache
+  initialize_find_by_cache
+end
+
+
+ +
+ +
+

+ + sequence_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 278
+def sequence_name
+  if base_class == self
+    @sequence_name ||= reset_sequence_name
+  else
+    (@sequence_name ||= nil) || base_class.sequence_name
+  end
+end
+
+
+ +
+ +
+

+ + sequence_name=(value) + +

+ + +
+

Sets the name of the sequence to use when generating ids to the given value, or (if the value is nil or false) to the value returned by the given block. This is required for Oracle and is useful for any database which relies on sequences for primary key generation.

+ +

If a sequence name is not explicitly set when using Oracle, it will default to the commonly used pattern of: #{table_name}_seq

+ +

If a sequence name is not explicitly set when using PostgreSQL, it will discover the sequence corresponding to your primary key for you.

+ +
class Project < ActiveRecord::Base
+  self.sequence_name = "projectseq"   # default would have been "project_seq"
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 305
+def sequence_name=(value)
+  @sequence_name          = value.to_s
+  @explicit_sequence_name = true
+end
+
+
+ +
+ +
+

+ + table_exists?() + +

+ + +
+

Indicates whether the table associated with this class exists

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 323
+def table_exists?
+  connection.schema_cache.data_source_exists?(table_name)
+end
+
+
+ +
+ +
+

+ + table_name() + +

+ + +
+

Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy looks like: Reply < Message < ActiveRecord::Base, then Message is used to guess the table name even when called on Reply. The rules used to do the guess are handled by the Inflector class in Active Support, which knows almost all common English inflections. You can add new inflections in config/initializers/inflections.rb.

+ +

Nested classes are given table names prefixed by the singular form of the parent's table name. Enclosing modules are not considered.

+ +

Examples

+ +
class Invoice < ActiveRecord::Base
+end
+
+file                  class               table_name
+invoice.rb            Invoice             invoices
+
+class Invoice < ActiveRecord::Base
+  class Lineitem < ActiveRecord::Base
+  end
+end
+
+file                  class               table_name
+invoice.rb            Invoice::Lineitem   invoice_lineitems
+
+module Invoice
+  class Lineitem < ActiveRecord::Base
+  end
+end
+
+file                  class               table_name
+invoice/lineitem.rb   Invoice::Lineitem   lineitems
+
+ +

Additionally, the class-level table_name_prefix is prepended and the table_name_suffix is appended. So if you have “myapp_” as a prefix, the table name guess for an Invoice class becomes “myapp_invoices”. Invoice::Lineitem becomes “myapp_invoice_lineitems”.

+ +

You can also set your own table name explicitly:

+ +
class Mouse < ActiveRecord::Base
+  self.table_name = "mice"
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 179
+def table_name
+  reset_table_name unless defined?(@table_name)
+  @table_name
+end
+
+
+ +
+ +
+

+ + table_name=(value) + +

+ + +
+

Sets the table name explicitly. Example:

+ +
class Project < ActiveRecord::Base
+  self.table_name = "project"
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 189
+def table_name=(value)
+  value = value && value.to_s
+
+  if defined?(@table_name)
+    return if value == @table_name
+    reset_column_information if connected?
+  end
+
+  @table_name        = value
+  @quoted_table_name = nil
+  @arel_table        = nil
+  @sequence_name     = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name
+  @predicate_builder = nil
+end
+
+
+ +
+ +
+

+ + type_for_attribute(attr_name, &block) + +

+ + +
+

Returns the type of the attribute with the given name, after applying all modifiers. This method is the only valid source of information for anything related to the types of a model's attributes. This method will access the database and load the model's schema if it is required.

+ +

The return value of this method will implement the interface described by ActiveModel::Type::Value (though the object itself may not subclass it).

+ +

attr_name The name of the attribute to retrieve the type for. Must be a string or a symbol.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 365
+def type_for_attribute(attr_name, &block)
+  attr_name = attr_name.to_s
+  if block
+    attribute_types.fetch(attr_name, &block)
+  else
+    attribute_types[attr_name]
+  end
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + initialize_load_schema_monitor() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/model_schema.rb, line 439
+def initialize_load_schema_monitor
+  @load_schema_monitor = Monitor.new
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/MultiparameterAssignmentErrors.html b/src/5.2/classes/ActiveRecord/MultiparameterAssignmentErrors.html new file mode 100644 index 0000000000..f58a22a582 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/MultiparameterAssignmentErrors.html @@ -0,0 +1,127 @@ +--- +title: ActiveRecord::MultiparameterAssignmentErrors +layout: default +--- +
+ +
+
+ +
+ +

Raised when there are multiple errors while doing a mass assignment through the ActiveRecord::Base#attributes= method. The exception has an errors property that contains an array of AttributeAssignmentError objects, each corresponding to the error while assigning to an attribute.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + errors
+ + + + +

Class Public methods

+ +
+

+ + new(errors = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 274
+def initialize(errors = nil)
+  @errors = errors
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/NestedAttributes.html b/src/5.2/classes/ActiveRecord/NestedAttributes.html new file mode 100644 index 0000000000..fd2103a7a8 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/NestedAttributes.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::NestedAttributes +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/NestedAttributes/ClassMethods.html b/src/5.2/classes/ActiveRecord/NestedAttributes/ClassMethods.html new file mode 100644 index 0000000000..fdb5163e6d --- /dev/null +++ b/src/5.2/classes/ActiveRecord/NestedAttributes/ClassMethods.html @@ -0,0 +1,406 @@ +--- +title: ActiveRecord::NestedAttributes::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Nested Attributes

+ +

Nested attributes allow you to save attributes on associated records through the parent. By default nested attribute updating is turned off and you can enable it using the accepts_nested_attributes_for class method. When you enable nested attributes an attribute writer is defined on the model.

+ +

The attribute writer is named after the association, which means that in the following example, two new methods are added to your model:

+ +

author_attributes=(attributes) and pages_attributes=(attributes).

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

Note that the :autosave option is automatically enabled on every association that accepts_nested_attributes_for is used for.

+ +

One-to-one

+ +

Consider a Member model that has one Avatar:

+ +
class Member < ActiveRecord::Base
+  has_one :avatar
+  accepts_nested_attributes_for :avatar
+end
+
+ +

Enabling nested attributes on a one-to-one association allows you to create the member and avatar in one go:

+ +
params = { member: { name: 'Jack', avatar_attributes: { icon: 'smiling' } } }
+member = Member.create(params[:member])
+member.avatar.id # => 2
+member.avatar.icon # => 'smiling'
+
+ +

It also allows you to update the avatar through the member:

+ +
params = { member: { avatar_attributes: { id: '2', icon: 'sad' } } }
+member.update params[:member]
+member.avatar.icon # => 'sad'
+
+ +

If you want to update the current avatar without providing the id, you must add :update_only option.

+ +
class Member < ActiveRecord::Base
+  has_one :avatar
+  accepts_nested_attributes_for :avatar, update_only: true
+end
+
+params = { member: { avatar_attributes: { icon: 'sad' } } }
+member.update params[:member]
+member.avatar.id # => 2
+member.avatar.icon # => 'sad'
+
+ +

By default you will only be able to set and update attributes on the associated model. If you want to destroy the associated model through the attributes hash, you have to enable it first using the :allow_destroy option.

+ +
class Member < ActiveRecord::Base
+  has_one :avatar
+  accepts_nested_attributes_for :avatar, allow_destroy: true
+end
+
+ +

Now, when you add the _destroy key to the attributes hash, with a value that evaluates to true, you will destroy the associated model:

+ +
member.avatar_attributes = { id: '2', _destroy: '1' }
+member.avatar.marked_for_destruction? # => true
+member.save
+member.reload.avatar # => nil
+
+ +

Note that the model will not be destroyed until the parent is saved.

+ +

Also note that the model will not be destroyed unless you also specify its id in the updated hash.

+ +

One-to-many

+ +

Consider a member that has a number of posts:

+ +
class Member < ActiveRecord::Base
+  has_many :posts
+  accepts_nested_attributes_for :posts
+end
+
+ +

You can now set or update attributes on the associated posts through an attribute hash for a member: include the key :posts_attributes with an array of hashes of post attributes as a value.

+ +

For each hash that does not have an id key a new record will be instantiated, unless the hash also contains a _destroy key that evaluates to true.

+ +
params = { member: {
+  name: 'joe', posts_attributes: [
+    { title: 'Kari, the awesome Ruby documentation browser!' },
+    { title: 'The egalitarian assumption of the modern citizen' },
+    { title: '', _destroy: '1' } # this will be ignored
+  ]
+}}
+
+member = Member.create(params[:member])
+member.posts.length # => 2
+member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
+member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
+
+ +

You may also set a :reject_if proc to silently ignore any new record hashes if they fail to pass your criteria. For example, the previous example could be rewritten as:

+ +
class Member < ActiveRecord::Base
+  has_many :posts
+  accepts_nested_attributes_for :posts, reject_if: proc { |attributes| attributes['title'].blank? }
+end
+
+params = { member: {
+  name: 'joe', posts_attributes: [
+    { title: 'Kari, the awesome Ruby documentation browser!' },
+    { title: 'The egalitarian assumption of the modern citizen' },
+    { title: '' } # this will be ignored because of the :reject_if proc
+  ]
+}}
+
+member = Member.create(params[:member])
+member.posts.length # => 2
+member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
+member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
+
+ +

Alternatively, :reject_if also accepts a symbol for using methods:

+ +
class Member < ActiveRecord::Base
+  has_many :posts
+  accepts_nested_attributes_for :posts, reject_if: :new_record?
+end
+
+class Member < ActiveRecord::Base
+  has_many :posts
+  accepts_nested_attributes_for :posts, reject_if: :reject_posts
+
+  def reject_posts(attributes)
+    attributes['title'].blank?
+  end
+end
+
+ +

If the hash contains an id key that matches an already associated record, the matching record will be modified:

+ +
member.attributes = {
+  name: 'Joe',
+  posts_attributes: [
+    { id: 1, title: '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' },
+    { id: 2, title: '[UPDATED] other post' }
+  ]
+}
+
+member.posts.first.title # => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!'
+member.posts.second.title # => '[UPDATED] other post'
+
+ +

However, the above applies if the parent model is being updated as well. For example, If you wanted to create a member named joe and wanted to update the posts at the same time, that would give an ActiveRecord::RecordNotFound error.

+ +

By default the associated records are protected from being destroyed. If you want to destroy any of the associated records through the attributes hash, you have to enable it first using the :allow_destroy option. This will allow you to also use the _destroy key to destroy existing records:

+ +
class Member < ActiveRecord::Base
+  has_many :posts
+  accepts_nested_attributes_for :posts, allow_destroy: true
+end
+
+params = { member: {
+  posts_attributes: [{ id: '2', _destroy: '1' }]
+}}
+
+member.attributes = params[:member]
+member.posts.detect { |p| p.id == 2 }.marked_for_destruction? # => true
+member.posts.length # => 2
+member.save
+member.reload.posts.length # => 1
+
+ +

Nested attributes for an associated collection can also be passed in the form of a hash of hashes instead of an array of hashes:

+ +
Member.create(
+  name: 'joe',
+  posts_attributes: {
+    first:  { title: 'Foo' },
+    second: { title: 'Bar' }
+  }
+)
+
+ +

has the same effect as

+ +
Member.create(
+  name: 'joe',
+  posts_attributes: [
+    { title: 'Foo' },
+    { title: 'Bar' }
+  ]
+)
+
+ +

The keys of the hash which is the value for :posts_attributes are ignored in this case. However, it is not allowed to use 'id' or :id for one of such keys, otherwise the hash will be wrapped in an array and interpreted as an attribute hash for a single post.

+ +

Passing attributes for an associated collection in the form of a hash of hashes can be used with hashes generated from HTTP/HTML parameters, where there may be no natural way to submit an array of hashes.

+ +

Saving

+ +

All changes to models, including the destruction of those marked for destruction, are saved and destroyed automatically and atomically when the parent model is saved. This happens inside the transaction initiated by the parent's save method. See ActiveRecord::AutosaveAssociation.

+ +

Validating the presence of a parent model

+ +

If you want to validate that a child record is associated with a parent record, you can use the validates_presence_of method and the :inverse_of key as this example illustrates:

+ +
class Member < ActiveRecord::Base
+  has_many :posts, inverse_of: :member
+  accepts_nested_attributes_for :posts
+end
+
+class Post < ActiveRecord::Base
+  belongs_to :member, inverse_of: :posts
+  validates_presence_of :member
+end
+
+ +

Note that if you do not specify the :inverse_of option, then Active Record will try to automatically guess the inverse association based on heuristics.

+ +

For one-to-one nested associations, if you build the new (in-memory) child object yourself before assignment, then this module will not overwrite it, e.g.:

+ +
class Member < ActiveRecord::Base
+  has_one :avatar
+  accepts_nested_attributes_for :avatar
+
+  def avatar
+    super || build_avatar(width: 200)
+  end
+end
+
+member = Member.new
+member.avatar_attributes = {icon: 'sad'}
+member.avatar.width # => 200
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
REJECT_ALL_BLANK_PROC=proc { |attributes| attributes.all? { |key, value| key == "_destroy" || value.blank? } }
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + accepts_nested_attributes_for(*attr_names) + +

+ + +
+

Defines an attributes writer for the specified association(s).

+ +

Supported options:

+
:allow_destroy +
+

If true, destroys any members from the attributes hash with a _destroy key and a value that evaluates to true (eg. 1, '1', true, or 'true'). This option is off by default.

+
:reject_if +
+

Allows you to specify a Proc or a Symbol pointing to a method that checks whether a record should be built for a certain attribute hash. The hash is passed to the supplied Proc or the method and it should return either true or false. When no :reject_if is specified, a record will be built for all attribute hashes that do not have a _destroy value that evaluates to true. Passing :all_blank instead of a Proc will create a proc that will reject a record where all the attributes are blank excluding any value for _destroy.

+
:limit +
+

Allows you to specify the maximum number of associated records that can be processed with the nested attributes. Limit also can be specified as a Proc or a Symbol pointing to a method that should return a number. If the size of the nested attributes array exceeds the specified limit, NestedAttributes::TooManyRecords exception is raised. If omitted, any number of associations can be processed. Note that the :limit option is only applicable to one-to-many associations.

+
:update_only +
+

For a one-to-one association, this option allows you to specify how nested attributes are going to be used when an associated record already exists. In general, an existing record may either be updated with the new set of attribute values or be replaced by a wholly new record containing those values. By default the :update_only option is false and the nested attributes are used to update the existing record only if they include the record's :id value. Otherwise a new record will be instantiated and used to replace the existing one. However if the :update_only option is true, the nested attributes are used to update the record's attributes always, regardless of whether the :id is present. The option is ignored for collection associations.

+
+ +

Examples:

+ +
# creates avatar_attributes=
+accepts_nested_attributes_for :avatar, reject_if: proc { |attributes| attributes['name'].blank? }
+# creates avatar_attributes=
+accepts_nested_attributes_for :avatar, reject_if: :all_blank
+# creates avatar_attributes= and posts_attributes=
+accepts_nested_attributes_for :avatar, :posts, allow_destroy: true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/nested_attributes.rb, line 333
+def accepts_nested_attributes_for(*attr_names)
+  options = { allow_destroy: false, update_only: false }
+  options.update(attr_names.extract_options!)
+  options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
+  options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
+
+  attr_names.each do |association_name|
+    if reflection = _reflect_on_association(association_name)
+      reflection.autosave = true
+      define_autosave_validation_callbacks(reflection)
+
+      nested_attributes_options = self.nested_attributes_options.dup
+      nested_attributes_options[association_name.to_sym] = options
+      self.nested_attributes_options = nested_attributes_options
+
+      type = (reflection.collection? ? :collection : :one_to_one)
+      generate_association_writer(association_name, type)
+    else
+      raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/NestedAttributes/TooManyRecords.html b/src/5.2/classes/ActiveRecord/NestedAttributes/TooManyRecords.html new file mode 100644 index 0000000000..d0c406aa04 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/NestedAttributes/TooManyRecords.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::NestedAttributes::TooManyRecords +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/NoDatabaseError.html b/src/5.2/classes/ActiveRecord/NoDatabaseError.html new file mode 100644 index 0000000000..bd6d659314 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/NoDatabaseError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::NoDatabaseError +layout: default +--- +
+ +
+
+ +
+ +

Raised when a given database does not exist.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/NoTouching.html b/src/5.2/classes/ActiveRecord/NoTouching.html new file mode 100644 index 0000000000..0b84715681 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/NoTouching.html @@ -0,0 +1,120 @@ +--- +title: ActiveRecord::NoTouching +layout: default +--- +
+ +
+
+ +
+ +

Active Record No Touching

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + no_touching?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/no_touching.rb, line 46
+def no_touching?
+  NoTouching.applied_to?(self.class)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/NoTouching/ClassMethods.html b/src/5.2/classes/ActiveRecord/NoTouching/ClassMethods.html new file mode 100644 index 0000000000..52c9380031 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/NoTouching/ClassMethods.html @@ -0,0 +1,114 @@ +--- +title: ActiveRecord::NoTouching::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + no_touching(&block) + +

+ + +
+

Lets you selectively disable calls to touch for the duration of a block.

+ +

Examples

+ +
ActiveRecord::Base.no_touching do
+  Project.first.touch  # does nothing
+  Message.first.touch  # does nothing
+end
+
+Project.no_touching do
+  Project.first.touch  # does nothing
+  Message.first.touch  # works, but does not touch the associated project
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/no_touching.rb, line 23
+def no_touching(&block)
+  NoTouching.apply_to(self, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/NotNullViolation.html b/src/5.2/classes/ActiveRecord/NotNullViolation.html new file mode 100644 index 0000000000..5b6b5f1a80 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/NotNullViolation.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::NotNullViolation +layout: default +--- +
+ +
+
+ +
+ +

Raised when a record cannot be inserted or updated because it would violate a not null constraint.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Persistence.html b/src/5.2/classes/ActiveRecord/Persistence.html new file mode 100644 index 0000000000..e8379b288a --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Persistence.html @@ -0,0 +1,1283 @@ +--- +title: ActiveRecord::Persistence +layout: default +--- +
+ +
+
+ +
+ +

Active Record Persistence

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + becomes(klass) + +

+ + +
+

Returns an instance of the specified klass with the attributes of the current record. This is mostly useful in relation to single-table inheritance structures where you want a subclass to appear as the superclass. This can be used along with record identification in Action Pack to allow, say, Client < Company to do something like render partial: @client.becomes(Company) to render that instance using the companies/company partial instead of clients/client.

+ +

Note: The new instance will share a link to the same attributes as the original class. Therefore the sti column value will still be the same. Any change to the attributes on either instance will affect both instances. If you want to change the sti column as well, use becomes! instead.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 372
+def becomes(klass)
+  became = klass.allocate
+  became.send(:initialize)
+  became.instance_variable_set("@attributes", @attributes)
+  became.instance_variable_set("@mutations_from_database", @mutations_from_database ||= nil)
+  became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
+  became.instance_variable_set("@new_record", new_record?)
+  became.instance_variable_set("@destroyed", destroyed?)
+  became.errors.copy!(errors)
+  became
+end
+
+
+ +
+ +
+

+ + becomes!(klass) + +

+ + +
+

Wrapper around becomes that also changes the instance's sti column value. This is especially useful if you want to persist the changed class in your database.

+ +

Note: The old instance's sti column value will be changed too, as both objects share the same set of attributes.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 390
+def becomes!(klass)
+  became = becomes(klass)
+  sti_type = nil
+  if !klass.descends_from_active_record?
+    sti_type = klass.sti_name
+  end
+  became.public_send("#{klass.inheritance_column}=", sti_type)
+  became
+end
+
+
+ +
+ +
+

+ + decrement(attribute, by = 1) + +

+ + +
+

Initializes attribute to zero if nil and subtracts the value passed as by (default is 1). The decrement is performed directly on the underlying attribute, no setter is invoked. Only makes sense for number-based attributes. Returns self.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 515
+def decrement(attribute, by = 1)
+  increment(attribute, -by)
+end
+
+
+ +
+ +
+

+ + decrement!(attribute, by = 1, touch: nil) + +

+ + +
+

Wrapper around decrement that writes the update to the database. Only attribute is updated; the record itself is not saved. This means that any other modified attributes will still be dirty. Validations and callbacks are skipped. Supports the touch option from update_counters, see that for more. Returns self.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 525
+def decrement!(attribute, by = 1, touch: nil)
+  increment!(attribute, -by, touch: touch)
+end
+
+
+ +
+ +
+

+ + delete() + +

+ + +
+

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted). Returns the frozen instance.

+ +

The row is simply removed with an SQL DELETE statement on the record's primary key, and no callbacks are executed.

+ +

Note that this will also delete records marked as #readonly?.

+ +

To enforce the object's before_destroy and after_destroy callbacks or any :dependent association options, use #destroy.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 323
+def delete
+  _delete_row if persisted?
+  @destroyed = true
+  freeze
+end
+
+
+ +
+ +
+

+ + destroy() + +

+ + +
+

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted).

+ +

There's a series of callbacks associated with destroy. If the before_destroy callback throws :abort the action is cancelled and destroy returns false. See ActiveRecord::Callbacks for further details.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 336
+def destroy
+  _raise_readonly_record_error if readonly?
+  destroy_associations
+  self.class.connection.add_transaction_record(self)
+  @_trigger_destroy_callback = if persisted?
+    destroy_row > 0
+  else
+    true
+  end
+  @destroyed = true
+  freeze
+end
+
+
+ +
+ +
+

+ + destroy!() + +

+ + +
+

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can't be persisted).

+ +

There's a series of callbacks associated with destroy!. If the before_destroy callback throws :abort the action is cancelled and destroy! raises ActiveRecord::RecordNotDestroyed. See ActiveRecord::Callbacks for further details.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 356
+def destroy!
+  destroy || _raise_record_not_destroyed
+end
+
+
+ +
+ +
+

+ + destroyed?() + +

+ + +
+

Returns true if this object has been destroyed, otherwise returns false.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 237
+def destroyed?
+  sync_with_transaction_state
+  @destroyed
+end
+
+
+ +
+ +
+

+ + increment(attribute, by = 1) + +

+ + +
+

Initializes attribute to zero if nil and adds the value passed as by (default is 1). The increment is performed directly on the underlying attribute, no setter is invoked. Only makes sense for number-based attributes. Returns self.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 492
+def increment(attribute, by = 1)
+  self[attribute] ||= 0
+  self[attribute] += by
+  self
+end
+
+
+ +
+ +
+

+ + increment!(attribute, by = 1, touch: nil) + +

+ + +
+

Wrapper around increment that writes the update to the database. Only attribute is updated; the record itself is not saved. This means that any other modified attributes will still be dirty. Validations and callbacks are skipped. Supports the touch option from update_counters, see that for more. Returns self.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 504
+def increment!(attribute, by = 1, touch: nil)
+  increment(attribute, by)
+  change = public_send(attribute) - (attribute_in_database(attribute.to_s) || 0)
+  self.class.update_counters(id, attribute => change, touch: touch)
+  clear_attribute_change(attribute) # eww
+  self
+end
+
+
+ +
+ +
+

+ + new_record?() + +

+ + +
+

Returns true if this object hasn't been saved yet – that is, a record for the object doesn't exist in the database yet; otherwise, returns false.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 231
+def new_record?
+  sync_with_transaction_state
+  @new_record
+end
+
+
+ +
+ +
+

+ + persisted?() + +

+ + +
+

Returns true if the record is persisted, i.e. it's not a new record and it was not destroyed, otherwise returns false.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 244
+def persisted?
+  sync_with_transaction_state
+  !(@new_record || @destroyed)
+end
+
+
+ +
+ +
+

+ + reload(options = nil) + +

+ + +
+

Reloads the record from the database.

+ +

This method finds the record by its primary key (which could be assigned manually) and modifies the receiver in-place:

+ +
account = Account.new
+# => #<Account id: nil, email: nil>
+account.id = 1
+account.reload
+# Account Load (1.2ms)  SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT 1  [["id", 1]]
+# => #<Account id: 1, email: 'account@example.com'>
+
+ +

Attributes are reloaded from the database, and caches busted, in particular the associations cache and the QueryCache.

+ +

If the record no longer exists in the database ActiveRecord::RecordNotFound is raised. Otherwise, in addition to the in-place modification the method returns self for convenience.

+ +

The optional :lock flag option allows you to lock the reloaded record:

+ +
reload(lock: true) # reload with pessimistic locking
+
+ +

Reloading is commonly used in test suites to test something is actually written to the database, or when some action modifies the corresponding row in the database but not the object in memory:

+ +
assert account.deposit!(25)
+assert_equal 25, account.credit        # check it is updated in memory
+assert_equal 25, account.reload.credit # check it is also persisted
+
+ +

Another common use case is optimistic locking handling:

+ +
def with_optimistic_retry
+  begin
+    yield
+  rescue ActiveRecord::StaleObjectError
+    begin
+      # Reload lock_version in particular.
+      reload
+    rescue ActiveRecord::RecordNotFound
+      # If the record is gone there is nothing to do.
+    else
+      retry
+    end
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 602
+def reload(options = nil)
+  self.class.connection.clear_query_cache
+
+  fresh_object =
+    if options && options[:lock]
+      self.class.unscoped { self.class.lock(options[:lock]).find(id) }
+    else
+      self.class.unscoped { self.class.find(id) }
+    end
+
+  @attributes = fresh_object.instance_variable_get("@attributes")
+  @new_record = false
+  self
+end
+
+
+ +
+ +
+

+ + save(*args) + + +

+ + +
+

Saves the model.

+ +

If the model is new, a record gets created in the database, otherwise the existing record gets updated.

+ +

By default, save always runs validations. If any of them fail the action is cancelled and save returns false, and the record won't be saved. However, if you supply validate: false, validations are bypassed altogether. See ActiveRecord::Validations for more information.

+ +

By default, save also sets the updated_at/updated_on attributes to the current time. However, if you supply touch: false, these timestamps will not be updated.

+ +

There's a series of callbacks associated with save. If any of the before_* callbacks throws :abort the action is cancelled and save returns false. See ActiveRecord::Callbacks for further details.

+ +

Attributes marked as readonly are silently ignored if the record is being updated.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 274
+def save(*args, &block)
+  create_or_update(*args, &block)
+rescue ActiveRecord::RecordInvalid
+  false
+end
+
+
+ +
+ +
+

+ + save!(*args) + + +

+ + +
+

Saves the model.

+ +

If the model is new, a record gets created in the database, otherwise the existing record gets updated.

+ +

By default, save! always runs validations. If any of them fail ActiveRecord::RecordInvalid gets raised, and the record won't be saved. However, if you supply validate: false, validations are bypassed altogether. See ActiveRecord::Validations for more information.

+ +

By default, save! also sets the updated_at/updated_on attributes to the current time. However, if you supply touch: false, these timestamps will not be updated.

+ +

There's a series of callbacks associated with save!. If any of the before_* callbacks throws :abort the action is cancelled and save! raises ActiveRecord::RecordNotSaved. See ActiveRecord::Callbacks for further details.

+ +

Attributes marked as readonly are silently ignored if the record is being updated.

+ +

Unless an error is raised, returns true.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 307
+def save!(*args, &block)
+  create_or_update(*args, &block) || raise(RecordNotSaved.new("Failed to save the record", self))
+end
+
+
+ +
+ +
+

+ + toggle(attribute) + +

+ + +
+

Assigns to attribute the boolean opposite of attribute?. So if the predicate returns true the attribute will become false. This method toggles directly the underlying value without calling any setter. Returns self.

+ +

Example:

+ +
user = User.first
+user.banned? # => false
+user.toggle(:banned)
+user.banned? # => true
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 541
+def toggle(attribute)
+  self[attribute] = !public_send("#{attribute}?")
+  self
+end
+
+
+ +
+ +
+

+ + toggle!(attribute) + +

+ + +
+

Wrapper around toggle that saves the record. This method differs from its non-bang version in the sense that it passes through the attribute setter. Saving is not subjected to validation checks. Returns true if the record could be saved.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 550
+def toggle!(attribute)
+  toggle(attribute).update_attribute(attribute, self[attribute])
+end
+
+
+ +
+ +
+

+ + touch(*names, time: nil) + +

+ + +
+

Saves the record with the updated_at/on attributes set to the current time or the time specified. Please note that no validation is performed and only the after_touch, after_commit and after_rollback callbacks are executed.

+ +

This method can be passed attribute names and an optional time argument. If attribute names are passed, they are updated along with updated_at/on attributes. If no time argument is passed, the current time is used as default.

+ +
product.touch                         # updates updated_at/on with current time
+product.touch(time: Time.new(2015, 2, 16, 0, 0, 0)) # updates updated_at/on with specified time
+product.touch(:designed_at)           # updates the designed_at attribute and updated_at/on
+product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes
+
+ +

If used along with belongs_to then touch will invoke touch method on associated object.

+ +
class Brake < ActiveRecord::Base
+  belongs_to :car, touch: true
+end
+
+class Car < ActiveRecord::Base
+  belongs_to :corporation, touch: true
+end
+
+# triggers @brake.car.touch and @brake.car.corporation.touch
+@brake.touch
+
+ +

Note that touch must be used on a persisted object, or else an ActiveRecordError will be thrown. For example:

+ +
ball = Ball.new
+ball.touch(:updated_at)   # => raises ActiveRecordError
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 651
+    def touch(*names, time: nil)
+      unless persisted?
+        raise ActiveRecordError, <<-MSG.squish
+          cannot touch on a new or destroyed record object. Consider using
+          persisted?, new_record?, or destroyed? before touching
+        MSG
+      end
+
+      attribute_names = timestamp_attributes_for_update_in_model
+      attribute_names |= names.map(&:to_s)
+
+      unless attribute_names.empty?
+        affected_rows = _touch_row(attribute_names, time)
+        @_trigger_update_callback = affected_rows == 1
+      else
+        true
+      end
+    end
+
+
+ +
+ +
+

+ + update(attributes) + +

+ + +
+

Updates the attributes of the model from the passed-in hash and saves the record, all wrapped in a transaction. If the object is invalid, the saving will fail and false will be returned.

+
+ + + +
+ Also aliased as: update_attributes +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 423
+def update(attributes)
+  # The following transaction covers any possible database side-effects of the
+  # attributes assignment. For example, setting the IDs of a child collection.
+  with_transaction_returning_status do
+    assign_attributes(attributes)
+    save
+  end
+end
+
+
+ +
+ +
+

+ + update!(attributes) + +

+ + +
+

Updates its receiver just like update but calls save! instead of save, so an exception is raised if the record is invalid and saving will fail.

+
+ + + +
+ Also aliased as: update_attributes! +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 436
+def update!(attributes)
+  # The following transaction covers any possible database side-effects of the
+  # attributes assignment. For example, setting the IDs of a child collection.
+  with_transaction_returning_status do
+    assign_attributes(attributes)
+    save!
+  end
+end
+
+
+ +
+ +
+

+ + update_attribute(name, value) + +

+ + +
+

Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records. Also note that

+
  • +

    Validation is skipped.

    +
  • +

    Callbacks are invoked.

    +
  • +

    updated_at/updated_on column is updated if that column is available.

    +
  • +

    Updates all the attributes that are dirty in this object.

    +
+ +

This method raises an ActiveRecord::ActiveRecordError if the attribute is marked as readonly.

+ +

Also see update_column.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 412
+def update_attribute(name, value)
+  name = name.to_s
+  verify_readonly_attribute(name)
+  public_send("#{name}=", value)
+
+  save(validate: false)
+end
+
+
+ +
+ +
+

+ + update_attributes(attributes) + +

+ + +
+ +
+ + + + + +
+ Alias for: update +
+ + + +
+ +
+

+ + update_attributes!(attributes) + +

+ + +
+ +
+ + + + + +
+ Alias for: update! +
+ + + +
+ +
+

+ + update_column(name, value) + +

+ + +
+

Equivalent to update_columns(name => value).

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 448
+def update_column(name, value)
+  update_columns(name => value)
+end
+
+
+ +
+ +
+

+ + update_columns(attributes) + +

+ + +
+

Updates the attributes directly in the database issuing an UPDATE SQL statement and sets them in the receiver:

+ +
user.update_columns(last_request_at: Time.current)
+
+ +

This is the fastest way to update attributes because it goes straight to the database, but take into account that in consequence the regular update procedures are totally bypassed. In particular:

+
  • +

    Validations are skipped.

    +
  • +

    Callbacks are skipped.

    +
  • +

    updated_at/updated_on are not updated.

    +
  • +

    However, attributes are serialized with the same rules as ActiveRecord::Relation#update_all

    +
+ +

This method raises an ActiveRecord::ActiveRecordError when called on new objects, or when at least one of the attributes is marked as readonly.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 468
+def update_columns(attributes)
+  raise ActiveRecordError, "cannot update a new record" if new_record?
+  raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
+
+  attributes.each_key do |key|
+    verify_readonly_attribute(key.to_s)
+  end
+
+  id_in_database = self.id_in_database
+  attributes.each do |k, v|
+    write_attribute_without_type_cast(k, v)
+  end
+
+  affected_rows = self.class._update_record(
+    attributes,
+    self.class.primary_key => id_in_database
+  )
+
+  affected_rows == 1
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Persistence/ClassMethods.html b/src/5.2/classes/ActiveRecord/Persistence/ClassMethods.html new file mode 100644 index 0000000000..6fdbca16fb --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Persistence/ClassMethods.html @@ -0,0 +1,409 @@ +--- +title: ActiveRecord::Persistence::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + create(attributes = nil, &block) + +

+ + +
+

Creates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

+ +

The attributes parameter can be either a Hash or an Array of Hashes. These Hashes describe the attributes on the objects that are to be created.

+ +

Examples

+ +
# Create a single new object
+User.create(first_name: 'Jamie')
+
+# Create an Array of new objects
+User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
+
+# Create a single object and pass it into a block to set other attributes.
+User.create(first_name: 'Jamie') do |u|
+  u.is_admin = false
+end
+
+# Creating an Array of new objects using a block, where the block is executed for each object:
+User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
+  u.is_admin = false
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 31
+def create(attributes = nil, &block)
+  if attributes.is_a?(Array)
+    attributes.collect { |attr| create(attr, &block) }
+  else
+    object = new(attributes, &block)
+    object.save
+    object
+  end
+end
+
+
+ +
+ +
+

+ + create!(attributes = nil, &block) + +

+ + +
+

Creates an object (or multiple objects) and saves it to the database, if validations pass. Raises a RecordInvalid error if validations fail, unlike Base#create.

+ +

The attributes parameter can be either a Hash or an Array of Hashes. These describe which attributes to be created on the object, or multiple objects when given an Array of Hashes.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 48
+def create!(attributes = nil, &block)
+  if attributes.is_a?(Array)
+    attributes.collect { |attr| create!(attr, &block) }
+  else
+    object = new(attributes, &block)
+    object.save!
+    object
+  end
+end
+
+
+ +
+ +
+

+ + delete(id_or_array) + +

+ + +
+

Deletes the row with a primary key matching the id argument, using a SQL DELETE statement, and returns the number of rows deleted. Active Record objects are not instantiated, so the object's callbacks are not executed, including any :dependent association options.

+ +

You can delete multiple rows at once by passing an Array of ids.

+ +

Note: Although it is often much faster than the alternative, destroy, skipping callbacks might bypass business logic in your application that ensures referential integrity or performs other essential jobs.

+ +

Examples

+ +
# Delete a single row
+Todo.delete(1)
+
+# Delete multiple rows
+Todo.delete([2,3,4])
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 164
+def delete(id_or_array)
+  where(primary_key => id_or_array).delete_all
+end
+
+
+ +
+ +
+

+ + destroy(id) + +

+ + +
+

Destroy an object (or multiple objects) that has the given id. The object is instantiated first, therefore all callbacks and filters are fired off before the object is deleted. This method is less efficient than delete but allows cleanup methods and other actions to be run.

+ +

This essentially finds the object (or multiple objects) with the given id, creates a new object from the attributes, and then calls destroy on it.

+ +

Parameters

+
  • +

    id - This should be the id or an array of ids to be destroyed.

    +
+ +

Examples

+ +
# Destroy a single object
+Todo.destroy(1)
+
+# Destroy multiple objects
+todos = [1,2,3]
+Todo.destroy(todos)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 138
+def destroy(id)
+  if id.is_a?(Array)
+    find(id).each(&:destroy)
+  else
+    find(id).destroy
+  end
+end
+
+
+ +
+ +
+

+ + instantiate(attributes, column_types = {}, &block) + +

+ + +
+

Given an attributes hash, instantiate returns a new instance of the appropriate class. Accepts only keys as strings.

+ +

For example, Post.all may return Comments, Messages, and Emails by storing the record's subclass in a type attribute. By calling instantiate instead of new, finder methods ensure they get new instances of the appropriate class for each record.

+ +

See ActiveRecord::Inheritance#discriminate_class_for_record to see how this “single-table” inheritance mapping is implemented.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 68
+def instantiate(attributes, column_types = {}, &block)
+  klass = discriminate_class_for_record(attributes)
+  attributes = klass.attributes_builder.build_from_database(attributes, column_types)
+  klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block)
+end
+
+
+ +
+ +
+

+ + update(id = :all, attributes) + +

+ + +
+

Updates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

+ +

Parameters

+
  • +

    id - This should be the id or an array of ids to be updated.

    +
  • +

    attributes - This should be a hash of attributes or an array of hashes.

    +
+ +

Examples

+ +
# Updates one record
+Person.update(15, user_name: "Samuel", group: "expert")
+
+# Updates multiple records
+people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
+Person.update(people.keys, people.values)
+
+# Updates multiple records from the result of a relation
+people = Person.where(group: "expert")
+people.update(group: "masters")
+
+ +

Note: Updating a large number of records will run an UPDATE query for each record, which may cause a performance issue. When running callbacks is not needed for each record update, it is preferred to use update_all for updating all records in a single query.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/persistence.rb, line 100
+def update(id = :all, attributes)
+  if id.is_a?(Array)
+    id.map { |one_id| find(one_id) }.each_with_index { |object, idx|
+      object.update(attributes[idx])
+    }
+  elsif id == :all
+    all.each { |record| record.update(attributes) }
+  else
+    if ActiveRecord::Base === id
+      raise ArgumentError,
+        "You are passing an instance of ActiveRecord::Base to `update`. " \
+        "Please pass the id of the object by calling `.id`."
+    end
+    object = find(id)
+    object.update(attributes)
+    object
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/PredicateBuilder.html b/src/5.2/classes/ActiveRecord/PredicateBuilder.html new file mode 100644 index 0000000000..5a957bf3c8 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/PredicateBuilder.html @@ -0,0 +1,87 @@ +--- +title: ActiveRecord::PredicateBuilder +layout: default +--- + diff --git a/src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler.html b/src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler.html new file mode 100644 index 0000000000..9460843fb5 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::PredicateBuilder::RangeHandler +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler/RangeWithBinds.html b/src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler/RangeWithBinds.html new file mode 100644 index 0000000000..66e0601216 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/PredicateBuilder/RangeHandler/RangeWithBinds.html @@ -0,0 +1,107 @@ +--- +title: ActiveRecord::PredicateBuilder::RangeHandler::RangeWithBinds +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + exclude_end?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/predicate_builder/range_handler.rb, line 7
+def exclude_end?
+  false
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/PreparedStatementCacheExpired.html b/src/5.2/classes/ActiveRecord/PreparedStatementCacheExpired.html new file mode 100644 index 0000000000..2848170113 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/PreparedStatementCacheExpired.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::PreparedStatementCacheExpired +layout: default +--- +
+ +
+
+ +
+ +

Raised when PostgreSQL returns 'cached plan must not change result type' and we cannot retry gracefully (e.g. inside a transaction)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/PreparedStatementInvalid.html b/src/5.2/classes/ActiveRecord/PreparedStatementInvalid.html new file mode 100644 index 0000000000..32421a5e6c --- /dev/null +++ b/src/5.2/classes/ActiveRecord/PreparedStatementInvalid.html @@ -0,0 +1,71 @@ +--- +title: ActiveRecord::PreparedStatementInvalid +layout: default +--- +
+ +
+
+ +
+ +

Raised when number of bind variables in statement given to :condition key (for example, when using ActiveRecord::Base.find method) does not match number of expected values supplied.

+ +

For example, when there are two placeholders with only one value supplied:

+ +
Location.where("lat = ? AND lng = ?", 53.7362)
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/QueryCache.html b/src/5.2/classes/ActiveRecord/QueryCache.html new file mode 100644 index 0000000000..dd81388637 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/QueryCache.html @@ -0,0 +1,209 @@ +--- +title: ActiveRecord::QueryCache +layout: default +--- +
+ +
+
+ +
+ +

Active Record Query Cache

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + complete(pools) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/query_cache.rb, line 33
+def self.complete(pools)
+  pools.each { |pool| pool.disable_query_cache! }
+
+  ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
+    pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
+  end
+end
+
+
+ +
+ +
+

+ + install_executor_hooks(executor = ActiveSupport::Executor) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/query_cache.rb, line 41
+def self.install_executor_hooks(executor = ActiveSupport::Executor)
+  executor.register_hook(self)
+end
+
+
+ +
+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/query_cache.rb, line 28
+def self.run
+  ActiveRecord::Base.connection_handler.connection_pool_list.
+    reject { |p| p.query_cache_enabled }.each { |p| p.enable_query_cache! }
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/QueryCache/ClassMethods.html b/src/5.2/classes/ActiveRecord/QueryCache/ClassMethods.html new file mode 100644 index 0000000000..f160e9ccb9 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/QueryCache/ClassMethods.html @@ -0,0 +1,148 @@ +--- +title: ActiveRecord::QueryCache::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + cache(&block) + +

+ + +
+

Enable the query cache within the block if Active Record is configured. If it's not, it will execute the given block.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/query_cache.rb, line 9
+def cache(&block)
+  if connected? || !configurations.empty?
+    connection.cache(&block)
+  else
+    yield
+  end
+end
+
+
+ +
+ +
+

+ + uncached(&block) + +

+ + +
+

Disable the query cache within the block if Active Record is configured. If it's not, it will execute the given block.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/query_cache.rb, line 19
+def uncached(&block)
+  if connected? || !configurations.empty?
+    connection.uncached(&block)
+  else
+    yield
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/QueryCanceled.html b/src/5.2/classes/ActiveRecord/QueryCanceled.html new file mode 100644 index 0000000000..93ec12658e --- /dev/null +++ b/src/5.2/classes/ActiveRecord/QueryCanceled.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::QueryCanceled +layout: default +--- +
+ +
+
+ +
+ +

QueryCanceled will be raised when canceling statement due to user request.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/QueryMethods.html b/src/5.2/classes/ActiveRecord/QueryMethods.html new file mode 100644 index 0000000000..4cb13df0a9 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/QueryMethods.html @@ -0,0 +1,1634 @@ +--- +title: ActiveRecord::QueryMethods +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_VALUES={ +create_with: FROZEN_EMPTY_HASH, +where: Relation::WhereClause.empty, +having: Relation::WhereClause.empty, +from: Relation::FromClause.empty +}
 
FROZEN_EMPTY_ARRAY=[].freeze
 
FROZEN_EMPTY_HASH={}.freeze
 
STRUCTURAL_OR_METHODS=Relation::VALUE_METHODS - [:extending, :where, :having, :unscope, :references]
 
VALID_UNSCOPING_VALUES=Set.new([:where, :select, :group, :order, :lock, +:limit, :offset, :joins, :left_outer_joins, +:includes, :from, :readonly, :having])
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + create_with(value) + +

+ + +
+

Sets attributes to be used when creating new records from a relation object.

+ +
users = User.where(name: 'Oscar')
+users.new.name # => 'Oscar'
+
+users = users.create_with(name: 'DHH')
+users.new.name # => 'DHH'
+
+ +

You can pass nil to create_with to reset attributes:

+ +
users = users.create_with(nil)
+users.new.name # => 'Oscar'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 768
+def create_with(value)
+  spawn.create_with!(value)
+end
+
+
+ +
+ +
+

+ + distinct(value = true) + +

+ + +
+

Specifies whether the records should be unique or not. For example:

+ +
User.select(:name)
+# Might return two records with the same name
+
+User.select(:name).distinct
+# Returns 1 record per distinct name
+
+User.select(:name).distinct.distinct(false)
+# You can also remove the uniqueness
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 815
+def distinct(value = true)
+  spawn.distinct!(value)
+end
+
+
+ +
+ +
+

+ + eager_load(*args) + +

+ + +
+

Forces eager loading by performing a LEFT OUTER JOIN on args:

+ +
User.eager_load(:posts)
+# SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ...
+# FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
+# "users"."id"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 133
+def eager_load(*args)
+  check_if_method_has_arguments!(:eager_load, args)
+  spawn.eager_load!(*args)
+end
+
+
+ +
+ +
+

+ + extending(*modules, &block) + +

+ + +
+

Used to extend a scope with additional methods, either through a module or through a block provided.

+ +

The object returned is a relation, which can be further extended.

+ +

Using a module

+ +
module Pagination
+  def page(number)
+    # pagination code goes here
+  end
+end
+
+scope = Model.all.extending(Pagination)
+scope.page(params[:page])
+
+ +

You can also pass a list of modules:

+ +
scope = Model.all.extending(Pagination, SomethingElse)
+
+ +

Using a block

+ +
scope = Model.all.extending do
+  def page(number)
+    # pagination code goes here
+  end
+end
+scope.page(params[:page])
+
+ +

You can also use a block and a module list:

+ +
scope = Model.all.extending(Pagination) do
+  def per_page(number)
+    # pagination code goes here
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 861
+def extending(*modules, &block)
+  if modules.any? || block
+    spawn.extending!(*modules, &block)
+  else
+    self
+  end
+end
+
+
+ +
+ +
+

+ + from(value, subquery_name = nil) + +

+ + +
+

Specifies table from which the records will be fetched. For example:

+ +
Topic.select('title').from('posts')
+# SELECT title FROM posts
+
+ +

Can accept other relation objects. For example:

+ +
Topic.select('title').from(Topic.approved)
+# SELECT title FROM (SELECT * FROM topics WHERE approved = 't') subquery
+
+Topic.select('a.title').from(Topic.approved, :a)
+# SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 796
+def from(value, subquery_name = nil)
+  spawn.from!(value, subquery_name)
+end
+
+
+ +
+ +
+

+ + group(*args) + +

+ + +
+

Allows to specify a group attribute:

+ +
User.group(:name)
+# SELECT "users".* FROM "users" GROUP BY name
+
+ +

Returns an array with distinct records based on the group attribute:

+ +
User.select([:id, :name])
+# => [#<User id: 1, name: "Oscar">, #<User id: 2, name: "Oscar">, #<User id: 3, name: "Foo">]
+
+User.group(:name)
+# => [#<User id: 3, name: "Foo", ...>, #<User id: 2, name: "Oscar", ...>]
+
+User.group('name AS grouped_name, age')
+# => [#<User id: 3, name: "Foo", age: 21, ...>, #<User id: 2, name: "Oscar", age: 21, ...>, #<User id: 5, name: "Foo", age: 23, ...>]
+
+ +

Passing in an array of attributes to group by is also supported.

+ +
User.select([:id, :first_name]).group(:id, :first_name).first(3)
+# => [#<User id: 1, first_name: "Bill">, #<User id: 2, first_name: "Earl">, #<User id: 3, first_name: "Beto">]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 259
+def group(*args)
+  check_if_method_has_arguments!(:group, args)
+  spawn.group!(*args)
+end
+
+
+ +
+ +
+

+ + having(opts, *rest) + +

+ + +
+

Allows to specify a HAVING clause. Note that you can't use HAVING without also specifying a GROUP clause.

+ +
Order.having('SUM(price) > 30').group('user_id')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 645
+def having(opts, *rest)
+  opts.blank? ? self : spawn.having!(opts, *rest)
+end
+
+
+ +
+ +
+

+ + includes(*args) + +

+ + +
+

Specify relationships to be included in the result set. For example:

+ +
users = User.includes(:address)
+users.each do |user|
+  user.address.city
+end
+
+ +

allows you to access the address attribute of the User model without firing an additional query. This will often result in a performance improvement over a simple join.

+ +

You can also specify multiple relationships, like this:

+ +
users = User.includes(:address, :friends)
+
+ +

Loading nested relationships is possible using a Hash:

+ +
users = User.includes(:address, friends: [:address, :followers])
+
+ +

conditions

+ +

If you want to add conditions to your included models you'll have to explicitly reference them. For example:

+ +
User.includes(:posts).where('posts.name = ?', 'example')
+
+ +

Will throw an error, but this will work:

+ +
User.includes(:posts).where('posts.name = ?', 'example').references(:posts)
+
+ +

Note that includes works with association names while references needs the actual table name.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 114
+def includes(*args)
+  check_if_method_has_arguments!(:includes, args)
+  spawn.includes!(*args)
+end
+
+
+ +
+ +
+

+ + joins(*args) + +

+ + +
+

Performs a joins on args. The given symbol(s) should match the name of the association(s).

+ +
User.joins(:posts)
+# SELECT "users".*
+# FROM "users"
+# INNER JOIN "posts" ON "posts"."user_id" = "users"."id"
+
+ +

Multiple joins:

+ +
User.joins(:posts, :account)
+# SELECT "users".*
+# FROM "users"
+# INNER JOIN "posts" ON "posts"."user_id" = "users"."id"
+# INNER JOIN "accounts" ON "accounts"."id" = "users"."account_id"
+
+ +

Nested joins:

+ +
User.joins(posts: [:comments])
+# SELECT "users".*
+# FROM "users"
+# INNER JOIN "posts" ON "posts"."user_id" = "users"."id"
+# INNER JOIN "comments" "comments_posts"
+#   ON "comments_posts"."post_id" = "posts"."id"
+
+ +

You can use strings in order to customize your joins:

+ +
User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
+# SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 426
+def joins(*args)
+  check_if_method_has_arguments!(:joins, args)
+  spawn.joins!(*args)
+end
+
+
+ +
+ +
+

+ + left_joins(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: left_outer_joins +
+ + + +
+ +
+

+ + left_outer_joins(*args) + +

+ + +
+

Performs a left outer joins on args:

+ +
User.left_outer_joins(:posts)
+=> SELECT "users".* FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
+
+
+ + + +
+ Also aliased as: left_joins +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 443
+def left_outer_joins(*args)
+  check_if_method_has_arguments!(__callee__, args)
+  spawn.left_outer_joins!(*args)
+end
+
+
+ +
+ +
+

+ + limit(value) + +

+ + +
+

Specifies a limit for the number of records to retrieve.

+ +
User.limit(10) # generated SQL has 'LIMIT 10'
+
+User.limit(10).limit(20) # generated SQL has 'LIMIT 20'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 662
+def limit(value)
+  spawn.limit!(value)
+end
+
+
+ +
+ +
+

+ + lock(locks = true) + +

+ + +
+

Specifies locking settings (default to true). For more information on locking, please see ActiveRecord::Locking.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 689
+def lock(locks = true)
+  spawn.lock!(locks)
+end
+
+
+ +
+ +
+

+ + none() + +

+ + +
+

Returns a chainable relation with zero records.

+ +

The returned relation implements the Null Object pattern. It is an object with defined null behavior and always returns an empty array of records without querying the database.

+ +

Any subsequent condition chained to the returned relation will continue generating an empty relation and will not fire any query to the database.

+ +

Used in cases where a method or scope could return zero records but the result needs to be chainable.

+ +

For example:

+ +
@posts = current_user.visible_posts.where(name: params[:name])
+# the visible_posts method is expected to return a chainable Relation
+
+def visible_posts
+  case role
+  when 'Country Manager'
+    Post.where(country: country)
+  when 'Reviewer'
+    Post.published
+  when 'Bad User'
+    Post.none # It can't be chained if [] is returned.
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 732
+def none
+  spawn.none!
+end
+
+
+ +
+ +
+

+ + offset(value) + +

+ + +
+

Specifies the number of rows to skip before returning rows.

+ +
User.offset(10) # generated SQL has "OFFSET 10"
+
+ +

Should be used with order.

+ +
User.offset(10).order("name ASC")
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 678
+def offset(value)
+  spawn.offset!(value)
+end
+
+
+ +
+ +
+

+ + or(other) + +

+ + +
+

Returns a new relation, which is the logical union of this relation and the one passed as an argument.

+ +

The two relations must be structurally compatible: they must be scoping the same model, and they must differ only by where (if no group has been defined) or having (if a group is present). Neither relation may have a limit, offset, or distinct set.

+ +
Post.where("id = 1").or(Post.where("author_id = 3"))
+# SELECT `posts`.* FROM `posts` WHERE ((id = 1) OR (author_id = 3))
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 619
+def or(other)
+  unless other.is_a? Relation
+    raise ArgumentError, "You have passed #{other.class.name} object to #or. Pass an ActiveRecord::Relation object instead."
+  end
+
+  spawn.or!(other)
+end
+
+
+ +
+ +
+

+ + order(*args) + +

+ + +
+

Allows to specify an order attribute:

+ +
User.order(:name)
+# SELECT "users".* FROM "users" ORDER BY "users"."name" ASC
+
+User.order(email: :desc)
+# SELECT "users".* FROM "users" ORDER BY "users"."email" DESC
+
+User.order(:name, email: :desc)
+# SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
+
+User.order('name')
+# SELECT "users".* FROM "users" ORDER BY name
+
+User.order('name DESC')
+# SELECT "users".* FROM "users" ORDER BY name DESC
+
+User.order('name DESC, email')
+# SELECT "users".* FROM "users" ORDER BY name DESC, email
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 290
+def order(*args)
+  check_if_method_has_arguments!(:order, args)
+  spawn.order!(*args)
+end
+
+
+ +
+ +
+

+ + preload(*args) + +

+ + +
+

Allows preloading of args, in the same way that includes does:

+ +
User.preload(:posts)
+# SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 147
+def preload(*args)
+  check_if_method_has_arguments!(:preload, args)
+  spawn.preload!(*args)
+end
+
+
+ +
+ +
+

+ + readonly(value = true) + +

+ + +
+

Sets readonly attributes for the returned relation. If value is true (default), attempting to update a record will result in an error.

+ +
users = User.readonly
+users.first.save
+=> ActiveRecord::ReadOnlyRecord: User is marked as readonly
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 746
+def readonly(value = true)
+  spawn.readonly!(value)
+end
+
+
+ +
+ +
+

+ + references(*table_names) + +

+ + +
+

Use to indicate that the given table_names are referenced by an SQL string, and should therefore be JOINed in any query rather than loaded separately. This method only works in conjunction with includes. See includes for more details.

+ +
User.includes(:posts).where("posts.name = 'foo'")
+# Doesn't JOIN the posts table, resulting in an error.
+
+User.includes(:posts).where("posts.name = 'foo'").references(:posts)
+# Query now knows the string references posts, so adds a JOIN
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 167
+def references(*table_names)
+  check_if_method_has_arguments!(:references, table_names)
+  spawn.references!(*table_names)
+end
+
+
+ +
+ +
+

+ + reorder(*args) + +

+ + +
+

Replaces any existing order defined on the relation with the specified order.

+ +
User.order('email DESC').reorder('id ASC') # generated SQL has 'ORDER BY id ASC'
+
+ +

Subsequent calls to order on the same relation will be appended. For example:

+ +
User.order('email DESC').reorder('id ASC').order('name ASC')
+
+ +

generates a query with 'ORDER BY id ASC, name ASC'.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 312
+def reorder(*args)
+  check_if_method_has_arguments!(:reorder, args)
+  spawn.reorder!(*args)
+end
+
+
+ +
+ +
+

+ + reverse_order() + +

+ + +
+

Reverse the existing order clause on the relation.

+ +
User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 882
+def reverse_order
+  spawn.reverse_order!
+end
+
+
+ +
+ +
+

+ + rewhere(conditions) + +

+ + +
+

Allows you to change a previously set where condition for a given attribute, instead of appending to that condition.

+ +
Post.where(trashed: true).where(trashed: false)
+# WHERE `trashed` = 1 AND `trashed` = 0
+
+Post.where(trashed: true).rewhere(trashed: false)
+# WHERE `trashed` = 0
+
+Post.where(active: true).where(trashed: true).rewhere(trashed: false)
+# WHERE `active` = 1 AND `trashed` = 0
+
+ +

This is short-hand for unscope(where: conditions.keys).where(conditions). Note that unlike reorder, we're only unscoping the named conditions – not the entire where statement.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 605
+def rewhere(conditions)
+  unscope(where: conditions.keys).where(conditions)
+end
+
+
+ +
+ +
+

+ + select(*fields) + +

+ + +
+

Works in two unique ways.

+ +

First: takes a block so it can be used just like Array#select.

+ +
Model.all.select { |m| m.field == value }
+
+ +

This will build an array of objects from the database for the scope, converting them into an array and iterating through them using Array#select.

+ +

Second: Modifies the SELECT statement for the query so that only certain fields are retrieved:

+ +
Model.select(:field)
+# => [#<Model id: nil, field: "value">]
+
+ +

Although in the above example it looks as though this method returns an array, it actually returns a relation object and can have other query methods appended to it, such as the other methods in ActiveRecord::QueryMethods.

+ +

The argument to the method can also be an array of fields.

+ +
Model.select(:field, :other_field, :and_one_more)
+# => [#<Model id: nil, field: "value", other_field: "value", and_one_more: "value">]
+
+ +

You can also use one or more strings, which will be used unchanged as SELECT fields.

+ +
Model.select('field AS field_one', 'other_field AS field_two')
+# => [#<Model id: nil, field: "value", other_field: "value">]
+
+ +

If an alias was specified, it will be accessible from the resulting objects:

+ +
Model.select('field AS field_one').first.field_one
+# => "value"
+
+ +

Accessing attributes of an object that do not have fields retrieved by a select except id will throw ActiveModel::MissingAttributeError:

+ +
Model.select(:field).first.other_field
+# => ActiveModel::MissingAttributeError: missing attribute: other_field
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 220
+def select(*fields)
+  if block_given?
+    if fields.any?
+      raise ArgumentError, "`select' with block doesn't take arguments."
+    end
+
+    return super()
+  end
+
+  raise ArgumentError, "Call `select' with at least one field" if fields.empty?
+  spawn._select!(*fields)
+end
+
+
+ +
+ +
+

+ + unscope(*args) + +

+ + +
+

Removes an unwanted relation that is already defined on a chain of relations. This is useful when passing around chains of relations and would like to modify the relations without reconstructing the entire chain.

+ +
User.order('email DESC').unscope(:order) == User.all
+
+ +

The method arguments are symbols which correspond to the names of the methods which should be unscoped. The valid arguments are given in VALID_UNSCOPING_VALUES. The method can also be called with multiple arguments. For example:

+ +
User.order('email DESC').select('id').where(name: "John")
+    .unscope(:order, :select, :where) == User.all
+
+ +

One can additionally pass a hash as an argument to unscope specific :where values. This is done by passing a hash with a single key-value pair. The key should be :where and the value should be the where value to unscope. For example:

+ +
User.where(name: "John", active: true).unscope(where: :name)
+    == User.where(active: true)
+
+ +

This method is similar to except, but unlike except, it persists across merges:

+ +
User.order('email').merge(User.except(:order))
+    == User.order('email')
+
+User.order('email').merge(User.unscope(:order))
+    == User.all
+
+ +

This means it can be used in association definitions:

+ +
has_many :comments, -> { unscope(where: :trashed) }
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 363
+def unscope(*args)
+  check_if_method_has_arguments!(:unscope, args)
+  spawn.unscope!(*args)
+end
+
+
+ +
+ +
+

+ + where(opts = :chain, *rest) + +

+ + +
+

Returns a new relation, which is the result of filtering the current relation according to the conditions in the arguments.

+ +

where accepts conditions in one of several formats. In the examples below, the resulting SQL is given as an illustration; the actual query generated may be different depending on the database adapter.

+ +

string

+ +

A single string, without additional arguments, is passed to the query constructor as an SQL fragment, and used in the where clause of the query.

+ +
Client.where("orders_count = '2'")
+# SELECT * from clients where orders_count = '2';
+
+ +

Note that building your own string from user input may expose your application to injection attacks if not done properly. As an alternative, it is recommended to use one of the following methods.

+ +

array

+ +

If an array is passed, then the first element of the array is treated as a template, and the remaining elements are inserted into the template to generate the condition. Active Record takes care of building the query to avoid injection attacks, and will convert from the ruby type to the database type where needed. Elements are inserted into the string in the order in which they appear.

+ +
User.where(["name = ? and email = ?", "Joe", "joe@example.com"])
+# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
+
+ +

Alternatively, you can use named placeholders in the template, and pass a hash as the second element of the array. The names in the template are replaced with the corresponding values from the hash.

+ +
User.where(["name = :name and email = :email", { name: "Joe", email: "joe@example.com" }])
+# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
+
+ +

This can make for more readable code in complex queries.

+ +

Lastly, you can use sprintf-style % escapes in the template. This works slightly differently than the previous methods; you are responsible for ensuring that the values in the template are properly quoted. The values are passed to the connector for quoting, but the caller is responsible for ensuring they are enclosed in quotes in the resulting SQL. After quoting, the values are inserted using the same escapes as the Ruby core method Kernel::sprintf.

+ +
User.where(["name = '%s' and email = '%s'", "Joe", "joe@example.com"])
+# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
+
+ +

If where is called with multiple arguments, these are treated as if they were passed as the elements of a single array.

+ +
User.where("name = :name and email = :email", { name: "Joe", email: "joe@example.com" })
+# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
+
+ +

When using strings to specify conditions, you can use any operator available from the database. While this provides the most flexibility, you can also unintentionally introduce dependencies on the underlying database. If your code is intended for general consumption, test with multiple database backends.

+ +

hash

+ +

where will also accept a hash condition, in which the keys are fields and the values are values to be searched for.

+ +

Fields can be symbols or strings. Values can be single values, arrays, or ranges.

+ +
User.where({ name: "Joe", email: "joe@example.com" })
+# SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'
+
+User.where({ name: ["Alice", "Bob"]})
+# SELECT * FROM users WHERE name IN ('Alice', 'Bob')
+
+User.where({ created_at: (Time.now.midnight - 1.day)..Time.now.midnight })
+# SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000')
+
+ +

In the case of a belongs_to relationship, an association key can be used to specify the model if an ActiveRecord object is used as the value.

+ +
author = Author.find(1)
+
+# The following queries will be equivalent:
+Post.where(author: author)
+Post.where(author_id: author)
+
+ +

This also works with polymorphic belongs_to relationships:

+ +
treasure = Treasure.create(name: 'gold coins')
+treasure.price_estimates << PriceEstimate.create(price: 125)
+
+# The following queries will be equivalent:
+PriceEstimate.where(estimate_of: treasure)
+PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure)
+
+ +

Joins

+ +

If the relation is the result of a join, you may create a condition which uses any of the tables in the join. For string and array conditions, use the table name in the condition.

+ +
User.joins(:posts).where("posts.created_at < ?", Time.now)
+
+ +

For hash conditions, you can either use the table name in the key, or use a sub-hash.

+ +
User.joins(:posts).where({ "posts.published" => true })
+User.joins(:posts).where({ posts: { published: true } })
+
+ +

no argument

+ +

If no argument is passed, where returns a new instance of WhereChain, that can be chained with not to return a new relation that negates the where clause.

+ +
User.where.not(name: "Jon")
+# SELECT * FROM users WHERE name != 'Jon'
+
+ +

See WhereChain for more details on not.

+ +

blank condition

+ +

If the condition is any blank-ish object, then where is a no-op and returns the current relation.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 575
+def where(opts = :chain, *rest)
+  if :chain == opts
+    WhereChain.new(spawn)
+  elsif opts.blank?
+    self
+  else
+    spawn.where!(opts, *rest)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/QueryMethods/WhereChain.html b/src/5.2/classes/ActiveRecord/QueryMethods/WhereChain.html new file mode 100644 index 0000000000..3ceaa03392 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/QueryMethods/WhereChain.html @@ -0,0 +1,182 @@ +--- +title: ActiveRecord::QueryMethods::WhereChain +layout: default +--- +
+ +
+
+ +
+ +

WhereChain objects act as placeholder for queries in which where does not have any parameter. In this case, where must be chained with not to return a new relation.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(scope) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 20
+def initialize(scope)
+  @scope = scope
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + not(opts, *rest) + +

+ + +
+

Returns a new relation expressing WHERE + NOT condition according to the conditions in the arguments.

+ +

not accepts conditions as a string, array, or hash. See QueryMethods#where for more details on each format.

+ +
User.where.not("name = 'Jon'")
+# SELECT * FROM users WHERE NOT (name = 'Jon')
+
+User.where.not(["name = ?", "Jon"])
+# SELECT * FROM users WHERE NOT (name = 'Jon')
+
+User.where.not(name: "Jon")
+# SELECT * FROM users WHERE name != 'Jon'
+
+User.where.not(name: nil)
+# SELECT * FROM users WHERE name IS NOT NULL
+
+User.where.not(name: %w(Ko1 Nobu))
+# SELECT * FROM users WHERE name NOT IN ('Ko1', 'Nobu')
+
+User.where.not(name: "Jon", role: "admin")
+# SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/query_methods.rb, line 47
+def not(opts, *rest)
+  opts = sanitize_forbidden_attributes(opts)
+
+  where_clause = @scope.send(:where_clause_factory).build(opts, rest)
+
+  @scope.references!(PredicateBuilder.references(opts)) if Hash === opts
+  @scope.where_clause += where_clause.invert
+  @scope
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Querying.html b/src/5.2/classes/ActiveRecord/Querying.html new file mode 100644 index 0000000000..f6a24cbe00 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Querying.html @@ -0,0 +1,176 @@ +--- +title: ActiveRecord::Querying +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + count_by_sql(sql) + +

+ + +
+

Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part. The use of this method should be restricted to complicated SQL queries that can't be executed using the ActiveRecord::Calculations class methods. Look into those before using this.

+ +
Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
+# => 12
+
+ +

Parameters

+
  • +

    sql - An SQL statement which should return a count query from the database, see the example above.

    +
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/querying.rb, line 66
+def count_by_sql(sql)
+  connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
+end
+
+
+ +
+ +
+

+ + find_by_sql(sql, binds = [], preparable: nil, &block) + +

+ + +
+

Executes a custom SQL query against your database and returns all the results. The results will be returned as an array with columns requested encapsulated as attributes of the model you call this method from. If you call Product.find_by_sql then the results will be returned in a Product object with the attributes you specified in the SQL query.

+ +

If you call a complicated SQL query which spans multiple tables the columns specified by the SELECT will be attributes of the model, whether or not they are columns of the corresponding table.

+ +

The sql parameter is a full SQL query as a string. It will be called as is, there will be no database agnostic conversions performed. This should be a last resort because using, for example, MySQL specific terms will lock you to using that particular database engine or require you to change your call if you switch engines.

+ +
# A simple SQL query spanning multiple tables
+Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
+# => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
+
+ +

You can use the same string replacement techniques as you can with ActiveRecord::QueryMethods#where:

+ +
Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
+Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/querying.rb, line 40
+def find_by_sql(sql, binds = [], preparable: nil, &block)
+  result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
+  column_types = result_set.column_types.dup
+  attribute_types.each_key { |k| column_types.delete k }
+  message_bus = ActiveSupport::Notifications.instrumenter
+
+  payload = {
+    record_count: result_set.length,
+    class_name: name
+  }
+
+  message_bus.instrument("instantiation.active_record", payload) do
+    result_set.map { |record| instantiate(record, column_types, &block) }
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/RangeError.html b/src/5.2/classes/ActiveRecord/RangeError.html new file mode 100644 index 0000000000..c7a70d15aa --- /dev/null +++ b/src/5.2/classes/ActiveRecord/RangeError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::RangeError +layout: default +--- +
+ +
+
+ +
+ +

Raised when values that executed are out of range.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ReadOnlyRecord.html b/src/5.2/classes/ActiveRecord/ReadOnlyRecord.html new file mode 100644 index 0000000000..b63965cfa6 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ReadOnlyRecord.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ReadOnlyRecord +layout: default +--- +
+ +
+
+ +
+ +

Raised on attempt to update record that is instantiated as read only.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ReadonlyAttributes.html b/src/5.2/classes/ActiveRecord/ReadonlyAttributes.html new file mode 100644 index 0000000000..dd4c9c4834 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ReadonlyAttributes.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::ReadonlyAttributes +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html b/src/5.2/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html new file mode 100644 index 0000000000..0aadb5ffda --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html @@ -0,0 +1,140 @@ +--- +title: ActiveRecord::ReadonlyAttributes::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attr_readonly(*attributes) + +

+ + +
+

Attributes listed as readonly will be used to create a new record but update operations will ignore these fields.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/readonly_attributes.rb, line 14
+def attr_readonly(*attributes)
+  self._attr_readonly = Set.new(attributes.map(&:to_s)) + (_attr_readonly || [])
+end
+
+
+ +
+ +
+

+ + readonly_attributes() + +

+ + +
+

Returns an array of all the attributes that have been specified as readonly.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/readonly_attributes.rb, line 19
+def readonly_attributes
+  _attr_readonly
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/RecordInvalid.html b/src/5.2/classes/ActiveRecord/RecordInvalid.html new file mode 100644 index 0000000000..4f9ffe5589 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/RecordInvalid.html @@ -0,0 +1,144 @@ +--- +title: ActiveRecord::RecordInvalid +layout: default +--- +
+ +
+
+ +
+ +

Active Record RecordInvalid

+ +

Raised by ActiveRecord::Base#save! and ActiveRecord::Base#create! when the record is invalid. Use the record method to retrieve the record which did not validate.

+ +
begin
+  complex_operation_that_internally_calls_save!
+rescue ActiveRecord::RecordInvalid => invalid
+  puts invalid.record.errors
+end
+
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(record = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations.rb, line 18
+def initialize(record = nil)
+  if record
+    @record = record
+    errors = @record.errors.full_messages.join(", ")
+    message = I18n.t(:"#{@record.class.i18n_scope}.errors.messages.record_invalid", errors: errors, default: :"errors.messages.record_invalid")
+  else
+    message = "Record invalid"
+  end
+
+  super(message)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/RecordNotDestroyed.html b/src/5.2/classes/ActiveRecord/RecordNotDestroyed.html new file mode 100644 index 0000000000..4c5f36afb8 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/RecordNotDestroyed.html @@ -0,0 +1,135 @@ +--- +title: ActiveRecord::RecordNotDestroyed +layout: default +--- +
+ +
+
+ +
+ +

Raised by ActiveRecord::Base#destroy! when a call to #destroy would return false.

+ +
begin
+  complex_operation_that_internally_calls_destroy!
+rescue ActiveRecord::RecordNotDestroyed => invalid
+  puts invalid.record.errors
+end
+
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, record = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 90
+def initialize(message = nil, record = nil)
+  @record = record
+  super(message)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/RecordNotFound.html b/src/5.2/classes/ActiveRecord/RecordNotFound.html new file mode 100644 index 0000000000..188f162b53 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/RecordNotFound.html @@ -0,0 +1,147 @@ +--- +title: ActiveRecord::RecordNotFound +layout: default +--- +
+ +
+
+ +
+ +

Raised when Active Record cannot find a record by given id or set of ids.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + id
+ [R] + model
+ [R] + primary_key
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, model = nil, primary_key = nil, id = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 56
+def initialize(message = nil, model = nil, primary_key = nil, id = nil)
+  @primary_key = primary_key
+  @model = model
+  @id = id
+
+  super(message)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/RecordNotSaved.html b/src/5.2/classes/ActiveRecord/RecordNotSaved.html new file mode 100644 index 0000000000..48e5700e62 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/RecordNotSaved.html @@ -0,0 +1,128 @@ +--- +title: ActiveRecord::RecordNotSaved +layout: default +--- +
+ +
+
+ +
+ +

Raised by ActiveRecord::Base#save! and ActiveRecord::Base.create! methods when a record is invalid and can not be saved.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, record = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 71
+def initialize(message = nil, record = nil)
+  @record = record
+  super(message)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/RecordNotUnique.html b/src/5.2/classes/ActiveRecord/RecordNotUnique.html new file mode 100644 index 0000000000..4dcd99cc2f --- /dev/null +++ b/src/5.2/classes/ActiveRecord/RecordNotUnique.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::RecordNotUnique +layout: default +--- +
+ +
+
+ +
+ +

Raised when a record cannot be inserted or updated because it would violate a uniqueness constraint.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Reflection.html b/src/5.2/classes/ActiveRecord/Reflection.html new file mode 100644 index 0000000000..9d71ebef0b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Reflection.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::Reflection +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Reflection/ClassMethods.html b/src/5.2/classes/ActiveRecord/Reflection/ClassMethods.html new file mode 100644 index 0000000000..71b9f80fa5 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Reflection/ClassMethods.html @@ -0,0 +1,337 @@ +--- +title: ActiveRecord::Reflection::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Reflection enables the ability to examine the associations and aggregations of Active Record classes and objects. This information, for example, can be used in a form builder that takes an Active Record object and creates input fields for all of the attributes depending on their type and displays the associations to other objects.

+ +

MacroReflection class has info for AggregateReflection and AssociationReflection classes.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + reflect_on_aggregation(aggregation) + +

+ + +
+

Returns the AggregateReflection object for the named aggregation (use the symbol).

+ +
Account.reflect_on_aggregation(:balance) # => the balance AggregateReflection
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 63
+def reflect_on_aggregation(aggregation)
+  aggregate_reflections[aggregation.to_s]
+end
+
+
+ +
+ +
+

+ + reflect_on_all_aggregations() + +

+ + +
+

Returns an array of AggregateReflection objects for all the aggregations in the class.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 55
+def reflect_on_all_aggregations
+  aggregate_reflections.values
+end
+
+
+ +
+ +
+

+ + reflect_on_all_associations(macro = nil) + +

+ + +
+

Returns an array of AssociationReflection objects for all the associations in the class. If you only want to reflect on a certain association type, pass in the symbol (:has_many, :has_one, :belongs_to) as the first parameter.

+ +

Example:

+ +
Account.reflect_on_all_associations             # returns an array of all associations
+Account.reflect_on_all_associations(:has_many)  # returns an array of all has_many associations
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 100
+def reflect_on_all_associations(macro = nil)
+  association_reflections = reflections.values
+  association_reflections.select! { |reflection| reflection.macro == macro } if macro
+  association_reflections
+end
+
+
+ +
+ +
+

+ + reflect_on_all_autosave_associations() + +

+ + +
+

Returns an array of AssociationReflection objects for all associations which have :autosave enabled.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 120
+def reflect_on_all_autosave_associations
+  reflections.values.select { |reflection| reflection.options[:autosave] }
+end
+
+
+ +
+ +
+

+ + reflect_on_association(association) + +

+ + +
+

Returns the AssociationReflection object for the association (use the symbol).

+ +
Account.reflect_on_association(:owner)             # returns the owner AssociationReflection
+Invoice.reflect_on_association(:line_items).macro  # returns :has_many
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 111
+def reflect_on_association(association)
+  reflections[association.to_s]
+end
+
+
+ +
+ +
+

+ + reflections() + +

+ + +
+

Returns a Hash of name of the reflection as the key and an AssociationReflection as the value.

+ +
Account.reflections # => {"balance" => AggregateReflection}
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 71
+def reflections
+  @__reflections ||= begin
+    ref = {}
+
+    _reflections.each do |name, reflection|
+      parent_reflection = reflection.parent_reflection
+
+      if parent_reflection
+        parent_name = parent_reflection.name
+        ref[parent_name.to_s] = parent_reflection
+      else
+        ref[name] = reflection
+      end
+    end
+
+    ref
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Reflection/MacroReflection.html b/src/5.2/classes/ActiveRecord/Reflection/MacroReflection.html new file mode 100644 index 0000000000..e7b3636424 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Reflection/MacroReflection.html @@ -0,0 +1,379 @@ +--- +title: ActiveRecord::Reflection::MacroReflection +layout: default +--- +
+ +
+
+ +
+ +

Base class for AggregateReflection and AssociationReflection. Objects of AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + active_record
+ [R] + name

Returns the name of the macro.

+ +

composed_of :balance, class_name: 'Money' returns :balance has_many :clients returns :clients

+ [R] + options

Returns the hash of options used for the macro.

+ +

composed_of :balance, class_name: 'Money' returns { class_name: "Money" } has_many :clients returns {}

+ [R] + scope
+ + + + +

Class Public methods

+ +
+

+ + new(name, scope, options, active_record) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 341
+def initialize(name, scope, options, active_record)
+  @name          = name
+  @scope         = scope
+  @options       = options
+  @active_record = active_record
+  @klass         = options[:anonymous_class]
+  @plural_name   = active_record.pluralize_table_names ?
+                      name.to_s.pluralize : name.to_s
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other_aggregation) + +

+ + +
+

Returns true if self and other_aggregation have the same name attribute, active_record attribute, and other_aggregation has an options hash assigned to it.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 384
+def ==(other_aggregation)
+  super ||
+    other_aggregation.kind_of?(self.class) &&
+    name == other_aggregation.name &&
+    !other_aggregation.options.nil? &&
+    active_record == other_aggregation.active_record
+end
+
+
+ +
+ +
+

+ + autosave=(autosave) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 351
+def autosave=(autosave)
+  @options[:autosave] = autosave
+  parent_reflection = self.parent_reflection
+  if parent_reflection
+    parent_reflection.autosave = autosave
+  end
+end
+
+
+ +
+ +
+

+ + compute_class(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 378
+def compute_class(name)
+  name.constantize
+end
+
+
+ +
+ +
+

+ + klass() + +

+ + +
+

Returns the class for the macro.

+ +

composed_of :balance, class_name: 'Money' returns the Money class has_many :clients returns the Client class

+ +
class Company < ActiveRecord::Base
+  has_many :clients
+end
+
+Company.reflect_on_association(:clients).klass
+# => Client
+
+ +

Note: Do not call klass.new or klass.create to instantiate a new association object. Use build_association or create_association instead. This allows plugins to hook into association object creation.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 374
+def klass
+  @klass ||= compute_class(class_name)
+end
+
+
+ +
+ +
+

+ + scope_for(relation, owner = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/reflection.rb, line 392
+def scope_for(relation, owner = nil)
+  relation.instance_exec(owner, &scope) || relation
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Relation.html b/src/5.2/classes/ActiveRecord/Relation.html new file mode 100644 index 0000000000..2727cb7c31 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Relation.html @@ -0,0 +1,1968 @@ +--- +title: ActiveRecord::Relation +layout: default +--- +
+ +
+
+ +
+ +

Active Record Relation

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CLAUSE_METHODS=[:where, :having, :from]
 
INVALID_METHODS_FOR_DELETE_ALL=[:distinct, :group, :having]
 
MULTI_VALUE_METHODS=[:includes, :eager_load, :preload, :select, :group, +:order, :joins, :left_outer_joins, :references, +:extending, :unscope]
 
SINGLE_VALUE_METHODS=[:limit, :offset, :lock, :readonly, :reordering, +:reverse_order, :distinct, :create_with, :skip_query_cache]
 
VALUE_METHODS=MULTI_VALUE_METHODS + SINGLE_VALUE_METHODS + CLAUSE_METHODS
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + klass
+ [R] + loaded
+ [R] + loaded?
+ [R] + model
+ [R] + predicate_builder
+ [R] + table
+ + + + +

Class Public methods

+ +
+

+ + new(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 25
+def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {})
+  @klass  = klass
+  @table  = table
+  @values = values
+  @offsets = {}
+  @loaded = false
+  @predicate_builder = predicate_builder
+  @delegate_to_klass = false
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+

Compares two relations for equality.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 487
+def ==(other)
+  case other
+  when Associations::CollectionProxy, AssociationRelation
+    self == other.records
+  when Relation
+    other.to_sql == to_sql
+  when Array
+    records == other
+  end
+end
+
+
+ +
+ +
+

+ + any?() + +

+ + +
+

Returns true if there are any records.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 227
+def any?
+  return super if block_given?
+  !empty?
+end
+
+
+ +
+ +
+

+ + blank?() + +

+ + +
+

Returns true if relation is blank.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 503
+def blank?
+  records.blank?
+end
+
+
+ +
+ +
+

+ + build(attributes = nil, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: new +
+ + + +
+ +
+

+ + cache_key(timestamp_column = :updated_at) + +

+ + +
+

Returns a cache key that can be used to identify the records fetched by this query. The cache key is built with a fingerprint of the sql query, the number of records matched by the query and a timestamp of the last updated record. When a new record comes to match the query, or any of the existing records is updated or deleted, the cache key changes.

+ +
Product.where("name like ?", "%Cosmic Encounter%").cache_key
+# => "products/query-1850ab3d302391b85b8693e941286659-1-20150714212553907087000"
+
+ +

If the collection is loaded, the method will iterate through the records to generate the timestamp, otherwise it will trigger one SQL query like:

+ +
SELECT COUNT(*), MAX("products"."updated_at") FROM "products" WHERE (name like '%Cosmic Encounter%')
+
+ +

You can also pass a custom timestamp column to fetch the timestamp of the last updated record.

+ +
Product.where("name like ?", "%Game%").cache_key(:last_reviewed_at)
+
+ +

You can customize the strategy to generate the key on a per model basis overriding ActiveRecord::Base#collection_cache_key.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 265
+def cache_key(timestamp_column = :updated_at)
+  @cache_keys ||= {}
+  @cache_keys[timestamp_column] ||= @klass.collection_cache_key(self, timestamp_column)
+end
+
+
+ +
+ +
+

+ + create(attributes = nil, &block) + +

+ + +
+

Tries to create a new record with the same scoped attributes defined in the relation. Returns the initialized object if validation fails.

+ +

Expects arguments in the same format as ActiveRecord::Base.create.

+ +

Examples

+ +
users = User.where(name: 'Oscar')
+users.create # => #<User id: 3, name: "Oscar", ...>
+
+users.create(name: 'fxn')
+users.create # => #<User id: 4, name: "fxn", ...>
+
+users.create { |user| user.name = 'tenderlove' }
+# => #<User id: 5, name: "tenderlove", ...>
+
+users.create(name: nil) # validation on name
+# => #<User id: nil, name: nil, ...>
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 81
+def create(attributes = nil, &block)
+  if attributes.is_a?(Array)
+    attributes.collect { |attr| create(attr, &block) }
+  else
+    scoping { klass.create(values_for_create(attributes), &block) }
+  end
+end
+
+
+ +
+ +
+

+ + create!(attributes = nil, &block) + +

+ + +
+

Similar to create, but calls create! on the base class. Raises an exception if a validation error occurs.

+ +

Expects arguments in the same format as ActiveRecord::Base.create!.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 95
+def create!(attributes = nil, &block)
+  if attributes.is_a?(Array)
+    attributes.collect { |attr| create!(attr, &block) }
+  else
+    scoping { klass.create!(values_for_create(attributes), &block) }
+  end
+end
+
+
+ +
+ +
+

+ + delete_all() + +

+ + +
+

Deletes the records without instantiating the records first, and hence not calling the #destroy method nor invoking callbacks. This is a single SQL DELETE statement that goes straight to the database, much more efficient than destroy_all. Be careful with relations though, in particular :dependent rules defined on associations are not honored. Returns the number of rows affected.

+ +
Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
+
+ +

Both calls delete the affected posts all at once with a single DELETE statement. If you need to destroy dependent associations or call your before_* or after_destroy callbacks, use the destroy_all method instead.

+ +

If an invalid method is supplied, delete_all raises an ActiveRecordError:

+ +
Post.distinct.delete_all
+# => ActiveRecord::ActiveRecordError: delete_all doesn't support distinct
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 386
+def delete_all
+  invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select do |method|
+    value = get_value(method)
+    SINGLE_VALUE_METHODS.include?(method) ? value : value.any?
+  end
+  if invalid_methods.any?
+    raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
+  end
+
+  if eager_loading?
+    relation = apply_join_dependency
+    return relation.delete_all
+  end
+
+  stmt = Arel::DeleteManager.new
+  stmt.from(table)
+
+  if has_join_values? || has_limit_or_offset?
+    @klass.connection.join_to_delete(stmt, arel, arel_attribute(primary_key))
+  else
+    stmt.wheres = arel.constraints
+  end
+
+  affected = @klass.connection.delete(stmt, "#{@klass} Destroy")
+
+  reset
+  affected
+end
+
+
+ +
+ +
+

+ + destroy_all() + +

+ + +
+

Destroys the records by instantiating each record and calling its #destroy method. Each object's callbacks are executed (including :dependent association options). Returns the collection of objects that were destroyed; each will be frozen, to reflect that no changes should be made (since they can't be persisted).

+ +

Note: Instantiation, callback execution, and deletion of each record can be time consuming when you're removing many records at once. It generates at least one SQL DELETE query per record (or possibly more, to enforce your callbacks). If you want to delete many rows quickly, without concern for their associations or callbacks, use delete_all instead.

+ +

Examples

+ +
Person.where(age: 0..18).destroy_all
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 364
+def destroy_all
+  records.each(&:destroy).tap { reset }
+end
+
+
+ +
+ +
+

+ + eager_loading?() + +

+ + +
+

Returns true if relation needs eager loading.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 472
+def eager_loading?
+  @should_eager_load ||=
+    eager_load_values.any? ||
+    includes_values.any? && (joined_includes_values.any? || references_eager_loaded_tables?)
+end
+
+
+ +
+ +
+

+ + empty?() + +

+ + +
+

Returns true if there are no records.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 215
+def empty?
+  return @records.empty? if loaded?
+  !exists?
+end
+
+
+ +
+ +
+

+ + encode_with(coder) + +

+ + +
+

Serializes the relation objects Array.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 205
+def encode_with(coder)
+  coder.represent_seq(nil, records)
+end
+
+
+ +
+ +
+

+ + explain() + +

+ + +
+

Runs EXPLAIN on the query or queries triggered by this relation and returns the result as a string. The string is formatted imitating the ones printed by the database shell.

+ +

Note that this method actually runs the queries, since the results of some are needed by the next ones when eager loading is going on.

+ +

Please see further details in the Active Record Query Interface guide.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 189
+def explain
+  exec_explain(collecting_queries_for_explain { exec_queries })
+end
+
+
+ +
+ +
+

+ + find_or_create_by(attributes, &block) + +

+ + +
+

Finds the first record with the given attributes, or creates a record with the attributes if one is not found:

+ +
# Find the first user named "Penélope" or create a new one.
+User.find_or_create_by(first_name: 'Penélope')
+# => #<User id: 1, first_name: "Penélope", last_name: nil>
+
+# Find the first user named "Penélope" or create a new one.
+# We already have one so the existing record will be returned.
+User.find_or_create_by(first_name: 'Penélope')
+# => #<User id: 1, first_name: "Penélope", last_name: nil>
+
+# Find the first user named "Scarlett" or create a new one with
+# a particular last name.
+User.create_with(last_name: 'Johansson').find_or_create_by(first_name: 'Scarlett')
+# => #<User id: 2, first_name: "Scarlett", last_name: "Johansson">
+
+ +

This method accepts a block, which is passed down to create. The last example above can be alternatively written this way:

+ +
# Find the first user named "Scarlett" or create a new one with a
+# different last name.
+User.find_or_create_by(first_name: 'Scarlett') do |user|
+  user.last_name = 'Johansson'
+end
+# => #<User id: 2, first_name: "Scarlett", last_name: "Johansson">
+
+ +

This method always returns a record, but if creation was attempted and failed due to validation errors it won't be persisted, you get what create returns in such situation.

+ +

Please note *this method is not atomic*, it runs first a SELECT, and if there are no results an INSERT is attempted. If there are other threads or processes there is a race condition between both calls and it could be the case that you end up with two similar records.

+ +

Whether that is a problem or not depends on the logic of the application, but in the particular case in which rows have a UNIQUE constraint an exception may be raised, just retry:

+ +
begin
+  CreditAccount.transaction(requires_new: true) do
+    CreditAccount.find_or_create_by(user_id: user.id)
+  end
+rescue ActiveRecord::RecordNotUnique
+  retry
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 163
+def find_or_create_by(attributes, &block)
+  find_by(attributes) || create(attributes, &block)
+end
+
+
+ +
+ +
+

+ + find_or_create_by!(attributes, &block) + +

+ + +
+

Like find_or_create_by, but calls create! so an exception is raised if the created record is invalid.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 170
+def find_or_create_by!(attributes, &block)
+  find_by(attributes) || create!(attributes, &block)
+end
+
+
+ +
+ +
+

+ + find_or_initialize_by(attributes, &block) + +

+ + +
+

Like find_or_create_by, but calls new instead of create.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 176
+def find_or_initialize_by(attributes, &block)
+  find_by(attributes) || new(attributes, &block)
+end
+
+
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 35
+def initialize_copy(other)
+  @values = @values.dup
+  reset
+end
+
+
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 511
+def inspect
+  subject = loaded? ? records : self
+  entries = subject.take([limit_value, 11].compact.min).map!(&:inspect)
+
+  entries[10] = "..." if entries.size == 11
+
+  "#<#{self.class.name} [#{entries.join(', ')}]>"
+end
+
+
+ +
+ +
+

+ + joined_includes_values() + +

+ + +
+

Joins that are also marked for preloading. In which case we should just eager load them. Note that this is a naive implementation because we could have strings and symbols which represent the same association, but that aren't matched by this. Also, we could have nested hashes which partially match, e.g. { a: :b } & { a: [:b, :c] }

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 482
+def joined_includes_values
+  includes_values & joins_values
+end
+
+
+ +
+ +
+

+ + load(&block) + +

+ + +
+

Causes the records to be loaded from the database if they have not been loaded already. You can use this if for some reason you need to explicitly load some records before actually using them. The return value is the relation itself, not the records.

+ +
Post.where(published: true).load # => #<ActiveRecord::Relation>
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 421
+def load(&block)
+  exec_queries(&block) unless loaded?
+
+  self
+end
+
+
+ +
+ +
+

+ + many?() + +

+ + +
+

Returns true if there is more than one record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 239
+def many?
+  return super if block_given?
+  limit_value ? records.many? : size > 1
+end
+
+
+ +
+ +
+

+ + new(attributes = nil, &block) + +

+ + +
+

Initializes new record from relation while maintaining the current scope.

+ +

Expects arguments in the same format as ActiveRecord::Base.new.

+ +
users = User.where(name: 'DHH')
+user = users.new # => #<User id: nil, name: "DHH", created_at: nil, updated_at: nil>
+
+ +

You can also pass a block to new with the new record as argument:

+ +
user = users.new { |user| user.name = 'Oscar' }
+user.name # => Oscar
+
+
+ + + +
+ Also aliased as: build +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 56
+def new(attributes = nil, &block)
+  scoping { klass.new(values_for_create(attributes), &block) }
+end
+
+
+ +
+ +
+

+ + none?() + +

+ + +
+

Returns true if there are no records.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 221
+def none?
+  return super if block_given?
+  empty?
+end
+
+
+ +
+ +
+

+ + one?() + +

+ + +
+

Returns true if there is exactly one record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 233
+def one?
+  return super if block_given?
+  limit_value ? records.one? : size == 1
+end
+
+
+ +
+ +
+

+ + pretty_print(q) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 498
+def pretty_print(q)
+  q.pp(records)
+end
+
+
+ +
+ +
+

+ + reload() + +

+ + +
+

Forces reloading of relation.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 428
+def reload
+  reset
+  load
+end
+
+
+ +
+ +
+

+ + reset() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 433
+def reset
+  @delegate_to_klass = false
+  @to_sql = @arel = @loaded = @should_eager_load = nil
+  @records = [].freeze
+  @offsets = {}
+  self
+end
+
+
+ +
+ +
+

+ + scope_for_create() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 467
+def scope_for_create
+  where_values_hash.merge!(create_with_value.stringify_keys)
+end
+
+
+ +
+ +
+

+ + scoping() + +

+ + +
+

Scope all queries to the current scope.

+ +
Comment.where(post_id: 1).scoping do
+  Comment.first
+end
+# => SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 ORDER BY "comments"."id" ASC LIMIT 1
+
+ +

Please check unscoped if you want to remove all previous scopes (including the default_scope) during the execution of a block.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 279
+def scoping
+  previous, klass.current_scope = klass.current_scope(true), self unless @delegate_to_klass
+  yield
+ensure
+  klass.current_scope = previous unless @delegate_to_klass
+end
+
+
+ +
+ +
+

+ + size() + +

+ + +
+

Returns size of the records.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 210
+def size
+  loaded? ? @records.length : count(:all)
+end
+
+
+ +
+ +
+

+ + to_a() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_ary +
+ + + +
+ +
+

+ + to_ary() + +

+ + +
+

Converts relation objects to Array.

+
+ + + +
+ Also aliased as: to_a +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 194
+def to_ary
+  records.dup
+end
+
+
+ +
+ +
+

+ + to_sql() + +

+ + +
+

Returns sql statement for the relation.

+ +
User.where(name: 'Oscar').to_sql
+# => SELECT "users".* FROM "users"  WHERE "users"."name" = 'Oscar'
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 445
+def to_sql
+  @to_sql ||= begin
+    if eager_loading?
+      apply_join_dependency do |relation, join_dependency|
+        relation = join_dependency.apply_column_aliases(relation)
+        relation.to_sql
+      end
+    else
+      conn = klass.connection
+      conn.unprepared_statement { conn.to_sql(arel) }
+    end
+  end
+end
+
+
+ +
+ +
+

+ + update_all(updates) + +

+ + +
+

Updates all records in the current relation with details given. This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks or validations. However, values passed to update_all will still go through Active Record's normal type casting and serialization.

+ +

Parameters

+
  • +

    updates - A string, array, or hash representing the SET part of an SQL statement.

    +
+ +

Examples

+ +
# Update all customers with the given attributes
+Customer.update_all wants_email: true
+
+# Update all books with 'Rails' in their title
+Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')
+
+# Update all books that match conditions, but limit it to 5 ordered by date
+Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(author: 'David')
+
+# Update all invoices and set the number column to its id value.
+Invoice.update_all('number = id')
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 315
+def update_all(updates)
+  raise ArgumentError, "Empty list of attributes to change" if updates.blank?
+
+  if eager_loading?
+    relation = apply_join_dependency
+    return relation.update_all(updates)
+  end
+
+  stmt = Arel::UpdateManager.new
+
+  stmt.set Arel.sql(@klass.sanitize_sql_for_assignment(updates))
+  stmt.table(table)
+
+  if has_join_values? || offset_value
+    @klass.connection.join_to_update(stmt, arel, arel_attribute(primary_key))
+  else
+    stmt.key = arel_attribute(primary_key)
+    stmt.take(arel.limit)
+    stmt.order(*arel.orders)
+    stmt.wheres = arel.constraints
+  end
+
+  @klass.connection.update stmt, "#{@klass} Update All"
+end
+
+
+ +
+ +
+

+ + values() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 507
+def values
+  @values.dup
+end
+
+
+ +
+ +
+

+ + where_values_hash(relation_table_name = klass.table_name) + +

+ + +
+

Returns a hash of where conditions.

+ +
User.where(name: 'Oscar').where_values_hash
+# => {name: "Oscar"}
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 463
+def where_values_hash(relation_table_name = klass.table_name)
+  where_clause.to_h(relation_table_name)
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + load_records(records) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation.rb, line 535
+def load_records(records)
+  @records = records.freeze
+  @loaded = true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Relation/RecordFetchWarning.html b/src/5.2/classes/ActiveRecord/Relation/RecordFetchWarning.html new file mode 100644 index 0000000000..6bf0323ebb --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Relation/RecordFetchWarning.html @@ -0,0 +1,111 @@ +--- +title: ActiveRecord::Relation::RecordFetchWarning +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + exec_queries() + +

+ + +
+

When this module is prepended to ActiveRecord::Relation and config.active_record.warn_on_records_fetched_greater_than is set to an integer, if the number of records a query returns is greater than the value of warn_on_records_fetched_greater_than, a warning is logged. This allows for the detection of queries that return a large number of records, which could cause memory bloat.

+ +

In most cases, fetching large number of records can be performed efficiently using the ActiveRecord::Batches methods. See ActiveRecord::Batches for more information.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/record_fetch_warning.rb, line 16
+def exec_queries
+  QueryRegistry.reset
+
+  super.tap do
+    if logger && warn_on_records_fetched_greater_than
+      if @records.length > warn_on_records_fetched_greater_than
+        logger.warn "Query fetched #{@records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
+      end
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Result.html b/src/5.2/classes/ActiveRecord/Result.html new file mode 100644 index 0000000000..5d40742efe --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Result.html @@ -0,0 +1,552 @@ +--- +title: ActiveRecord::Result +layout: default +--- +
+ +
+
+ +
+ +

This class encapsulates a result returned from calling #exec_query on any database connection adapter. For example:

+ +
result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
+result # => #<ActiveRecord::Result:0xdeadbeef>
+
+# Get the column names of the result:
+result.columns
+# => ["id", "title", "body"]
+
+# Get the record values of the result:
+result.rows
+# => [[1, "title_1", "body_1"],
+      [2, "title_2", "body_2"],
+      ...
+     ]
+
+# Get an array of hashes representing the result (column => value):
+result.to_hash
+# => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
+      {"id" => 2, "title" => "title_2", "body" => "body_2"},
+      ...
+     ]
+
+# ActiveRecord::Result also includes Enumerable.
+result.each do |row|
+  puts row['title'] + " " + row['body']
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + column_types
+ [R] + columns
+ [R] + rows
+ + + + +

Class Public methods

+ +
+

+ + new(columns, rows, column_types = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 39
+def initialize(columns, rows, column_types = {})
+  @columns      = columns
+  @rows         = rows
+  @hash_rows    = nil
+  @column_types = column_types
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](idx) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 81
+def [](idx)
+  hash_rows[idx]
+end
+
+
+ +
+ +
+

+ + each() + +

+ + +
+

Calls the given block once for each element in row collection, passing row as parameter.

+ +

Returns an Enumerator if no block is given.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 55
+def each
+  if block_given?
+    hash_rows.each { |row| yield row }
+  else
+    hash_rows.to_enum { @rows.size }
+  end
+end
+
+
+ +
+ +
+

+ + empty?() + +

+ + +
+

Returns true if there are no records, otherwise false.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 72
+def empty?
+  rows.empty?
+end
+
+
+ +
+ +
+

+ + first() + +

+ + +
+

Returns the first record from the rows collection. If the rows collection is empty, returns nil.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 87
+def first
+  return nil if @rows.empty?
+  Hash[@columns.zip(@rows.first)]
+end
+
+
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 108
+def initialize_copy(other)
+  @columns      = columns.dup
+  @rows         = rows.dup
+  @column_types = column_types.dup
+  @hash_rows    = nil
+end
+
+
+ +
+ +
+

+ + last() + +

+ + +
+

Returns the last record from the rows collection. If the rows collection is empty, returns nil.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 94
+def last
+  return nil if @rows.empty?
+  Hash[@columns.zip(@rows.last)]
+end
+
+
+ +
+ +
+

+ + length() + +

+ + +
+

Returns the number of elements in the rows array.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 47
+def length
+  @rows.length
+end
+
+
+ +
+ +
+

+ + to_ary() + +

+ + +
+

Returns an array of hashes representing each row record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 77
+def to_ary
+  hash_rows
+end
+
+
+ +
+ +
+

+ + to_hash() + +

+ + +
+

Returns an array of hashes representing each row record.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/result.rb, line 64
+def to_hash
+  hash_rows
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Rollback.html b/src/5.2/classes/ActiveRecord/Rollback.html new file mode 100644 index 0000000000..7229f48582 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Rollback.html @@ -0,0 +1,88 @@ +--- +title: ActiveRecord::Rollback +layout: default +--- +
+ +
+
+ +
+ +

ActiveRecord::Base.transaction uses this exception to distinguish a deliberate rollback from other exceptional situations. Normally, raising an exception will cause the .transaction method to rollback the database transaction and pass on the exception. But if you raise an ActiveRecord::Rollback exception, then the database transaction will be rolled back, without passing on the exception.

+ +

For example, you could do this in your controller to rollback a transaction:

+ +
class BooksController < ActionController::Base
+  def create
+    Book.transaction do
+      book = Book.new(params[:book])
+      book.save!
+      if today_is_friday?
+        # The system must fail on Friday so that our support department
+        # won't be out of job. We silently rollback this transaction
+        # without telling the user.
+        raise ActiveRecord::Rollback, "Call tech support!"
+      end
+    end
+    # ActiveRecord::Rollback is the only exception that won't be passed on
+    # by ActiveRecord::Base.transaction, so this line will still be reached
+    # even on Friday.
+    redirect_to root_url
+  end
+end
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Sanitization.html b/src/5.2/classes/ActiveRecord/Sanitization.html new file mode 100644 index 0000000000..8c74f4d367 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Sanitization.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Sanitization +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Sanitization/ClassMethods.html b/src/5.2/classes/ActiveRecord/Sanitization/ClassMethods.html new file mode 100644 index 0000000000..09abd2e412 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Sanitization/ClassMethods.html @@ -0,0 +1,499 @@ +--- +title: ActiveRecord::Sanitization::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + sanitize_sql(condition) + +

+ + +
+ +
+ + + + + + + + + +
+ +
+

+ + sanitize_sql_array(ary) + +

+ + +
+

Accepts an array of conditions. The array has each value sanitized and interpolated into the SQL statement.

+ +
sanitize_sql_array(["name=? and group_id=?", "foo'bar", 4])
+# => "name='foo''bar' and group_id=4"
+
+sanitize_sql_array(["name=:name and group_id=:group_id", name: "foo'bar", group_id: 4])
+# => "name='foo''bar' and group_id=4"
+
+sanitize_sql_array(["name='%s' and group_id='%s'", "foo'bar", 4])
+# => "name='foo''bar' and group_id='4'"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/sanitization.rb, line 123
+def sanitize_sql_array(ary)
+  statement, *values = ary
+  if values.first.is_a?(Hash) && /:\w+/.match?(statement)
+    replace_named_bind_variables(statement, values.first)
+  elsif statement.include?("?")
+    replace_bind_variables(statement, values)
+  elsif statement.blank?
+    statement
+  else
+    statement % values.collect { |value| connection.quote_string(value.to_s) }
+  end
+end
+
+
+ +
+ +
+

+ + sanitize_sql_for_assignment(assignments, default_table_name = table_name) + +

+ + +
+

Accepts an array, hash, or string of SQL conditions and sanitizes them into a valid SQL fragment for a SET clause.

+ +
sanitize_sql_for_assignment(["name=? and group_id=?", nil, 4])
+# => "name=NULL and group_id=4"
+
+sanitize_sql_for_assignment(["name=:name and group_id=:group_id", name: nil, group_id: 4])
+# => "name=NULL and group_id=4"
+
+Post.sanitize_sql_for_assignment({ name: nil, group_id: 4 })
+# => "`posts`.`name` = NULL, `posts`.`group_id` = 4"
+
+sanitize_sql_for_assignment("name=NULL and group_id='4'")
+# => "name=NULL and group_id='4'"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/sanitization.rb, line 46
+def sanitize_sql_for_assignment(assignments, default_table_name = table_name)
+  case assignments
+  when Array; sanitize_sql_array(assignments)
+  when Hash;  sanitize_sql_hash_for_assignment(assignments, default_table_name)
+  else        assignments
+  end
+end
+
+
+ +
+ +
+

+ + sanitize_sql_for_conditions(condition) + +

+ + +
+

Accepts an array or string of SQL conditions and sanitizes them into a valid SQL fragment for a WHERE clause.

+ +
sanitize_sql_for_conditions(["name=? and group_id=?", "foo'bar", 4])
+# => "name='foo''bar' and group_id=4"
+
+sanitize_sql_for_conditions(["name=:name and group_id=:group_id", name: "foo'bar", group_id: 4])
+# => "name='foo''bar' and group_id='4'"
+
+sanitize_sql_for_conditions(["name='%s' and group_id='%s'", "foo'bar", 4])
+# => "name='foo''bar' and group_id='4'"
+
+sanitize_sql_for_conditions("name='foo''bar' and group_id='4'")
+# => "name='foo''bar' and group_id='4'"
+
+
+ + + +
+ Also aliased as: sanitize_sql +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/sanitization.rb, line 22
+def sanitize_sql_for_conditions(condition)
+  return nil if condition.blank?
+
+  case condition
+  when Array; sanitize_sql_array(condition)
+  else        condition
+  end
+end
+
+
+ +
+ +
+

+ + sanitize_sql_for_order(condition) + +

+ + +
+

Accepts an array, or string of SQL conditions and sanitizes them into a valid SQL fragment for an ORDER clause.

+ +
sanitize_sql_for_order(["field(id, ?)", [1,3,2]])
+# => "field(id, 1,3,2)"
+
+sanitize_sql_for_order("id ASC")
+# => "id ASC"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/sanitization.rb, line 62
+def sanitize_sql_for_order(condition)
+  if condition.is_a?(Array) && condition.first.to_s.include?("?")
+    enforce_raw_sql_whitelist([condition.first],
+      whitelist: AttributeMethods::ClassMethods::COLUMN_NAME_ORDER_WHITELIST
+    )
+
+    # Ensure we aren't dealing with a subclass of String that might
+    # override methods we use (eg. Arel::Nodes::SqlLiteral).
+    if condition.first.kind_of?(String) && !condition.first.instance_of?(String)
+      condition = [String.new(condition.first), *condition[1..-1]]
+    end
+
+    Arel.sql(sanitize_sql_array(condition))
+  else
+    condition
+  end
+end
+
+
+ +
+ +
+

+ + sanitize_sql_hash_for_assignment(attrs, table) + +

+ + +
+

Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.

+ +
sanitize_sql_hash_for_assignment({ status: nil, group_id: 1 }, "posts")
+# => "`posts`.`status` = NULL, `posts`.`group_id` = 1"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/sanitization.rb, line 84
+def sanitize_sql_hash_for_assignment(attrs, table)
+  c = connection
+  attrs.map do |attr, value|
+    type = type_for_attribute(attr)
+    value = type.serialize(type.cast(value))
+    "#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
+  end.join(", ")
+end
+
+
+ +
+ +
+

+ + sanitize_sql_like(string, escape_character = "\\") + +

+ + +
+

Sanitizes a string so that it is safe to use within an SQL LIKE statement. This method uses escape_character to escape all occurrences of “", ”_“ and ”%“.

+ +
sanitize_sql_like("100%")
+# => "100\\%"
+
+sanitize_sql_like("snake_cased_string")
+# => "snake\\_cased\\_string"
+
+sanitize_sql_like("100%", "!")
+# => "100!%"
+
+sanitize_sql_like("snake_cased_string", "!")
+# => "snake!_cased!_string"
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/sanitization.rb, line 107
+def sanitize_sql_like(string, escape_character = "\\")
+  pattern = Regexp.union(escape_character, "%", "_")
+  string.gsub(pattern) { |x| [escape_character, x].join }
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + expand_hash_conditions_for_aggregates(attrs) + +

+ + +
+

Accepts a hash of SQL conditions and replaces those attributes that correspond to a #composed_of relationship with their expanded aggregate attribute values.

+ +

Given:

+ +
class Person < ActiveRecord::Base
+  composed_of :address, class_name: "Address",
+    mapping: [%w(address_street street), %w(address_city city)]
+end
+
+ +

Then:

+ +
{ address: Address.new("813 abc st.", "chicago") }
+# => { address_street: "813 abc st.", address_city: "chicago" }
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/sanitization.rb, line 152
+def expand_hash_conditions_for_aggregates(attrs) # :doc:
+  expanded_attrs = {}
+  attrs.each do |attr, value|
+    if aggregation = reflect_on_aggregation(attr.to_sym)
+      mapping = aggregation.mapping
+      mapping.each do |field_attr, aggregate_attr|
+        expanded_attrs[field_attr] = if value.is_a?(Array)
+          value.map { |it| it.send(aggregate_attr) }
+        elsif mapping.size == 1 && !value.respond_to?(aggregate_attr)
+          value
+        else
+          value.send(aggregate_attr)
+        end
+      end
+    else
+      expanded_attrs[attr] = value
+    end
+  end
+  expanded_attrs
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Schema.html b/src/5.2/classes/ActiveRecord/Schema.html new file mode 100644 index 0000000000..169b181364 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Schema.html @@ -0,0 +1,144 @@ +--- +title: ActiveRecord::Schema +layout: default +--- +
+ +
+
+ +
+ +

Active Record Schema

+ +

Allows programmers to programmatically define a schema in a portable DSL. This means you can define tables, indexes, etc. without using SQL directly, so your applications can more easily support multiple databases.

+ +

Usage:

+ +
ActiveRecord::Schema.define do
+  create_table :authors do |t|
+    t.string :name, null: false
+  end
+
+  add_index :authors, :name, :unique
+
+  create_table :posts do |t|
+    t.integer :author_id, null: false
+    t.string :subject
+    t.text :body
+    t.boolean :private, default: false
+  end
+
+  add_index :posts, :author_id
+end
+
+ +

ActiveRecord::Schema is only supported by database adapters that also support migrations, the two features being very similar.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + define(info = {}, &block) + +

+ + +
+

Eval the given block. All methods available to the current connection adapter are available within the block, so you can easily use the database definition DSL to build up your schema ( create_table, add_index, etc.).

+ +

The info hash is optional, and if given is used to define metadata about the current schema (currently, only the schema's version):

+ +
ActiveRecord::Schema.define(version: 2038_01_19_000001) do
+  ...
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/schema.rb, line 45
+def self.define(info = {}, &block)
+  new.define(info, &block)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Scoping.html b/src/5.2/classes/ActiveRecord/Scoping.html new file mode 100644 index 0000000000..5ab4785b30 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Scoping.html @@ -0,0 +1,101 @@ +--- +title: ActiveRecord::Scoping +layout: default +--- +
+ +
+
+ +
+ +

Active Record Named Scopes

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Scoping/Default.html b/src/5.2/classes/ActiveRecord/Scoping/Default.html new file mode 100644 index 0000000000..9203144365 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Scoping/Default.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Scoping::Default +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Scoping/Default/ClassMethods.html b/src/5.2/classes/ActiveRecord/Scoping/Default/ClassMethods.html new file mode 100644 index 0000000000..28cd65008b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Scoping/Default/ClassMethods.html @@ -0,0 +1,207 @@ +--- +title: ActiveRecord::Scoping::Default::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + unscoped() + +

+ + +
+

Returns a scope for the model without the previously set scopes.

+ +
class Post < ActiveRecord::Base
+  def self.default_scope
+    where(published: true)
+  end
+end
+
+Post.all                                  # Fires "SELECT * FROM posts WHERE published = true"
+Post.unscoped.all                         # Fires "SELECT * FROM posts"
+Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
+
+ +

This method also accepts a block. All queries inside the block will not use the previously set scopes.

+ +
Post.unscoped {
+  Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
+}
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/scoping/default.rb, line 33
+def unscoped
+  block_given? ? relation.scoping { yield } : relation
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + default_scope(scope = nil, &block) + +

+ + +
+

Use this macro in your model to set a default scope for all operations on the model.

+ +
class Article < ActiveRecord::Base
+  default_scope { where(published: true) }
+end
+
+Article.all # => SELECT * FROM articles WHERE published = true
+
+ +

The default_scope is also applied while creating/building a record. It is not applied while updating a record.

+ +
Article.new.published    # => true
+Article.create.published # => true
+
+ +

(You can also pass any object which responds to call to the default_scope macro, and it will be called when building the default scope.)

+ +

If you use multiple default_scope declarations in your model then they will be merged together:

+ +
class Article < ActiveRecord::Base
+  default_scope { where(published: true) }
+  default_scope { where(rating: 'G') }
+end
+
+Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
+
+ +

This is also the case with inheritance and module includes where the parent or module defines a default_scope and the child or including class defines a second one.

+ +

If you need to do more complex things with a default scope, you can alternatively define it as a class method:

+ +
class Article < ActiveRecord::Base
+  def self.default_scope
+    # Should return a scope, you can call 'super' here etc.
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/scoping/default.rb, line 89
+def default_scope(scope = nil, &block) # :doc:
+  scope = block if block_given?
+
+  if scope.is_a?(Relation) || !scope.respond_to?(:call)
+    raise ArgumentError,
+      "Support for calling #default_scope without a block is removed. For example instead " \
+      "of `default_scope where(color: 'red')`, please use " \
+      "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
+      "self.default_scope.)"
+  end
+
+  self.default_scopes += [scope]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Scoping/Named.html b/src/5.2/classes/ActiveRecord/Scoping/Named.html new file mode 100644 index 0000000000..edbf6ccb31 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Scoping/Named.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Scoping::Named +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Scoping/Named/ClassMethods.html b/src/5.2/classes/ActiveRecord/Scoping/Named/ClassMethods.html new file mode 100644 index 0000000000..44fe1a83ac --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Scoping/Named/ClassMethods.html @@ -0,0 +1,273 @@ +--- +title: ActiveRecord::Scoping::Named::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + all() + +

+ + +
+

Returns an ActiveRecord::Relation scope object.

+ +
posts = Post.all
+posts.size # Fires "select count(*) from  posts" and returns the count
+posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
+
+fruits = Fruit.all
+fruits = fruits.where(color: 'red') if options[:red_only]
+fruits = fruits.limit(10) if limited?
+
+ +

You can define a scope that applies to all finders using default_scope.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/scoping/named.rb, line 26
+def all
+  current_scope = self.current_scope
+
+  if current_scope
+    if self == current_scope.klass
+      current_scope.clone
+    else
+      relation.merge!(current_scope)
+    end
+  else
+    default_scoped
+  end
+end
+
+
+ +
+ +
+

+ + scope(name, body, &block) + +

+ + +
+

Adds a class method for retrieving and querying objects. The method is intended to return an ActiveRecord::Relation object, which is composable with other scopes. If it returns nil or false, an all scope is returned instead.

+ +

A scope represents a narrowing of a database query, such as where(color: :red).select('shirts.*').includes(:washing_instructions).

+ +
class Shirt < ActiveRecord::Base
+  scope :red, -> { where(color: 'red') }
+  scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) }
+end
+
+ +

The above calls to scope define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red, in effect, represents the query Shirt.where(color: 'red').

+ +

You should always pass a callable object to the scopes defined with scope. This ensures that the scope is re-evaluated each time it is called.

+ +

Note that this is simply 'syntactic sugar' for defining an actual class method:

+ +
class Shirt < ActiveRecord::Base
+  def self.red
+    where(color: 'red')
+  end
+end
+
+ +

Unlike Shirt.find(...), however, the object returned by Shirt.red is not an Array but an ActiveRecord::Relation, which is composable with other scopes; it resembles the association object constructed by a has_many declaration. For instance, you can invoke Shirt.red.first, Shirt.red.count, Shirt.red.where(size: 'small'). Also, just as with the association objects, named scopes act like an Array, implementing Enumerable; Shirt.red.each(&block), Shirt.red.first, and Shirt.red.inject(memo, &block) all behave as if Shirt.red really was an array.

+ +

These named scopes are composable. For instance, Shirt.red.dry_clean_only will produce all shirts that are both red and dry clean only. Nested finds and calculations also work with these compositions: Shirt.red.dry_clean_only.count returns the number of garments for which these criteria obtain. Similarly with Shirt.red.dry_clean_only.average(:thread_count).

+ +

All scopes are available as class methods on the ActiveRecord::Base descendant upon which the scopes were defined. But they are also available to has_many associations. If,

+ +
class Person < ActiveRecord::Base
+  has_many :shirts
+end
+
+ +

then elton.shirts.red.dry_clean_only will return all of Elton's red, dry clean only shirts.

+ +

Named scopes can also have extensions, just as with has_many declarations:

+ +
class Shirt < ActiveRecord::Base
+  scope :red, -> { where(color: 'red') } do
+    def dom_id
+      'red_shirts'
+    end
+  end
+end
+
+ +

Scopes can also be used while creating/building a record.

+ +
class Article < ActiveRecord::Base
+  scope :published, -> { where(published: true) }
+end
+
+Article.published.new.published    # => true
+Article.published.create.published # => true
+
+ +

Class methods on your model are automatically available on scopes. Assuming the following setup:

+ +
class Article < ActiveRecord::Base
+  scope :published, -> { where(published: true) }
+  scope :featured, -> { where(featured: true) }
+
+  def self.latest_article
+    order('published_at desc').first
+  end
+
+  def self.titles
+    pluck(:title)
+  end
+end
+
+ +

We are able to call the methods like this:

+ +
Article.published.featured.latest_article
+Article.featured.titles
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/scoping/named.rb, line 163
+def scope(name, body, &block)
+  unless body.respond_to?(:call)
+    raise ArgumentError, "The scope body needs to be callable."
+  end
+
+  if dangerous_class_method?(name)
+    raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
+      "on the model \"#{self.name}\", but Active Record already defined " \
+      "a class method with the same name."
+  end
+
+  if method_defined_within?(name, Relation)
+    raise ArgumentError, "You tried to define a scope named \"#{name}\" " \
+      "on the model \"#{self.name}\", but ActiveRecord::Relation already defined " \
+      "an instance method with the same name."
+  end
+
+  valid_scope_name?(name)
+  extension = Module.new(&block) if block
+
+  if body.respond_to?(:to_proc)
+    singleton_class.send(:define_method, name) do |*args|
+      scope = all
+      scope = scope._exec_scope(*args, &body)
+      scope = scope.extending(extension) if extension
+      scope
+    end
+  else
+    singleton_class.send(:define_method, name) do |*args|
+      scope = all
+      scope = scope.scoping { body.call(*args) || scope }
+      scope = scope.extending(extension) if extension
+      scope
+    end
+  end
+
+  generate_relation_method(name)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/SecureToken.html b/src/5.2/classes/ActiveRecord/SecureToken.html new file mode 100644 index 0000000000..5a60dc7077 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/SecureToken.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::SecureToken +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/SecureToken/ClassMethods.html b/src/5.2/classes/ActiveRecord/SecureToken/ClassMethods.html new file mode 100644 index 0000000000..cfd8006dde --- /dev/null +++ b/src/5.2/classes/ActiveRecord/SecureToken/ClassMethods.html @@ -0,0 +1,161 @@ +--- +title: ActiveRecord::SecureToken::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + generate_unique_secure_token() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/secure_token.rb, line 35
+def generate_unique_secure_token
+  SecureRandom.base58(24)
+end
+
+
+ +
+ +
+

+ + has_secure_token(attribute = :token) + +

+ + +
+

Example using has_secure_token

+ +
# Schema: User(token:string, auth_token:string)
+class User < ActiveRecord::Base
+  has_secure_token
+  has_secure_token :auth_token
+end
+
+user = User.new
+user.save
+user.token # => "pX27zsMN2ViQKta1bGfLmVJE"
+user.auth_token # => "77TMHrHJFvFDwodq8w7Ev2m7"
+user.regenerate_token # => true
+user.regenerate_auth_token # => true
+
+ +

SecureRandom::base58 is used to generate the 24-character unique token, so collisions are highly unlikely.

+ +

Note that it's still possible to generate a race condition in the database in the same way that validates_uniqueness_of can. You're encouraged to add a unique index in the database to deal with this even more unlikely scenario.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/secure_token.rb, line 28
+def has_secure_token(attribute = :token)
+  # Load securerandom only when has_secure_token is used.
+  require "active_support/core_ext/securerandom"
+  define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token }
+  before_create { send("#{attribute}=", self.class.generate_unique_secure_token) unless send("#{attribute}?") }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Serialization.html b/src/5.2/classes/ActiveRecord/Serialization.html new file mode 100644 index 0000000000..edebc05287 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Serialization.html @@ -0,0 +1,126 @@ +--- +title: ActiveRecord::Serialization +layout: default +--- +
+ +
+
+ +
+ +

Active Record Serialization

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + serializable_hash(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/serialization.rb, line 13
+def serializable_hash(options = nil)
+  options = options.try(:dup) || {}
+
+  options[:except] = Array(options[:except]).map(&:to_s)
+  options[:except] |= Array(self.class.inheritance_column)
+
+  super(options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/SerializationFailure.html b/src/5.2/classes/ActiveRecord/SerializationFailure.html new file mode 100644 index 0000000000..5f17e437ee --- /dev/null +++ b/src/5.2/classes/ActiveRecord/SerializationFailure.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::SerializationFailure +layout: default +--- +
+ +
+
+ +
+ +

SerializationFailure will be raised when a transaction is rolled back by the database due to a serialization failure.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/SerializationTypeMismatch.html b/src/5.2/classes/ActiveRecord/SerializationTypeMismatch.html new file mode 100644 index 0000000000..a0f0f25f46 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/SerializationTypeMismatch.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::SerializationTypeMismatch +layout: default +--- +
+ +
+
+ +
+ +

Raised when unserialized object's type mismatches one specified for serializable field.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/SpawnMethods.html b/src/5.2/classes/ActiveRecord/SpawnMethods.html new file mode 100644 index 0000000000..0d742e251f --- /dev/null +++ b/src/5.2/classes/ActiveRecord/SpawnMethods.html @@ -0,0 +1,210 @@ +--- +title: ActiveRecord::SpawnMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + except(*skips) + +

+ + +
+

Removes from the query the condition(s) specified in skips.

+ +
Post.order('id asc').except(:order)                  # discards the order condition
+Post.where('id > 10').order('id asc').except(:where) # discards the where condition but keeps the order
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/spawn_methods.rb, line 57
+def except(*skips)
+  relation_with values.except(*skips)
+end
+
+
+ +
+ +
+

+ + merge(other) + +

+ + +
+

Merges in the conditions from other, if other is an ActiveRecord::Relation. Returns an array representing the intersection of the resulting records with other, if other is an array.

+ +
Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
+# Performs a single join query with both where conditions.
+
+recent_posts = Post.order('created_at DESC').first(5)
+Post.where(published: true).merge(recent_posts)
+# Returns the intersection of all published posts with the 5 most recently created posts.
+# (This is just an example. You'd probably want to do this with a single query!)
+
+ +

Procs will be evaluated by merge:

+ +
Post.where(published: true).merge(-> { joins(:comments) })
+# => Post.where(published: true).joins(:comments)
+
+ +

This is mainly intended for sharing common conditions between multiple associations.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/spawn_methods.rb, line 31
+def merge(other)
+  if other.is_a?(Array)
+    records & other
+  elsif other
+    spawn.merge!(other)
+  else
+    raise ArgumentError, "invalid argument: #{other.inspect}."
+  end
+end
+
+
+ +
+ +
+

+ + only(*onlies) + +

+ + +
+

Removes any condition from the query other than the one(s) specified in onlies.

+ +
Post.order('id asc').only(:where)         # discards the order condition
+Post.order('id asc').only(:where, :order) # uses the specified order
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/relation/spawn_methods.rb, line 65
+def only(*onlies)
+  relation_with values.slice(*onlies)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/StaleObjectError.html b/src/5.2/classes/ActiveRecord/StaleObjectError.html new file mode 100644 index 0000000000..2a37f8f0ab --- /dev/null +++ b/src/5.2/classes/ActiveRecord/StaleObjectError.html @@ -0,0 +1,143 @@ +--- +title: ActiveRecord::StaleObjectError +layout: default +--- +
+ +
+
+ +
+ +

Raised on attempt to save stale record. Record is stale when it's being saved in another query after instantiation, for example, when two users edit the same wiki page and one starts editing and saves the page before the other.

+ +

Read more about optimistic locking in ActiveRecord::Locking module documentation.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + attempted_action
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(record = nil, attempted_action = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 192
+def initialize(record = nil, attempted_action = nil)
+  if record && attempted_action
+    @record = record
+    @attempted_action = attempted_action
+    super("Attempted to #{attempted_action} a stale object: #{record.class.name}.")
+  else
+    super("Stale object error.")
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/StatementInvalid.html b/src/5.2/classes/ActiveRecord/StatementInvalid.html new file mode 100644 index 0000000000..c53086500f --- /dev/null +++ b/src/5.2/classes/ActiveRecord/StatementInvalid.html @@ -0,0 +1,115 @@ +--- +title: ActiveRecord::StatementInvalid +layout: default +--- +
+ +
+
+ +
+ +

Superclass for all database execution errors.

+ +

Wraps the underlying database error as cause.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 100
+def initialize(message = nil)
+  super(message || $!.try(:message))
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/StatementTimeout.html b/src/5.2/classes/ActiveRecord/StatementTimeout.html new file mode 100644 index 0000000000..4a1f99f307 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/StatementTimeout.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::StatementTimeout +layout: default +--- +
+ +
+
+ +
+ +

StatementTimeout will be raised when statement timeout exceeded.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Store.html b/src/5.2/classes/ActiveRecord/Store.html new file mode 100644 index 0000000000..367d69b3ef --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Store.html @@ -0,0 +1,232 @@ +--- +title: ActiveRecord::Store +layout: default +--- +
+ +
+
+ +
+ +

Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column. It's like a simple key/value store baked into your record when you don't care about being able to query that store outside the context of a single record.

+ +

You can then declare accessors to this store that are then accessible just like any other attribute of the model. This is very helpful for easily exposing store keys to a form or elsewhere that's already built around just accessing attributes on the model.

+ +

Make sure that you declare the database column used for the serialized store as a text, so there's plenty of room.

+ +

You can set custom coder to encode/decode your serialized attributes to/from different formats. JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides load and dump.

+ +

NOTE: If you are using PostgreSQL specific columns like hstore or json there is no need for the serialization provided by .store. Simply use .store_accessor instead to generate the accessor methods. Be aware that these columns use a string keyed hash and do not allow access using a symbol.

+ +

NOTE: The default validations with the exception of uniqueness will work. For example, if you want to check for uniqueness with hstore you will need to use a custom validation to handle it.

+ +

Examples:

+ +
class User < ActiveRecord::Base
+  store :settings, accessors: [ :color, :homepage ], coder: JSON
+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
+
+# There is no difference between strings and symbols for accessing custom attributes
+u.settings[:country]  # => 'Denmark'
+u.settings['country'] # => 'Denmark'
+
+# Add additional accessors to an existing store through store_accessor
+class SuperUser < User
+  store_accessor :settings, :privileges, :servants
+end
+
+ +

The stored attribute names can be retrieved using .stored_attributes.

+ +
User.stored_attributes[:settings] # [:color, :homepage]
+
+ +

Overwriting default accessors

+ +

All stored values are automatically available through accessors on the Active Record object, but sometimes you want to specialize this behavior. This can be done by overwriting the default accessors (using the same name as the attribute) and calling super to actually change things.

+ +
class Song < ActiveRecord::Base
+  # Uses a stored integer to hold the volume adjustment of the song
+  store :settings, accessors: [:volume_adjustment]
+
+  def volume_adjustment=(decibels)
+    super(decibels.to_i)
+  end
+
+  def volume_adjustment
+    super.to_i
+  end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + local_stored_attributes
+ + + + + +

Instance Private methods

+ +
+

+ + read_store_attribute(store_attribute, key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/store.rb, line 127
+def read_store_attribute(store_attribute, key) # :doc:
+  accessor = store_accessor_for(store_attribute)
+  accessor.read(self, store_attribute, key)
+end
+
+
+ +
+ +
+

+ + write_store_attribute(store_attribute, key, value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/store.rb, line 132
+def write_store_attribute(store_attribute, key, value) # :doc:
+  accessor = store_accessor_for(store_attribute)
+  accessor.write(self, store_attribute, key, value)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Store/ClassMethods.html b/src/5.2/classes/ActiveRecord/Store/ClassMethods.html new file mode 100644 index 0000000000..6992b535b3 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Store/ClassMethods.html @@ -0,0 +1,202 @@ +--- +title: ActiveRecord::Store::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + store(store_attribute, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/store.rb, line 82
+def store(store_attribute, options = {})
+  serialize store_attribute, IndifferentCoder.new(store_attribute, options[:coder])
+  store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors
+end
+
+
+ +
+ +
+

+ + store_accessor(store_attribute, *keys) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/store.rb, line 87
+def store_accessor(store_attribute, *keys)
+  keys = keys.flatten
+
+  _store_accessors_module.module_eval do
+    keys.each do |key|
+      define_method("#{key}=") do |value|
+        write_store_attribute(store_attribute, key, value)
+      end
+
+      define_method(key) do
+        read_store_attribute(store_attribute, key)
+      end
+    end
+  end
+
+  # assign new store attribute and create new hash to ensure that each class in the hierarchy
+  # has its own hash of stored attributes.
+  self.local_stored_attributes ||= {}
+  self.local_stored_attributes[store_attribute] ||= []
+  self.local_stored_attributes[store_attribute] |= keys
+end
+
+
+ +
+ +
+

+ + stored_attributes() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/store.rb, line 117
+def stored_attributes
+  parent = superclass.respond_to?(:stored_attributes) ? superclass.stored_attributes : {}
+  if local_stored_attributes
+    parent.merge!(local_stored_attributes) { |k, a, b| a | b }
+  end
+  parent
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/SubclassNotFound.html b/src/5.2/classes/ActiveRecord/SubclassNotFound.html new file mode 100644 index 0000000000..5285b969f3 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/SubclassNotFound.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::SubclassNotFound +layout: default +--- +
+ +
+
+ +
+ +

Raised when the single-table inheritance mechanism fails to locate the subclass (for example due to improper usage of column that ActiveRecord::Base.inheritance_column points to).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Suppressor.html b/src/5.2/classes/ActiveRecord/Suppressor.html new file mode 100644 index 0000000000..712a378f59 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Suppressor.html @@ -0,0 +1,94 @@ +--- +title: ActiveRecord::Suppressor +layout: default +--- +
+ +
+
+ +
+ +

ActiveRecord::Suppressor prevents the receiver from being saved during a given block.

+ +

For example, here's a pattern of creating notifications when new comments are posted. (The notification may in turn trigger an email, a push notification, or just appear in the UI somewhere):

+ +
class Comment < ActiveRecord::Base
+  belongs_to :commentable, polymorphic: true
+  after_create -> { Notification.create! comment: self,
+    recipients: commentable.recipients }
+end
+
+ +

That's what you want the bulk of the time. New comment creates a new Notification. But there may well be off cases, like copying a commentable and its comments, where you don't want that. So you'd have a concern something like this:

+ +
module Copyable
+  def copy_to(destination)
+    Notification.suppress do
+      # Copy logic that creates new comments that we do not want
+      # triggering notifications.
+    end
+  end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Suppressor/ClassMethods.html b/src/5.2/classes/ActiveRecord/Suppressor/ClassMethods.html new file mode 100644 index 0000000000..92edc7fbf2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Suppressor/ClassMethods.html @@ -0,0 +1,105 @@ +--- +title: ActiveRecord::Suppressor::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + suppress(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/suppressor.rb, line 34
+def suppress(&block)
+  previous_state = SuppressorRegistry.suppressed[name]
+  SuppressorRegistry.suppressed[name] = true
+  yield
+ensure
+  SuppressorRegistry.suppressed[name] = previous_state
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Tasks.html b/src/5.2/classes/ActiveRecord/Tasks.html new file mode 100644 index 0000000000..e701fa8a61 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Tasks.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Tasks +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Tasks/DatabaseTasks.html b/src/5.2/classes/ActiveRecord/Tasks/DatabaseTasks.html new file mode 100644 index 0000000000..a0cdd680cb --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Tasks/DatabaseTasks.html @@ -0,0 +1,1609 @@ +--- +title: ActiveRecord::Tasks::DatabaseTasks +layout: default +--- +
+ +
+
+ +
+ +

ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates logic behind common tasks used to manage database and migrations.

+ +

The tasks defined here are used with Rake tasks provided by Active Record.

+ +

In order to use DatabaseTasks, a few config values need to be set. All the needed config values are set by Rails already, so it's necessary to do it only if you want to change the defaults or when you want to use Active Record outside of Rails (in such case after configuring the database tasks, you can also use the rake tasks defined in Active Record).

+ +

The possible config values are:

+
  • +

    env: current environment (like Rails.env).

    +
  • +

    database_configuration: configuration of your databases (as in config/database.yml).

    +
  • +

    db_dir: your db directory.

    +
  • +

    fixtures_path: a path to fixtures directory.

    +
  • +

    migrations_paths: a list of paths to directories with migrations.

    +
  • +

    seed_loader: an object which will load seeds, it needs to respond to the load_seed method.

    +
  • +

    root: a path to the root of the application.

    +
+ +

Example usage of DatabaseTasks outside Rails could look as such:

+ +
include ActiveRecord::Tasks
+DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml')
+DatabaseTasks.db_dir = 'db'
+# other settings...
+
+DatabaseTasks.create_current('production')
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
LOCAL_HOSTS=["127.0.0.1", "localhost"]
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [W] + current_config
+ [RW] + database_configuration
+ [W] + db_dir
+ [W] + env
+ [W] + fixtures_path
+ [W] + migrations_paths
+ [W] + root
+ [W] + seed_loader
+ + + + +

Class Public methods

+ +
+

+ + structure_dump_flags + +

+ + +
+

Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:structure:dump

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 41
+mattr_accessor :structure_dump_flags, instance_accessor: false
+
+
+
+ +
+ +
+

+ + structure_load_flags + +

+ + +
+

Extra flags passed to database CLI tool when calling db:structure:load

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 46
+mattr_accessor :structure_load_flags, instance_accessor: false
+
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + charset(*arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 194
+def charset(*arguments)
+  configuration = arguments.first
+  class_for_adapter(configuration["adapter"]).new(*arguments).charset
+end
+
+
+ +
+ +
+

+ + charset_current(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 190
+def charset_current(environment = env)
+  charset ActiveRecord::Base.configurations[environment]
+end
+
+
+ +
+ +
+

+ + check_protected_environments!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 55
+def check_protected_environments!
+  unless ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
+    current = ActiveRecord::Base.connection.migration_context.current_environment
+    stored  = ActiveRecord::Base.connection.migration_context.last_stored_environment
+
+    if ActiveRecord::Base.connection.migration_context.protected_environment?
+      raise ActiveRecord::ProtectedEnvironmentError.new(stored)
+    end
+
+    if stored && stored != current
+      raise ActiveRecord::EnvironmentMismatchError.new(current: current, stored: stored)
+    end
+  end
+rescue ActiveRecord::NoDatabaseError
+end
+
+
+ +
+ +
+

+ + check_schema_file(filename) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 271
+def check_schema_file(filename)
+  unless File.exist?(filename)
+    message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}.dup
+    message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails.root)
+    Kernel.abort message
+  end
+end
+
+
+ +
+ +
+

+ + check_target_version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 180
+def check_target_version
+  if target_version && !(Migration::MigrationFilenameRegexp.match?(ENV["VERSION"]) || /\A\d+\z/.match?(ENV["VERSION"]))
+    raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
+  end
+end
+
+
+ +
+ +
+

+ + collation(*arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 203
+def collation(*arguments)
+  configuration = arguments.first
+  class_for_adapter(configuration["adapter"]).new(*arguments).collation
+end
+
+
+ +
+ +
+

+ + collation_current(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 199
+def collation_current(environment = env)
+  collation ActiveRecord::Base.configurations[environment]
+end
+
+
+ +
+ +
+

+ + create(*arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 117
+def create(*arguments)
+  configuration = arguments.first
+  class_for_adapter(configuration["adapter"]).new(*arguments).create
+  $stdout.puts "Created database '#{configuration['database']}'"
+rescue DatabaseAlreadyExists
+  $stderr.puts "Database '#{configuration['database']}' already exists"
+rescue Exception => error
+  $stderr.puts error
+  $stderr.puts "Couldn't create '#{configuration['database']}' database. Please check your configuration."
+  raise
+end
+
+
+ +
+ +
+

+ + create_all() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 129
+def create_all
+  old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
+  each_local_configuration { |configuration| create configuration }
+  if old_pool
+    ActiveRecord::Base.connection_handler.establish_connection(old_pool.spec.to_hash)
+  end
+end
+
+
+ +
+ +
+

+ + create_current(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 137
+def create_current(environment = env)
+  each_current_configuration(environment) { |configuration|
+    create configuration
+  }
+  ActiveRecord::Base.establish_connection(environment.to_sym)
+end
+
+
+ +
+ +
+

+ + current_config(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 108
+def current_config(options = {})
+  options.reverse_merge! env: env
+  if options.has_key?(:config)
+    @current_config = options[:config]
+  else
+    @current_config ||= ActiveRecord::Base.configurations[options[:env]]
+  end
+end
+
+
+ +
+ +
+

+ + db_dir() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 80
+def db_dir
+  @db_dir ||= Rails.application.config.paths["db"].first
+end
+
+
+ +
+ +
+

+ + drop(*arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 144
+def drop(*arguments)
+  configuration = arguments.first
+  class_for_adapter(configuration["adapter"]).new(*arguments).drop
+  $stdout.puts "Dropped database '#{configuration['database']}'"
+rescue ActiveRecord::NoDatabaseError
+  $stderr.puts "Database '#{configuration['database']}' does not exist"
+rescue Exception => error
+  $stderr.puts error
+  $stderr.puts "Couldn't drop database '#{configuration['database']}'"
+  raise
+end
+
+
+ +
+ +
+

+ + drop_all() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 156
+def drop_all
+  each_local_configuration { |configuration| drop configuration }
+end
+
+
+ +
+ +
+

+ + drop_current(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 160
+def drop_current(environment = env)
+  each_current_configuration(environment) { |configuration|
+    drop configuration
+  }
+end
+
+
+ +
+ +
+

+ + dump_schema_cache(conn, filename) + +

+ + +
+

Dumps the schema cache in YAML format for the connection into the file

+ +

Examples:

+ +
ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 293
+def dump_schema_cache(conn, filename)
+  conn.schema_cache.clear!
+  conn.data_sources.each { |table| conn.schema_cache.add(table) }
+  open(filename, "wb") { |f| f.write(YAML.dump(conn.schema_cache)) }
+end
+
+
+ +
+ +
+

+ + env() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 100
+def env
+  @env ||= Rails.env
+end
+
+
+ +
+ +
+

+ + fixtures_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 88
+def fixtures_path
+  @fixtures_path ||= if ENV["FIXTURES_PATH"]
+    File.join(root, ENV["FIXTURES_PATH"])
+  else
+    File.join(root, "test", "fixtures")
+  end
+end
+
+
+ +
+ +
+

+ + load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 264
+def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
+  each_current_configuration(environment) { |configuration, configuration_environment|
+    load_schema configuration, format, file, configuration_environment
+  }
+  ActiveRecord::Base.establish_connection(environment.to_sym)
+end
+
+
+ +
+ +
+

+ + load_seed() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 279
+def load_seed
+  if seed_loader
+    seed_loader.load_seed
+  else
+    raise "You tried to load seed data, but no seed loader is specified. Please specify seed " \
+          "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" \
+          "Seed loader should respond to load_seed method"
+  end
+end
+
+
+ +
+ +
+

+ + migrate() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 166
+def migrate
+  check_target_version
+
+  verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
+  scope = ENV["SCOPE"]
+  verbose_was, Migration.verbose = Migration.verbose, verbose
+  Base.connection.migration_context.migrate(target_version) do |migration|
+    scope.blank? || scope == migration.scope
+  end
+  ActiveRecord::Base.clear_cache!
+ensure
+  Migration.verbose = verbose_was
+end
+
+
+ +
+ +
+

+ + migrations_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 84
+def migrations_paths
+  @migrations_paths ||= Rails.application.paths["db/migrate"].to_a
+end
+
+
+ +
+ +
+

+ + purge(configuration) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 208
+def purge(configuration)
+  class_for_adapter(configuration["adapter"]).new(configuration).purge
+end
+
+
+ +
+ +
+

+ + purge_all() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 212
+def purge_all
+  each_local_configuration { |configuration|
+    purge configuration
+  }
+end
+
+
+ +
+ +
+

+ + purge_current(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 218
+def purge_current(environment = env)
+  each_current_configuration(environment) { |configuration|
+    purge configuration
+  }
+  ActiveRecord::Base.establish_connection(environment.to_sym)
+end
+
+
+ +
+ +
+

+ + register_task(pattern, task) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 71
+def register_task(pattern, task)
+  @tasks ||= {}
+  @tasks[pattern] = task
+end
+
+
+ +
+ +
+

+ + root() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 96
+def root
+  @root ||= Rails.root
+end
+
+
+ +
+ +
+

+ + schema_file(format = ActiveRecord::Base.schema_format) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 255
+def schema_file(format = ActiveRecord::Base.schema_format)
+  case format
+  when :ruby
+    File.join(db_dir, "schema.rb")
+  when :sql
+    File.join(db_dir, "structure.sql")
+  end
+end
+
+
+ +
+ +
+

+ + seed_loader() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 104
+def seed_loader
+  @seed_loader ||= Rails.application
+end
+
+
+ +
+ +
+

+ + structure_dump(*arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 225
+def structure_dump(*arguments)
+  configuration = arguments.first
+  filename = arguments.delete_at 1
+  class_for_adapter(configuration["adapter"]).new(*arguments).structure_dump(filename, structure_dump_flags)
+end
+
+
+ +
+ +
+

+ + structure_load(*arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 231
+def structure_load(*arguments)
+  configuration = arguments.first
+  filename = arguments.delete_at 1
+  class_for_adapter(configuration["adapter"]).new(*arguments).structure_load(filename, structure_load_flags)
+end
+
+
+ +
+ +
+

+ + target_version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 186
+def target_version
+  ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/TestFixtures.html b/src/5.2/classes/ActiveRecord/TestFixtures.html new file mode 100644 index 0000000000..a920961718 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/TestFixtures.html @@ -0,0 +1,296 @@ +--- +title: ActiveRecord::TestFixtures +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + enlist_fixture_connections() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 1025
+def enlist_fixture_connections
+  ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
+end
+
+
+ +
+ +
+

+ + run_in_transaction?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 948
+def run_in_transaction?
+  use_transactional_tests &&
+    !self.class.uses_transaction?(method_name)
+end
+
+
+ +
+ +
+

+ + setup_fixtures(config = ActiveRecord::Base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 953
+def setup_fixtures(config = ActiveRecord::Base)
+  if pre_loaded_fixtures && !use_transactional_tests
+    raise RuntimeError, "pre_loaded_fixtures requires use_transactional_tests"
+  end
+
+  @fixture_cache = {}
+  @fixture_connections = []
+  @@already_loaded_fixtures ||= {}
+  @connection_subscriber = nil
+
+  # Load fixtures once and begin transaction.
+  if run_in_transaction?
+    if @@already_loaded_fixtures[self.class]
+      @loaded_fixtures = @@already_loaded_fixtures[self.class]
+    else
+      @loaded_fixtures = load_fixtures(config)
+      @@already_loaded_fixtures[self.class] = @loaded_fixtures
+    end
+
+    # Begin transactions for connections already established
+    @fixture_connections = enlist_fixture_connections
+    @fixture_connections.each do |connection|
+      connection.begin_transaction joinable: false
+      connection.pool.lock_thread = true
+    end
+
+    # When connections are established in the future, begin a transaction too
+    @connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
+      spec_name = payload[:spec_name] if payload.key?(:spec_name)
+
+      if spec_name
+        begin
+          connection = ActiveRecord::Base.connection_handler.retrieve_connection(spec_name)
+        rescue ConnectionNotEstablished
+          connection = nil
+        end
+
+        if connection && !@fixture_connections.include?(connection)
+          connection.begin_transaction joinable: false
+          connection.pool.lock_thread = true
+          @fixture_connections << connection
+        end
+      end
+    end
+
+  # Load fixtures for every test.
+  else
+    ActiveRecord::FixtureSet.reset_cache
+    @@already_loaded_fixtures[self.class] = nil
+    @loaded_fixtures = load_fixtures(config)
+  end
+
+  # Instantiate fixtures for every test if requested.
+  instantiate_fixtures if use_instantiated_fixtures
+end
+
+
+ +
+ +
+

+ + teardown_fixtures() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 1009
+def teardown_fixtures
+  # Rollback changes if a transaction is active.
+  if run_in_transaction?
+    ActiveSupport::Notifications.unsubscribe(@connection_subscriber) if @connection_subscriber
+    @fixture_connections.each do |connection|
+      connection.rollback_transaction if connection.transaction_open?
+      connection.pool.lock_thread = false
+    end
+    @fixture_connections.clear
+  else
+    ActiveRecord::FixtureSet.reset_cache
+  end
+
+  ActiveRecord::Base.clear_active_connections!
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/TestFixtures/ClassMethods.html b/src/5.2/classes/ActiveRecord/TestFixtures/ClassMethods.html new file mode 100644 index 0000000000..d67642cd7b --- /dev/null +++ b/src/5.2/classes/ActiveRecord/TestFixtures/ClassMethods.html @@ -0,0 +1,304 @@ +--- +title: ActiveRecord::TestFixtures::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + fixtures(*fixture_set_names) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 892
+def fixtures(*fixture_set_names)
+  if fixture_set_names.first == :all
+    fixture_set_names = Dir["#{fixture_path}/{**,*}/*.{yml}"].uniq
+    fixture_set_names.map! { |f| f[(fixture_path.to_s.size + 1)..-5] }
+  else
+    fixture_set_names = fixture_set_names.flatten.map(&:to_s)
+  end
+
+  self.fixture_table_names |= fixture_set_names
+  setup_fixture_accessors(fixture_set_names)
+end
+
+
+ +
+ +
+

+ + set_fixture_class(class_names = {}) + +

+ + +
+

Sets the model class for a fixture when the class name cannot be inferred from the fixture name.

+ +

Examples:

+ +
set_fixture_class some_fixture:        SomeModel,
+                  'namespaced/fixture' => Another::Model
+
+ +

The keys must be the fixture names, that coincide with the short paths to the fixture files.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 888
+def set_fixture_class(class_names = {})
+  self.fixture_class_names = fixture_class_names.merge(class_names.stringify_keys)
+end
+
+
+ +
+ +
+

+ + setup_fixture_accessors(fixture_set_names = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 904
+def setup_fixture_accessors(fixture_set_names = nil)
+  fixture_set_names = Array(fixture_set_names || fixture_table_names)
+  methods = Module.new do
+    fixture_set_names.each do |fs_name|
+      fs_name = fs_name.to_s
+      accessor_name = fs_name.tr("/", "_").to_sym
+
+      define_method(accessor_name) do |*fixture_names|
+        force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
+        return_single_record = fixture_names.size == 1
+        fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
+
+        @fixture_cache[fs_name] ||= {}
+
+        instances = fixture_names.map do |f_name|
+          f_name = f_name.to_s if f_name.is_a?(Symbol)
+          @fixture_cache[fs_name].delete(f_name) if force_reload
+
+          if @loaded_fixtures[fs_name][f_name]
+            @fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find
+          else
+            raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'"
+          end
+        end
+
+        return_single_record ? instances.first : instances
+      end
+      private accessor_name
+    end
+  end
+  include methods
+end
+
+
+ +
+ +
+

+ + uses_transaction(*methods) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 937
+def uses_transaction(*methods)
+  @uses_transaction = [] unless defined?(@uses_transaction)
+  @uses_transaction.concat methods.map(&:to_s)
+end
+
+
+ +
+ +
+

+ + uses_transaction?(method) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/fixtures.rb, line 942
+def uses_transaction?(method)
+  @uses_transaction = [] unless defined?(@uses_transaction)
+  @uses_transaction.include?(method.to_s)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Timestamp.html b/src/5.2/classes/ActiveRecord/Timestamp.html new file mode 100644 index 0000000000..b98d1480df --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Timestamp.html @@ -0,0 +1,98 @@ +--- +title: ActiveRecord::Timestamp +layout: default +--- +
+ +
+
+ +
+ +

Active Record Timestamp

+ +

Active Record automatically timestamps create and update operations if the table has fields named created_at/created_on or updated_at/updated_on.

+ +

Timestamping can be turned off by setting:

+ +
config.active_record.record_timestamps = false
+
+ +

Timestamps are in UTC by default but you can use the local timezone by setting:

+ +
config.active_record.default_timezone = :local
+
+ +

Time Zone aware attributes

+ +

Active Record keeps all the datetime and time columns timezone aware. By default, these values are stored in the database as UTC and converted back to the current Time.zone when pulled from the database.

+ +

This feature can be turned off completely by setting:

+ +
config.active_record.time_zone_aware_attributes = false
+
+ +

You can also specify that only datetime columns should be time-zone aware (while time should not) by setting:

+ +
ActiveRecord::Base.time_zone_aware_types = [:datetime]
+
+ +

You can also add database specific timezone aware types. For example, for PostgreSQL:

+ +
ActiveRecord::Base.time_zone_aware_types += [:tsrange, :tstzrange]
+
+ +

Finally, you can indicate specific attributes of a model for which time zone conversion should not applied, for instance by setting:

+ +
class Topic < ActiveRecord::Base
+  self.skip_time_zone_conversion_for_attributes = [:written_on]
+end
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/TouchLater.html b/src/5.2/classes/ActiveRecord/TouchLater.html new file mode 100644 index 0000000000..393c5f4cc7 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/TouchLater.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::TouchLater +layout: default +--- +
+ +
+
+ +
+ +

Active Record Touch Later

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/TransactionIsolationError.html b/src/5.2/classes/ActiveRecord/TransactionIsolationError.html new file mode 100644 index 0000000000..4ea6d7d039 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/TransactionIsolationError.html @@ -0,0 +1,75 @@ +--- +title: ActiveRecord::TransactionIsolationError +layout: default +--- +
+ +
+
+ +
+ +

TransactionIsolationError will be raised under the following conditions:

+
  • +

    The adapter does not support setting the isolation level

    +
  • +

    You are joining an existing open transaction

    +
  • +

    You are creating a nested (savepoint) transaction

    +
+ +

The mysql2 and postgresql adapters support setting the transaction isolation level.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/TransactionRollbackError.html b/src/5.2/classes/ActiveRecord/TransactionRollbackError.html new file mode 100644 index 0000000000..d8520d6bbe --- /dev/null +++ b/src/5.2/classes/ActiveRecord/TransactionRollbackError.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::TransactionRollbackError +layout: default +--- +
+ +
+
+ +
+ +

TransactionRollbackError will be raised when a transaction is rolled back by the database due to a serialization failure or a deadlock.

+ +

See the following:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Transactions.html b/src/5.2/classes/ActiveRecord/Transactions.html new file mode 100644 index 0000000000..62366dc6d6 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Transactions.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Transactions +layout: default +--- +
+ +
+
+ +
+ +

See ActiveRecord::Transactions::ClassMethods for documentation.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Transactions/ClassMethods.html b/src/5.2/classes/ActiveRecord/Transactions/ClassMethods.html new file mode 100644 index 0000000000..745b94c132 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Transactions/ClassMethods.html @@ -0,0 +1,452 @@ +--- +title: ActiveRecord::Transactions::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Transactions

+ +

Transactions are protective blocks where SQL statements are only permanent if they can all succeed as one atomic action. The classic example is a transfer between two accounts where you can only have a deposit if the withdrawal succeeded and vice versa. Transactions enforce the integrity of the database and guard the data against program errors or database break-downs. So basically you should use transaction blocks whenever you have a number of statements that must be executed together or not at all.

+ +

For example:

+ +
ActiveRecord::Base.transaction do
+  david.withdrawal(100)
+  mary.deposit(100)
+end
+
+ +

This example will only take money from David and give it to Mary if neither withdrawal nor deposit raise an exception. Exceptions will force a ROLLBACK that returns the database to the state before the transaction began. Be aware, though, that the objects will not have their instance data returned to their pre-transactional state.

+ +

Different Active Record classes in a single transaction

+ +

Though the transaction class method is called on some Active Record class, the objects within the transaction block need not all be instances of that class. This is because transactions are per-database connection, not per-model.

+ +

In this example a balance record is transactionally saved even though transaction is called on the Account class:

+ +
Account.transaction do
+  balance.save!
+  account.save!
+end
+
+ +

The transaction method is also available as a model instance method. For example, you can also do this:

+ +
balance.transaction do
+  balance.save!
+  account.save!
+end
+
+ +

Transactions are not distributed across database connections

+ +

A transaction acts on a single database connection. If you have multiple class-specific databases, the transaction will not protect interaction among them. One workaround is to begin a transaction on each class whose models you alter:

+ +
Student.transaction do
+  Course.transaction do
+    course.enroll(student)
+    student.units += course.units
+  end
+end
+
+ +

This is a poor solution, but fully distributed transactions are beyond the scope of Active Record.

+ +

save and destroy are automatically wrapped in a transaction

+ +

Both #save and #destroy come wrapped in a transaction that ensures that whatever you do in validations or callbacks will happen under its protected cover. So you can use validations to check for values that the transaction depends on or you can raise exceptions in the callbacks to rollback, including after_* callbacks.

+ +

As a consequence changes to the database are not seen outside your connection until the operation is complete. For example, if you try to update the index of a search engine in after_save the indexer won't see the updated record. The after_commit callback is the only one that is triggered once the update is committed. See below.

+ +

Exception handling and rolling back

+ +

Also have in mind that exceptions thrown within a transaction block will be propagated (after triggering the ROLLBACK), so you should be ready to catch those in your application code.

+ +

One exception is the ActiveRecord::Rollback exception, which will trigger a ROLLBACK when raised, but not be re-raised by the transaction block.

+ +

Warning: one should not catch ActiveRecord::StatementInvalid exceptions inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an error occurred at the database level, for example when a unique constraint is violated. On some database systems, such as PostgreSQL, database errors inside a transaction cause the entire transaction to become unusable until it's restarted from the beginning. Here is an example which demonstrates the problem:

+ +
# Suppose that we have a Number model with a unique column called 'i'.
+Number.transaction do
+  Number.create(i: 0)
+  begin
+    # This will raise a unique constraint error...
+    Number.create(i: 0)
+  rescue ActiveRecord::StatementInvalid
+    # ...which we ignore.
+  end
+
+  # On PostgreSQL, the transaction is now unusable. The following
+  # statement will cause a PostgreSQL error, even though the unique
+  # constraint is no longer violated:
+  Number.create(i: 1)
+  # => "PG::Error: ERROR:  current transaction is aborted, commands
+  #     ignored until end of transaction block"
+end
+
+ +

One should restart the entire transaction if an ActiveRecord::StatementInvalid occurred.

+ +

Nested transactions

+ +

transaction calls can be nested. By default, this makes all database statements in the nested transaction block become part of the parent transaction. For example, the following behavior may be surprising:

+ +
User.transaction do
+  User.create(username: 'Kotori')
+  User.transaction do
+    User.create(username: 'Nemu')
+    raise ActiveRecord::Rollback
+  end
+end
+
+ +

creates both “Kotori” and “Nemu”. Reason is the ActiveRecord::Rollback exception in the nested block does not issue a ROLLBACK. Since these exceptions are captured in transaction blocks, the parent block does not see it and the real transaction is committed.

+ +

In order to get a ROLLBACK for the nested transaction you may ask for a real sub-transaction by passing requires_new: true. If anything goes wrong, the database rolls back to the beginning of the sub-transaction without rolling back the parent transaction. If we add it to the previous example:

+ +
User.transaction do
+  User.create(username: 'Kotori')
+  User.transaction(requires_new: true) do
+    User.create(username: 'Nemu')
+    raise ActiveRecord::Rollback
+  end
+end
+
+ +

only “Kotori” is created. This works on MySQL and PostgreSQL. SQLite3 version >= '3.6.8' also supports it.

+ +

Most databases don't support true nested transactions. At the time of writing, the only database that we're aware of that supports true nested transactions, is MS-SQL. Because of this, Active Record emulates nested transactions by using savepoints on MySQL and PostgreSQL. See dev.mysql.com/doc/refman/5.7/en/savepoint.html for more information about savepoints.

+ +

Callbacks

+ +

There are two types of callbacks associated with committing and rolling back transactions: after_commit and after_rollback.

+ +

after_commit callbacks are called on every record saved or destroyed within a transaction immediately after the transaction is committed. after_rollback callbacks are called on every record saved or destroyed within a transaction immediately after the transaction or savepoint is rolled back.

+ +

These callbacks are useful for interacting with other systems since you will be guaranteed that the callback is only executed when the database is in a permanent state. For example, after_commit is a good spot to put in a hook to clearing a cache since clearing it from within a transaction could trigger the cache to be regenerated before the database is updated.

+ +

Caveats

+ +

If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested transactions blocks that are emulated with savepoints. That is, do not execute statements like 'CREATE TABLE' inside such blocks. This is because MySQL automatically releases all savepoints upon executing a DDL operation. When transaction is finished and tries to release the savepoint it created earlier, a database error will occur because the savepoint has already been automatically released. The following example demonstrates the problem:

+ +
Model.connection.transaction do                           # BEGIN
+  Model.connection.transaction(requires_new: true) do     # CREATE SAVEPOINT active_record_1
+    Model.connection.create_table(...)                    # active_record_1 now automatically released
+  end                                                     # RELEASE SAVEPOINT active_record_1
+                                                          # ^^^^ BOOM! database error!
+end
+
+ +

Note that “TRUNCATE” is also a MySQL DDL statement!

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + after_commit(*args, &block) + +

+ + +
+

This callback is called after a record has been created, updated, or destroyed.

+ +

You can specify that the callback should only be fired by a certain action with the :on option:

+ +
after_commit :do_foo, on: :create
+after_commit :do_bar, on: :update
+after_commit :do_baz, on: :destroy
+
+after_commit :do_foo_bar, on: [:create, :update]
+after_commit :do_bar_baz, on: [:update, :destroy]
+
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/transactions.rb, line 232
+def after_commit(*args, &block)
+  set_options_for_callbacks!(args)
+  set_callback(:commit, :after, *args, &block)
+end
+
+
+ +
+ +
+

+ + after_create_commit(*args, &block) + +

+ + +
+

Shortcut for after_commit :hook, on: :create.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/transactions.rb, line 238
+def after_create_commit(*args, &block)
+  set_options_for_callbacks!(args, on: :create)
+  set_callback(:commit, :after, *args, &block)
+end
+
+
+ +
+ +
+

+ + after_destroy_commit(*args, &block) + +

+ + +
+

Shortcut for after_commit :hook, on: :destroy.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/transactions.rb, line 250
+def after_destroy_commit(*args, &block)
+  set_options_for_callbacks!(args, on: :destroy)
+  set_callback(:commit, :after, *args, &block)
+end
+
+
+ +
+ +
+

+ + after_rollback(*args, &block) + +

+ + +
+

This callback is called after a create, update, or destroy are rolled back.

+ +

Please check the documentation of after_commit for options.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/transactions.rb, line 258
+def after_rollback(*args, &block)
+  set_options_for_callbacks!(args)
+  set_callback(:rollback, :after, *args, &block)
+end
+
+
+ +
+ +
+

+ + after_update_commit(*args, &block) + +

+ + +
+

Shortcut for after_commit :hook, on: :update.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/transactions.rb, line 244
+def after_update_commit(*args, &block)
+  set_options_for_callbacks!(args, on: :update)
+  set_callback(:commit, :after, *args, &block)
+end
+
+
+ +
+ +
+

+ + transaction(options = {}, &block) + +

+ + + + + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/transactions.rb, line 211
+def transaction(options = {}, &block)
+  connection.transaction(options, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Translation.html b/src/5.2/classes/ActiveRecord/Translation.html new file mode 100644 index 0000000000..e3de936ec1 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Translation.html @@ -0,0 +1,68 @@ +--- +title: ActiveRecord::Translation +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type.html b/src/5.2/classes/ActiveRecord/Type.html new file mode 100644 index 0000000000..75c03b330f --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type.html @@ -0,0 +1,302 @@ +--- +title: ActiveRecord::Type +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BigInteger=ActiveModel::Type::BigInteger
 
Binary=ActiveModel::Type::Binary
 
Boolean=ActiveModel::Type::Boolean
 

Active Model Type Boolean

+ +

A class that behaves like a boolean type, including rules for coercion of user input.

+ +

Coercion

+ +

Values set from user input will first be coerced into the appropriate ruby type. Coercion behavior is roughly mapped to Ruby's boolean semantics.

+
  • +

    “false”, “f” , “0”, 0 or any other value in FALSE_VALUES will be coerced to false

    +
  • +

    Empty strings are coerced to nil

    +
  • +

    All other values will be coerced to true

    +
Decimal=ActiveModel::Type::Decimal
 
Float=ActiveModel::Type::Float
 
Helpers=ActiveModel::Type::Helpers
 
Integer=ActiveModel::Type::Integer
 
String=ActiveModel::Type::String
 
Value=ActiveModel::Type::Value
 
+ + + + + + +

Class Public methods

+ +
+

+ + register(type_name, klass = nil, **options, &block) + +

+ + +
+

Add a new type to the registry, allowing it to be referenced as a symbol by ActiveRecord::Base.attribute. If your type is only meant to be used with a specific database adapter, you can do so by passing adapter: :postgresql. If your type has the same name as a native type for the current adapter, an exception will be raised unless you specify an :override option. override: true will cause your type to be used instead of the native type. override: false will cause the native type to be used over yours if one exists.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type.rb, line 37
+def register(type_name, klass = nil, **options, &block)
+  registry.register(type_name, klass, **options, &block)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/AdapterSpecificRegistry.html b/src/5.2/classes/ActiveRecord/Type/AdapterSpecificRegistry.html new file mode 100644 index 0000000000..5d9a63b5c3 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/AdapterSpecificRegistry.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::AdapterSpecificRegistry +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/Date.html b/src/5.2/classes/ActiveRecord/Type/Date.html new file mode 100644 index 0000000000..0c4d97a387 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/Date.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::Type::Date +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/DateTime.html b/src/5.2/classes/ActiveRecord/Type/DateTime.html new file mode 100644 index 0000000000..f82bf9139f --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/DateTime.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::Type::DateTime +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/DecorationRegistration.html b/src/5.2/classes/ActiveRecord/Type/DecorationRegistration.html new file mode 100644 index 0000000000..38daa690f4 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/DecorationRegistration.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::DecorationRegistration +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/Internal.html b/src/5.2/classes/ActiveRecord/Type/Internal.html new file mode 100644 index 0000000000..29208db6f1 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/Internal.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Type::Internal +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/Internal/Timezone.html b/src/5.2/classes/ActiveRecord/Type/Internal/Timezone.html new file mode 100644 index 0000000000..03340e4f56 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/Internal/Timezone.html @@ -0,0 +1,140 @@ +--- +title: ActiveRecord::Type::Internal::Timezone +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + default_timezone() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/internal/timezone.rb, line 11
+def default_timezone
+  ActiveRecord::Base.default_timezone
+end
+
+
+ +
+ +
+

+ + is_utc?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/internal/timezone.rb, line 7
+def is_utc?
+  ActiveRecord::Base.default_timezone == :utc
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/Json.html b/src/5.2/classes/ActiveRecord/Type/Json.html new file mode 100644 index 0000000000..9a820faeab --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/Json.html @@ -0,0 +1,278 @@ +--- +title: ActiveRecord::Type::Json +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + accessor() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/json.rb, line 25
+def accessor
+  ActiveRecord::Store::StringKeyedHashAccessor
+end
+
+
+ +
+ +
+

+ + changed_in_place?(raw_old_value, new_value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/json.rb, line 21
+def changed_in_place?(raw_old_value, new_value)
+  deserialize(raw_old_value) != new_value
+end
+
+
+ +
+ +
+

+ + deserialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/json.rb, line 12
+def deserialize(value)
+  return value unless value.is_a?(::String)
+  ActiveSupport::JSON.decode(value) rescue nil
+end
+
+
+ +
+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/json.rb, line 17
+def serialize(value)
+  ActiveSupport::JSON.encode(value) unless value.nil?
+end
+
+
+ +
+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/json.rb, line 8
+def type
+  :json
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/Registration.html b/src/5.2/classes/ActiveRecord/Type/Registration.html new file mode 100644 index 0000000000..1678cb6229 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/Registration.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Type::Registration +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Type/Time.html b/src/5.2/classes/ActiveRecord/Type/Time.html new file mode 100644 index 0000000000..c62f201b57 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Type/Time.html @@ -0,0 +1,126 @@ +--- +title: ActiveRecord::Type::Time +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/type/time.rb, line 11
+def serialize(value)
+  case value = super
+  when ::Time
+    Value.new(value)
+  else
+    value
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/TypeConflictError.html b/src/5.2/classes/ActiveRecord/TypeConflictError.html new file mode 100644 index 0000000000..832563c1b2 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/TypeConflictError.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::TypeConflictError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/UnknownAttributeReference.html b/src/5.2/classes/ActiveRecord/UnknownAttributeReference.html new file mode 100644 index 0000000000..7a26dc224c --- /dev/null +++ b/src/5.2/classes/ActiveRecord/UnknownAttributeReference.html @@ -0,0 +1,80 @@ +--- +title: ActiveRecord::UnknownAttributeReference +layout: default +--- +
+ +
+
+ +
+ +

UnknownAttributeReference is raised when an unknown and potentially unsafe value is passed to a query method when allow_unsafe_raw_sql is set to :disabled. For example, passing a non column name value to a relation's order method might cause this exception.

+ +

When working around this exception, caution should be taken to avoid SQL injection vulnerabilities when passing user-provided values to query methods. Known-safe values can be passed to query methods by wrapping them in Arel.sql.

+ +

For example, with allow_unsafe_raw_sql set to :disabled, the following code would raise this exception:

+ +
Post.order("length(title)").first
+
+ +

The desired result can be accomplished by wrapping the known-safe string in Arel.sql:

+ +
Post.order(Arel.sql("length(title)")).first
+
+ +

Again, such a workaround should not be used when passing user-provided values, such as request parameters or model attributes to query methods.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/UnknownPrimaryKey.html b/src/5.2/classes/ActiveRecord/UnknownPrimaryKey.html new file mode 100644 index 0000000000..c52576982d --- /dev/null +++ b/src/5.2/classes/ActiveRecord/UnknownPrimaryKey.html @@ -0,0 +1,134 @@ +--- +title: ActiveRecord::UnknownPrimaryKey +layout: default +--- +
+ +
+
+ +
+ +

Raised when a primary key is needed, but not specified in the schema or model.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + model
+ + + + +

Class Public methods

+ +
+

+ + new(model = nil, description = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/errors.rb, line 283
+def initialize(model = nil, description = nil)
+  if model
+    message = "Unknown primary key for table #{model.table_name} in model #{model}."
+    message += "\n#{description}" if description
+    @model = model
+    super(message)
+  else
+    super("Unknown primary key.")
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/VERSION.html b/src/5.2/classes/ActiveRecord/VERSION.html new file mode 100644 index 0000000000..e94771e58c --- /dev/null +++ b/src/5.2/classes/ActiveRecord/VERSION.html @@ -0,0 +1,122 @@ +--- +title: ActiveRecord::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Validations.html b/src/5.2/classes/ActiveRecord/Validations.html new file mode 100644 index 0000000000..3a6edf4b54 --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Validations.html @@ -0,0 +1,264 @@ +--- +title: ActiveRecord::Validations +layout: default +--- +
+ +
+
+ +
+ +

Active Record Validations

+ +

Active Record includes the majority of its validations from ActiveModel::Validations all of which accept the :on argument to define the context where the validations are active. Active Record will always supply either the context of :create or :update dependent on whether the model is a new_record?.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + save(options = {}) + +

+ + +
+

The validation process on save can be skipped by passing validate: false. The regular ActiveRecord::Base#save method is replaced with this when the validations module is mixed in, which it is by default.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations.rb, line 45
+def save(options = {})
+  perform_validations(options) ? super : false
+end
+
+
+ +
+ +
+

+ + save!(options = {}) + +

+ + +
+

Attempts to save the record just like ActiveRecord::Base#save but will raise an ActiveRecord::RecordInvalid exception instead of returning false if the record is not valid.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations.rb, line 51
+def save!(options = {})
+  perform_validations(options) ? super : raise_validation_error
+end
+
+
+ +
+ +
+

+ + valid?(context = nil) + +

+ + +
+

Runs all the validations within the specified context. Returns true if no errors are found, false otherwise.

+ +

Aliased as validate.

+ +

If the argument is false (default is nil), the context is set to :create if new_record? is true, and to :update if it is not.

+ +

Validations with no :on option will run no matter the context. Validations with some :on option will only run in the specified context.

+
+ + + +
+ Also aliased as: validate +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations.rb, line 65
+def valid?(context = nil)
+  context ||= default_validation_context
+  output = super(context)
+  errors.empty? && output
+end
+
+
+ +
+ +
+

+ + validate(context = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: valid? +
+ + + +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/Validations/ClassMethods.html b/src/5.2/classes/ActiveRecord/Validations/ClassMethods.html new file mode 100644 index 0000000000..c9f9dafefa --- /dev/null +++ b/src/5.2/classes/ActiveRecord/Validations/ClassMethods.html @@ -0,0 +1,447 @@ +--- +title: ActiveRecord::Validations::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + validates_absence_of(*attr_names) + +

+ + +
+

Validates that the specified attributes are not present (as defined by Object#present?). If the attribute is an association, the associated object is considered absent if it was marked for destruction.

+ +

See ActiveModel::Validations::HelperMethods.validates_absence_of for more information.

+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations/absence.rb, line 20
+def validates_absence_of(*attr_names)
+  validates_with AbsenceValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_associated(*attr_names) + +

+ + +
+

Validates whether the associated object or objects are all valid. Works with any kind of association.

+ +
class Book < ActiveRecord::Base
+  has_many :pages
+  belongs_to :library
+
+  validates_associated :pages, :library
+end
+
+ +

WARNING: This validation must not be used on both ends of an association. Doing so will lead to a circular dependency and cause infinite recursion.

+ +

NOTE: This validation will not fail if the association hasn't been assigned. If you want to ensure that the association is both present and guaranteed to be valid, you also need to use validates_presence_of.

+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “is invalid”).

    +
  • +

    :on - Specifies the contexts where this validation is active. Runs in all validation contexts by default nil. You can pass a symbol or an array of symbols. (e.g. on: :create or on: :custom_validation_context or on: [:create, :custom_validation_context])

    +
  • +

    :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations/associated.rb, line 55
+def validates_associated(*attr_names)
+  validates_with AssociatedValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_length_of(*attr_names) + +

+ + +
+

Validates that the specified attributes match the length restrictions supplied. If the attribute is an association, records that are marked for destruction are not counted.

+ +

See ActiveModel::Validations::HelperMethods.validates_length_of for more information.

+
+ + + +
+ Also aliased as: validates_size_of +
+ + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations/length.rb, line 19
+def validates_length_of(*attr_names)
+  validates_with LengthValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_presence_of(*attr_names) + +

+ + +
+

Validates that the specified attributes are not blank (as defined by Object#blank?), and, if the attribute is an association, that the associated object is not marked for destruction. Happens by default on save.

+ +
class Person < ActiveRecord::Base
+  has_one :face
+  validates_presence_of :face
+end
+
+ +

The face attribute must be in the object and it cannot be blank or marked for destruction.

+ +

If you want to validate the presence of a boolean field (where the real values are true and false), you will want to use validates_inclusion_of :field_name, in: [true, false].

+ +

This is due to the way Object#blank? handles boolean values: false.blank? # => true.

+ +

This validator defers to the Active Model validation for presence, adding the check to see that an associated object is not marked for destruction. This prevents the parent object from validating successfully and saving, which then deletes the associated object, thus putting the parent object into an invalid state.

+ +

NOTE: This validation will not fail while using it with an association if the latter was assigned but not valid. If you want to ensure that it is both present and valid, you also need to use validates_associated.

+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: “can't be blank”).

    +
  • +

    :on - Specifies the contexts where this validation is active. Runs in all validation contexts by default nil. You can pass a symbol or an array of symbols. (e.g. on: :create or on: :custom_validation_context or on: [:create, :custom_validation_context])

    +
  • +

    :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :strict - Specifies whether validation should be strict. See ActiveModel::Validations#validates! for more information.

    +
+
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations/presence.rb, line 63
+def validates_presence_of(*attr_names)
+  validates_with PresenceValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ +
+

+ + validates_size_of(*attr_names) + +

+ + +
+ +
+ + + + + +
+ Alias for: validates_length_of +
+ + + +
+ +
+

+ + validates_uniqueness_of(*attr_names) + +

+ + +
+

Validates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user can be named “davidhh”.

+ +
class Person < ActiveRecord::Base
+  validates_uniqueness_of :user_name
+end
+
+ +

It can also validate whether the value of the specified attributes are unique based on a :scope parameter:

+ +
class Person < ActiveRecord::Base
+  validates_uniqueness_of :user_name, scope: :account_id
+end
+
+ +

Or even multiple scope parameters. For example, making sure that a teacher can only be on the schedule once per semester for a particular class.

+ +
class TeacherSchedule < ActiveRecord::Base
+  validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
+end
+
+ +

It is also possible to limit the uniqueness constraint to a set of records matching certain conditions. In this example archived articles are not being taken into consideration when validating uniqueness of the title attribute:

+ +
class Article < ActiveRecord::Base
+  validates_uniqueness_of :title, conditions: -> { where.not(status: 'archived') }
+end
+
+ +

When the record is created, a check is performed to make sure that no record exists in the database with the given value for the specified attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.

+ +

Configuration options:

+
  • +

    :message - Specifies a custom error message (default is: “has already been taken”).

    +
  • +

    :scope - One or more columns by which to limit the scope of the uniqueness constraint.

    +
  • +

    :conditions - Specify the conditions to be included as a WHERE SQL fragment to limit the uniqueness constraint lookup (e.g. conditions: -> { where(status: 'active') }).

    +
  • +

    :case_sensitive - Looks for an exact match. Ignored by non-text columns (true by default).

    +
  • +

    :allow_nil - If set to true, skips this validation if the attribute is nil (default is false).

    +
  • +

    :allow_blank - If set to true, skips this validation if the attribute is blank (default is false).

    +
  • +

    :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. if: :allow_validation, or if: Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
  • +

    :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. unless: :skip_validation, or unless: Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.

    +
+ +

Concurrency and integrity

+ +

Using this validation method in conjunction with ActiveRecord::Base#save does not guarantee the absence of duplicate record insertions, because uniqueness checks on the application level are inherently prone to race conditions. For example, suppose that two users try to post a Comment at the same time, and a Comment's title must be unique. At the database-level, the actions performed by these users could be interleaved in the following manner:

+ +
             User 1                 |               User 2
+------------------------------------+--------------------------------------
+# User 1 checks whether there's     |
+# already a comment with the title  |
+# 'My Post'. This is not the case.  |
+SELECT * FROM comments              |
+WHERE title = 'My Post'             |
+                                    |
+                                    | # User 2 does the same thing and also
+                                    | # infers that their title is unique.
+                                    | SELECT * FROM comments
+                                    | WHERE title = 'My Post'
+                                    |
+# User 1 inserts their comment.     |
+INSERT INTO comments                |
+(title, content) VALUES             |
+('My Post', 'hi!')                  |
+                                    |
+                                    | # User 2 does the same thing.
+                                    | INSERT INTO comments
+                                    | (title, content) VALUES
+                                    | ('My Post', 'hello!')
+                                    |
+                                    | # ^^^^^^
+                                    | # Boom! We now have a duplicate
+                                    | # title!
+
+ +

The best way to work around this problem is to add a unique index to the database table using connection.add_index. In the rare case that a race condition occurs, the database will guarantee the field's uniqueness.

+ +

When the database catches such a duplicate insertion, ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid exception. You can either choose to let this error propagate (which will result in the default Rails exception page being shown), or you can catch it and restart the transaction (e.g. by telling the user that the title already exists, and asking them to re-enter the title). This technique is also known as optimistic concurrency control.

+ +

The bundled ActiveRecord::ConnectionAdapters distinguish unique index constraint errors from other types of database errors by throwing an ActiveRecord::RecordNotUnique exception. For other adapters you will have to parse the (database-specific) exception message to detect such a case.

+ +

The following bundled adapters throw the ActiveRecord::RecordNotUnique exception:

+ +
+ + + + + + + + +
+ + +
+
# File activerecord/lib/active_record/validations/uniqueness.rb, line 233
+def validates_uniqueness_of(*attr_names)
+  validates_with UniquenessValidator, _merge_attributes(attr_names)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/ValueTooLong.html b/src/5.2/classes/ActiveRecord/ValueTooLong.html new file mode 100644 index 0000000000..0d4f1fb07c --- /dev/null +++ b/src/5.2/classes/ActiveRecord/ValueTooLong.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ValueTooLong +layout: default +--- +
+ +
+
+ +
+ +

Raised when a record cannot be inserted or updated because a value too long for a column type.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveRecord/WrappedDatabaseException.html b/src/5.2/classes/ActiveRecord/WrappedDatabaseException.html new file mode 100644 index 0000000000..892d05e07e --- /dev/null +++ b/src/5.2/classes/ActiveRecord/WrappedDatabaseException.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::WrappedDatabaseException +layout: default +--- +
+ +
+
+ +
+ +

Defunct wrapper class kept for compatibility. StatementInvalid wraps the original exception now.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage.html b/src/5.2/classes/ActiveStorage.html new file mode 100644 index 0000000000..ae45df6524 --- /dev/null +++ b/src/5.2/classes/ActiveStorage.html @@ -0,0 +1,294 @@ +--- +title: ActiveStorage +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Active Storage as a Gem::Version.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded ActiveStorage as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/version.rb, line 7
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/AnalyzeJob.html b/src/5.2/classes/ActiveStorage/AnalyzeJob.html new file mode 100644 index 0000000000..83591e7eb3 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/AnalyzeJob.html @@ -0,0 +1,113 @@ +--- +title: ActiveStorage::AnalyzeJob +layout: default +--- +
+ +
+
+ +
+ +

Provides asynchronous analysis of ActiveStorage::Blob records via ActiveStorage::Blob#analyze_later.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + perform(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/jobs/active_storage/analyze_job.rb, line 5
+def perform(blob)
+  blob.analyze
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Analyzer.html b/src/5.2/classes/ActiveStorage/Analyzer.html new file mode 100644 index 0000000000..4ab2216054 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Analyzer.html @@ -0,0 +1,287 @@ +--- +title: ActiveStorage::Analyzer +layout: default +--- +
+ +
+
+ +
+ +

This is an abstract base class for analyzers, which extract metadata from blobs. See ActiveStorage::Analyzer::ImageAnalyzer for an example of a concrete subclass.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + blob
+ + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+

Implement this method in a concrete subclass. Have it return true when given a blob from which the analyzer can extract metadata.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer.rb, line 15
+def self.accept?(blob)
+  false
+end
+
+
+ +
+ +
+

+ + new(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer.rb, line 19
+def initialize(blob)
+  @blob = blob
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + metadata() + +

+ + +
+

Override this method in a concrete subclass. Have it return a Hash of metadata.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer.rb, line 24
+def metadata
+  raise NotImplementedError
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer.rb, line 29
+def logger #:doc:
+  ActiveStorage.logger
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Analyzer/ImageAnalyzer.html b/src/5.2/classes/ActiveStorage/Analyzer/ImageAnalyzer.html new file mode 100644 index 0000000000..62146b54b4 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Analyzer/ImageAnalyzer.html @@ -0,0 +1,174 @@ +--- +title: ActiveStorage::Analyzer::ImageAnalyzer +layout: default +--- +
+ +
+
+ +
+ +

Extracts width and height in pixels from an image blob.

+ +

If the image contains EXIF data indicating its angle is 90 or 270 degrees, its width and height are swapped for convenience.

+ +

Example:

+ +
ActiveStorage::Analyzer::ImageAnalyzer.new(blob).metadata
+# => { width: 4104, height: 2736 }
+
+ +

This analyzer relies on the third-party MiniMagick gem. MiniMagick requires the ImageMagick system library.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer/image_analyzer.rb, line 16
+def self.accept?(blob)
+  blob.image?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + metadata() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer/image_analyzer.rb, line 20
+def metadata
+  read_image do |image|
+    if rotated_image?(image)
+      { width: image.height, height: image.width }
+    else
+      { width: image.width, height: image.height }
+    end
+  end
+rescue LoadError
+  logger.info "Skipping image analysis because the mini_magick gem isn't installed"
+  {}
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Analyzer/VideoAnalyzer.html b/src/5.2/classes/ActiveStorage/Analyzer/VideoAnalyzer.html new file mode 100644 index 0000000000..51d4923d78 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Analyzer/VideoAnalyzer.html @@ -0,0 +1,176 @@ +--- +title: ActiveStorage::Analyzer::VideoAnalyzer +layout: default +--- +
+ +
+
+ +
+ +

Extracts the following from a video blob:

+
  • +

    Width (pixels)

    +
  • +

    Height (pixels)

    +
  • +

    Duration (seconds)

    +
  • +

    Angle (degrees)

    +
  • +

    Display aspect ratio

    +
+ +

Example:

+ +
ActiveStorage::VideoAnalyzer.new(blob).metadata
+# => { width: 640.0, height: 480.0, duration: 5.0, angle: 0, display_aspect_ratio: [4, 3] }
+
+ +

When a video's angle is 90 or 270 degrees, its width and height are automatically swapped for convenience.

+ +

This analyzer requires the ffmpeg system library, which is not provided by Rails.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer/video_analyzer.rb, line 23
+def self.accept?(blob)
+  blob.video?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + metadata() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/analyzer/video_analyzer.rb, line 27
+def metadata
+  { width: width, height: height, duration: duration, angle: angle, display_aspect_ratio: display_aspect_ratio }.compact
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Attached.html b/src/5.2/classes/ActiveStorage/Attached.html new file mode 100644 index 0000000000..8a1f12a0a5 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Attached.html @@ -0,0 +1,171 @@ +--- +title: ActiveStorage::Attached +layout: default +--- +
+ +
+
+ +
+ +

Abstract base class for the concrete ActiveStorage::Attached::One and ActiveStorage::Attached::Many classes that both provide proxy access to the blob association for a record.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + dependent
+ [R] + name
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(name, record, dependent:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached.rb, line 13
+def initialize(name, record, dependent:)
+  @name, @record, @dependent = name, record, dependent
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Attached/Macros.html b/src/5.2/classes/ActiveStorage/Attached/Macros.html new file mode 100644 index 0000000000..70cfead3a1 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Attached/Macros.html @@ -0,0 +1,310 @@ +--- +title: ActiveStorage::Attached::Macros +layout: default +--- +
+ +
+
+ +
+ +

Provides the class-level DSL for declaring that an Active Record model has attached blobs.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + has_many_attached(name, dependent: :purge_later) + +

+ + +
+

Specifies the relation between multiple attachments and the model.

+ +
class Gallery < ActiveRecord::Base
+  has_many_attached :photos
+end
+
+ +

There are no columns defined on the model side, Active Storage takes care of the mapping between your records and the attachments.

+ +

To avoid N+1 queries, you can include the attached blobs in your query like so:

+ +
Gallery.where(user: Current.user).with_attached_photos
+
+ +

Under the covers, this relationship is implemented as a has_many association to a ActiveStorage::Attachment record and a has_many-through association to a ActiveStorage::Blob record. These associations are available as photos_attachments and photos_blobs. But you shouldn't need to work with these associations directly in most circumstances.

+ +

The system has been designed to having you go through the ActiveStorage::Attached::Many proxy that provides the dynamic proxy to the associations and factory methods, like #attach.

+ +

If the :dependent option isn't set, all the attachments will be purged (i.e. destroyed) whenever the record is destroyed.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/macros.rb, line 77
+    def has_many_attached(name, dependent: :purge_later)
+      class_eval <<-CODE, __FILE__, __LINE__ + 1
+        def #{name}
+          @active_storage_attached_#{name} ||= ActiveStorage::Attached::Many.new("#{name}", self, dependent: #{dependent == :purge_later ? ":purge_later" : "false"})
+        end
+
+        def #{name}=(attachables)
+          #{name}.attach(attachables)
+        end
+      CODE
+
+      has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: false do
+        def purge
+          each(&:purge)
+          reset
+        end
+
+        def purge_later
+          each(&:purge_later)
+          reset
+        end
+      end
+      has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "ActiveStorage::Blob", source: :blob
+
+      scope :"with_attached_#{name}", -> { includes("#{name}_attachments": :blob) }
+
+      if dependent == :purge_later
+        after_destroy_commit { public_send(name).purge_later }
+      else
+        before_destroy { public_send(name).detach }
+      end
+    end
+
+
+ +
+ +
+

+ + has_one_attached(name, dependent: :purge_later) + +

+ + +
+

Specifies the relation between a single attachment and the model.

+ +
class User < ActiveRecord::Base
+  has_one_attached :avatar
+end
+
+ +

There is no column defined on the model side, Active Storage takes care of the mapping between your records and the attachment.

+ +

To avoid N+1 queries, you can include the attached blobs in your query like so:

+ +
User.with_attached_avatar
+
+ +

Under the covers, this relationship is implemented as a has_one association to a ActiveStorage::Attachment record and a has_one-through association to a ActiveStorage::Blob record. These associations are available as avatar_attachment and avatar_blob. But you shouldn't need to work with these associations directly in most circumstances.

+ +

The system has been designed to having you go through the ActiveStorage::Attached::One proxy that provides the dynamic proxy to the associations and factory methods, like attach.

+ +

If the :dependent option isn't set, the attachment will be purged (i.e. destroyed) whenever the record is destroyed.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/macros.rb, line 30
+    def has_one_attached(name, dependent: :purge_later)
+      class_eval <<-CODE, __FILE__, __LINE__ + 1
+        def #{name}
+          @active_storage_attached_#{name} ||= ActiveStorage::Attached::One.new("#{name}", self, dependent: #{dependent == :purge_later ? ":purge_later" : "false"})
+        end
+
+        def #{name}=(attachable)
+          #{name}.attach(attachable)
+        end
+      CODE
+
+      has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record, inverse_of: :record, dependent: false
+      has_one :"#{name}_blob", through: :"#{name}_attachment", class_name: "ActiveStorage::Blob", source: :blob
+
+      scope :"with_attached_#{name}", -> { includes("#{name}_attachment": :blob) }
+
+      if dependent == :purge_later
+        after_destroy_commit { public_send(name).purge_later }
+      else
+        before_destroy { public_send(name).detach }
+      end
+    end
+
+
+ +
+ +
+

+ + purge() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/macros.rb, line 89
+def purge
+  each(&:purge)
+  reset
+end
+
+
+ +
+ +
+

+ + purge_later() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/macros.rb, line 94
+def purge_later
+  each(&:purge_later)
+  reset
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Attached/Many.html b/src/5.2/classes/ActiveStorage/Attached/Many.html new file mode 100644 index 0000000000..f2171f3de5 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Attached/Many.html @@ -0,0 +1,325 @@ +--- +title: ActiveStorage::Attached::Many +layout: default +--- +
+ +
+
+ +
+ +

Decorated proxy object representing of multiple attachments to a model.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attach(*attachables) + +

+ + +
+

Associates one or several attachments with the current record, saving them to the database.

+ +
document.images.attach(params[:images]) # Array of ActionDispatch::Http::UploadedFile objects
+document.images.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload
+document.images.attach(io: File.open("/path/to/racecar.jpg"), filename: "racecar.jpg", content_type: "image/jpg")
+document.images.attach([ first_blob, second_blob ])
+
+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/many.rb, line 21
+def attach(*attachables)
+  attachables.flatten.collect do |attachable|
+    if record.new_record?
+      attachments.build(record: record, blob: create_blob_from(attachable))
+    else
+      attachments.create!(record: record, blob: create_blob_from(attachable))
+    end
+  end
+end
+
+
+ +
+ +
+

+ + attached?() + +

+ + +
+

Returns true if any attachments has been made.

+ +
class Gallery < ActiveRecord::Base
+  has_many_attached :photos
+end
+
+Gallery.new.photos.attached? # => false
+
+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/many.rb, line 38
+def attached?
+  attachments.any?
+end
+
+
+ +
+ +
+

+ + attachments() + +

+ + +
+

Returns all the associated attachment records.

+ +

All methods called on this proxy object that aren't listed here will automatically be delegated to attachments.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/many.rb, line 11
+def attachments
+  record.public_send("#{name}_attachments")
+end
+
+
+ +
+ +
+

+ + detach() + +

+ + +
+

Deletes associated attachments without purging them, leaving their respective blobs in place.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/many.rb, line 43
+def detach
+  attachments.destroy_all if attached?
+end
+
+
+ +
+ +
+

+ + purge + +

+ + +
+

Directly purges each associated attachment (i.e. destroys the blobs and attachments and deletes the files on the service).

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/many.rb, line 48
+    
+
+
+ +
+ +
+

+ + purge_later + +

+ + +
+

Purges each associated attachment through the queuing system.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/many.rb, line 55
+  
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Attached/One.html b/src/5.2/classes/ActiveStorage/Attached/One.html new file mode 100644 index 0000000000..182aa59a5b --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Attached/One.html @@ -0,0 +1,341 @@ +--- +title: ActiveStorage::Attached::One +layout: default +--- +
+ +
+
+ +
+ +

Representation of a single attachment to a model.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + attach(attachable) + +

+ + +
+

Associates a given attachment with the current record, saving it to the database.

+ +
person.avatar.attach(params[:avatar]) # ActionDispatch::Http::UploadedFile object
+person.avatar.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload
+person.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpg")
+person.avatar.attach(avatar_blob) # ActiveStorage::Blob object
+
+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/one.rb, line 22
+def attach(attachable)
+  blob_was = blob if attached?
+  blob = create_blob_from(attachable)
+
+  unless blob == blob_was
+    transaction do
+      detach
+      write_attachment build_attachment(blob: blob)
+    end
+
+    blob_was.purge_later if blob_was && dependent == :purge_later
+  end
+end
+
+
+ +
+ +
+

+ + attached?() + +

+ + +
+

Returns true if an attachment has been made.

+ +
class User < ActiveRecord::Base
+  has_one_attached :avatar
+end
+
+User.new.avatar.attached? # => false
+
+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/one.rb, line 43
+def attached?
+  attachment.present?
+end
+
+
+ +
+ +
+

+ + attachment() + +

+ + +
+

Returns the associated attachment record.

+ +

You don't have to call this method to access the attachment's methods as they are all available at the model level.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/one.rb, line 12
+def attachment
+  record.public_send("#{name}_attachment")
+end
+
+
+ +
+ +
+

+ + detach() + +

+ + +
+

Deletes the attachment without purging it, leaving its blob in place.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/one.rb, line 48
+def detach
+  if attached?
+    attachment.destroy
+    write_attachment nil
+  end
+end
+
+
+ +
+ +
+

+ + purge() + +

+ + +
+

Directly purges the attachment (i.e. destroys the blob and attachment and deletes the file on the service).

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/one.rb, line 57
+def purge
+  if attached?
+    attachment.purge
+    write_attachment nil
+  end
+end
+
+
+ +
+ +
+

+ + purge_later() + +

+ + +
+

Purges the attachment through the queuing system.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/attached/one.rb, line 65
+def purge_later
+  if attached?
+    attachment.purge_later
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Attachment.html b/src/5.2/classes/ActiveStorage/Attachment.html new file mode 100644 index 0000000000..62dfb64b8d --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Attachment.html @@ -0,0 +1,154 @@ +--- +title: ActiveStorage::Attachment +layout: default +--- +
+ +
+
+ +
+ +

Attachments associate records with blobs. Usually that's a one record-many blobs relationship, but it is possible to associate many different records with the same blob. If you're doing that, you'll want to declare with has_one/many_attached :thingy, dependent: false, so that destroying any one record won't destroy the blob as well. (Then you'll need to do your own garbage collecting, though).

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + purge() + +

+ + +
+

Synchronously purges the blob (deletes it from the configured service) and destroys the attachment.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/attachment.rb, line 20
+def purge
+  destroy
+  blob.purge
+end
+
+
+ +
+ +
+

+ + purge_later() + +

+ + +
+

Destroys the attachment and asynchronously purges the blob (deletes it from the configured service).

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/attachment.rb, line 26
+def purge_later
+  destroy
+  blob.purge_later
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/BaseController.html b/src/5.2/classes/ActiveStorage/BaseController.html new file mode 100644 index 0000000000..4fcecbe2d2 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/BaseController.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::BaseController +layout: default +--- +
+ +
+
+ +
+ +

The base controller for all ActiveStorage controllers.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/BaseJob.html b/src/5.2/classes/ActiveStorage/BaseJob.html new file mode 100644 index 0000000000..9fc6e59e5f --- /dev/null +++ b/src/5.2/classes/ActiveStorage/BaseJob.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::BaseJob +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Blob.html b/src/5.2/classes/ActiveStorage/Blob.html new file mode 100644 index 0000000000..74a9cc5685 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Blob.html @@ -0,0 +1,904 @@ +--- +title: ActiveStorage::Blob +layout: default +--- +
+ +
+
+ +
+ +

A blob is a record that contains the metadata about a file and a key for where that file resides on the service. Blobs can be created in two ways:

+
  1. +

    Subsequent to the file being uploaded server-side to the service via create_after_upload!.

    +
  2. +

    Ahead of the file being directly uploaded client-side to the service via create_before_direct_upload!.

    +
+ +

The first option doesn't require any client-side JavaScript integration, and can be used by any other back-end service that deals with files. The second option is faster, since you're not using your own server as a staging point for uploads, and can work with deployments like Heroku that do not provide large amounts of disk space.

+ +

Blobs are intended to be immutable in as-so-far as their reference to a specific file goes. You're allowed to update a blob's metadata on a subsequent pass, but you should not update the key or change the uploaded file. If you need to create a derivative or otherwise change the blob, simply create a new blob and purge the old one.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + build_after_upload(io:, filename:, content_type: nil, metadata: nil) + +

+ + +
+

Returns a new, unsaved blob instance after the io has been uploaded to the service.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 51
+def build_after_upload(io:, filename:, content_type: nil, metadata: nil)
+  new.tap do |blob|
+    blob.filename     = filename
+    blob.content_type = content_type
+    blob.metadata     = metadata
+
+    blob.upload io
+  end
+end
+
+
+ +
+ +
+

+ + create_after_upload!(io:, filename:, content_type: nil, metadata: nil) + +

+ + +
+

Returns a saved blob instance after the io has been uploaded to the service. Note, the blob is first built, then the io is uploaded, then the blob is saved. This is done this way to avoid uploading (which may take time), while having an open database transaction.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 64
+def create_after_upload!(io:, filename:, content_type: nil, metadata: nil)
+  build_after_upload(io: io, filename: filename, content_type: content_type, metadata: metadata).tap(&:save!)
+end
+
+
+ +
+ +
+

+ + create_before_direct_upload!(filename:, byte_size:, checksum:, content_type: nil, metadata: nil) + +

+ + +
+

Returns a saved blob without uploading a file to the service. This blob will point to a key where there is no file yet. It's intended to be used together with a client-side upload, which will first create the blob in order to produce the signed URL for uploading. This signed URL points to the key generated by the blob. Once the form using the direct upload is submitted, the blob can be associated with the right record using the signed ID.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 73
+def create_before_direct_upload!(filename:, byte_size:, checksum:, content_type: nil, metadata: nil)
+  create! filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, metadata: metadata
+end
+
+
+ +
+ +
+

+ + find_signed(id) + +

+ + +
+

You can used the signed ID of a blob to refer to it on the client side without fear of tampering. This is particularly helpful for direct uploads where the client-side needs to refer to the blob that was created ahead of the upload itself on form submission.

+ +

The signed ID is also used to create stable URLs for the blob through the BlobsController.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 46
+def find_signed(id)
+  find ActiveStorage.verifier.verify(id, purpose: :blob_id)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + audio?() + +

+ + +
+

Returns true if the content_type of this blob is in the audio range, like audio/mpeg.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 105
+def audio?
+  content_type.start_with?("audio")
+end
+
+
+ +
+ +
+

+ + delete() + +

+ + +
+

Deletes the file on the service that's associated with this blob. This should only be done if the blob is going to be deleted as well or you will essentially have a dead reference. It's recommended to use the #purge and #purge_later methods in most circumstances.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 172
+def delete
+  service.delete(key)
+  service.delete_prefixed("variants/#{key}/") if image?
+end
+
+
+ +
+ +
+

+ + download(&block) + +

+ + +
+

Downloads the file associated with this blob. If no block is given, the entire file is read into memory and returned. That'll use a lot of RAM for very large files. If a block is given, then the download is streamed and yielded in chunks.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 164
+def download(&block)
+  service.download key, &block
+end
+
+
+ +
+ +
+

+ + filename() + +

+ + +
+

Returns an ActiveStorage::Filename instance of the filename that can be queried for basename, extension, and a sanitized version of the filename that's safe to use in URLs.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 95
+def filename
+  ActiveStorage::Filename.new(self[:filename])
+end
+
+
+ +
+ +
+

+ + image?() + +

+ + +
+

Returns true if the content_type of this blob is in the image range, like image/png.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 100
+def image?
+  content_type.start_with?("image")
+end
+
+
+ +
+ +
+

+ + key() + +

+ + +
+

Returns the key pointing to the file on the service that's associated with this blob. The key is in the standard secure-token format from Rails. So it'll look like: XTAPjJCJiuDrLk3TmwyJGpUo. This key is not intended to be revealed directly to the user. Always refer to blobs using the signed_id or a verified form of the key.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 87
+def key
+  # We can't wait until the record is first saved to have a key for it
+  self[:key] ||= self.class.generate_unique_secure_token
+end
+
+
+ +
+ +
+

+ + purge() + +

+ + +
+

Deletes the file on the service and then destroys the blob record. This is the recommended way to dispose of unwanted blobs. Note, though, that deleting the file off the service will initiate a HTTP connection to the service, which may be slow or prevented, so you should not use this method inside a transaction or in callbacks. Use #purge_later instead.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 180
+def purge
+  destroy
+  delete
+rescue ActiveRecord::InvalidForeignKey
+end
+
+
+ +
+ +
+

+ + purge_later() + +

+ + +
+

Enqueues an ActiveStorage::PurgeJob job that'll call purge. This is the recommended way to purge blobs when the call needs to be made from a transaction, a callback, or any other real-time scenario.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 188
+def purge_later
+  ActiveStorage::PurgeJob.perform_later(self)
+end
+
+
+ +
+ +
+

+ + service_headers_for_direct_upload() + +

+ + +
+

Returns a Hash of headers for service_url_for_direct_upload requests.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 138
+def service_headers_for_direct_upload
+  service.headers_for_direct_upload key, filename: filename, content_type: content_type, content_length: byte_size, checksum: checksum
+end
+
+
+ +
+ +
+

+ + service_url(expires_in: service.url_expires_in, disposition: :inline, filename: nil, **options) + +

+ + +
+

Returns the URL of the blob on the service. This URL is intended to be short-lived for security and not used directly with users. Instead, the service_url should only be exposed as a redirect from a stable, possibly authenticated URL. Hiding the service_url behind a redirect also gives you the power to change services without updating all URLs. And it allows permanent URLs that redirect to the service_url to be cached in the view.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 124
+def service_url(expires_in: service.url_expires_in, disposition: :inline, filename: nil, **options)
+  filename = ActiveStorage::Filename.wrap(filename || self.filename)
+
+  service.url key, expires_in: expires_in, filename: filename, content_type: content_type_for_service_url,
+    disposition: forced_disposition_for_service_url || disposition, **options
+end
+
+
+ +
+ +
+

+ + service_url_for_direct_upload(expires_in: service.url_expires_in) + +

+ + +
+

Returns a URL that can be used to directly upload a file for this blob on the service. This URL is intended to be short-lived for security and only generated on-demand by the client-side JavaScript responsible for doing the uploading.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 133
+def service_url_for_direct_upload(expires_in: service.url_expires_in)
+  service.url_for_direct_upload key, expires_in: expires_in, content_type: content_type, content_length: byte_size, checksum: checksum
+end
+
+
+ +
+ +
+

+ + signed_id() + +

+ + +
+

Returns a signed ID for this blob that's suitable for reference on the client-side without fear of tampering. It uses the framework-wide verifier on ActiveStorage.verifier, but with a dedicated purpose.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 80
+def signed_id
+  ActiveStorage.verifier.generate(id, purpose: :blob_id)
+end
+
+
+ +
+ +
+

+ + text?() + +

+ + +
+

Returns true if the content_type of this blob is in the text range, like text/plain.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 115
+def text?
+  content_type.start_with?("text")
+end
+
+
+ +
+ +
+

+ + upload(io) + +

+ + +
+

Uploads the io to the service on the key for this blob. Blobs are intended to be immutable, so you shouldn't be using this method after a file has already been uploaded to fit with a blob. If you want to create a derivative blob, you should instead simply create a new blob based on the old one.

+ +

Prior to uploading, we compute the checksum, which is sent to the service for transit integrity validation. If the checksum does not match what the service receives, an exception will be raised. We also measure the size of the io and store that in byte_size on the blob record.

+ +

Normally, you do not have to call this method directly at all. Use the factory class methods of build_after_upload and create_after_upload!.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 153
+def upload(io)
+  self.checksum     = compute_checksum_in_chunks(io)
+  self.content_type = extract_content_type(io)
+  self.byte_size    = io.size
+  self.identified   = true
+
+  service.upload key, io, checksum: checksum, **service_metadata
+end
+
+
+ +
+ +
+

+ + video?() + +

+ + +
+

Returns true if the content_type of this blob is in the video range, like video/mp4.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob.rb, line 110
+def video?
+  content_type.start_with?("video")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Blob/Analyzable.html b/src/5.2/classes/ActiveStorage/Blob/Analyzable.html new file mode 100644 index 0000000000..8cd0e25947 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Blob/Analyzable.html @@ -0,0 +1,196 @@ +--- +title: ActiveStorage::Blob::Analyzable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + analyze() + +

+ + +
+

Extracts and stores metadata from the file associated with this blob using a relevant analyzer. Active Storage comes with built-in analyzers for images and videos. See ActiveStorage::Analyzer::ImageAnalyzer and ActiveStorage::Analyzer::VideoAnalyzer for information about the specific attributes they extract and the third-party libraries they require.

+ +

To choose the analyzer for a blob, Active Storage calls accept? on each registered analyzer in order. It uses the first analyzer for which accept? returns true when given the blob. If no registered analyzer accepts the blob, no metadata is extracted from it.

+ +

In a Rails application, add or remove analyzers by manipulating Rails.application.config.active_storage.analyzers in an initializer:

+ +
# Add a custom analyzer for Microsoft Office documents:
+Rails.application.config.active_storage.analyzers.append DOCXAnalyzer
+
+# Remove the built-in video analyzer:
+Rails.application.config.active_storage.analyzers.delete ActiveStorage::Analyzer::VideoAnalyzer
+
+ +

Outside of a Rails application, manipulate ActiveStorage.analyzers instead.

+ +

You won't ordinarily need to call this method from a Rails application. New blobs are automatically and asynchronously analyzed via analyze_later when they're attached for the first time.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/analyzable.rb, line 28
+def analyze
+  update! metadata: metadata.merge(extract_metadata_via_analyzer)
+end
+
+
+ +
+ +
+

+ + analyze_later() + +

+ + +
+

Enqueues an ActiveStorage::AnalyzeJob which calls analyze.

+ +

This method is automatically called for a blob when it's attached for the first time. You can call it to analyze a blob again (e.g. if you add a new analyzer or modify an existing one).

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/analyzable.rb, line 36
+def analyze_later
+  ActiveStorage::AnalyzeJob.perform_later(self)
+end
+
+
+ +
+ +
+

+ + analyzed?() + +

+ + +
+

Returns true if the blob has been analyzed.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/analyzable.rb, line 41
+def analyzed?
+  analyzed
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Blob/Identifiable.html b/src/5.2/classes/ActiveStorage/Blob/Identifiable.html new file mode 100644 index 0000000000..74a6f507e2 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Blob/Identifiable.html @@ -0,0 +1,143 @@ +--- +title: ActiveStorage::Blob::Identifiable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + identified?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/identifiable.rb, line 11
+def identified?
+  identified
+end
+
+
+ +
+ +
+

+ + identify() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/identifiable.rb, line 4
+def identify
+  unless identified?
+    update! content_type: identify_content_type, identified: true
+    update_service_metadata
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Blob/Representable.html b/src/5.2/classes/ActiveStorage/Blob/Representable.html new file mode 100644 index 0000000000..63a1c62e6e --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Blob/Representable.html @@ -0,0 +1,342 @@ +--- +title: ActiveStorage::Blob::Representable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + preview(transformations) + +

+ + +
+

Returns an ActiveStorage::Preview instance with the set of transformations provided. A preview is an image generated from a non-image blob. Active Storage comes with built-in previewers for videos and PDF documents. The video previewer extracts the first frame from a video and the PDF previewer extracts the first page from a PDF document.

+ +
blob.preview(resize: "100x100").processed.service_url
+
+ +

Avoid processing previews synchronously in views. Instead, link to a controller action that processes them on demand. Active Storage provides one, but you may want to create your own (for example, if you need authentication). Here’s how to use the built-in version:

+ +
<%= image_tag video.preview(resize: "100x100") %>
+
+ +

This method raises ActiveStorage::UnpreviewableError if no previewer accepts the receiving blob. To determine whether a blob is accepted by any previewer, call ActiveStorage::Blob#previewable?.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/representable.rb, line 56
+def preview(transformations)
+  if previewable?
+    ActiveStorage::Preview.new(self, transformations)
+  else
+    raise ActiveStorage::UnpreviewableError
+  end
+end
+
+
+ +
+ +
+

+ + previewable?() + +

+ + +
+

Returns true if any registered previewer accepts the blob. By default, this will return true for videos and PDF documents.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/representable.rb, line 65
+def previewable?
+  ActiveStorage.previewers.any? { |klass| klass.accept?(self) }
+end
+
+
+ +
+ +
+

+ + representable?() + +

+ + +
+

Returns true if the blob is variable or previewable.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/representable.rb, line 90
+def representable?
+  variable? || previewable?
+end
+
+
+ +
+ +
+

+ + representation(transformations) + +

+ + +
+

Returns an ActiveStorage::Preview for a previewable blob or an ActiveStorage::Variant for a variable image blob.

+ +
blob.representation(resize: "100x100").processed.service_url
+
+ +

Raises ActiveStorage::UnrepresentableError if the receiving blob is neither variable nor previewable. Call ActiveStorage::Blob#representable? to determine whether a blob is representable.

+ +

See ActiveStorage::Blob#preview and ActiveStorage::Blob#variant for more information.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/representable.rb, line 78
+def representation(transformations)
+  case
+  when previewable?
+    preview transformations
+  when variable?
+    variant transformations
+  else
+    raise ActiveStorage::UnrepresentableError
+  end
+end
+
+
+ +
+ +
+

+ + variable?() + +

+ + +
+

Returns true if ImageMagick can transform the blob (its content type is in ActiveStorage.variable_content_types).

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/representable.rb, line 37
+def variable?
+  ActiveStorage.variable_content_types.include?(content_type)
+end
+
+
+ +
+ +
+

+ + variant(transformations) + +

+ + +
+

Returns an ActiveStorage::Variant instance with the set of transformations provided. This is only relevant for image files, and it allows any image to be transformed for size, colors, and the like. Example:

+ +
avatar.variant(resize: "100x100").processed.service_url
+
+ +

This will create and process a variant of the avatar blob that's constrained to a height and width of 100px. Then it'll upload said variant to the service according to a derivative key of the blob and the transformations.

+ +

Frequently, though, you don't actually want to transform the variant right away. But rather simply refer to a specific variant that can be created by a controller on-demand. Like so:

+ +
<%= image_tag Current.user.avatar.variant(resize: "100x100") %>
+
+ +

This will create a URL for that specific blob with that specific variant, which the ActiveStorage::RepresentationsController can then produce on-demand.

+ +

Raises ActiveStorage::InvariableError if ImageMagick cannot transform the blob. To determine whether a blob is variable, call ActiveStorage::Blob#variable?.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/blob/representable.rb, line 28
+def variant(transformations)
+  if variable?
+    ActiveStorage::Variant.new(self, transformations)
+  else
+    raise ActiveStorage::InvariableError
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/BlobsController.html b/src/5.2/classes/ActiveStorage/BlobsController.html new file mode 100644 index 0000000000..280814b1a7 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/BlobsController.html @@ -0,0 +1,114 @@ +--- +title: ActiveStorage::BlobsController +layout: default +--- +
+ +
+
+ +
+ +

Take a signed permanent reference for a blob and turn it into an expiring service URL for download. Note: These URLs are publicly accessible. If you need to enforce access protection beyond the security-through-obscurity factor of the signed blob references, you'll need to implement your own authenticated redirection controller.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/controllers/active_storage/blobs_controller.rb, line 10
+def show
+  expires_in ActiveStorage::Blob.service.url_expires_in
+  redirect_to @blob.service_url(disposition: params[:disposition])
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/DirectUploadsController.html b/src/5.2/classes/ActiveStorage/DirectUploadsController.html new file mode 100644 index 0000000000..dae27d8382 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/DirectUploadsController.html @@ -0,0 +1,114 @@ +--- +title: ActiveStorage::DirectUploadsController +layout: default +--- +
+ +
+
+ +
+ +

Creates a new blob on the server side in anticipation of a direct-to-service upload from the client side. When the client-side upload is completed, the signed_blob_id can be submitted as part of the form to reference the blob that was created up front.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + create() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/controllers/active_storage/direct_uploads_controller.rb, line 7
+def create
+  blob = ActiveStorage::Blob.create_before_direct_upload!(blob_args)
+  render json: direct_upload_json(blob)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/DiskController.html b/src/5.2/classes/ActiveStorage/DiskController.html new file mode 100644 index 0000000000..302a7246e5 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/DiskController.html @@ -0,0 +1,165 @@ +--- +title: ActiveStorage::DiskController +layout: default +--- +
+ +
+
+ +
+ +

Serves files stored with the disk service in the same way that the cloud services do. This means using expiring, signed URLs that are meant for immediate access, not permanent linking. Always go through the BlobsController, or your own authenticated controller, rather than directly to the service url.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/controllers/active_storage/disk_controller.rb, line 10
+def show
+  if key = decode_verified_key
+    serve_file disk_service.path_for(key[:key]), content_type: key[:content_type], disposition: key[:disposition]
+  else
+    head :not_found
+  end
+end
+
+
+ +
+ +
+

+ + update() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/controllers/active_storage/disk_controller.rb, line 18
+def update
+  if token = decode_verified_token
+    if acceptable_content?(token)
+      disk_service.upload token[:key], request.body, checksum: token[:checksum]
+      head :no_content
+    else
+      head :unprocessable_entity
+    end
+  end
+rescue ActiveStorage::IntegrityError
+  head :unprocessable_entity
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Downloading.html b/src/5.2/classes/ActiveStorage/Downloading.html new file mode 100644 index 0000000000..9d748613da --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Downloading.html @@ -0,0 +1,185 @@ +--- +title: ActiveStorage::Downloading +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Private methods

+ +
+

+ + download_blob_to(file) + +

+ + +
+

Efficiently downloads blob data into the given file.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/downloading.rb, line 27
+def download_blob_to(file) #:doc:
+  file.binmode
+  blob.download { |chunk| file.write(chunk) }
+  file.flush
+  file.rewind
+end
+
+
+ +
+ +
+

+ + download_blob_to_tempfile() + +

+ + +
+

Opens a new tempfile in tempdir and copies blob data into it. Yields the tempfile.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/downloading.rb, line 9
+def download_blob_to_tempfile #:doc:
+  open_tempfile_for_blob do |file|
+    download_blob_to file
+    yield file
+  end
+end
+
+
+ +
+ +
+

+ + tempdir() + +

+ + +
+

Returns the directory in which tempfiles should be opened. Defaults to Dir.tmpdir.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/downloading.rb, line 35
+def tempdir #:doc:
+  Dir.tmpdir
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Filename.html b/src/5.2/classes/ActiveStorage/Filename.html new file mode 100644 index 0000000000..2387875873 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Filename.html @@ -0,0 +1,534 @@ +--- +title: ActiveStorage::Filename +layout: default +--- +
+ +
+
+ +
+ +

Encapsulates a string representing a filename to provide convenient access to parts of it and sanitization. A Filename instance is returned by ActiveStorage::Blob#filename, and is comparable so it can be used for sorting.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Comparable + +
  • + +
+ + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(filename) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 18
+def initialize(filename)
+  @filename = filename
+end
+
+
+ +
+ +
+

+ + wrap(filename) + +

+ + +
+

Returns a Filename instance based on the given filename. If the filename is a Filename, it is returned unmodified. If it is a String, it is passed to ActiveStorage::Filename.new.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 13
+def wrap(filename)
+  filename.kind_of?(self) ? filename : new(filename)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 80
+def <=>(other)
+  to_s.downcase <=> other.to_s.downcase
+end
+
+
+ +
+ +
+

+ + as_json(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 72
+def as_json(*)
+  to_s
+end
+
+
+ +
+ +
+

+ + base() + +

+ + +
+

Returns the part of the filename preceding any extension.

+ +
ActiveStorage::Filename.new("racecar.jpg").base # => "racecar"
+ActiveStorage::Filename.new("racecar").base     # => "racecar"
+ActiveStorage::Filename.new(".gitignore").base  # => ".gitignore"
+
+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 27
+def base
+  File.basename @filename, extension_with_delimiter
+end
+
+
+ +
+ +
+

+ + extension() + +

+ + +
+ +
+ + + + + + + + + +
+ +
+

+ + extension_with_delimiter() + +

+ + +
+

Returns the extension of the filename (i.e. the substring following the last dot, excluding a dot at the beginning) with the dot that precedes it. If the filename has no extension, an empty string is returned.

+ +
ActiveStorage::Filename.new("racecar.jpg").extension_with_delimiter # => ".jpg"
+ActiveStorage::Filename.new("racecar").extension_with_delimiter     # => ""
+ActiveStorage::Filename.new(".gitignore").extension_with_delimiter  # => ""
+
+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 37
+def extension_with_delimiter
+  File.extname @filename
+end
+
+
+ +
+ +
+

+ + extension_without_delimiter() + +

+ + +
+

Returns the extension of the filename (i.e. the substring following the last dot, excluding a dot at the beginning). If the filename has no extension, an empty string is returned.

+ +
ActiveStorage::Filename.new("racecar.jpg").extension_without_delimiter # => "jpg"
+ActiveStorage::Filename.new("racecar").extension_without_delimiter     # => ""
+ActiveStorage::Filename.new(".gitignore").extension_without_delimiter  # => ""
+
+
+ + + +
+ Also aliased as: extension +
+ + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 47
+def extension_without_delimiter
+  extension_with_delimiter.from(1).to_s
+end
+
+
+ +
+ +
+

+ + sanitized() + +

+ + +
+

Returns the sanitized filename.

+ +
ActiveStorage::Filename.new("foo:bar.jpg").sanitized # => "foo-bar.jpg"
+ActiveStorage::Filename.new("foo/bar.jpg").sanitized # => "foo-bar.jpg"
+
+ +

Characters considered unsafe for storage (e.g. , $, and the RTL override character) are replaced with a dash.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 59
+def sanitized
+  @filename.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: "�").strip.tr("\u{202E}%$|:;/\t\r\n\\", "-")
+end
+
+
+ +
+ +
+

+ + to_json() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 76
+def to_json
+  to_s
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+

Returns the sanitized version of the filename.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/filename.rb, line 68
+def to_s
+  sanitized.to_s
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/IntegrityError.html b/src/5.2/classes/ActiveStorage/IntegrityError.html new file mode 100644 index 0000000000..33e4732c7c --- /dev/null +++ b/src/5.2/classes/ActiveStorage/IntegrityError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::IntegrityError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/InvariableError.html b/src/5.2/classes/ActiveStorage/InvariableError.html new file mode 100644 index 0000000000..d1c1c60e9d --- /dev/null +++ b/src/5.2/classes/ActiveStorage/InvariableError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::InvariableError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/LogSubscriber.html b/src/5.2/classes/ActiveStorage/LogSubscriber.html new file mode 100644 index 0000000000..e360d6e7bb --- /dev/null +++ b/src/5.2/classes/ActiveStorage/LogSubscriber.html @@ -0,0 +1,375 @@ +--- +title: ActiveStorage::LogSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/log_subscriber.rb, line 35
+def logger
+  ActiveStorage.logger
+end
+
+
+ +
+ +
+

+ + service_delete(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/log_subscriber.rb, line 19
+def service_delete(event)
+  info event, color("Deleted file from key: #{key_in(event)}", RED)
+end
+
+
+ +
+ +
+

+ + service_delete_prefixed(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/log_subscriber.rb, line 23
+def service_delete_prefixed(event)
+  info event, color("Deleted files by key prefix: #{event.payload[:prefix]}", RED)
+end
+
+
+ +
+ +
+

+ + service_download(event) + +

+ + +
+ +
+ + + +
+ Also aliased as: service_streaming_download +
+ + + + + + +
+ + +
+
# File activestorage/lib/active_storage/log_subscriber.rb, line 13
+def service_download(event)
+  info event, color("Downloaded file from key: #{key_in(event)}", BLUE)
+end
+
+
+ +
+ +
+

+ + service_exist(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/log_subscriber.rb, line 27
+def service_exist(event)
+  debug event, color("Checked if file exists at key: #{key_in(event)} (#{event.payload[:exist] ? "yes" : "no"})", BLUE)
+end
+
+
+ +
+ +
+

+ + service_streaming_download(event) + +

+ + +
+ +
+ + + + + +
+ Alias for: service_download +
+ + + +
+ +
+

+ + service_upload(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/log_subscriber.rb, line 7
+def service_upload(event)
+  message = "Uploaded file to key: #{key_in(event)}"
+  message += " (checksum: #{event.payload[:checksum]})" if event.payload[:checksum]
+  info event, color(message, GREEN)
+end
+
+
+ +
+ +
+

+ + service_url(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/log_subscriber.rb, line 31
+def service_url(event)
+  debug event, color("Generated URL for file at key: #{key_in(event)} (#{event.payload[:url]})", BLUE)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Preview.html b/src/5.2/classes/ActiveStorage/Preview.html new file mode 100644 index 0000000000..a2182635ec --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Preview.html @@ -0,0 +1,298 @@ +--- +title: ActiveStorage::Preview +layout: default +--- +
+ +
+
+ +
+ +

Some non-image blobs can be previewed: that is, they can be presented as images. A video blob can be previewed by extracting its first frame, and a PDF blob can be previewed by extracting its first page.

+ +

A previewer extracts a preview image from a blob. Active Storage provides previewers for videos and PDFs: ActiveStorage::Previewer::VideoPreviewer and ActiveStorage::Previewer::PDFPreviewer. Build custom previewers by subclassing ActiveStorage::Previewer and implementing the requisite methods. Consult the ActiveStorage::Previewer documentation for more details on what's required of previewers.

+ +

To choose the previewer for a blob, Active Storage calls accept? on each registered previewer in order. It uses the first previewer for which accept? returns true when given the blob. In a Rails application, add or remove previewers by manipulating Rails.application.config.active_storage.previewers in an initializer:

+ +
Rails.application.config.active_storage.previewers
+# => [ ActiveStorage::Previewer::PDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
+
+# Add a custom previewer for Microsoft Office documents:
+Rails.application.config.active_storage.previewers << DOCXPreviewer
+# => [ ActiveStorage::Previewer::PDFPreviewer, ActiveStorage::Previewer::VideoPreviewer, DOCXPreviewer ]
+
+ +

Outside of a Rails application, modify ActiveStorage.previewers instead.

+ +

The built-in previewers rely on third-party system libraries. Specifically, the built-in video previewer requires ffmpeg. Two PDF previewers are provided: one requires Poppler, and the other requires mupdf (version 1.8 or newer). To preview PDFs, install either Poppler or mupdf.

+ +

These libraries are not provided by Rails. You must install them yourself to use the built-in previewers. Before you install and use third-party software, make sure you understand the licensing implications of doing so.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + blob
+ [R] + variation
+ + + + +

Class Public methods

+ +
+

+ + new(blob, variation_or_variation_key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/preview.rb, line 35
+def initialize(blob, variation_or_variation_key)
+  @blob, @variation = blob, ActiveStorage::Variation.wrap(variation_or_variation_key)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + image() + +

+ + +
+

Returns the blob's attached preview image.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/preview.rb, line 51
+def image
+  blob.preview_image
+end
+
+
+ +
+ +
+

+ + processed() + +

+ + +
+

Processes the preview if it has not been processed yet. Returns the receiving Preview instance for convenience:

+ +
blob.preview(resize: "100x100").processed.service_url
+
+ +

Processing a preview generates an image from its blob and attaches the preview image to the blob. Because the preview image is stored with the blob, it is only generated once.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/preview.rb, line 45
+def processed
+  process unless processed?
+  self
+end
+
+
+ +
+ +
+

+ + service_url(**options) + +

+ + +
+

Returns the URL of the preview's variant on the service. Raises ActiveStorage::Preview::UnprocessedError if the preview has not been processed yet.

+ +

This method synchronously processes a variant of the preview image, so do not call it in views. Instead, generate a stable URL that redirects to the short-lived URL returned by this method.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/preview.rb, line 60
+def service_url(**options)
+  if processed?
+    variant.service_url(options)
+  else
+    raise UnprocessedError
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Preview/UnprocessedError.html b/src/5.2/classes/ActiveStorage/Preview/UnprocessedError.html new file mode 100644 index 0000000000..17fd10635f --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Preview/UnprocessedError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::Preview::UnprocessedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Previewer.html b/src/5.2/classes/ActiveStorage/Previewer.html new file mode 100644 index 0000000000..ff982b7098 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Previewer.html @@ -0,0 +1,344 @@ +--- +title: ActiveStorage::Previewer +layout: default +--- +
+ +
+
+ +
+ +

This is an abstract base class for previewers, which generate images from blobs. See ActiveStorage::Previewer::MuPDFPreviewer and ActiveStorage::Previewer::VideoPreviewer for examples of concrete subclasses.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + blob
+ + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+

Implement this method in a concrete subclass. Have it return true when given a blob from which the previewer can generate an image.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer.rb, line 16
+def self.accept?(blob)
+  false
+end
+
+
+ +
+ +
+

+ + new(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer.rb, line 20
+def initialize(blob)
+  @blob = blob
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview() + +

+ + +
+

Override this method in a concrete subclass. Have it yield an attachable preview image (i.e. anything accepted by ActiveStorage::Attached::One#attach).

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer.rb, line 26
+def preview
+  raise NotImplementedError
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + draw(*argv) + +

+ + +
+

Executes a system command, capturing its binary output in a tempfile. Yields the tempfile.

+ +

Use this method to shell out to a system library (e.g. mupdf or ffmpeg) for preview image generation. The resulting tempfile can be used as the :io value in an attachable Hash:

+ +
def preview
+  download_blob_to_tempfile do |input|
+    draw "my-drawing-command", input.path, "--format", "png", "-" do |output|
+      yield io: output, filename: "#{blob.filename.base}.png", content_type: "image/png"
+    end
+  end
+end
+
+ +

The output tempfile is opened in the directory returned by ActiveStorage::Downloading#tempdir.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer.rb, line 45
+def draw(*argv) #:doc:
+  ActiveSupport::Notifications.instrument("preview.active_storage") do
+    open_tempfile_for_drawing do |file|
+      capture(*argv, to: file)
+      yield file
+    end
+  end
+end
+
+
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer.rb, line 70
+def logger #:doc:
+  ActiveStorage.logger
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Previewer/MuPDFPreviewer.html b/src/5.2/classes/ActiveStorage/Previewer/MuPDFPreviewer.html new file mode 100644 index 0000000000..a19e77267a --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Previewer/MuPDFPreviewer.html @@ -0,0 +1,235 @@ +--- +title: ActiveStorage::Previewer::MuPDFPreviewer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 6
+def accept?(blob)
+  blob.content_type == "application/pdf" && mutool_exists?
+end
+
+
+ +
+ +
+

+ + mutool_exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 14
+def mutool_exists?
+  return @mutool_exists unless @mutool_exists.nil?
+
+  system mutool_path, out: File::NULL, err: File::NULL
+
+  @mutool_exists = $?.exitstatus == 1
+end
+
+
+ +
+ +
+

+ + mutool_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 10
+def mutool_path
+  ActiveStorage.paths[:mutool] || "mutool"
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 23
+def preview
+  download_blob_to_tempfile do |input|
+    draw_first_page_from input do |output|
+      yield io: output, filename: "#{blob.filename.base}.png", content_type: "image/png"
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Previewer/PopplerPDFPreviewer.html b/src/5.2/classes/ActiveStorage/Previewer/PopplerPDFPreviewer.html new file mode 100644 index 0000000000..7ab4b6d0a4 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Previewer/PopplerPDFPreviewer.html @@ -0,0 +1,233 @@ +--- +title: ActiveStorage::Previewer::PopplerPDFPreviewer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 6
+def accept?(blob)
+  blob.content_type == "application/pdf" && pdftoppm_exists?
+end
+
+
+ +
+ +
+

+ + pdftoppm_exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 14
+def pdftoppm_exists?
+  return @pdftoppm_exists unless @pdftoppm_exists.nil?
+
+  @pdftoppm_exists = system(pdftoppm_path, "-v", out: File::NULL, err: File::NULL)
+end
+
+
+ +
+ +
+

+ + pdftoppm_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 10
+def pdftoppm_path
+  ActiveStorage.paths[:pdftoppm] || "pdftoppm"
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 21
+def preview
+  download_blob_to_tempfile do |input|
+    draw_first_page_from input do |output|
+      yield io: output, filename: "#{blob.filename.base}.png", content_type: "image/png"
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Previewer/VideoPreviewer.html b/src/5.2/classes/ActiveStorage/Previewer/VideoPreviewer.html new file mode 100644 index 0000000000..e35cf6814d --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Previewer/VideoPreviewer.html @@ -0,0 +1,153 @@ +--- +title: ActiveStorage::Previewer::VideoPreviewer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/video_previewer.rb, line 5
+def self.accept?(blob)
+  blob.video?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/previewer/video_previewer.rb, line 9
+def preview
+  download_blob_to_tempfile do |input|
+    draw_relevant_frame_from input do |output|
+      yield io: output, filename: "#{blob.filename.base}.png", content_type: "image/png"
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/PurgeJob.html b/src/5.2/classes/ActiveStorage/PurgeJob.html new file mode 100644 index 0000000000..25bb252733 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/PurgeJob.html @@ -0,0 +1,113 @@ +--- +title: ActiveStorage::PurgeJob +layout: default +--- +
+ +
+
+ +
+ +

Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + perform(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/jobs/active_storage/purge_job.rb, line 7
+def perform(blob)
+  blob.purge
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/RepresentationsController.html b/src/5.2/classes/ActiveStorage/RepresentationsController.html new file mode 100644 index 0000000000..01b39f4653 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/RepresentationsController.html @@ -0,0 +1,114 @@ +--- +title: ActiveStorage::RepresentationsController +layout: default +--- +
+ +
+
+ +
+ +

Take a signed permanent reference for a blob representation and turn it into an expiring service URL for download. Note: These URLs are publicly accessible. If you need to enforce access protection beyond the security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own authenticated redirection controller.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/controllers/active_storage/representations_controller.rb, line 10
+def show
+  expires_in ActiveStorage::Blob.service.url_expires_in
+  redirect_to @blob.representation(params[:variation_key]).processed.service_url(disposition: params[:disposition])
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Service.html b/src/5.2/classes/ActiveStorage/Service.html new file mode 100644 index 0000000000..fb2adc01e0 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Service.html @@ -0,0 +1,573 @@ +--- +title: ActiveStorage::Service +layout: default +--- +
+ +
+
+ +
+ +

Abstract class serving as an interface for concrete services.

+ +

The available services are:

+
  • +

    Disk, to manage attachments saved directly on the hard drive.

    +
  • +

    GCS, to manage attachments through Google Cloud Storage.

    +
  • +

    S3, to manage attachments through Amazon S3.

    +
  • +

    AzureStorage, to manage attachments through Microsoft Azure Storage.

    +
  • +

    Mirror, to be able to use several services to manage attachments.

    +
+ +

Inside a Rails application, you can set-up your services through the generated config/storage.yml file and reference one of the aforementioned constant under the service key. For example:

+ +
local:
+  service: Disk
+  root: <%= Rails.root.join("storage") %>
+
+ +

You can checkout the service's constructor to know which keys are required.

+ +

Then, in your application's configuration, you can specify the service to use like this:

+ +
config.active_storage.service = :local
+
+ +

If you are using Active Storage outside of a Ruby on Rails application, you can configure the service to use like this:

+ +
ActiveStorage::Blob.service = ActiveStorage::Service.configure(
+  :Disk,
+  root: Pathname("/foo/bar/storage")
+)
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + configure(service_name, configurations) + +

+ + +
+

Configure an Active Storage service by name from a set of configurations, typically loaded from a YAML file. The Active Storage engine uses this to set the global Active Storage service when the app boots.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 50
+def configure(service_name, configurations)
+  Configurator.build(service_name, configurations)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(key) + +

+ + +
+

Delete the file at the key.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 88
+def delete(key)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+

Delete files at keys starting with the prefix.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 93
+def delete_prefixed(prefix)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + download(key) + +

+ + +
+

Return the content of the file at the key.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 78
+def download(key)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+

Return the partial content in the byte range of the file at the key.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 83
+def download_chunk(key, range)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + exist?(key) + +

+ + +
+

Return true if a file exists at the key.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 98
+def exist?(key)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:) + +

+ + +
+

Returns a Hash of headers for url_for_direct_upload requests.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 118
+def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:)
+  {}
+end
+
+
+ +
+ +
+

+ + update_metadata(key, **metadata) + +

+ + +
+

Update metadata for the file identified by key in the service. Override in subclasses only if the service needs to store specific metadata that has to be updated upon identification.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 74
+def update_metadata(key, **metadata)
+end
+
+
+ +
+ +
+

+ + upload(key, io, checksum: nil, **options) + +

+ + +
+

Upload the io to the key specified. If a checksum is provided, the service will ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 67
+def upload(key, io, checksum: nil, **options)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + url(key, expires_in:, disposition:, filename:, content_type:) + +

+ + +
+

Returns a signed, temporary URL for the file at the key. The URL will be valid for the amount of seconds specified in expires_in. You most also provide the disposition (:inline or :attachment), filename, and content_type that you wish the file to be served with on request.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 105
+def url(key, expires_in:, disposition:, filename:, content_type:)
+  raise NotImplementedError
+end
+
+
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:) + +

+ + +
+

Returns a signed, temporary URL that a direct upload file can be PUT to on the key. The URL will be valid for the amount of seconds specified in expires_in. You must also provide the content_type, content_length, and checksum of the file that will be uploaded. All these attributes will be validated by the service upon upload.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service.rb, line 113
+def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
+  raise NotImplementedError
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Service/AzureStorageService.html b/src/5.2/classes/ActiveStorage/Service/AzureStorageService.html new file mode 100644 index 0000000000..cf08ababf6 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Service/AzureStorageService.html @@ -0,0 +1,572 @@ +--- +title: ActiveStorage::Service::AzureStorageService +layout: default +--- +
+ +
+
+ +
+ +

Wraps the Microsoft Azure Storage Blob Service as an Active Storage service. See ActiveStorage::Service for the generic API documentation that applies to all services.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + blobs
+ [R] + client
+ [R] + container
+ [R] + signer
+ + + + +

Class Public methods

+ +
+

+ + new(storage_account_name:, storage_access_key:, container:, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 13
+def initialize(storage_account_name:, storage_access_key:, container:, **options)
+  @client = Azure::Storage::Client.create(storage_account_name: storage_account_name, storage_access_key: storage_access_key, **options)
+  @signer = Azure::Storage::Core::Auth::SharedAccessSignature.new(storage_account_name, storage_access_key)
+  @blobs = client.blob_client
+  @container = container
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 50
+def delete(key)
+  instrument :delete, key: key do
+    begin
+      blobs.delete_blob(container, key)
+    rescue Azure::Core::Http::HTTPError
+      # Ignore files already deleted
+    end
+  end
+end
+
+
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 60
+def delete_prefixed(prefix)
+  instrument :delete_prefixed, prefix: prefix do
+    marker = nil
+
+    loop do
+      results = blobs.list_blobs(container, prefix: prefix, marker: marker)
+
+      results.each do |blob|
+        blobs.delete_blob(container, blob.name)
+      end
+
+      break unless marker = results.continuation_token.presence
+    end
+  end
+end
+
+
+ +
+ +
+

+ + download(key, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 30
+def download(key, &block)
+  if block_given?
+    instrument :streaming_download, key: key do
+      stream(key, &block)
+    end
+  else
+    instrument :download, key: key do
+      _, io = blobs.get_blob(container, key)
+      io.force_encoding(Encoding::BINARY)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 43
+def download_chunk(key, range)
+  instrument :download_chunk, key: key, range: range do
+    _, io = blobs.get_blob(container, key, start_range: range.begin, end_range: range.exclude_end? ? range.end - 1 : range.end)
+    io.force_encoding(Encoding::BINARY)
+  end
+end
+
+
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 76
+def exist?(key)
+  instrument :exist, key: key do |payload|
+    answer = blob_for(key).present?
+    payload[:exist] = answer
+    answer
+  end
+end
+
+
+ +
+ +
+

+ + headers_for_direct_upload(key, content_type:, checksum:, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 116
+def headers_for_direct_upload(key, content_type:, checksum:, **)
+  { "Content-Type" => content_type, "Content-MD5" => checksum, "x-ms-blob-type" => "BlockBlob" }
+end
+
+
+ +
+ +
+

+ + upload(key, io, checksum: nil, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 20
+def upload(key, io, checksum: nil, **)
+  instrument :upload, key: key, checksum: checksum do
+    begin
+      blobs.create_block_blob(container, key, IO.try_convert(io) || io, content_md5: checksum)
+    rescue Azure::Core::Http::HTTPError
+      raise ActiveStorage::IntegrityError
+    end
+  end
+end
+
+
+ +
+ +
+

+ + url(key, expires_in:, filename:, disposition:, content_type:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 84
+def url(key, expires_in:, filename:, disposition:, content_type:)
+  instrument :url, key: key do |payload|
+    generated_url = signer.signed_uri(
+      uri_for(key), false,
+      service: "b",
+      permissions: "r",
+      expiry: format_expiry(expires_in),
+      content_disposition: content_disposition_with(type: disposition, filename: filename),
+      content_type: content_type
+    ).to_s
+
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 101
+def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
+  instrument :url, key: key do |payload|
+    generated_url = signer.signed_uri(
+      uri_for(key), false,
+      service: "b",
+      permissions: "rw",
+      expiry: format_expiry(expires_in)
+    ).to_s
+
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Service/DiskService.html b/src/5.2/classes/ActiveStorage/Service/DiskService.html new file mode 100644 index 0000000000..f6dea37fdd --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Service/DiskService.html @@ -0,0 +1,557 @@ +--- +title: ActiveStorage::Service::DiskService +layout: default +--- +
+ +
+
+ +
+ +

Wraps a local disk path as an Active Storage service. See ActiveStorage::Service for the generic API documentation that applies to all services.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + root
+ + + + +

Class Public methods

+ +
+

+ + new(root:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 14
+def initialize(root:)
+  @root = root
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 50
+def delete(key)
+  instrument :delete, key: key do
+    begin
+      File.delete path_for(key)
+    rescue Errno::ENOENT
+      # Ignore files already deleted
+    end
+  end
+end
+
+
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 60
+def delete_prefixed(prefix)
+  instrument :delete_prefixed, prefix: prefix do
+    Dir.glob(path_for("#{prefix}*")).each do |path|
+      FileUtils.rm_rf(path)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + download(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 25
+def download(key)
+  if block_given?
+    instrument :streaming_download, key: key do
+      File.open(path_for(key), "rb") do |file|
+        while data = file.read(5.megabytes)
+          yield data
+        end
+      end
+    end
+  else
+    instrument :download, key: key do
+      File.binread path_for(key)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 41
+def download_chunk(key, range)
+  instrument :download_chunk, key: key, range: range do
+    File.open(path_for(key), "rb") do |file|
+      file.seek range.begin
+      file.read range.size
+    end
+  end
+end
+
+
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 68
+def exist?(key)
+  instrument :exist, key: key do |payload|
+    answer = File.exist? path_for(key)
+    payload[:exist] = answer
+    answer
+  end
+end
+
+
+ +
+ +
+

+ + headers_for_direct_upload(key, content_type:, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 126
+def headers_for_direct_upload(key, content_type:, **)
+  { "Content-Type" => content_type }
+end
+
+
+ +
+ +
+

+ + upload(key, io, checksum: nil, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 18
+def upload(key, io, checksum: nil, **)
+  instrument :upload, key: key, checksum: checksum do
+    IO.copy_stream(io, make_path_for(key))
+    ensure_integrity_of(key, checksum) if checksum
+  end
+end
+
+
+ +
+ +
+

+ + url(key, expires_in:, filename:, disposition:, content_type:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 76
+def url(key, expires_in:, filename:, disposition:, content_type:)
+  instrument :url, key: key do |payload|
+    content_disposition = content_disposition_with(type: disposition, filename: filename)
+    verified_key_with_expiration = ActiveStorage.verifier.generate(
+      {
+        key: key,
+        disposition: content_disposition,
+        content_type: content_type
+      },
+      { expires_in: expires_in,
+      purpose: :blob_key }
+    )
+
+    current_uri = URI.parse(current_host)
+
+    generated_url = url_helpers.rails_disk_service_url(verified_key_with_expiration,
+      protocol: current_uri.scheme,
+      host: current_uri.host,
+      port: current_uri.port,
+      disposition: content_disposition,
+      content_type: content_type,
+      filename: filename
+    )
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/disk_service.rb, line 105
+def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
+  instrument :url, key: key do |payload|
+    verified_token_with_expiration = ActiveStorage.verifier.generate(
+      {
+        key: key,
+        content_type: content_type,
+        content_length: content_length,
+        checksum: checksum
+      },
+      { expires_in: expires_in,
+      purpose: :blob_token }
+    )
+
+    generated_url = url_helpers.update_rails_disk_service_url(verified_token_with_expiration, host: current_host)
+
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Service/GCSService.html b/src/5.2/classes/ActiveStorage/Service/GCSService.html new file mode 100644 index 0000000000..1b5c4d1db7 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Service/GCSService.html @@ -0,0 +1,571 @@ +--- +title: ActiveStorage::Service::GCSService +layout: default +--- +
+ +
+
+ +
+ +

Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API documentation that applies to all services.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(**config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 14
+def initialize(**config)
+  @config = config
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 67
+def delete(key)
+  instrument :delete, key: key do
+    begin
+      file_for(key).delete
+    rescue Google::Cloud::NotFoundError
+      # Ignore files already deleted
+    end
+  end
+end
+
+
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 77
+def delete_prefixed(prefix)
+  instrument :delete_prefixed, prefix: prefix do
+    bucket.files(prefix: prefix).all do |file|
+      begin
+        file.delete
+      rescue Google::Cloud::NotFoundError
+        # Ignore concurrently-deleted files
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + download(key) + +

+ + +
+

FIXME: Download in chunks when given a block.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 43
+def download(key)
+  instrument :download, key: key do
+    io = file_for(key).download
+    io.rewind
+
+    if block_given?
+      yield io.string
+    else
+      io.string
+    end
+  end
+end
+
+
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 56
+def download_chunk(key, range)
+  instrument :download_chunk, key: key, range: range do
+    file = file_for(key)
+    uri  = URI(file.signed_url(expires: 30.seconds))
+
+    Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |client|
+      client.get(uri, "Range" => "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body
+    end
+  end
+end
+
+
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 89
+def exist?(key)
+  instrument :exist, key: key do |payload|
+    answer = file_for(key).exists?
+    payload[:exist] = answer
+    answer
+  end
+end
+
+
+ +
+ +
+

+ + headers_for_direct_upload(key, checksum:, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 120
+def headers_for_direct_upload(key, checksum:, **)
+  { "Content-MD5" => checksum }
+end
+
+
+ +
+ +
+

+ + update_metadata(key, content_type:, disposition: nil, filename: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 33
+def update_metadata(key, content_type:, disposition: nil, filename: nil)
+  instrument :update_metadata, key: key, content_type: content_type, disposition: disposition do
+    file_for(key).update do |file|
+      file.content_type = content_type
+      file.content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
+    end
+  end
+end
+
+
+ +
+ +
+

+ + upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 18
+def upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil)
+  instrument :upload, key: key, checksum: checksum do
+    begin
+      # GCS's signed URLs don't include params such as response-content-type response-content_disposition
+      # in the signature, which means an attacker can modify them and bypass our effort to force these to
+      # binary and attachment when the file's content type requires it. The only way to force them is to
+      # store them as object's metadata.
+      content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
+      bucket.create_file(io, key, md5: checksum, content_type: content_type, content_disposition: content_disposition)
+    rescue Google::Cloud::InvalidArgumentError
+      raise ActiveStorage::IntegrityError
+    end
+  end
+end
+
+
+ +
+ +
+

+ + url(key, expires_in:, filename:, content_type:, disposition:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 97
+def url(key, expires_in:, filename:, content_type:, disposition:)
+  instrument :url, key: key do |payload|
+    generated_url = file_for(key).signed_url expires: expires_in, query: {
+      "response-content-disposition" => content_disposition_with(type: disposition, filename: filename),
+      "response-content-type" => content_type
+    }
+
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, checksum:, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/gcs_service.rb, line 110
+def url_for_direct_upload(key, expires_in:, checksum:, **)
+  instrument :url, key: key do |payload|
+    generated_url = bucket.signed_url key, method: "PUT", expires: expires_in, content_md5: checksum
+
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Service/MirrorService.html b/src/5.2/classes/ActiveStorage/Service/MirrorService.html new file mode 100644 index 0000000000..3f0ecf1c42 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Service/MirrorService.html @@ -0,0 +1,257 @@ +--- +title: ActiveStorage::Service::MirrorService +layout: default +--- +
+ +
+
+ +
+ +

Wraps a set of mirror services and provides a single ActiveStorage::Service object that will all have the files uploaded to them. A primary service is designated to answer calls to download, exists?, and url.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + mirrors
+ [R] + primary
+ + + + +

Class Public methods

+ +
+

+ + new(primary:, mirrors:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/mirror_service.rb, line 21
+def initialize(primary:, mirrors:)
+  @primary, @mirrors = primary, mirrors
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(key) + +

+ + +
+

Delete the file at the key on all services.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/mirror_service.rb, line 34
+def delete(key)
+  perform_across_services :delete, key
+end
+
+
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+

Delete files at keys starting with the prefix on all services.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/mirror_service.rb, line 39
+def delete_prefixed(prefix)
+  perform_across_services :delete_prefixed, prefix
+end
+
+
+ +
+ +
+

+ + upload(key, io, checksum: nil, **options) + +

+ + +
+

Upload the io to the key specified to all services. If a checksum is provided, all services will ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.

+
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/mirror_service.rb, line 27
+def upload(key, io, checksum: nil, **options)
+  each_service.collect do |service|
+    service.upload key, io.tap(&:rewind), checksum: checksum, **options
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Service/S3Service.html b/src/5.2/classes/ActiveStorage/Service/S3Service.html new file mode 100644 index 0000000000..aa3752fdd6 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Service/S3Service.html @@ -0,0 +1,540 @@ +--- +title: ActiveStorage::Service::S3Service +layout: default +--- +
+ +
+
+ +
+ +

Wraps the Amazon Simple Storage Service (S3) as an Active Storage service. See ActiveStorage::Service for the generic API documentation that applies to all services.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + bucket
+ [R] + client
+ [R] + upload_options
+ + + + +

Class Public methods

+ +
+

+ + new(bucket:, upload: {}, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 14
+def initialize(bucket:, upload: {}, **options)
+  @client = Aws::S3::Resource.new(**options)
+  @bucket = @client.bucket(bucket)
+
+  @upload_options = upload
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 49
+def delete(key)
+  instrument :delete, key: key do
+    object_for(key).delete
+  end
+end
+
+
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 55
+def delete_prefixed(prefix)
+  instrument :delete_prefixed, prefix: prefix do
+    bucket.objects(prefix: prefix).batch_delete!
+  end
+end
+
+
+ +
+ +
+

+ + download(key, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 31
+def download(key, &block)
+  if block_given?
+    instrument :streaming_download, key: key do
+      stream(key, &block)
+    end
+  else
+    instrument :download, key: key do
+      object_for(key).get.body.string.force_encoding(Encoding::BINARY)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 43
+def download_chunk(key, range)
+  instrument :download_chunk, key: key, range: range do
+    object_for(key).get(range: "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body.read.force_encoding(Encoding::BINARY)
+  end
+end
+
+
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 61
+def exist?(key)
+  instrument :exist, key: key do |payload|
+    answer = object_for(key).exists?
+    payload[:exist] = answer
+    answer
+  end
+end
+
+
+ +
+ +
+

+ + headers_for_direct_upload(key, content_type:, checksum:, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 93
+def headers_for_direct_upload(key, content_type:, checksum:, **)
+  { "Content-Type" => content_type, "Content-MD5" => checksum }
+end
+
+
+ +
+ +
+

+ + upload(key, io, checksum: nil, **) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 21
+def upload(key, io, checksum: nil, **)
+  instrument :upload, key: key, checksum: checksum do
+    begin
+      object_for(key).put(upload_options.merge(body: io, content_md5: checksum))
+    rescue Aws::S3::Errors::BadDigest
+      raise ActiveStorage::IntegrityError
+    end
+  end
+end
+
+
+ +
+ +
+

+ + url(key, expires_in:, filename:, disposition:, content_type:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 69
+def url(key, expires_in:, filename:, disposition:, content_type:)
+  instrument :url, key: key do |payload|
+    generated_url = object_for(key).presigned_url :get, expires_in: expires_in.to_i,
+      response_content_disposition: content_disposition_with(type: disposition, filename: filename),
+      response_content_type: content_type
+
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/lib/active_storage/service/s3_service.rb, line 81
+def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
+  instrument :url, key: key do |payload|
+    generated_url = object_for(key).presigned_url :put, expires_in: expires_in.to_i,
+      content_type: content_type, content_length: content_length, content_md5: checksum,
+      whitelist_headers: ['content-length']
+
+    payload[:url] = generated_url
+
+    generated_url
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/UnpreviewableError.html b/src/5.2/classes/ActiveStorage/UnpreviewableError.html new file mode 100644 index 0000000000..da35803e07 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/UnpreviewableError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::UnpreviewableError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/UnrepresentableError.html b/src/5.2/classes/ActiveStorage/UnrepresentableError.html new file mode 100644 index 0000000000..c27dccd5d7 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/UnrepresentableError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::UnrepresentableError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/VERSION.html b/src/5.2/classes/ActiveStorage/VERSION.html new file mode 100644 index 0000000000..ae4951d410 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/VERSION.html @@ -0,0 +1,120 @@ +--- +title: ActiveStorage::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Variant.html b/src/5.2/classes/ActiveStorage/Variant.html new file mode 100644 index 0000000000..044c10f35a --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Variant.html @@ -0,0 +1,352 @@ +--- +title: ActiveStorage::Variant +layout: default +--- +
+ +
+
+ +
+ +

Image blobs can have variants that are the result of a set of transformations applied to the original. These variants are used to create thumbnails, fixed-size avatars, or any other derivative image from the original.

+ +

Variants rely on MiniMagick for the actual transformations of the file, so you must add gem "mini_magick" to your Gemfile if you wish to use variants.

+ +

Note that to create a variant it's necessary to download the entire blob file from the service and load it into memory. The larger the image, the more memory is used. Because of this process, you also want to be considerate about when the variant is actually processed. You shouldn't be processing variants inline in a template, for example. Delay the processing to an on-demand controller, like the one provided in ActiveStorage::RepresentationsController.

+ +

To refer to such a delayed on-demand variant, simply link to the variant through the resolved route provided by Active Storage like so:

+ +
<%= image_tag Current.user.avatar.variant(resize: "100x100") %>
+
+ +

This will create a URL for that specific blob with that specific variant, which the ActiveStorage::RepresentationsController can then produce on-demand.

+ +

When you do want to actually produce the variant needed, call processed. This will check that the variant has already been processed and uploaded to the service, and, if so, just return that. Otherwise it will perform the transformations, upload the variant to the service, and return itself again. Example:

+ +
avatar.variant(resize: "100x100").processed.service_url
+
+ +

This will create and process a variant of the avatar blob that's constrained to a height and width of 100. Then it'll upload said variant to the service according to a derivative key of the blob and the transformations.

+ +

A list of all possible transformations is available at www.imagemagick.org/script/mogrify.php. You can combine as many as you like freely:

+ +
avatar.variant(resize: "100x100", monochrome: true, rotate: "-90")
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
WEB_IMAGE_CONTENT_TYPES=%w( image/png image/jpeg image/jpg image/gif )
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + blob
+ [R] + variation
+ + + + +

Class Public methods

+ +
+

+ + new(blob, variation_or_variation_key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variant.rb, line 47
+def initialize(blob, variation_or_variation_key)
+  @blob, @variation = blob, ActiveStorage::Variation.wrap(variation_or_variation_key)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + image() + +

+ + +
+

Returns the receiving variant. Allows ActiveStorage::Variant and ActiveStorage::Preview instances to be used interchangeably.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variant.rb, line 75
+def image
+  self
+end
+
+
+ +
+ +
+

+ + key() + +

+ + +
+

Returns a combination key of the blob and the variation that together identifies a specific variant.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variant.rb, line 58
+def key
+  "variants/#{blob.key}/#{Digest::SHA256.hexdigest(variation.key)}"
+end
+
+
+ +
+ +
+

+ + processed() + +

+ + +
+

Returns the variant instance itself after it's been processed or an existing processing has been found on the service.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variant.rb, line 52
+def processed
+  process unless processed?
+  self
+end
+
+
+ +
+ +
+

+ + service_url(expires_in: service.url_expires_in, disposition: :inline) + +

+ + +
+

Returns the URL of the variant on the service. This URL is intended to be short-lived for security and not used directly with users. Instead, the service_url should only be exposed as a redirect from a stable, possibly authenticated URL. Hiding the service_url behind a redirect also gives you the power to change services without updating all URLs. And it allows permanent URLs that redirect to the service_url to be cached in the view.

+ +

Use url_for(variant) (or the implied form, like +link_to variant+ or +redirect_to variant+) to get the stable URL for a variant that points to the ActiveStorage::RepresentationsController, which in turn will use this service_call method for its redirection.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variant.rb, line 70
+def service_url(expires_in: service.url_expires_in, disposition: :inline)
+  service.url key, expires_in: expires_in, disposition: disposition, filename: filename, content_type: content_type
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveStorage/Variation.html b/src/5.2/classes/ActiveStorage/Variation.html new file mode 100644 index 0000000000..7155111812 --- /dev/null +++ b/src/5.2/classes/ActiveStorage/Variation.html @@ -0,0 +1,360 @@ +--- +title: ActiveStorage::Variation +layout: default +--- +
+ +
+
+ +
+ +

A set of transformations that can be applied to a blob to create a variant. This class is exposed via the ActiveStorage::Blob#variant method and should rarely be used directly.

+ +

In case you do need to use this directly, it's instantiated using a hash of transformations where the key is the command and the value is the arguments. Example:

+ +
ActiveStorage::Variation.new(resize: "100x100", monochrome: true, trim: true, rotate: "-90")
+
+ +

You can also combine multiple transformations in one step, e.g. for center-weighted cropping:

+ +
ActiveStorage::Variation.new(combine_options: {
+  resize: "100x100^",
+  gravity: "center",
+  crop: "100x100+0+0",
+})
+
+ +

A list of all possible transformations is available at www.imagemagick.org/script/mogrify.php.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + transformations
+ + + + +

Class Public methods

+ +
+

+ + decode(key) + +

+ + +
+

Returns a Variation instance with the transformations that were encoded by encode.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variation.rb, line 39
+def decode(key)
+  new ActiveStorage.verifier.verify(key, purpose: :variation)
+end
+
+
+ +
+ +
+

+ + encode(transformations) + +

+ + +
+

Returns a signed key for the transformations, which can be used to refer to a specific variation in a URL or combined key (like ActiveStorage::Variant#key).

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variation.rb, line 45
+def encode(transformations)
+  ActiveStorage.verifier.generate(transformations, purpose: :variation)
+end
+
+
+ +
+ +
+

+ + new(transformations) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variation.rb, line 50
+def initialize(transformations)
+  @transformations = transformations
+end
+
+
+ +
+ +
+

+ + wrap(variator) + +

+ + +
+

Returns a Variation instance based on the given variator. If the variator is a Variation, it is returned unmodified. If it is a String, it is passed to ActiveStorage::Variation.decode. Otherwise, it is assumed to be a transformations Hash and is passed directly to the constructor.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variation.rb, line 27
+def wrap(variator)
+  case variator
+  when self
+    variator
+  when String
+    decode variator
+  else
+    new variator
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + key() + +

+ + +
+

Returns a signed key for all the transformations that this variation was instantiated with.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variation.rb, line 73
+def key
+  self.class.encode(transformations)
+end
+
+
+ +
+ +
+

+ + transform(image) + +

+ + +
+

Accepts an open MiniMagick image instance, like what's returned by MiniMagick::Image.read(io), and performs the transformations against it. The transformed image instance is then returned.

+
+ + + + + + + + +
+ + +
+
# File activestorage/app/models/active_storage/variation.rb, line 56
+def transform(image)
+  ActiveSupport::Notifications.instrument("transform.active_storage") do
+    transformations.each do |name, argument_or_subtransformations|
+      image.mogrify do |command|
+        if name.to_s == "combine_options"
+          argument_or_subtransformations.each do |subtransformation_name, subtransformation_argument|
+            pass_transform_argument(command, subtransformation_name, subtransformation_argument)
+          end
+        else
+          pass_transform_argument(command, name, argument_or_subtransformations)
+        end
+      end
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport.html b/src/5.2/classes/ActiveSupport.html new file mode 100644 index 0000000000..be7db6ce11 --- /dev/null +++ b/src/5.2/classes/ActiveSupport.html @@ -0,0 +1,596 @@ +--- +title: ActiveSupport +layout: default +--- +
+ +
+
+ +
+ +

The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting their default behavior. That said, we need to define the basic to_json method in all of them, otherwise they will always use to_json gem implementation, which is backwards incompatible in several cases (for instance, the JSON implementation for Hash does not work) with inheritance and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.

+ +

On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the calls to the original to_json method.

+ +

It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is bypassed completely. This means that as_json won't be invoked and the JSON gem will simply ignore any options it does not natively understand. This also means that ::JSON.{generate,dump} should give exactly the same results with or without active support.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Active Support as a Gem::Version.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded ActiveSupport as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/version.rb, line 7
+def self.version
+  gem_version
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/ArrayInquirer.html b/src/5.2/classes/ActiveSupport/ArrayInquirer.html new file mode 100644 index 0000000000..a4a1ef7348 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/ArrayInquirer.html @@ -0,0 +1,136 @@ +--- +title: ActiveSupport::ArrayInquirer +layout: default +--- +
+ +
+
+ +
+ +

Wrapping an array in an ArrayInquirer gives a friendlier way to check its string-like contents:

+ +
variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
+
+variants.phone?    # => true
+variants.tablet?   # => true
+variants.desktop?  # => false
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + any?(*candidates) + +

+ + +
+

Passes each element of candidates collection to ArrayInquirer collection. The method returns true if any element from the ArrayInquirer collection is equal to the stringified or symbolized form of any element in the candidates collection.

+ +

If candidates collection is not given, method returns true.

+ +
variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
+
+variants.any?                      # => true
+variants.any?(:phone, :tablet)     # => true
+variants.any?('phone', 'desktop')  # => true
+variants.any?(:desktop, :watch)    # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/array_inquirer.rb, line 25
+def any?(*candidates)
+  if candidates.none?
+    super
+  else
+    candidates.any? do |candidate|
+      include?(candidate.to_sym) || include?(candidate.to_s)
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Autoload.html b/src/5.2/classes/ActiveSupport/Autoload.html new file mode 100644 index 0000000000..89c10e6489 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Autoload.html @@ -0,0 +1,338 @@ +--- +title: ActiveSupport::Autoload +layout: default +--- +
+ +
+
+ +
+ +

Autoload and eager load conveniences for your library.

+ +

This module allows you to define autoloads based on Rails conventions (i.e. no need to define the path it is automatically guessed based on the filename) and also define a set of constants that needs to be eager loaded:

+ +
module MyLib
+  extend ActiveSupport::Autoload
+
+  autoload :Model
+
+  eager_autoload do
+    autoload :Cache
+  end
+end
+
+ +

Then your library can be eager loaded by simply calling:

+ +
MyLib.eager_load!
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + autoload(const_name, path = @_at_path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/autoload.rb, line 37
+def autoload(const_name, path = @_at_path)
+  unless path
+    full = [name, @_under_path, const_name.to_s].compact.join("::")
+    path = Inflector.underscore(full)
+  end
+
+  if @_eager_autoload
+    @_autoloads[const_name] = path
+  end
+
+  super const_name, path
+end
+
+
+ +
+ +
+

+ + autoload_at(path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/autoload.rb, line 57
+def autoload_at(path)
+  @_at_path, old_path = path, @_at_path
+  yield
+ensure
+  @_at_path = old_path
+end
+
+
+ +
+ +
+

+ + autoload_under(path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/autoload.rb, line 50
+def autoload_under(path)
+  @_under_path, old_path = path, @_under_path
+  yield
+ensure
+  @_under_path = old_path
+end
+
+
+ +
+ +
+

+ + autoloads() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/autoload.rb, line 75
+def autoloads
+  @_autoloads
+end
+
+
+ +
+ +
+

+ + eager_autoload() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/autoload.rb, line 64
+def eager_autoload
+  old_eager, @_eager_autoload = @_eager_autoload, true
+  yield
+ensure
+  @_eager_autoload = old_eager
+end
+
+
+ +
+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/autoload.rb, line 71
+def eager_load!
+  @_autoloads.each_value { |file| require file }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/BacktraceCleaner.html b/src/5.2/classes/ActiveSupport/BacktraceCleaner.html new file mode 100644 index 0000000000..98e4a2d95f --- /dev/null +++ b/src/5.2/classes/ActiveSupport/BacktraceCleaner.html @@ -0,0 +1,372 @@ +--- +title: ActiveSupport::BacktraceCleaner +layout: default +--- +
+ +
+
+ +
+ +

Backtraces often include many lines that are not relevant for the context under review. This makes it hard to find the signal amongst the backtrace noise, and adds debugging time. With a BacktraceCleaner, filters and silencers are used to remove the noisy lines, so that only the most relevant lines remain.

+ +

Filters are used to modify lines of data, while silencers are used to remove lines entirely. The typical filter use case is to remove lengthy path information from the start of each line, and view file paths relevant to the app directory instead of the file system root. The typical silencer use case is to exclude the output of a noisy library from the backtrace, so that you can focus on the rest.

+ +
bc = ActiveSupport::BacktraceCleaner.new
+bc.add_filter   { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
+bc.add_silencer { |line| line =~ /puma|rubygems/ } # skip any lines from puma or rubygems
+bc.clean(exception.backtrace) # perform the cleanup
+
+ +

To reconfigure an existing BacktraceCleaner (like the default one in Rails) and show as much data as possible, you can always call BacktraceCleaner#remove_silencers!, which will restore the backtrace to a pristine state. If you need to reconfigure an existing BacktraceCleaner so that it does not filter or modify the paths of any lines of the backtrace, you can call BacktraceCleaner#remove_filters! These two methods will give you a completely untouched backtrace.

+ +

Inspired by the Quiet Backtrace gem by thoughtbot.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 32
+def initialize
+  @filters, @silencers = [], []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_filter(&block) + +

+ + +
+

Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.

+ +
# Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
+backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 57
+def add_filter(&block)
+  @filters << block
+end
+
+
+ +
+ +
+

+ + add_silencer(&block) + +

+ + +
+

Adds a silencer from the block provided. If the silencer returns true for a given line, it will be excluded from the clean backtrace.

+ +
# Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb"
+backtrace_cleaner.add_silencer { |line| line =~ /puma/ }
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 66
+def add_silencer(&block)
+  @silencers << block
+end
+
+
+ +
+ +
+

+ + clean(backtrace, kind = :silent) + +

+ + +
+

Returns the backtrace after all filters and silencers have been run against it. Filters run first, then silencers.

+
+ + + +
+ Also aliased as: filter +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 38
+def clean(backtrace, kind = :silent)
+  filtered = filter_backtrace(backtrace)
+
+  case kind
+  when :silent
+    silence(filtered)
+  when :noise
+    noise(filtered)
+  else
+    filtered
+  end
+end
+
+
+ +
+ +
+

+ + filter(backtrace, kind = :silent) + +

+ + +
+ +
+ + + + + +
+ Alias for: clean +
+ + + +
+ +
+

+ + remove_filters!() + +

+ + +
+

Removes all filters, but leaves in the silencers. Useful if you suddenly need to see entire filepaths in the backtrace that you had already filtered out.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 80
+def remove_filters!
+  @filters = []
+end
+
+
+ +
+ +
+

+ + remove_silencers!() + +

+ + +
+

Removes all silencers, but leaves in the filters. Useful if your context of debugging suddenly expands as you suspect a bug in one of the libraries you use.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 73
+def remove_silencers!
+  @silencers = []
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Benchmarkable.html b/src/5.2/classes/ActiveSupport/Benchmarkable.html new file mode 100644 index 0000000000..d6a979aa70 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Benchmarkable.html @@ -0,0 +1,132 @@ +--- +title: ActiveSupport::Benchmarkable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + benchmark(message = "Benchmarking", options = {}) + +

+ + +
+

Allows you to measure the execution time of a block in a template and records the result to the log. Wrap this block around expensive operations or possible bottlenecks to get a time reading for the operation. For example, let's say you thought your file processing method was taking too long; you could wrap it in a benchmark block.

+ +
<% benchmark 'Process data files' do %>
+  <%= expensive_files_operation %>
+<% end %>
+
+ +

That would add something like “Process data files (345.2ms)” to the log, which you can then use to compare timings when optimizing your code.

+ +

You may give an optional logger level (:debug, :info, :warn, :error) as the :level option. The default logger level value is :info.

+ +
<% benchmark 'Low-level files', level: :debug do %>
+  <%= lowlevel_files_operation %>
+<% end %>
+
+ +

Finally, you can pass true as the third argument to silence all log activity (other than the timing information) from inside the block. This is great for boiling down a noisy block to just a single statement that produces one log line:

+ +
<% benchmark 'Process data files', level: :info, silence: true do %>
+  <%= expensive_and_chatty_files_operation %>
+<% end %>
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/benchmarkable.rb, line 37
+def benchmark(message = "Benchmarking", options = {})
+  if logger
+    options.assert_valid_keys(:level, :silence)
+    options[:level] ||= :info
+
+    result = nil
+    ms = Benchmark.ms { result = options[:silence] ? logger.silence { yield } : yield }
+    logger.send(options[:level], "%s (%.1fms)" % [ message, ms ])
+    result
+  else
+    yield
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache.html b/src/5.2/classes/ActiveSupport/Cache.html new file mode 100644 index 0000000000..84daed2e67 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache.html @@ -0,0 +1,257 @@ +--- +title: ActiveSupport::Cache +layout: default +--- +
+ +
+
+ +
+ +

See ActiveSupport::Cache::Store for documentation.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
UNIVERSAL_OPTIONS=[:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
 

These options mean something to all cache implementations. Individual cache implementations may support additional options.

+ + + + + + +

Class Public methods

+ +
+

+ + expand_cache_key(key, namespace = nil) + +

+ + +
+

Expands out the key argument into a key that can be used for the cache store. Optionally accepts a namespace, and all keys will be scoped within that namespace.

+ +

If the key argument provided is an array, or responds to to_a, then each of elements in the array will be turned into parameters/keys and concatenated into a single key. For example:

+ +
ActiveSupport::Cache.expand_cache_key([:foo, :bar])               # => "foo/bar"
+ActiveSupport::Cache.expand_cache_key([:foo, :bar], "namespace")  # => "namespace/foo/bar"
+
+ +

The key argument can also respond to cache_key or to_param.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 80
+def expand_cache_key(key, namespace = nil)
+  expanded_cache_key = (namespace ? "#{namespace}/" : "").dup
+
+  if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
+    expanded_cache_key << "#{prefix}/"
+  end
+
+  expanded_cache_key << retrieve_cache_key(key)
+  expanded_cache_key
+end
+
+
+ +
+ +
+

+ + lookup_store(*store_option) + +

+ + +
+

Creates a new Store object according to the given options.

+ +

If no arguments are passed to this method, then a new ActiveSupport::Cache::MemoryStore object will be returned.

+ +

If you pass a Symbol as the first argument, then a corresponding cache store class under the ActiveSupport::Cache namespace will be created. For example:

+ +
ActiveSupport::Cache.lookup_store(:memory_store)
+# => returns a new ActiveSupport::Cache::MemoryStore object
+
+ActiveSupport::Cache.lookup_store(:mem_cache_store)
+# => returns a new ActiveSupport::Cache::MemCacheStore object
+
+ +

Any additional arguments will be passed to the corresponding cache store class's constructor:

+ +
ActiveSupport::Cache.lookup_store(:file_store, '/tmp/cache')
+# => same as: ActiveSupport::Cache::FileStore.new('/tmp/cache')
+
+ +

If the first argument is not a Symbol, then it will simply be returned:

+ +
ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
+# => returns MyOwnCacheStore.new
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 55
+def lookup_store(*store_option)
+  store, *parameters = *Array.wrap(store_option).flatten
+
+  case store
+  when Symbol
+    retrieve_store_class(store).new(*parameters)
+  when nil
+    ActiveSupport::Cache::MemoryStore.new
+  else
+    store
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/ConnectionPoolLike.html b/src/5.2/classes/ActiveSupport/Cache/ConnectionPoolLike.html new file mode 100644 index 0000000000..1d51570c12 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/ConnectionPoolLike.html @@ -0,0 +1,101 @@ +--- +title: ActiveSupport::Cache::ConnectionPoolLike +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + with() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 25
+def with
+  yield self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/FileStore.html b/src/5.2/classes/ActiveSupport/Cache/FileStore.html new file mode 100644 index 0000000000..963e5a31ee --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/FileStore.html @@ -0,0 +1,407 @@ +--- +title: ActiveSupport::Cache::FileStore +layout: default +--- +
+ +
+
+ +
+ +

A cache store implementation which stores everything on the filesystem.

+ +

FileStore implements the Strategy::LocalCache strategy which implements an in-memory cache inside of a block.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DIR_FORMATTER="%03X"
 
EXCLUDED_DIRS=[".", ".."].freeze
 
FILENAME_MAX_SIZE=228
 
FILEPATH_MAX_SIZE=900
 
GITKEEP_FILES=[".gitkeep", ".keep"].freeze
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + cache_path
+ + + + +

Class Public methods

+ +
+

+ + new(cache_path, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/file_store.rb, line 24
+def initialize(cache_path, options = nil)
+  super(options)
+  @cache_path = cache_path.to_s
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+

Preemptively iterates through all stored keys and removes the ones which have expired.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/file_store.rb, line 39
+def cleanup(options = nil)
+  options = merged_options(options)
+  search_dir(cache_path) do |fname|
+    entry = read_entry(fname, options)
+    delete_entry(fname, options) if entry && entry.expired?
+  end
+end
+
+
+ +
+ +
+

+ + clear(options = nil) + +

+ + +
+

Deletes all items from the cache. In this case it deletes all the entries in the specified file store directory except for .keep or .gitkeep. Be careful which directory is specified in your config file when using FileStore because everything in that directory will be deleted.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/file_store.rb, line 32
+def clear(options = nil)
+  root_dirs = exclude_from(cache_path, EXCLUDED_DIRS + GITKEEP_FILES)
+  FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) })
+rescue Errno::ENOENT
+end
+
+
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrements an already existing integer value that is stored in the cache. If the key is not found nothing is done.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/file_store.rb, line 55
+def decrement(name, amount = 1, options = nil)
+  modify_value(name, -amount, options)
+end
+
+
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/file_store.rb, line 59
+def delete_matched(matcher, options = nil)
+  options = merged_options(options)
+  instrument(:delete_matched, matcher.inspect) do
+    matcher = key_matcher(matcher, options)
+    search_dir(cache_path) do |path|
+      key = file_path_key(path)
+      delete_entry(path, options) if key.match(matcher)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increments an already existing integer value that is stored in the cache. If the key is not found nothing is done.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/file_store.rb, line 49
+def increment(name, amount = 1, options = nil)
+  modify_value(name, amount, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/MemCacheStore.html b/src/5.2/classes/ActiveSupport/Cache/MemCacheStore.html new file mode 100644 index 0000000000..4e1490a7e7 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/MemCacheStore.html @@ -0,0 +1,327 @@ +--- +title: ActiveSupport::Cache::MemCacheStore +layout: default +--- +
+ +
+
+ +
+ +

A cache store implementation which stores data in Memcached: memcached.org

+ +

This is currently the most popular cache store for production websites.

+ +

Special features:

+
  • +

    Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it comes back up.

    +
+ +

MemCacheStore implements the Strategy::LocalCache strategy which implements an in-memory cache inside of a block.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ESCAPE_KEY_CHARS=/[\x00-\x20%\x7F-\xFF]/n
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(*addresses) + +

+ + +
+

Creates a new MemCacheStore object, with the given memcached server addresses. Each address is either a host name, or a host-with-port string in the form of “host_name:port”. For example:

+ +
ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")
+
+ +

If no addresses are specified, then MemCacheStore will connect to localhost port 11211 (the default memcached port).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 76
+def initialize(*addresses)
+  addresses = addresses.flatten
+  options = addresses.extract_options!
+  super(options)
+
+  unless [String, Dalli::Client, NilClass].include?(addresses.first.class)
+    raise ArgumentError, "First argument must be an empty array, an array of hosts or a Dalli::Client instance."
+  end
+  if addresses.first.is_a?(Dalli::Client)
+    @data = addresses.first
+  else
+    mem_cache_options = options.dup
+    UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) }
+    @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + clear(options = nil) + +

+ + +
+

Clear the entire cache on all memcached servers. This method should be used with care when shared cache is being used.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 121
+def clear(options = nil)
+  rescue_error_with(nil) { @data.with { |c| c.flush_all } }
+end
+
+
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrement a cached value. This method uses the memcached decr atomic operator and can only be used on values written with the :raw option. Calling it on a value not stored with :raw will initialize that value to zero.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 110
+def decrement(name, amount = 1, options = nil)
+  options = merged_options(options)
+  instrument(:decrement, name, amount: amount) do
+    rescue_error_with nil do
+      @data.with { |c| c.decr(normalize_key(name, options), amount, options[:expires_in]) }
+    end
+  end
+end
+
+
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increment a cached value. This method uses the memcached incr atomic operator and can only be used on values written with the :raw option. Calling it on a value not stored with :raw will initialize that value to zero.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 97
+def increment(name, amount = 1, options = nil)
+  options = merged_options(options)
+  instrument(:increment, name, amount: amount) do
+    rescue_error_with nil do
+      @data.with { |c| c.incr(normalize_key(name, options), amount, options[:expires_in]) }
+    end
+  end
+end
+
+
+ +
+ +
+

+ + stats() + +

+ + +
+

Get the statistics from the memcached servers.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 126
+def stats
+  @data.with { |c| c.stats }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/MemoryStore.html b/src/5.2/classes/ActiveSupport/Cache/MemoryStore.html new file mode 100644 index 0000000000..37e7ed0a7a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/MemoryStore.html @@ -0,0 +1,451 @@ +--- +title: ActiveSupport::Cache::MemoryStore +layout: default +--- +
+ +
+
+ +
+ +

A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using Phusion Passenger or puma clustered mode), then this means that Rails server process instances won't be able to share cache data with each other and this may not be the most appropriate cache in that scenario.

+ +

This cache has a bounded size specified by the :size options to the initializer (default is 32Mb). When the cache exceeds the allotted size, a cleanup will occur which tries to prune the cache down to three quarters of the maximum size by removing the least recently used entries.

+ +

MemoryStore is thread-safe.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
PER_ENTRY_OVERHEAD=240
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 21
+def initialize(options = nil)
+  options ||= {}
+  super(options)
+  @data = {}
+  @key_access = {}
+  @max_size = options[:size] || 32.megabytes
+  @max_prune_time = options[:max_prune_time] || 2
+  @cache_size = 0
+  @monitor = Monitor.new
+  @pruning = false
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+

Preemptively iterates through all stored keys and removes the ones which have expired.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 43
+def cleanup(options = nil)
+  options = merged_options(options)
+  instrument(:cleanup, size: @data.size) do
+    keys = synchronize { @data.keys }
+    keys.each do |key|
+      entry = @data[key]
+      delete_entry(key, options) if entry && entry.expired?
+    end
+  end
+end
+
+
+ +
+ +
+

+ + clear(options = nil) + +

+ + +
+

Delete all data stored in a given cache store.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 34
+def clear(options = nil)
+  synchronize do
+    @data.clear
+    @key_access.clear
+    @cache_size = 0
+  end
+end
+
+
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrement an integer value in the cache.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 85
+def decrement(name, amount = 1, options = nil)
+  modify_value(name, -amount, options)
+end
+
+
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+

Deletes cache entries if the cache key matches a given pattern.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 90
+def delete_matched(matcher, options = nil)
+  options = merged_options(options)
+  instrument(:delete_matched, matcher.inspect) do
+    matcher = key_matcher(matcher, options)
+    keys = synchronize { @data.keys }
+    keys.each do |key|
+      delete_entry(key, options) if key.match(matcher)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increment an integer value in the cache.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 80
+def increment(name, amount = 1, options = nil)
+  modify_value(name, amount, options)
+end
+
+
+ +
+ +
+

+ + prune(target_size, max_time = nil) + +

+ + +
+

To ensure entries fit within the specified memory prune the cache by removing the least recently accessed entries.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 56
+def prune(target_size, max_time = nil)
+  return if pruning?
+  @pruning = true
+  begin
+    start_time = Time.now
+    cleanup
+    instrument(:prune, target_size, from: @cache_size) do
+      keys = synchronize { @key_access.keys.sort { |a, b| @key_access[a].to_f <=> @key_access[b].to_f } }
+      keys.each do |key|
+        delete_entry(key, options)
+        return if @cache_size <= target_size || (max_time && Time.now - start_time > max_time)
+      end
+    end
+  ensure
+    @pruning = false
+  end
+end
+
+
+ +
+ +
+

+ + pruning?() + +

+ + +
+

Returns true if the cache is currently being pruned.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/memory_store.rb, line 75
+def pruning?
+  @pruning
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/NullStore.html b/src/5.2/classes/ActiveSupport/Cache/NullStore.html new file mode 100644 index 0000000000..1b97b05abd --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/NullStore.html @@ -0,0 +1,266 @@ +--- +title: ActiveSupport::Cache::NullStore +layout: default +--- +
+ +
+
+ +
+ +

A cache store implementation which doesn't actually store anything. Useful in development and test environments where you don't want caching turned on but need to go through the caching interface.

+ +

This cache does implement the local cache strategy, so values will actually be cached inside blocks that utilize this strategy. See ActiveSupport::Cache::Strategy::LocalCache for more details.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/null_store.rb, line 18
+def cleanup(options = nil)
+end
+
+
+ +
+ +
+

+ + clear(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/null_store.rb, line 15
+def clear(options = nil)
+end
+
+
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/null_store.rb, line 24
+def decrement(name, amount = 1, options = nil)
+end
+
+
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/null_store.rb, line 27
+def delete_matched(matcher, options = nil)
+end
+
+
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/null_store.rb, line 21
+def increment(name, amount = 1, options = nil)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/RedisCacheStore.html b/src/5.2/classes/ActiveSupport/Cache/RedisCacheStore.html new file mode 100644 index 0000000000..888dd637cd --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/RedisCacheStore.html @@ -0,0 +1,614 @@ +--- +title: ActiveSupport::Cache::RedisCacheStore +layout: default +--- +
+ +
+
+ +
+ +

Redis cache store.

+ +

Deployment note: Take care to use a *dedicated Redis cache* rather than pointing this at your existing Redis server. It won't cope well with mixed usage patterns and it won't expire cache entries by default.

+ +

Redis cache server setup guide: redis.io/topics/lru-cache

+
  • +

    Supports vanilla Redis, hiredis, and Redis::Distributed.

    +
  • +

    Supports Memcached-like sharding across Redises with Redis::Distributed.

    +
  • +

    Fault tolerant. If the Redis server is unavailable, no exceptions are raised. Cache fetches are all misses and writes are dropped.

    +
  • +

    Local cache. Hot in-memory primary cache within block/middleware scope.

    +
  • +

    read_multi and write_multi support for Redis mget/mset. Use Redis::Distributed 4.0.1+ for distributed mget support.

    +
  • +

    delete_matched support for Redis KEYS globs.

    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_ERROR_HANDLER=-> (method:, returning:, exception:) do +if logger +logger.error { "RedisCacheStore: #{method} failed, returned #{returning.inspect}: #{exception.class}: #{exception.message}" } +end +end
 
DEFAULT_REDIS_OPTIONS={ +connect_timeout: 20, +read_timeout: 1, +write_timeout: 1, +reconnect_attempts: 0, +}
 
MAX_KEY_BYTESIZE=1024
 

Keys are truncated with their own SHA2 digest if they exceed 1kB

+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + max_key_bytesize
+ [R] + redis_options
+ + + + +

Class Public methods

+ +
+

+ + new(namespace: nil, compress: true, compress_threshold: 1.kilobyte, expires_in: nil, race_condition_ttl: nil, error_handler: DEFAULT_ERROR_HANDLER, **redis_options) + +

+ + +
+

Creates a new Redis cache store.

+ +

Handles three options: block provided to instantiate, single URL provided, and multiple URLs provided.

+ +
:redis Proc   -> options[:redis].call
+:url   String -> Redis.new(url: …)
+:url   Array  -> Redis::Distributed.new([{ url: … }, { url: … }, …])
+
+ +

No namespace is set by default. Provide one if the Redis cache server is shared with other apps: <tt>namespace: 'myapp-cache'<tt>.

+ +

Compression is enabled by default with a 1kB threshold, so cached values larger than 1kB are automatically compressed. Disable by passing compress: false or change the threshold by passing compress_threshold: 4.kilobytes.

+ +

No expiry is set on cache entries by default. Redis is expected to be configured with an eviction policy that automatically deletes least-recently or -frequently used keys when it reaches max memory. See redis.io/topics/lru-cache for cache server setup.

+ +

Race condition TTL is not set by default. This can be used to avoid “thundering herd” cache writes when hot cache entries are expired. See ActiveSupport::Cache::Store#fetch for more.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 166
+def initialize(namespace: nil, compress: true, compress_threshold: 1.kilobyte, expires_in: nil, race_condition_ttl: nil, error_handler: DEFAULT_ERROR_HANDLER, **redis_options)
+  @redis_options = redis_options
+
+  @max_key_bytesize = MAX_KEY_BYTESIZE
+  @error_handler = error_handler
+
+  super namespace: namespace,
+    compress: compress, compress_threshold: compress_threshold,
+    expires_in: expires_in, race_condition_ttl: race_condition_ttl
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+

Cache Store API implementation.

+ +

Removes expired entries. Handled natively by Redis least-recently-/ least-frequently-used expiry, so manual cleanup is not supported.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 279
+def cleanup(options = nil)
+  super
+end
+
+
+ +
+ +
+

+ + clear(options = nil) + +

+ + +
+

Clear the entire cache on all Redis servers. Safe to use on shared servers if the cache is namespaced.

+ +

Failsafe: Raises errors.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 287
+def clear(options = nil)
+  failsafe :clear do
+    if namespace = merged_options(options)[:namespace]
+      delete_matched "*", namespace: namespace
+    else
+      redis.with { |c| c.flushdb }
+    end
+  end
+end
+
+
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Cache Store API implementation.

+ +

Decrement a cached value. This method uses the Redis decr atomic operator and can only be used on values written with the :raw option. Calling it on a value not stored with :raw will initialize that value to zero.

+ +

Failsafe: Raises errors.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 267
+def decrement(name, amount = 1, options = nil)
+  instrument :decrement, name, amount: amount do
+    failsafe :decrement do
+      redis.with { |c| c.decrby normalize_key(name, options), amount }
+    end
+  end
+end
+
+
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+

Cache Store API implementation.

+ +

Supports Redis KEYS glob patterns:

+ +
h?llo matches hello, hallo and hxllo
+h*llo matches hllo and heeeello
+h[ae]llo matches hello and hallo, but not hillo
+h[^e]llo matches hallo, hbllo, ... but not hello
+h[a-b]llo matches hallo and hbllo
+
+ +

Use \ to escape special characters if you want to match them verbatim.

+ +

See redis.io/commands/KEYS for more.

+ +

Failsafe: Raises errors.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 226
+def delete_matched(matcher, options = nil)
+  instrument :delete_matched, matcher do
+    unless String === matcher
+      raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}"
+    end
+    redis.with do |c|
+      pattern = namespace_key(matcher, options)
+      cursor = "0"
+      # Fetch keys in batches using SCAN to avoid blocking the Redis server.
+      begin
+        cursor, keys = c.scan(cursor, match: pattern, count: SCAN_BATCH_SIZE)
+        c.del(*keys) unless keys.empty?
+      end until cursor == "0"
+    end
+  end
+end
+
+
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Cache Store API implementation.

+ +

Increment a cached value. This method uses the Redis incr atomic operator and can only be used on values written with the :raw option. Calling it on a value not stored with :raw will initialize that value to zero.

+ +

Failsafe: Raises errors.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 251
+def increment(name, amount = 1, options = nil)
+  instrument :increment, name, amount: amount do
+    failsafe :increment do
+      redis.with { |c| c.incrby normalize_key(name, options), amount }
+    end
+  end
+end
+
+
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 190
+def inspect
+  instance = @redis || @redis_options
+  "<##{self.class} options=#{options.inspect} redis=#{instance.inspect}>"
+end
+
+
+ +
+ +
+

+ + read_multi(*names) + +

+ + +
+

Cache Store API implementation.

+ +

Read multiple values at once. Returns a hash of requested keys -> fetched values.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 199
+def read_multi(*names)
+  if mget_capable?
+    instrument(:read_multi, names, options) do |payload|
+      read_multi_mget(*names).tap do |results|
+        payload[:hits] = results.keys
+      end
+    end
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + redis() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 177
+def redis
+  @redis ||= begin
+    pool_options = self.class.send(:retrieve_pool_options, redis_options)
+
+    if pool_options.any?
+      self.class.send(:ensure_connection_pool_added!)
+      ::ConnectionPool.new(pool_options) { self.class.build_redis(**redis_options) }
+    else
+      self.class.build_redis(**redis_options)
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/Store.html b/src/5.2/classes/ActiveSupport/Cache/Store.html new file mode 100644 index 0000000000..3acda7ada0 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/Store.html @@ -0,0 +1,1026 @@ +--- +title: ActiveSupport::Cache::Store +layout: default +--- +
+ +
+
+ +
+ +

An abstract cache store class. There are multiple cache store implementations, each having its own additional features. See the classes under the ActiveSupport::Cache module, e.g. ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most popular cache store for large production websites.

+ +

Some implementations may not support all methods beyond the basic cache methods of fetch, write, read, exist?, and delete.

+ +

ActiveSupport::Cache::Store can store any serializable Ruby object.

+ +
cache = ActiveSupport::Cache::MemoryStore.new
+
+cache.read('city')   # => nil
+cache.write('city', "Duckburgh")
+cache.read('city')   # => "Duckburgh"
+
+ +

Keys are always translated into Strings and are case sensitive. When an object is specified as a key and has a cache_key method defined, this method will be called to define the key. Otherwise, the to_param method will be called. Hashes and Arrays can also be used as keys. The elements will be delimited by slashes, and the elements within a Hash will be sorted by key so they are consistent.

+ +
cache.read('city') == cache.read(:city)   # => true
+
+ +

Nil values can be cached.

+ +

If your cache is on a shared infrastructure, you can define a namespace for your cache entries. If a namespace is defined, it will be prefixed on to every key. The namespace can be either a static value or a Proc. If it is a Proc, it will be invoked when each key is evaluated so that you can use application logic to invalidate keys.

+ +
cache.namespace = -> { @last_mod_time }  # Set the namespace to a variable
+@last_mod_time = Time.now  # Invalidate the entire cache by changing namespace
+
+ +

Cached data larger than 1kB are compressed by default. To turn off compression, pass compress: false to the initializer or to individual fetch or write method calls. The 1kB compression threshold is configurable with the :compress_threshold option, specified in bytes.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + options
+ [R] + silence
+ [R] + silence?
+ + + + +

Class Public methods

+ +
+

+ + new(options = nil) + +

+ + +
+

Creates a new cache. The options will be passed to any write method calls except for :namespace which can be used to set the global namespace for the cache.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 183
+def initialize(options = nil)
+  @options = options ? options.dup : {}
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+

Cleanups the cache by removing expired entries.

+ +

Options are passed to the underlying cache implementation.

+ +

All implementations may not support this method.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 505
+def cleanup(options = nil)
+  raise NotImplementedError.new("#{self.class.name} does not support cleanup")
+end
+
+
+ +
+ +
+

+ + clear(options = nil) + +

+ + +
+

Clears the entire cache. Be careful with this method since it could affect other processes if shared cache is being used.

+ +

The options hash is passed to the underlying cache implementation.

+ +

All implementations may not support this method.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 515
+def clear(options = nil)
+  raise NotImplementedError.new("#{self.class.name} does not support clear")
+end
+
+
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrements an integer value in the cache.

+ +

Options are passed to the underlying cache implementation.

+ +

All implementations may not support this method.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 496
+def decrement(name, amount = 1, options = nil)
+  raise NotImplementedError.new("#{self.class.name} does not support decrement")
+end
+
+
+ +
+ +
+

+ + delete(name, options = nil) + +

+ + +
+

Deletes an entry in the cache. Returns true if an entry is deleted.

+ +

Options are passed to the underlying cache implementation.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 453
+def delete(name, options = nil)
+  options = merged_options(options)
+
+  instrument(:delete, name) do
+    delete_entry(normalize_key(name, options), options)
+  end
+end
+
+
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+

Deletes all entries with keys matching the pattern.

+ +

Options are passed to the underlying cache implementation.

+ +

All implementations may not support this method.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 478
+def delete_matched(matcher, options = nil)
+  raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
+end
+
+
+ +
+ +
+

+ + exist?(name, options = nil) + +

+ + +
+

Returns true if the cache contains an entry for the given key.

+ +

Options are passed to the underlying cache implementation.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 464
+def exist?(name, options = nil)
+  options = merged_options(options)
+
+  instrument(:exist?, name) do
+    entry = read_entry(normalize_key(name, options), options)
+    (entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false
+  end
+end
+
+
+ +
+ +
+

+ + fetch(name, options = nil) + +

+ + +
+

Fetches data from the cache, using the given key. If there is data in the cache with the given key, then that data is returned.

+ +

If there is no such data in the cache (a cache miss), then nil will be returned. However, if a block has been passed, that block will be passed the key and executed in the event of a cache miss. The return value of the block will be written to the cache under the given cache key, and that return value will be returned.

+ +
cache.write('today', 'Monday')
+cache.fetch('today')  # => "Monday"
+
+cache.fetch('city')   # => nil
+cache.fetch('city') do
+  'Duckburgh'
+end
+cache.fetch('city')   # => "Duckburgh"
+
+ +

You may also specify additional options via the options argument. Setting force: true forces a cache “miss,” meaning we treat the cache value as missing even if it's present. Passing a block is required when force is true so this always results in a cache write.

+ +
cache.write('today', 'Monday')
+cache.fetch('today', force: true) { 'Tuesday' } # => 'Tuesday'
+cache.fetch('today', force: true) # => ArgumentError
+
+ +

The :force option is useful when you're calling some other method to ask whether you should force a cache write. Otherwise, it's clearer to just call Cache#write.

+ +

Setting compress: false disables compression of the cache entry.

+ +

Setting :expires_in will set an expiration time on the cache. All caches support auto-expiring content after a specified number of seconds. This value can be specified as an option to the constructor (in which case all entries will be affected), or it can be supplied to the fetch or write method to effect just one entry.

+ +
cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
+cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
+
+ +

Setting :version verifies the cache stored under name is of the same version. nil is returned on mismatches despite contents. This feature is used to support recyclable cache keys.

+ +

Setting :race_condition_ttl is very useful in situations where a cache entry is used very frequently and is under heavy load. If a cache expires and due to heavy load several different processes will try to read data natively and then they all will try to write to cache. To avoid that case the first process to find an expired cache entry will bump the cache expiration time by the value set in :race_condition_ttl. Yes, this process is extending the time for a stale value by another few seconds. Because of extended life of the previous cache, other processes will continue to use slightly stale data for a just a bit longer. In the meantime that first process will go ahead and will write into cache the new value. After that all the processes will start getting the new value. The key is to keep :race_condition_ttl small.

+ +

If the process regenerating the entry errors out, the entry will be regenerated after the specified number of seconds. Also note that the life of stale cache is extended only if it expired recently. Otherwise a new value is generated and :race_condition_ttl does not play any role.

+ +
# Set all values to expire after one minute.
+cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)
+
+cache.write('foo', 'original value')
+val_1 = nil
+val_2 = nil
+sleep 60
+
+Thread.new do
+  val_1 = cache.fetch('foo', race_condition_ttl: 10.seconds) do
+    sleep 1
+    'new value 1'
+  end
+end
+
+Thread.new do
+  val_2 = cache.fetch('foo', race_condition_ttl: 10.seconds) do
+    'new value 2'
+  end
+end
+
+cache.fetch('foo') # => "original value"
+sleep 10 # First thread extended the life of cache by another 10 seconds
+cache.fetch('foo') # => "new value 1"
+val_1 # => "new value 1"
+val_2 # => "original value"
+
+ +

Other options will be handled by the specific cache store implementation. Internally, fetch calls read_entry, and calls write_entry on a cache miss. options will be passed to the read and write calls.

+ +

For example, MemCacheStore's write method supports the :raw option, which tells the memcached server to store all values as strings. We can use this option with fetch too:

+ +
cache = ActiveSupport::Cache::MemCacheStore.new
+cache.fetch("foo", force: true, raw: true) do
+  :bar
+end
+cache.fetch('foo') # => "bar"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 306
+def fetch(name, options = nil)
+  if block_given?
+    options = merged_options(options)
+    key = normalize_key(name, options)
+
+    entry = nil
+    instrument(:read, name, options) do |payload|
+      cached_entry = read_entry(key, options) unless options[:force]
+      entry = handle_expired_entry(cached_entry, key, options)
+      entry = nil if entry && entry.mismatched?(normalize_version(name, options))
+      payload[:super_operation] = :fetch if payload
+      payload[:hit] = !!entry if payload
+    end
+
+    if entry
+      get_entry_value(entry, name, options)
+    else
+      save_block_result_to_cache(name, options) { |_name| yield _name }
+    end
+  elsif options && options[:force]
+    raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block."
+  else
+    read(name, options)
+  end
+end
+
+
+ +
+ +
+

+ + fetch_multi(*names) + +

+ + +
+

Fetches data from the cache, using the given keys. If there is data in the cache with the given keys, then that data is returned. Otherwise, the supplied block is called for each key for which there was no data, and the result will be written to the cache and returned. Therefore, you need to pass a block that returns the data to be written to the cache. If you do not want to write the cache when the cache is not found, use read_multi.

+ +

Options are passed to the underlying cache implementation.

+ +

Returns a hash with the data for each of the names. For example:

+ +
cache.write("bim", "bam")
+cache.fetch_multi("bim", "unknown_key") do |key|
+  "Fallback value for key: #{key}"
+end
+# => { "bim" => "bam",
+#      "unknown_key" => "Fallback value for key: unknown_key" }
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 416
+def fetch_multi(*names)
+  raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?
+
+  options = names.extract_options!
+  options = merged_options(options)
+
+  instrument :read_multi, names, options do |payload|
+    read_multi_entries(names, options).tap do |results|
+      payload[:hits] = results.keys
+      payload[:super_operation] = :fetch_multi
+
+      writes = {}
+
+      (names - results.keys).each do |name|
+        results[name] = writes[name] = yield(name)
+      end
+
+      write_multi writes, options
+    end
+  end
+end
+
+
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increments an integer value in the cache.

+ +

Options are passed to the underlying cache implementation.

+ +

All implementations may not support this method.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 487
+def increment(name, amount = 1, options = nil)
+  raise NotImplementedError.new("#{self.class.name} does not support increment")
+end
+
+
+ +
+ +
+

+ + mute() + +

+ + +
+

Silences the logger within a block.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 194
+def mute
+  previous_silence, @silence = defined?(@silence) && @silence, true
+  yield
+ensure
+  @silence = previous_silence
+end
+
+
+ +
+ +
+

+ + read(name, options = nil) + +

+ + +
+

Reads data from the cache, using the given key. If there is data in the cache with the given key, then that data is returned. Otherwise, nil is returned.

+ +

Note, if data was written with the :expires_in<tt> or <tt>:version options, both of these conditions are applied before the data is returned.

+ +

Options are passed to the underlying cache implementation.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 340
+def read(name, options = nil)
+  options = merged_options(options)
+  key     = normalize_key(name, options)
+  version = normalize_version(name, options)
+
+  instrument(:read, name, options) do |payload|
+    entry = read_entry(key, options)
+
+    if entry
+      if entry.expired?
+        delete_entry(key, options)
+        payload[:hit] = false if payload
+        nil
+      elsif entry.mismatched?(version)
+        payload[:hit] = false if payload
+        nil
+      else
+        payload[:hit] = true if payload
+        entry.value
+      end
+    else
+      payload[:hit] = false if payload
+      nil
+    end
+  end
+end
+
+
+ +
+ +
+

+ + read_multi(*names) + +

+ + +
+

Reads multiple values at once from the cache. Options can be passed in the last argument.

+ +

Some cache implementation may optimize this method.

+ +

Returns a hash mapping the names provided to the values found.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 373
+def read_multi(*names)
+  options = names.extract_options!
+  options = merged_options(options)
+
+  instrument :read_multi, names, options do |payload|
+    read_multi_entries(names, options).tap do |results|
+      payload[:hits] = results.keys
+    end
+  end
+end
+
+
+ +
+ +
+

+ + silence!() + +

+ + +
+

Silences the logger.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 188
+def silence!
+  @silence = true
+  self
+end
+
+
+ +
+ +
+

+ + write(name, value, options = nil) + +

+ + +
+

Writes the value to the cache, with the key.

+ +

Options are passed to the underlying cache implementation.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 441
+def write(name, value, options = nil)
+  options = merged_options(options)
+
+  instrument(:write, name, options) do
+    entry = Entry.new(value, options.merge(version: normalize_version(name, options)))
+    write_entry(normalize_key(name, options), entry, options)
+  end
+end
+
+
+ +
+ +
+

+ + write_multi(hash, options = nil) + +

+ + +
+

Cache Storage API to write multiple values at once.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 385
+def write_multi(hash, options = nil)
+  options = merged_options(options)
+
+  instrument :write_multi, hash, options do |payload|
+    entries = hash.each_with_object({}) do |(name, value), memo|
+      memo[normalize_key(name, options)] = Entry.new(value, options.merge(version: normalize_version(name, options)))
+    end
+
+    write_multi_entries entries, options
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + key_matcher(pattern, options) + +

+ + +
+

Adds the namespace defined in the options to a pattern designed to match keys. Implementations that support delete_matched should call this method to translate a pattern that matches names into one that matches namespaced keys.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache.rb, line 524
+def key_matcher(pattern, options) # :doc:
+  prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
+  if prefix
+    source = pattern.source
+    if source.start_with?("^")
+      source = source[1, source.length]
+    else
+      source = ".*#{source[0, source.length]}"
+    end
+    Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options)
+  else
+    pattern
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/Strategy.html b/src/5.2/classes/ActiveSupport/Cache/Strategy.html new file mode 100644 index 0000000000..259b8dbc9f --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/Strategy.html @@ -0,0 +1,79 @@ +--- +title: ActiveSupport::Cache::Strategy +layout: default +--- + diff --git a/src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache.html b/src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache.html new file mode 100644 index 0000000000..d54c9b135a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache.html @@ -0,0 +1,163 @@ +--- +title: ActiveSupport::Cache::Strategy::LocalCache +layout: default +--- +
+ +
+
+ +
+ +

Caches that implement LocalCache will be backed by an in-memory cache for the duration of a block. Repeated calls to the cache for the same key will hit the in-memory cache for faster access.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + middleware() + +

+ + +
+

Middleware class can be inserted as a Rack handler to be local cache for the duration of request.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 89
+def middleware
+  @middleware ||= Middleware.new(
+    "ActiveSupport::Cache::Strategy::LocalCache",
+    local_cache_key)
+end
+
+
+ +
+ +
+

+ + with_local_cache() + +

+ + +
+

Use a local cache for the duration of block.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 83
+def with_local_cache
+  use_temporary_local_cache(LocalStore.new) { yield }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache/LocalStore.html b/src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache/LocalStore.html new file mode 100644 index 0000000000..eb2dbe521c --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Cache/Strategy/LocalCache/LocalStore.html @@ -0,0 +1,320 @@ +--- +title: ActiveSupport::Cache::Strategy::LocalCache::LocalStore +layout: default +--- +
+ +
+
+ +
+ +

Simple memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 39
+def initialize
+  super
+  @data = {}
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + clear(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 49
+def clear(options = nil)
+  @data.clear
+end
+
+
+ +
+ +
+

+ + delete_entry(key, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 73
+def delete_entry(key, options)
+  !!@data.delete(key)
+end
+
+
+ +
+ +
+

+ + read_entry(key, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 53
+def read_entry(key, options)
+  @data[key]
+end
+
+
+ +
+ +
+

+ + read_multi_entries(keys, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 57
+def read_multi_entries(keys, options)
+  values = {}
+
+  keys.each do |name|
+    entry = read_entry(name, options)
+    values[name] = entry.value if entry
+  end
+
+  values
+end
+
+
+ +
+ +
+

+ + write_entry(key, value, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 68
+def write_entry(key, value, options)
+  @data[key] = value
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/CachingKeyGenerator.html b/src/5.2/classes/ActiveSupport/CachingKeyGenerator.html new file mode 100644 index 0000000000..ef166acae4 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/CachingKeyGenerator.html @@ -0,0 +1,156 @@ +--- +title: ActiveSupport::CachingKeyGenerator +layout: default +--- +
+ +
+
+ +
+ +

CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid re-executing the key generation process when it's called using the same salt and key_size.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(key_generator) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/key_generator.rb, line 31
+def initialize(key_generator)
+  @key_generator = key_generator
+  @cache_keys = Concurrent::Map.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + generate_key(*args) + +

+ + +
+

Returns a derived key suitable for use.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/key_generator.rb, line 37
+def generate_key(*args)
+  @cache_keys[args.join] ||= @key_generator.generate_key(*args)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Callbacks.html b/src/5.2/classes/ActiveSupport/Callbacks.html new file mode 100644 index 0000000000..30b04a0576 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Callbacks.html @@ -0,0 +1,231 @@ +--- +title: ActiveSupport::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Callbacks are code hooks that are run at key points in an object's life cycle. The typical use case is to have a base class define a set of callbacks relevant to the other functionality it supplies, so that subclasses can install callbacks that enhance or modify the base functionality without needing to override or redefine methods of the base class.

+ +

Mixing in this module allows you to define the events in the object's life cycle that will support callbacks (via ClassMethods.define_callbacks), set the instance methods, procs, or callback objects to be called (via ClassMethods.set_callback), and run the installed callbacks at the appropriate times (via run_callbacks).

+ +

Three kinds of callbacks are supported: before callbacks, run before a certain event; after callbacks, run after the event; and around callbacks, blocks that surround the event, triggering it when they yield. Callback code can be contained in instance methods, procs or lambdas, or callback objects that respond to certain predetermined methods. See ClassMethods.set_callback for details.

+ +
class Record
+  include ActiveSupport::Callbacks
+  define_callbacks :save
+
+  def save
+    run_callbacks :save do
+      puts "- save"
+    end
+  end
+end
+
+class PersonRecord < Record
+  set_callback :save, :before, :saving_message
+  def saving_message
+    puts "saving..."
+  end
+
+  set_callback :save, :after do |object|
+    puts "saved"
+  end
+end
+
+person = PersonRecord.new
+person.save
+
+ +

Output:

+ +
saving...
+- save
+saved
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
CALLBACK_FILTER_TYPES=[:before, :after, :around]
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + run_callbacks(kind) + +

+ + +
+

Runs the callbacks for the given event.

+ +

Calls the before and around callbacks in the order they were set, yields the block (if given one), and then runs the after callbacks in reverse order.

+ +

If the callback chain was halted, returns false. Otherwise returns the result of the block, nil if no callbacks have been set, or true if callbacks have been set but no block is given.

+ +
run_callbacks :save do
+  save
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 94
+def run_callbacks(kind)
+  callbacks = __callbacks[kind.to_sym]
+
+  if callbacks.empty?
+    yield if block_given?
+  else
+    env = Filters::Environment.new(self, false, nil)
+    next_sequence = callbacks.compile
+
+    invoke_sequence = Proc.new do
+      skipped = nil
+      while true
+        current = next_sequence
+        current.invoke_before(env)
+        if current.final?
+          env.value = !env.halted && (!block_given? || yield)
+        elsif current.skip?(env)
+          (skipped ||= []) << current
+          next_sequence = next_sequence.nested
+          next
+        else
+          next_sequence = next_sequence.nested
+          begin
+            target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
+            target.send(method, *arguments, &block)
+          ensure
+            next_sequence = current
+          end
+        end
+        current.invoke_after(env)
+        skipped.pop.invoke_after(env) while skipped && skipped.first
+        break env.value
+      end
+    end
+
+    # Common case: no 'around' callbacks defined
+    if next_sequence.final?
+      next_sequence.invoke_before(env)
+      env.value = !env.halted && (!block_given? || yield)
+      next_sequence.invoke_after(env)
+      env.value
+    else
+      invoke_sequence.call
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Callbacks/ClassMethods.html b/src/5.2/classes/ActiveSupport/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..5675c19328 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Callbacks/ClassMethods.html @@ -0,0 +1,378 @@ +--- +title: ActiveSupport::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + define_callbacks(*names) + +

+ + +
+

Define sets of events in the object life cycle that support callbacks.

+ +
define_callbacks :validate
+define_callbacks :initialize, :save, :destroy
+
+ +
Options
+
  • +

    :terminator - Determines when a before filter will halt the callback chain, preventing following before and around callbacks from being called and the event from being triggered. This should be a lambda to be executed. The current object and the result lambda of the callback will be provided to the terminator lambda.

    + +
    define_callbacks :validate, terminator: ->(target, result_lambda) { result_lambda.call == false }
    +
    + +

    In this example, if any before validate callbacks returns false, any successive before and around callback is not executed.

    + +

    The default terminator halts the chain when a callback throws :abort.

    +
  • +

    :skip_after_callbacks_if_terminated - Determines if after callbacks should be terminated by the :terminator option. By default after callbacks are executed no matter if callback chain was terminated or not. This option has no effect if :terminator option is set to nil.

    +
  • +

    :scope - Indicates which methods should be executed when an object is used as a callback.

    + +
    class Audit
    +  def before(caller)
    +    puts 'Audit: before is called'
    +  end
    +
    +  def before_save(caller)
    +    puts 'Audit: before_save is called'
    +  end
    +end
    +
    +class Account
    +  include ActiveSupport::Callbacks
    +
    +  define_callbacks :save
    +  set_callback :save, :before, Audit.new
    +
    +  def save
    +    run_callbacks :save do
    +      puts 'save in main'
    +    end
    +  end
    +end
    +
    + +

    In the above case whenever you save an account the method Audit#before will be called. On the other hand

    + +
    define_callbacks :save, scope: [:kind, :name]
    +
    + +

    would trigger Audit#before_save instead. That's constructed by calling #{kind}_#{name} on the given instance. In this case “kind” is “before” and “name” is “save”. In this context :kind and :name have special meanings: :kind refers to the kind of callback (before/after/around) and :name refers to the method on which callbacks are being defined.

    + +

    A declaration like

    + +
    define_callbacks :save, scope: [:name]
    +
    + +

    would call Audit#save.

    +
+ +
Notes
+ +

names passed to define_callbacks must not end with !, ? or =.

+ +

Calling define_callbacks multiple times with the same names will overwrite previous callbacks registered with set_callback.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 806
+        def define_callbacks(*names)
+          options = names.extract_options!
+
+          names.each do |name|
+            name = name.to_sym
+
+            set_callbacks name, CallbackChain.new(name, options)
+
+            module_eval <<-RUBY, __FILE__, __LINE__ + 1
+              def _run_#{name}_callbacks(&block)
+                run_callbacks #{name.inspect}, &block
+              end
+
+              def self._#{name}_callbacks
+                get_callbacks(#{name.inspect})
+              end
+
+              def self._#{name}_callbacks=(value)
+                set_callbacks(#{name.inspect}, value)
+              end
+
+              def _#{name}_callbacks
+                __callbacks[#{name.inspect}]
+              end
+            RUBY
+          end
+        end
+
+
+ +
+ +
+

+ + reset_callbacks(name) + +

+ + +
+

Remove all set callbacks for the given event.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 716
+def reset_callbacks(name)
+  callbacks = get_callbacks name
+
+  ActiveSupport::DescendantsTracker.descendants(self).each do |target|
+    chain = target.get_callbacks(name).dup
+    callbacks.each { |c| chain.delete(c) }
+    target.set_callbacks name, chain
+  end
+
+  set_callbacks(name, callbacks.dup.clear)
+end
+
+
+ +
+ +
+

+ + set_callback(name, *filter_list, &block) + +

+ + +
+

Install a callback for the given event.

+ +
set_callback :save, :before, :before_method
+set_callback :save, :after,  :after_method, if: :condition
+set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff }
+
+ +

The second argument indicates whether the callback is to be run :before, :after, or :around the event. If omitted, :before is assumed. This means the first example above can also be written as:

+ +
set_callback :save, :before_method
+
+ +

The callback can be specified as a symbol naming an instance method; as a proc, lambda, or block; or as an object that responds to a certain method determined by the :scope argument to define_callbacks.

+ +

If a proc, lambda, or block is given, its body is evaluated in the context of the current object. It can also optionally accept the current object as an argument.

+ +

Before and around callbacks are called in the order that they are set; after callbacks are called in the reverse order.

+ +

Around callbacks can access the return value from the event, if it wasn't halted, from the yield call.

+ +
Options
+
  • +

    :if - A symbol or an array of symbols, each naming an instance method or a proc; the callback will be called only when they all return a true value.

    +
  • +

    :unless - A symbol or an array of symbols, each naming an instance method or a proc; the callback will be called only when they all return a false value.

    +
  • +

    :prepend - If true, the callback will be prepended to the existing chain rather than appended.

    +
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 667
+def set_callback(name, *filter_list, &block)
+  type, filters, options = normalize_callback_params(filter_list, block)
+
+  self_chain = get_callbacks name
+  mapped = filters.map do |filter|
+    Callback.build(self_chain, filter, type, options)
+  end
+
+  __update_callbacks(name) do |target, chain|
+    options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped)
+    target.set_callbacks name, chain
+  end
+end
+
+
+ +
+ +
+

+ + skip_callback(name, *filter_list, &block) + +

+ + +
+

Skip a previously set callback. Like set_callback, :if or :unless options may be passed in order to control when the callback is skipped.

+ +
class Writer < Person
+   skip_callback :validate, :before, :check_membership, if: -> { age > 18 }
+end
+
+ +

An ArgumentError will be raised if the callback has not already been set (unless the :raise option is set to false).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 691
+def skip_callback(name, *filter_list, &block)
+  type, filters, options = normalize_callback_params(filter_list, block)
+
+  options[:raise] = true unless options.key?(:raise)
+
+  __update_callbacks(name) do |target, chain|
+    filters.each do |filter|
+      callback = chain.find { |c| c.matches?(type, filter) }
+
+      if !callback && options[:raise]
+        raise ArgumentError, "#{type.to_s.capitalize} #{name} callback #{filter.inspect} has not been defined"
+      end
+
+      if callback && (options.key?(:if) || options.key?(:unless))
+        new_callback = callback.merge_conditional_options(chain, if_option: options[:if], unless_option: options[:unless])
+        chain.insert(chain.index(callback), new_callback)
+      end
+
+      chain.delete(callback)
+    end
+    target.set_callbacks name, chain
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Callbacks/Conditionals.html b/src/5.2/classes/ActiveSupport/Callbacks/Conditionals.html new file mode 100644 index 0000000000..64d5bc67a6 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Callbacks/Conditionals.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::Callbacks::Conditionals +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Callbacks/Conditionals/Value.html b/src/5.2/classes/ActiveSupport/Callbacks/Conditionals/Value.html new file mode 100644 index 0000000000..3ba2455d25 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Callbacks/Conditionals/Value.html @@ -0,0 +1,147 @@ +--- +title: ActiveSupport::Callbacks::Conditionals::Value +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 151
+def initialize(&block)
+  @block = block
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(target, value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 154
+def call(target, value); @block.call(value); end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Callbacks/Filters.html b/src/5.2/classes/ActiveSupport/Callbacks/Filters.html new file mode 100644 index 0000000000..5eba7342b1 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Callbacks/Filters.html @@ -0,0 +1,87 @@ +--- +title: ActiveSupport::Callbacks::Filters +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
Environment=Struct.new(:target, :halted, :value)
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Callbacks/Filters/After.html b/src/5.2/classes/ActiveSupport/Callbacks/Filters/After.html new file mode 100644 index 0000000000..8e922bed89 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Callbacks/Filters/After.html @@ -0,0 +1,119 @@ +--- +title: ActiveSupport::Callbacks::Filters::After +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + build(callback_sequence, user_callback, user_conditions, chain_config) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 213
+def self.build(callback_sequence, user_callback, user_conditions, chain_config)
+  if chain_config[:skip_after_callbacks_if_terminated]
+    if user_conditions.any?
+      halting_and_conditional(callback_sequence, user_callback, user_conditions)
+    else
+      halting(callback_sequence, user_callback)
+    end
+  else
+    if user_conditions.any?
+      conditional callback_sequence, user_callback, user_conditions
+    else
+      simple callback_sequence, user_callback
+    end
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Callbacks/Filters/Before.html b/src/5.2/classes/ActiveSupport/Callbacks/Filters/Before.html new file mode 100644 index 0000000000..5dc4e56bc9 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Callbacks/Filters/Before.html @@ -0,0 +1,113 @@ +--- +title: ActiveSupport::Callbacks::Filters::Before +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + build(callback_sequence, user_callback, user_conditions, chain_config, filter) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/callbacks.rb, line 162
+def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter)
+  halted_lambda = chain_config[:terminator]
+
+  if user_conditions.any?
+    halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
+  else
+    halting(callback_sequence, user_callback, halted_lambda, filter)
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Concern.html b/src/5.2/classes/ActiveSupport/Concern.html new file mode 100644 index 0000000000..22faf73156 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Concern.html @@ -0,0 +1,304 @@ +--- +title: ActiveSupport::Concern +layout: default +--- +
+ +
+
+ +
+ +

A typical module looks like this:

+ +
module M
+  def self.included(base)
+    base.extend ClassMethods
+    base.class_eval do
+      scope :disabled, -> { where(disabled: true) }
+    end
+  end
+
+  module ClassMethods
+    ...
+  end
+end
+
+ +

By using ActiveSupport::Concern the above module could instead be written as:

+ +
require 'active_support/concern'
+
+module M
+  extend ActiveSupport::Concern
+
+  included do
+    scope :disabled, -> { where(disabled: true) }
+  end
+
+  class_methods do
+    ...
+  end
+end
+
+ +

Moreover, it gracefully handles module dependencies. Given a Foo module and a Bar module which depends on the former, we would typically write the following:

+ +
module Foo
+  def self.included(base)
+    base.class_eval do
+      def self.method_injected_by_foo
+        ...
+      end
+    end
+  end
+end
+
+module Bar
+  def self.included(base)
+    base.method_injected_by_foo
+  end
+end
+
+class Host
+  include Foo # We need to include this dependency for Bar
+  include Bar # Bar is the module that Host really needs
+end
+
+ +

But why should Host care about Bar's dependencies, namely Foo? We could try to hide these from Host directly including Foo in Bar:

+ +
module Bar
+  include Foo
+  def self.included(base)
+    base.method_injected_by_foo
+  end
+end
+
+class Host
+  include Bar
+end
+
+ +

Unfortunately this won't work, since when Foo is included, its base is the Bar module, not the Host class. With ActiveSupport::Concern, module dependencies are properly resolved:

+ +
require 'active_support/concern'
+
+module Foo
+  extend ActiveSupport::Concern
+  included do
+    def self.method_injected_by_foo
+      ...
+    end
+  end
+end
+
+module Bar
+  extend ActiveSupport::Concern
+  include Foo
+
+  included do
+    self.method_injected_by_foo
+  end
+end
+
+class Host
+  include Bar # It works, now Bar takes care of its dependencies
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + append_features(base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concern.rb, line 113
+def append_features(base)
+  if base.instance_variable_defined?(:@_dependencies)
+    base.instance_variable_get(:@_dependencies) << self
+    false
+  else
+    return false if base < self
+    @_dependencies.each { |dep| base.include(dep) }
+    super
+    base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
+    base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block)
+  end
+end
+
+
+ +
+ +
+

+ + class_methods(&class_methods_module_definition) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concern.rb, line 140
+def class_methods(&class_methods_module_definition)
+  mod = const_defined?(:ClassMethods, false) ?
+    const_get(:ClassMethods) :
+    const_set(:ClassMethods, Module.new)
+
+  mod.module_eval(&class_methods_module_definition)
+end
+
+
+ +
+ +
+

+ + included(base = nil, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concern.rb, line 126
+def included(base = nil, &block)
+  if base.nil?
+    if instance_variable_defined?(:@_included_block)
+      if @_included_block.source_location != block.source_location
+        raise MultipleIncludedBlocks
+      end
+    else
+      @_included_block = block
+    end
+  else
+    super
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Concurrency.html b/src/5.2/classes/ActiveSupport/Concurrency.html new file mode 100644 index 0000000000..706b6fd585 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Concurrency.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::Concurrency +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Concurrency/LoadInterlockAwareMonitor.html b/src/5.2/classes/ActiveSupport/Concurrency/LoadInterlockAwareMonitor.html new file mode 100644 index 0000000000..70bcf053e1 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Concurrency/LoadInterlockAwareMonitor.html @@ -0,0 +1,114 @@ +--- +title: ActiveSupport::Concurrency::LoadInterlockAwareMonitor +layout: default +--- +
+ +
+
+ +
+ +

A monitor that will permit dependency loading while blocked waiting for the lock.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + mon_enter() + +

+ + +
+

Enters an exclusive section, but allows dependency loading while blocked

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb, line 11
+def mon_enter
+  mon_try_enter ||
+    ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Concurrency/ShareLock.html b/src/5.2/classes/ActiveSupport/Concurrency/ShareLock.html new file mode 100644 index 0000000000..24e65a2527 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Concurrency/ShareLock.html @@ -0,0 +1,503 @@ +--- +title: ActiveSupport::Concurrency::ShareLock +layout: default +--- +
+ +
+
+ +
+ +

A share/exclusive lock, otherwise known as a read/write lock.

+ +

en.wikipedia.org/wiki/Readers%E2%80%93writer_lock

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + MonitorMixin + +
  • + +
+ + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 50
+def initialize
+  super()
+
+  @cv = new_cond
+
+  @sharing = Hash.new(0)
+  @waiting = {}
+  @sleeping = {}
+  @exclusive_thread = nil
+  @exclusive_depth = 0
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + exclusive(purpose: nil, compatible: [], after_compatible: [], no_wait: false) + +

+ + +
+

Execute the supplied block while holding the Exclusive lock. If no_wait is set and the lock is not immediately available, returns nil without yielding. Otherwise, returns the result of the block.

+ +

See start_exclusive for other options.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 148
+def exclusive(purpose: nil, compatible: [], after_compatible: [], no_wait: false)
+  if start_exclusive(purpose: purpose, compatible: compatible, no_wait: no_wait)
+    begin
+      yield
+    ensure
+      stop_exclusive(compatible: after_compatible)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + sharing() + +

+ + +
+

Execute the supplied block while holding the Share lock.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 159
+def sharing
+  start_sharing
+  begin
+    yield
+  ensure
+    stop_sharing
+  end
+end
+
+
+ +
+ +
+

+ + start_exclusive(purpose: nil, compatible: [], no_wait: false) + +

+ + +
+

Returns false if no_wait is set and the lock is not immediately available. Otherwise, returns true after the lock has been acquired.

+ +

purpose and compatible work together; while this thread is waiting for the exclusive lock, it will yield its share (if any) to any other attempt whose purpose appears in this attempt's compatible list. This allows a “loose” upgrade, which, being less strict, prevents some classes of deadlocks.

+ +

For many resources, loose upgrades are sufficient: if a thread is awaiting a lock, it is not running any other code. With purpose matching, it is possible to yield only to other threads whose activity will not interfere.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 76
+def start_exclusive(purpose: nil, compatible: [], no_wait: false)
+  synchronize do
+    unless @exclusive_thread == Thread.current
+      if busy_for_exclusive?(purpose)
+        return false if no_wait
+
+        yield_shares(purpose: purpose, compatible: compatible, block_share: true) do
+          wait_for(:start_exclusive) { busy_for_exclusive?(purpose) }
+        end
+      end
+      @exclusive_thread = Thread.current
+    end
+    @exclusive_depth += 1
+
+    true
+  end
+end
+
+
+ +
+ +
+

+ + start_sharing() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 114
+def start_sharing
+  synchronize do
+    if @sharing[Thread.current] > 0 || @exclusive_thread == Thread.current
+      # We already hold a lock; nothing to wait for
+    elsif @waiting[Thread.current]
+      # We're nested inside a +yield_shares+ call: we'll resume as
+      # soon as there isn't an exclusive lock in our way
+      wait_for(:start_sharing) { @exclusive_thread }
+    else
+      # This is an initial / outermost share call: any outstanding
+      # requests for an exclusive lock get to go first
+      wait_for(:start_sharing) { busy_for_sharing?(false) }
+    end
+    @sharing[Thread.current] += 1
+  end
+end
+
+
+ +
+ +
+

+ + stop_exclusive(compatible: []) + +

+ + +
+

Relinquish the exclusive lock. Must only be called by the thread that called start_exclusive (and currently holds the lock).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 96
+def stop_exclusive(compatible: [])
+  synchronize do
+    raise "invalid unlock" if @exclusive_thread != Thread.current
+
+    @exclusive_depth -= 1
+    if @exclusive_depth == 0
+      @exclusive_thread = nil
+
+      if eligible_waiters?(compatible)
+        yield_shares(compatible: compatible, block_share: true) do
+          wait_for(:stop_exclusive) { @exclusive_thread || eligible_waiters?(compatible) }
+        end
+      end
+      @cv.broadcast
+    end
+  end
+end
+
+
+ +
+ +
+

+ + stop_sharing() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 131
+def stop_sharing
+  synchronize do
+    if @sharing[Thread.current] > 1
+      @sharing[Thread.current] -= 1
+    else
+      @sharing.delete Thread.current
+      @cv.broadcast
+    end
+  end
+end
+
+
+ +
+ +
+

+ + yield_shares(purpose: nil, compatible: [], block_share: false) + +

+ + +
+

Temporarily give up all held Share locks while executing the supplied block, allowing any compatible exclusive lock request to proceed.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 171
+def yield_shares(purpose: nil, compatible: [], block_share: false)
+  loose_shares = previous_wait = nil
+  synchronize do
+    if loose_shares = @sharing.delete(Thread.current)
+      if previous_wait = @waiting[Thread.current]
+        purpose = nil unless purpose == previous_wait[0]
+        compatible &= previous_wait[1]
+      end
+      compatible |= [false] unless block_share
+      @waiting[Thread.current] = [purpose, compatible]
+    end
+
+    @cv.broadcast
+  end
+
+  begin
+    yield
+  ensure
+    synchronize do
+      wait_for(:yield_shares) { @exclusive_thread && @exclusive_thread != Thread.current }
+
+      if previous_wait
+        @waiting[Thread.current] = previous_wait
+      else
+        @waiting.delete Thread.current
+      end
+      @sharing[Thread.current] = loose_shares if loose_shares
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Configurable.html b/src/5.2/classes/ActiveSupport/Configurable.html new file mode 100644 index 0000000000..8865073daa --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Configurable.html @@ -0,0 +1,142 @@ +--- +title: ActiveSupport::Configurable +layout: default +--- +
+ +
+
+ +
+ +

Configurable provides a config method to store and retrieve configuration options as an OrderedHash.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+

Reads and writes attributes from a configuration OrderedHash.

+ +
require 'active_support/configurable'
+
+class User
+  include ActiveSupport::Configurable
+end
+
+user = User.new
+
+user.config.allowed_access = true
+user.config.level = 1
+
+user.config.allowed_access # => true
+user.config.level          # => 1
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/configurable.rb, line 146
+def config
+  @_config ||= self.class.config.inheritable_copy
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Configurable/ClassMethods.html b/src/5.2/classes/ActiveSupport/Configurable/ClassMethods.html new file mode 100644 index 0000000000..543f3c0d7e --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Configurable/ClassMethods.html @@ -0,0 +1,145 @@ +--- +title: ActiveSupport::Configurable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/configurable.rb, line 30
+def config
+  @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
+    superclass.config.inheritable_copy
+  else
+    # create a new "anonymous" class that will host the compiled reader methods
+    Class.new(Configuration).new
+  end
+end
+
+
+ +
+ +
+

+ + configure() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/configurable.rb, line 39
+def configure
+  yield config
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Configurable/Configuration.html b/src/5.2/classes/ActiveSupport/Configurable/Configuration.html new file mode 100644 index 0000000000..117e80d973 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Configurable/Configuration.html @@ -0,0 +1,153 @@ +--- +title: ActiveSupport::Configurable::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + compile_methods!(keys) + +

+ + +
+

Compiles reader methods so we don't have to go through method_missing.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/configurable.rb, line 20
+      def self.compile_methods!(keys)
+        keys.reject { |m| method_defined?(m) }.each do |key|
+          class_eval <<-RUBY, __FILE__, __LINE__ + 1
+            def #{key}; _get(#{key.inspect}); end
+          RUBY
+        end
+      end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + compile_methods!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/configurable.rb, line 15
+def compile_methods!
+  self.class.compile_methods!(keys)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/CurrentAttributes.html b/src/5.2/classes/ActiveSupport/CurrentAttributes.html new file mode 100644 index 0000000000..e0cd6f0d20 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/CurrentAttributes.html @@ -0,0 +1,448 @@ +--- +title: ActiveSupport::CurrentAttributes +layout: default +--- +
+ +
+
+ +
+ +

Abstract super class that provides a thread-isolated attributes singleton, which resets automatically before and after each request. This allows you to keep all the per-request attributes easily available to the whole system.

+ +

The following full app-like example demonstrates how to use a Current class to facilitate easy access to the global, per-request attributes without passing them deeply around everywhere:

+ +
# app/models/current.rb
+class Current < ActiveSupport::CurrentAttributes
+  attribute :account, :user
+  attribute :request_id, :user_agent, :ip_address
+
+  resets { Time.zone = nil }
+
+  def user=(user)
+    super
+    self.account = user.account
+    Time.zone    = user.time_zone
+  end
+end
+
+# app/controllers/concerns/authentication.rb
+module Authentication
+  extend ActiveSupport::Concern
+
+  included do
+    before_action :authenticate
+  end
+
+  private
+    def authenticate
+      if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
+        Current.user = authenticated_user
+      else
+        redirect_to new_session_url
+      end
+    end
+end
+
+# app/controllers/concerns/set_current_request_details.rb
+module SetCurrentRequestDetails
+  extend ActiveSupport::Concern
+
+  included do
+    before_action do
+      Current.request_id = request.uuid
+      Current.user_agent = request.user_agent
+      Current.ip_address = request.ip
+    end
+  end
+end
+
+class ApplicationController < ActionController::Base
+  include Authentication
+  include SetCurrentRequestDetails
+end
+
+class MessagesController < ApplicationController
+  def create
+    Current.account.messages.create(message_params)
+  end
+end
+
+class Message < ApplicationRecord
+  belongs_to :creator, default: -> { Current.user }
+  after_create { |message| Event.create(record: message) }
+end
+
+class Event < ApplicationRecord
+  before_create do
+    self.request_id = Current.request_id
+    self.user_agent = Current.user_agent
+    self.ip_address = Current.ip_address
+  end
+end
+
+ +

A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result. Current should only be used for a few, top-level globals, like account, user, and request details. The attributes stuck in Current should be used by more or less all actions on all requests. If you start sticking controller-specific attributes in there, you're going to create a mess.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + attributes
+ + + + +

Class Public methods

+ +
+

+ + attribute(*names) + +

+ + +
+

Declares one or more attributes that will be given both class and instance accessor methods.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/current_attributes.rb, line 96
+def attribute(*names)
+  generated_attribute_methods.module_eval do
+    names.each do |name|
+      define_method(name) do
+        attributes[name.to_sym]
+      end
+
+      define_method("#{name}=") do |attribute|
+        attributes[name.to_sym] = attribute
+      end
+    end
+  end
+
+  names.each do |name|
+    define_singleton_method(name) do
+      instance.public_send(name)
+    end
+
+    define_singleton_method("#{name}=") do |attribute|
+      instance.public_send("#{name}=", attribute)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + instance() + +

+ + +
+

Returns singleton instance for this class in this thread. If none exists, one is created.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/current_attributes.rb, line 91
+def instance
+  current_instances[name] ||= new
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/current_attributes.rb, line 157
+def initialize
+  @attributes = {}
+end
+
+
+ +
+ +
+

+ + resets(&block) + +

+ + +
+

Calls this block after reset is called on the instance. Used for resetting external collaborators, like Time.zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/current_attributes.rb, line 121
+def resets(&block)
+  set_callback :reset, :after, &block
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + reset() + +

+ + +
+

Reset all attributes. Should be called before and after actions, when used as a per-request singleton.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/current_attributes.rb, line 180
+def reset
+  run_callbacks :reset do
+    self.attributes = {}
+  end
+end
+
+
+ +
+ +
+

+ + set(set_attributes) + +

+ + +
+

Expose one or more attributes within a block. Old values are returned after the block concludes. Example demonstrating the common use of needing to set Current attributes outside the request-cycle:

+ +
class Chat::PublicationJob < ApplicationJob
+  def perform(attributes, room_number, creator)
+    Current.set(person: creator) do
+      Chat::Publisher.publish(attributes: attributes, room_number: room_number)
+    end
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/current_attributes.rb, line 171
+def set(set_attributes)
+  old_attributes = compute_attributes(set_attributes.keys)
+  assign_attributes(set_attributes)
+  yield
+ensure
+  assign_attributes(old_attributes)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Dependencies.html b/src/5.2/classes/ActiveSupport/Dependencies.html new file mode 100644 index 0000000000..ef773b784a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Dependencies.html @@ -0,0 +1,205 @@ +--- +title: ActiveSupport::Dependencies +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + load_interlock() + +

+ + +
+

Execute the supplied block while holding an exclusive lock, preventing any other thread from being inside a run_interlock block at the same time.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 36
+def self.load_interlock
+  Dependencies.interlock.loading { yield }
+end
+
+
+ +
+ +
+

+ + run_interlock() + +

+ + +
+

Execute the supplied block without interference from any concurrent loads.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 29
+def self.run_interlock
+  Dependencies.interlock.running { yield }
+end
+
+
+ +
+ +
+

+ + unload_interlock() + +

+ + +
+

Execute the supplied block while holding an exclusive lock, preventing any other thread from being inside a run_interlock block at the same time.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 43
+def self.unload_interlock
+  Dependencies.interlock.unloading { yield }
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Dependencies/ClassCache.html b/src/5.2/classes/ActiveSupport/Dependencies/ClassCache.html new file mode 100644 index 0000000000..d895879690 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Dependencies/ClassCache.html @@ -0,0 +1,381 @@ +--- +title: ActiveSupport::Dependencies::ClassCache +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 568
+def initialize
+  @store = Concurrent::Map.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](key) + +

+ + +
+ +
+ + + + + +
+ Alias for: get +
+ + + +
+ +
+

+ + clear!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 598
+def clear!
+  @store.clear
+end
+
+
+ +
+ +
+

+ + empty?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 572
+def empty?
+  @store.empty?
+end
+
+
+ +
+ +
+

+ + get(key) + +

+ + +
+ +
+ + + +
+ Also aliased as: [] +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 580
+def get(key)
+  key = key.name if key.respond_to?(:name)
+  @store[key] ||= Inflector.constantize(key)
+end
+
+
+ +
+ +
+

+ + key?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 576
+def key?(key)
+  @store.key?(key)
+end
+
+
+ +
+ +
+

+ + safe_get(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 586
+def safe_get(key)
+  key = key.name if key.respond_to?(:name)
+  @store[key] ||= Inflector.safe_constantize(key)
+end
+
+
+ +
+ +
+

+ + store(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 591
+def store(klass)
+  return self unless klass.respond_to?(:name)
+  raise(ArgumentError, "anonymous classes cannot be cached") if klass.name.empty?
+  @store[klass.name] = klass
+  self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Dependencies/Interlock.html b/src/5.2/classes/ActiveSupport/Dependencies/Interlock.html new file mode 100644 index 0000000000..fe043e407f --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Dependencies/Interlock.html @@ -0,0 +1,388 @@ +--- +title: ActiveSupport::Dependencies::Interlock +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + done_running() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 36
+def done_running
+  @lock.stop_sharing
+end
+
+
+ +
+ +
+

+ + done_unloading() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 28
+def done_unloading
+  @lock.stop_exclusive(compatible: [:load, :unload])
+end
+
+
+ +
+ +
+

+ + loading() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 12
+def loading
+  @lock.exclusive(purpose: :load, compatible: [:load], after_compatible: [:load]) do
+    yield
+  end
+end
+
+
+ +
+ +
+

+ + permit_concurrent_loads() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 46
+def permit_concurrent_loads
+  @lock.yield_shares(compatible: [:load]) do
+    yield
+  end
+end
+
+
+ +
+ +
+

+ + running() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 40
+def running
+  @lock.sharing do
+    yield
+  end
+end
+
+
+ +
+ +
+

+ + start_running() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 32
+def start_running
+  @lock.start_sharing
+end
+
+
+ +
+ +
+

+ + start_unloading() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 24
+def start_unloading
+  @lock.start_exclusive(purpose: :unload, compatible: [:load, :unload])
+end
+
+
+ +
+ +
+

+ + unloading() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies/interlock.rb, line 18
+def unloading
+  @lock.exclusive(purpose: :unload, compatible: [:load, :unload], after_compatible: [:load, :unload]) do
+    yield
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Dependencies/Loadable.html b/src/5.2/classes/ActiveSupport/Dependencies/Loadable.html new file mode 100644 index 0000000000..ae98bd78d5 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Dependencies/Loadable.html @@ -0,0 +1,108 @@ +--- +title: ActiveSupport::Dependencies::Loadable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + require_dependency(file_name, message = "No such file to load -- %s.rb") + +

+ + +
+

Interprets a file using mechanism and marks its defined constants as autoloaded. file_name can be either a string or respond to to_path.

+ +

Use this method in code that absolutely needs a certain constant to be defined at that point. A typical use case is to make constant name resolution deterministic for constants with the same relative name in different namespaces whose evaluation would depend on load order otherwise.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 240
+def require_dependency(file_name, message = "No such file to load -- %s.rb")
+  file_name = file_name.to_path if file_name.respond_to?(:to_path)
+  unless file_name.is_a?(String)
+    raise ArgumentError, "the file name must either be a String or implement #to_path -- you passed #{file_name.inspect}"
+  end
+
+  Dependencies.depend_on(file_name, message)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Dependencies/WatchStack.html b/src/5.2/classes/ActiveSupport/Dependencies/WatchStack.html new file mode 100644 index 0000000000..96a950404d --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Dependencies/WatchStack.html @@ -0,0 +1,343 @@ +--- +title: ActiveSupport::Dependencies::WatchStack +layout: default +--- +
+ +
+
+ +
+ +

The WatchStack keeps a stack of the modules being watched as files are loaded. If a file in the process of being loaded (parent.rb) triggers the load of another file (child.rb) the stack will ensure that child.rb handles the new constants.

+ +

If child.rb is being autoloaded, its constants will be added to autoloaded_constants. If it was being required, they will be discarded.

+ +

This is handled by walking back up the watch stack and adding the constants found by child.rb to the list of original constants in parent.rb.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + watching

@watching is a stack of lists of constants being watched. For instance, if parent.rb is autoloaded, the stack will look like [[Object]]. If parent.rb then requires namespace/child.rb, the stack will look like [[Object], [Namespace]].

+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 102
+def initialize
+  @watching = []
+  @stack = Hash.new { |h, k| h[k] = [] }
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 107
+def each(&block)
+  @stack.each(&block)
+end
+
+
+ +
+ +
+

+ + new_constants() + +

+ + +
+

Returns a list of new constants found since the last call to watch_namespaces.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 117
+def new_constants
+  constants = []
+
+  # Grab the list of namespaces that we're looking for new constants under
+  @watching.last.each do |namespace|
+    # Retrieve the constants that were present under the namespace when watch_namespaces
+    # was originally called
+    original_constants = @stack[namespace].last
+
+    mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace)
+    next unless mod.is_a?(Module)
+
+    # Get a list of the constants that were added
+    new_constants = mod.constants(false) - original_constants
+
+    # @stack[namespace] returns an Array of the constants that are being evaluated
+    # for that namespace. For instance, if parent.rb requires child.rb, the first
+    # element of @stack[Object] will be an Array of the constants that were present
+    # before parent.rb was required. The second element will be an Array of the
+    # constants that were present before child.rb was required.
+    @stack[namespace].each do |namespace_constants|
+      namespace_constants.concat(new_constants)
+    end
+
+    # Normalize the list of new constants, and add them to the list we will return
+    new_constants.each do |suffix|
+      constants << ([namespace, suffix] - ["Object"]).join("::".freeze)
+    end
+  end
+  constants
+ensure
+  # A call to new_constants is always called after a call to watch_namespaces
+  pop_modules(@watching.pop)
+end
+
+
+ +
+ +
+

+ + watch_namespaces(namespaces) + +

+ + +
+

Add a set of modules to the watch stack, remembering the initial constants.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 154
+def watch_namespaces(namespaces)
+  @watching << namespaces.map do |namespace|
+    module_name = Dependencies.to_constant_name(namespace)
+    original_constants = Dependencies.qualified_const_defined?(module_name) ?
+      Inflector.constantize(module_name).constants(false) : []
+
+    @stack[module_name] << original_constants
+    module_name
+  end
+end
+
+
+ +
+ +
+

+ + watching?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/dependencies.rb, line 111
+def watching?
+  !@watching.empty?
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation.html b/src/5.2/classes/ActiveSupport/Deprecation.html new file mode 100644 index 0000000000..ab4ac3784d --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation.html @@ -0,0 +1,264 @@ +--- +title: ActiveSupport::Deprecation +layout: default +--- +
+ +
+
+ +
+ +

Deprecation specifies the API used by Rails to deprecate methods, instance variables, objects and constants.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_BEHAVIORS={ +raise: ->(message, callstack, deprecation_horizon, gem_name) { +e = DeprecationException.new(message) +e.set_backtrace(callstack.map(&:to_s)) +raise e +}, + +stderr: ->(message, callstack, deprecation_horizon, gem_name) { +$stderr.puts(message) +$stderr.puts callstack.join("\n ") if debug +}, + +log: ->(message, callstack, deprecation_horizon, gem_name) { +logger = +if defined?(Rails.logger) && Rails.logger +Rails.logger +else +require "active_support/logger" +ActiveSupport::Logger.new($stderr) +end +logger.warn message +logger.debug callstack.join("\n ") if debug +}, + +notify: ->(message, callstack, deprecation_horizon, gem_name) { +notification_name = "deprecation.#{gem_name.underscore.tr('/', '_')}" +ActiveSupport::Notifications.instrument(notification_name, +message: message, +callstack: callstack, +gem_name: gem_name, +deprecation_horizon: deprecation_horizon) +}, + +silence: ->(message, callstack, deprecation_horizon, gem_name) {}, +}
 

Default warning behaviors per Rails.env.

+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + deprecation_horizon

The version number in which the deprecated behavior will be removed, by default.

+ + + + +

Class Public methods

+ +
+

+ + new(deprecation_horizon = "6.0", gem_name = "Rails") + +

+ + +
+

It accepts two parameters on initialization. The first is a version of library and the second is a library name.

+ +
ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation.rb, line 38
+def initialize(deprecation_horizon = "6.0", gem_name = "Rails")
+  self.gem_name = gem_name
+  self.deprecation_horizon = deprecation_horizon
+  # By default, warnings are not silenced and debugging is off.
+  self.silenced = false
+  self.debug = false
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation/Behavior.html b/src/5.2/classes/ActiveSupport/Deprecation/Behavior.html new file mode 100644 index 0000000000..2d6f44810a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation/Behavior.html @@ -0,0 +1,206 @@ +--- +title: ActiveSupport::Deprecation::Behavior +layout: default +--- +
+ +
+
+ +
+ +

Behavior module allows to determine how to display deprecation messages. You can create a custom behavior or set any from the DEFAULT_BEHAVIORS constant. Available behaviors are:

+
raise +
+

Raise ActiveSupport::DeprecationException.

+
stderr +
+

Log all deprecation warnings to +$stderr+.

+
log +
+

Log all deprecation warnings to Rails.logger.

+
notify +
+

Use ActiveSupport::Notifications to notify deprecation.rails.

+
silence +
+

Do nothing.

+
+ +

Setting behaviors only affects deprecations that happen after boot time. For more information you can read the documentation of the behavior= method.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + debug

Whether to print a backtrace along with the warning.

+ + + + + +

Instance Public methods

+ +
+

+ + behavior() + +

+ + +
+

Returns the current behavior or if one isn't set, defaults to :stderr.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/behaviors.rb, line 66
+def behavior
+  @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
+end
+
+
+ +
+ +
+

+ + behavior=(behavior) + +

+ + +
+

Sets the behavior to the specified value. Can be a single value, array, or an object that responds to call.

+ +

Available behaviors:

+
raise +
+

Raise ActiveSupport::DeprecationException.

+
stderr +
+

Log all deprecation warnings to +$stderr+.

+
log +
+

Log all deprecation warnings to Rails.logger.

+
notify +
+

Use ActiveSupport::Notifications to notify deprecation.rails.

+
silence +
+

Do nothing.

+
+ +

Setting behaviors only affects deprecations that happen after boot time. Deprecation warnings raised by gems are not affected by this setting because they happen before Rails boots up.

+ +
ActiveSupport::Deprecation.behavior = :stderr
+ActiveSupport::Deprecation.behavior = [:stderr, :log]
+ActiveSupport::Deprecation.behavior = MyCustomHandler
+ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
+  # custom stuff
+}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/behaviors.rb, line 91
+def behavior=(behavior)
+  @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantAccessor.html b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantAccessor.html new file mode 100644 index 0000000000..b79c5c0782 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantAccessor.html @@ -0,0 +1,231 @@ +--- +title: ActiveSupport::Deprecation::DeprecatedConstantAccessor +layout: default +--- +
+ +
+
+ +
+ +

DeprecatedConstantAccessor transforms a constant into a deprecated one by hooking const_missing.

+ +

It takes the names of an old (deprecated) constant and of a new constant (both in string form) and optionally a deprecator. The deprecator defaults to ActiveSupport::Deprecator if none is specified.

+ +

The deprecated constant now returns the same object as the new one rather than a proxy object, so it can be used transparently in rescue blocks etc.

+ +
PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
+
+# (In a later update, the original implementation of `PLANETS` has been removed.)
+
+PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
+include ActiveSupport::Deprecation::DeprecatedConstantAccessor
+deprecate_constant 'PLANETS', 'PLANETS_POST_2006'
+
+PLANETS.map { |planet| planet.capitalize }
+# => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead.
+     (Backtrace information…)
+     ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + included(base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 29
+def self.included(base)
+  require "active_support/inflector/methods"
+
+  extension = Module.new do
+    def const_missing(missing_const_name)
+      if class_variable_defined?(:@@_deprecated_constants)
+        if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s])
+          replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations)
+          return ActiveSupport::Inflector.constantize(replacement[:new].to_s)
+        end
+      end
+      super
+    end
+
+    def deprecate_constant(const_name, new_constant, message: nil, deprecator: ActiveSupport::Deprecation.instance)
+      class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
+      class_variable_get(:@@_deprecated_constants)[const_name.to_s] = { new: new_constant, message: message, deprecator: deprecator }
+    end
+  end
+  base.singleton_class.prepend extension
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + const_missing(missing_const_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 33
+def const_missing(missing_const_name)
+  if class_variable_defined?(:@@_deprecated_constants)
+    if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s])
+      replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations)
+      return ActiveSupport::Inflector.constantize(replacement[:new].to_s)
+    end
+  end
+  super
+end
+
+
+ +
+ +
+

+ + deprecate_constant(const_name, new_constant, message: nil, deprecator: ActiveSupport::Deprecation.instance) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 43
+def deprecate_constant(const_name, new_constant, message: nil, deprecator: ActiveSupport::Deprecation.instance)
+  class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
+  class_variable_get(:@@_deprecated_constants)[const_name.to_s] = { new: new_constant, message: message, deprecator: deprecator }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantProxy.html b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantProxy.html new file mode 100644 index 0000000000..1a28766810 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedConstantProxy.html @@ -0,0 +1,178 @@ +--- +title: ActiveSupport::Deprecation::DeprecatedConstantProxy +layout: default +--- +
+ +
+
+ +
+ +

DeprecatedConstantProxy transforms a constant into a deprecated one. It takes the names of an old (deprecated) constant and of a new constant (both in string form) and optionally a deprecator. The deprecator defaults to ActiveSupport::Deprecator if none is specified. The deprecated constant now returns the value of the new one.

+ +
PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto)
+
+# (In a later update, the original implementation of `PLANETS` has been removed.)
+
+PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
+PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006')
+
+PLANETS.map { |planet| planet.capitalize }
+# => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead.
+     (Backtrace information…)
+     ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance, message: "#{old_const} is deprecated! Use #{new_const} instead.") + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 126
+def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance, message: "#{old_const} is deprecated! Use #{new_const} instead.")
+  require "active_support/inflector/methods"
+
+  @old_const = old_const
+  @new_const = new_const
+  @deprecator = deprecator
+  @message = message
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + class() + +

+ + +
+

Returns the class of the new constant.

+ +
PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
+PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006')
+PLANETS.class # => Array
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 140
+def class
+  target.class
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedInstanceVariableProxy.html b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedInstanceVariableProxy.html new file mode 100644 index 0000000000..7c0d26135a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedInstanceVariableProxy.html @@ -0,0 +1,144 @@ +--- +title: ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy +layout: default +--- +
+ +
+
+ +
+ +

DeprecatedInstanceVariableProxy transforms an instance variable into a deprecated one. It takes an instance of a class, a method on that class and an instance variable. It optionally takes a deprecator as the last argument. The deprecator defaults to ActiveSupport::Deprecator if none is specified.

+ +
class Example
+  def initialize
+    @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request)
+    @_request = :special_request
+  end
+
+  def request
+    @_request
+  end
+
+  def old_request
+    @request
+  end
+end
+
+example = Example.new
+# => #<Example:0x007fb9b31090b8 @_request=:special_request, @request=:special_request>
+
+example.old_request.to_s
+# => DEPRECATION WARNING: @request is deprecated! Call request.to_s instead of
+   @request.to_s
+   (Backtrace information…)
+   "special_request"
+
+example.request.to_s
+# => "special_request"
+
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 91
+def initialize(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance)
+  @instance = instance
+  @method = method
+  @var = var
+  @deprecator = deprecator
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedObjectProxy.html b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedObjectProxy.html new file mode 100644 index 0000000000..cc952c956c --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation/DeprecatedObjectProxy.html @@ -0,0 +1,124 @@ +--- +title: ActiveSupport::Deprecation::DeprecatedObjectProxy +layout: default +--- +
+ +
+
+ +
+ +

DeprecatedObjectProxy transforms an object into a deprecated one. It takes an object, a deprecation message and optionally a deprecator. The deprecator defaults to ActiveSupport::Deprecator if none is specified.

+ +
deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, "This object is now deprecated")
+# => #<Object:0x007fb9b34c34b0>
+
+deprecated_object.to_s
+DEPRECATION WARNING: This object is now deprecated.
+(Backtrace)
+# => "#<Object:0x007fb9b34c34b0>"
+
+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(object, message, deprecator = ActiveSupport::Deprecation.instance) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 42
+def initialize(object, message, deprecator = ActiveSupport::Deprecation.instance)
+  @object = object
+  @message = message
+  @deprecator = deprecator
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation/MethodWrapper.html b/src/5.2/classes/ActiveSupport/Deprecation/MethodWrapper.html new file mode 100644 index 0000000000..05f4e45e75 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation/MethodWrapper.html @@ -0,0 +1,183 @@ +--- +title: ActiveSupport::Deprecation::MethodWrapper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + deprecate_methods(target_module, *method_names) + +

+ + +
+

Declare that a method has been deprecated.

+ +
class Fred
+  def aaa; end
+  def bbb; end
+  def ccc; end
+  def ddd; end
+  def eee; end
+end
+
+ +

Using the default deprecator:

+ +
ActiveSupport::Deprecation.deprecate_methods(Fred, :aaa, bbb: :zzz, ccc: 'use Bar#ccc instead')
+# => Fred
+
+Fred.new.aaa
+# DEPRECATION WARNING: aaa is deprecated and will be removed from Rails 5.1. (called from irb_binding at (irb):10)
+# => nil
+
+Fred.new.bbb
+# DEPRECATION WARNING: bbb is deprecated and will be removed from Rails 5.1 (use zzz instead). (called from irb_binding at (irb):11)
+# => nil
+
+Fred.new.ccc
+# DEPRECATION WARNING: ccc is deprecated and will be removed from Rails 5.1 (use Bar#ccc instead). (called from irb_binding at (irb):12)
+# => nil
+
+ +

Passing in a custom deprecator:

+ +
custom_deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem')
+ActiveSupport::Deprecation.deprecate_methods(Fred, ddd: :zzz, deprecator: custom_deprecator)
+# => [:ddd]
+
+Fred.new.ddd
+DEPRECATION WARNING: ddd is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):15)
+# => nil
+
+ +

Using a custom deprecator directly:

+ +
custom_deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem')
+custom_deprecator.deprecate_methods(Fred, eee: :zzz)
+# => [:eee]
+
+Fred.new.eee
+DEPRECATION WARNING: eee is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):18)
+# => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/method_wrappers.rb, line 52
+def deprecate_methods(target_module, *method_names)
+  options = method_names.extract_options!
+  deprecator = options.delete(:deprecator) || self
+  method_names += options.keys
+  mod = Module.new
+
+  method_names.each do |method_name|
+    if target_module.method_defined?(method_name) || target_module.private_method_defined?(method_name)
+      aliased_method, punctuation = method_name.to_s.sub(/([?!=])$/, ""), $1
+      with_method = "#{aliased_method}_with_deprecation#{punctuation}"
+      without_method = "#{aliased_method}_without_deprecation#{punctuation}"
+
+      target_module.send(:define_method, with_method) do |*args, &block|
+        deprecator.deprecation_warning(method_name, options[method_name])
+        send(without_method, *args, &block)
+      end
+
+      target_module.send(:alias_method, without_method, method_name)
+      target_module.send(:alias_method, method_name, with_method)
+
+      case
+      when target_module.protected_method_defined?(without_method)
+        target_module.send(:protected, method_name)
+      when target_module.private_method_defined?(without_method)
+        target_module.send(:private, method_name)
+      end
+    else
+      mod.send(:define_method, method_name) do |*args, &block|
+        deprecator.deprecation_warning(method_name, options[method_name])
+        super(*args, &block)
+      end
+    end
+  end
+
+  target_module.prepend(mod) unless mod.instance_methods(false).empty?
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Deprecation/Reporting.html b/src/5.2/classes/ActiveSupport/Deprecation/Reporting.html new file mode 100644 index 0000000000..a2880f713c --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Deprecation/Reporting.html @@ -0,0 +1,243 @@ +--- +title: ActiveSupport::Deprecation::Reporting +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RAILS_GEM_ROOT=File.expand_path("../../../..", __dir__) + "/"
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + gem_name

Name of gem where method is deprecated

+ [RW] + silenced

Whether to print a message (silent mode)

+ + + + + +

Instance Public methods

+ +
+

+ + deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/reporting.rb, line 43
+def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
+  caller_backtrace ||= caller_locations(2)
+  deprecated_method_warning(deprecated_method_name, message).tap do |msg|
+    warn(msg, caller_backtrace)
+  end
+end
+
+
+ +
+ +
+

+ + silence() + +

+ + +
+

Silence deprecation warnings within the block.

+ +
ActiveSupport::Deprecation.warn('something broke!')
+# => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+
+ActiveSupport::Deprecation.silence do
+  ActiveSupport::Deprecation.warn('something broke!')
+end
+# => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/reporting.rb, line 36
+def silence
+  old_silenced, @silenced = @silenced, true
+  yield
+ensure
+  @silenced = old_silenced
+end
+
+
+ +
+ +
+

+ + warn(message = nil, callstack = nil) + +

+ + +
+

Outputs a deprecation warning to the output configured by ActiveSupport::Deprecation.behavior.

+ +
ActiveSupport::Deprecation.warn('something broke!')
+# => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/deprecation/reporting.rb, line 18
+def warn(message = nil, callstack = nil)
+  return if silenced
+
+  callstack ||= caller_locations(2)
+  deprecation_message(callstack, message).tap do |m|
+    behavior.each { |b| b.call(m, callstack, deprecation_horizon, gem_name) }
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/DeprecationException.html b/src/5.2/classes/ActiveSupport/DeprecationException.html new file mode 100644 index 0000000000..a5465d280a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/DeprecationException.html @@ -0,0 +1,66 @@ +--- +title: ActiveSupport::DeprecationException +layout: default +--- +
+ +
+
+ +
+ +

Raised when ActiveSupport::Deprecation::Behavior#behavior is set with :raise. You would set :raise, as a behavior to raise errors and proactively report exceptions from deprecations.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/DescendantsTracker.html b/src/5.2/classes/ActiveSupport/DescendantsTracker.html new file mode 100644 index 0000000000..4e2e458a74 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/DescendantsTracker.html @@ -0,0 +1,357 @@ +--- +title: ActiveSupport::DescendantsTracker +layout: default +--- +
+ +
+
+ +
+ +

This module provides an internal implementation to track descendants which is faster than iterating through ObjectSpace.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + clear() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/descendants_tracker.rb, line 20
+def clear
+  if defined? ActiveSupport::Dependencies
+    @@direct_descendants.each do |klass, descendants|
+      if ActiveSupport::Dependencies.autoloaded?(klass)
+        @@direct_descendants.delete(klass)
+      else
+        descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
+      end
+    end
+  else
+    @@direct_descendants.clear
+  end
+end
+
+
+ +
+ +
+

+ + descendants(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/descendants_tracker.rb, line 14
+def descendants(klass)
+  arr = []
+  accumulate_descendants(klass, arr)
+  arr
+end
+
+
+ +
+ +
+

+ + direct_descendants(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/descendants_tracker.rb, line 10
+def direct_descendants(klass)
+  @@direct_descendants[klass] || []
+end
+
+
+ +
+ +
+

+ + store_inherited(klass, descendant) + +

+ + +
+

This is the only method that is not thread safe, but is only ever called during the eager loading phase.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/descendants_tracker.rb, line 36
+def store_inherited(klass, descendant)
+  (@@direct_descendants[klass] ||= []) << descendant
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + descendants() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/descendants_tracker.rb, line 58
+def descendants
+  DescendantsTracker.descendants(self)
+end
+
+
+ +
+ +
+

+ + direct_descendants() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/descendants_tracker.rb, line 54
+def direct_descendants
+  DescendantsTracker.direct_descendants(self)
+end
+
+
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/descendants_tracker.rb, line 49
+def inherited(base)
+  DescendantsTracker.store_inherited(self, base)
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Duration.html b/src/5.2/classes/ActiveSupport/Duration.html new file mode 100644 index 0000000000..12bf7930fc --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Duration.html @@ -0,0 +1,1049 @@ +--- +title: ActiveSupport::Duration +layout: default +--- +
+ +
+
+ +
+ +

Provides accurate date and time measurements using Date#advance and Time#advance, respectively. It mainly supports the methods on Numeric.

+ +
1.month.ago       # equivalent to Time.now.advance(months: -1)
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARTS=[:years, :months, :weeks, :days, :hours, :minutes, :seconds].freeze
 
PARTS_IN_SECONDS={ +seconds: 1, +minutes: SECONDS_PER_MINUTE, +hours: SECONDS_PER_HOUR, +days: SECONDS_PER_DAY, +weeks: SECONDS_PER_WEEK, +months: SECONDS_PER_MONTH, +years: SECONDS_PER_YEAR +}.freeze
 
SECONDS_PER_DAY=86400
 
SECONDS_PER_HOUR=3600
 
SECONDS_PER_MINUTE=60
 
SECONDS_PER_MONTH=2629746
 
SECONDS_PER_WEEK=604800
 
SECONDS_PER_YEAR=31556952
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + parts
+ [RW] + value
+ + + + +

Class Public methods

+ +
+

+ + build(value) + +

+ + +
+

Creates a new Duration from a seconds value that is converted to the individual parts:

+ +
ActiveSupport::Duration.build(31556952).parts # => {:years=>1}
+ActiveSupport::Duration.build(2716146).parts  # => {:months=>1, :days=>1}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 184
+def build(value)
+  parts = {}
+  remainder = value.round(9)
+
+  PARTS.each do |part|
+    unless part == :seconds
+      part_in_seconds = PARTS_IN_SECONDS[part]
+      parts[part] = remainder.div(part_in_seconds)
+      remainder %= part_in_seconds
+    end
+  end unless value == 0
+
+  parts[:seconds] = remainder
+
+  new(value, parts)
+end
+
+
+ +
+ +
+

+ + parse(iso8601duration) + +

+ + +
+

Creates a new Duration from string formatted according to ISO 8601 Duration.

+ +

See ISO 8601 for more information. This method allows negative parts to be present in pattern. If invalid string is provided, it will raise ActiveSupport::Duration::ISO8601Parser::ParsingError.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 139
+def parse(iso8601duration)
+  parts = ISO8601Parser.new(iso8601duration).parse!
+  new(calculate_total_seconds(parts), parts)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + %(other) + +

+ + +
+

Returns the modulo of this Duration by another Duration or Numeric. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 281
+def %(other)
+  if Duration === other || Scalar === other
+    Duration.build(value % other.value)
+  elsif Numeric === other
+    Duration.build(value % other)
+  else
+    raise_type_error(other)
+  end
+end
+
+
+ +
+ +
+

+ + *(other) + +

+ + +
+

Multiplies this Duration by a Numeric and returns a new Duration.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 256
+def *(other)
+  if Scalar === other || Duration === other
+    Duration.new(value * other.value, parts.map { |type, number| [type, number * other.value] })
+  elsif Numeric === other
+    Duration.new(value * other, parts.map { |type, number| [type, number * other] })
+  else
+    raise_type_error(other)
+  end
+end
+
+
+ +
+ +
+

+ + +(other) + +

+ + +
+

Adds another Duration or a Numeric to this Duration. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 236
+def +(other)
+  if Duration === other
+    parts = @parts.dup
+    other.parts.each do |(key, value)|
+      parts[key] += value
+    end
+    Duration.new(value + other.value, parts)
+  else
+    seconds = @parts[:seconds] + other
+    Duration.new(value + other, @parts.merge(seconds: seconds))
+  end
+end
+
+
+ +
+ +
+

+ + -(other) + +

+ + +
+

Subtracts another Duration or a Numeric from this Duration. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 251
+def -(other)
+  self + (-other)
+end
+
+
+ +
+ +
+

+ + /(other) + +

+ + +
+

Divides this Duration by a Numeric and returns a new Duration.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 267
+def /(other)
+  if Scalar === other
+    Duration.new(value / other.value, parts.map { |type, number| [type, number / other.value] })
+  elsif Duration === other
+    value / other.value
+  elsif Numeric === other
+    Duration.new(value / other, parts.map { |type, number| [type, number / other] })
+  else
+    raise_type_error(other)
+  end
+end
+
+
+ +
+ +
+

+ + <=>(other) + +

+ + +
+

Compares one Duration with another or a Numeric to this Duration. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 226
+def <=>(other)
+  if Duration === other
+    value <=> other.value
+  elsif Numeric === other
+    value <=> other
+  end
+end
+
+
+ +
+ +
+

+ + ==(other) + +

+ + +
+

Returns true if other is also a Duration instance with the same value, or if other == value.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 306
+def ==(other)
+  if Duration === other
+    other.value == value
+  else
+    other == value
+  end
+end
+
+
+ +
+ +
+

+ + after(time = ::Time.current) + +

+ + +
+ +
+ + + + + +
+ Alias for: since +
+ + + +
+ +
+

+ + ago(time = ::Time.current) + +

+ + +
+

Calculates a new Time or Date that is as far in the past as this Duration represents.

+
+ + + +
+ Also aliased as: until, before +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 366
+def ago(time = ::Time.current)
+  sum(-1, time)
+end
+
+
+ +
+ +
+

+ + before(time = ::Time.current) + +

+ + +
+ +
+ + + + + +
+ Alias for: ago +
+ + + +
+ +
+

+ + eql?(other) + +

+ + +
+

Returns true if other is also a Duration instance, which has the same parts as this one.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 348
+def eql?(other)
+  Duration === other && other.value.eql?(value)
+end
+
+
+ +
+ +
+

+ + from_now(time = ::Time.current) + +

+ + +
+ +
+ + + + + +
+ Alias for: since +
+ + + +
+ +
+

+ + hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 352
+def hash
+  @value.hash
+end
+
+
+ +
+ +
+

+ + iso8601(precision: nil) + +

+ + +
+

Build ISO 8601 Duration string for this duration. The precision parameter can be used to limit seconds' precision of duration.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 396
+def iso8601(precision: nil)
+  ISO8601Serializer.new(self, precision: precision).serialize
+end
+
+
+ +
+ +
+

+ + since(time = ::Time.current) + +

+ + +
+

Calculates a new Time or Date that is as far in the future as this Duration represents.

+
+ + + +
+ Also aliased as: from_now, after +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 358
+def since(time = ::Time.current)
+  sum(1, time)
+end
+
+
+ +
+ +
+

+ + to_i() + +

+ + +
+

Returns the number of seconds that this Duration represents.

+ +
1.minute.to_i   # => 60
+1.hour.to_i     # => 3600
+1.day.to_i      # => 86400
+
+ +

Note that this conversion makes some assumptions about the duration of some periods, e.g. months are always 1/12 of year and years are 365.2425 days:

+ +
# equivalent to (1.year / 12).to_i
+1.month.to_i    # => 2629746
+
+# equivalent to 365.2425.days.to_i
+1.year.to_i     # => 31556952
+
+ +

In such cases, Ruby's core Date and Time should be used for precision date and time arithmetic.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 342
+def to_i
+  @value.to_i
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+

Returns the amount of seconds a duration covers as a string. For more information check to_i method.

+ +
1.day.to_s # => "86400"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/duration.rb, line 318
+def to_s
+  @value.to_s
+end
+
+
+ +
+ +
+

+ + until(time = ::Time.current) + +

+ + +
+ +
+ + + + + +
+ Alias for: ago +
+ + + +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Duration/ISO8601Parser.html b/src/5.2/classes/ActiveSupport/Duration/ISO8601Parser.html new file mode 100644 index 0000000000..198074b58a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Duration/ISO8601Parser.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::Duration::ISO8601Parser +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Duration/ISO8601Parser/ParsingError.html b/src/5.2/classes/ActiveSupport/Duration/ISO8601Parser/ParsingError.html new file mode 100644 index 0000000000..a2ada906bc --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Duration/ISO8601Parser/ParsingError.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Duration::ISO8601Parser::ParsingError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/EncryptedConfiguration.html b/src/5.2/classes/ActiveSupport/EncryptedConfiguration.html new file mode 100644 index 0000000000..23026b8dea --- /dev/null +++ b/src/5.2/classes/ActiveSupport/EncryptedConfiguration.html @@ -0,0 +1,232 @@ +--- +title: ActiveSupport::EncryptedConfiguration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(config_path:, key_path:, env_key:, raise_if_missing_key:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_configuration.rb, line 14
+def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:)
+  super content_path: config_path, key_path: key_path,
+    env_key: env_key, raise_if_missing_key: raise_if_missing_key
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_configuration.rb, line 32
+def config
+  @config ||= deserialize(read).deep_symbolize_keys
+end
+
+
+ +
+ +
+

+ + read() + +

+ + +
+

Allow a config to be started without a file present

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_configuration.rb, line 20
+def read
+  super
+rescue ActiveSupport::EncryptedFile::MissingContentError
+  ""
+end
+
+
+ +
+ +
+

+ + write(contents) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_configuration.rb, line 26
+def write(contents)
+  deserialize(contents)
+
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/EncryptedFile.html b/src/5.2/classes/ActiveSupport/EncryptedFile.html new file mode 100644 index 0000000000..b0a6ab7b33 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/EncryptedFile.html @@ -0,0 +1,382 @@ +--- +title: ActiveSupport::EncryptedFile +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
CIPHER="aes-128-gcm"
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + content_path
+ [R] + env_key
+ [R] + key_path
+ [R] + raise_if_missing_key
+ + + + +

Class Public methods

+ +
+

+ + generate_key() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 24
+def self.generate_key
+  SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(CIPHER))
+end
+
+
+ +
+ +
+

+ + new(content_path:, key_path:, env_key:, raise_if_missing_key:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 31
+def initialize(content_path:, key_path:, env_key:, raise_if_missing_key:)
+  @content_path, @key_path = Pathname.new(content_path), Pathname.new(key_path)
+  @env_key, @raise_if_missing_key = env_key, raise_if_missing_key
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + change(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 53
+def change(&block)
+  writing read, &block
+end
+
+
+ +
+ +
+

+ + key() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 36
+def key
+  read_env_key || read_key_file || handle_missing_key
+end
+
+
+ +
+ +
+

+ + read() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 40
+def read
+  if !key.nil? && content_path.exist?
+    decrypt content_path.binread
+  else
+    raise MissingContentError, content_path
+  end
+end
+
+
+ +
+ +
+

+ + write(contents) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 48
+def write(contents)
+  IO.binwrite "#{content_path}.tmp", encrypt(contents)
+  FileUtils.mv "#{content_path}.tmp", content_path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/EncryptedFile/MissingContentError.html b/src/5.2/classes/ActiveSupport/EncryptedFile/MissingContentError.html new file mode 100644 index 0000000000..d24fb131c4 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/EncryptedFile/MissingContentError.html @@ -0,0 +1,107 @@ +--- +title: ActiveSupport::EncryptedFile::MissingContentError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(content_path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 9
+def initialize(content_path)
+  super "Missing encrypted content file in #{content_path}."
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/EncryptedFile/MissingKeyError.html b/src/5.2/classes/ActiveSupport/EncryptedFile/MissingKeyError.html new file mode 100644 index 0000000000..7d404dca40 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/EncryptedFile/MissingKeyError.html @@ -0,0 +1,109 @@ +--- +title: ActiveSupport::EncryptedFile::MissingKeyError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(key_path:, env_key:) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/encrypted_file.rb, line 15
+def initialize(key_path:, env_key:)
+  super \
+    "Missing encryption key to decrypt file with. " +
+    "Ask your team for your master key and write it to #{key_path} or put it in the ENV['#{env_key}']."
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/EventedFileUpdateChecker.html b/src/5.2/classes/ActiveSupport/EventedFileUpdateChecker.html new file mode 100644 index 0000000000..9830d59a6d --- /dev/null +++ b/src/5.2/classes/ActiveSupport/EventedFileUpdateChecker.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::EventedFileUpdateChecker +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/EventedFileUpdateChecker/PathHelper.html b/src/5.2/classes/ActiveSupport/EventedFileUpdateChecker/PathHelper.html new file mode 100644 index 0000000000..af95937b00 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/EventedFileUpdateChecker/PathHelper.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::EventedFileUpdateChecker::PathHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/ExecutionWrapper.html b/src/5.2/classes/ActiveSupport/ExecutionWrapper.html new file mode 100644 index 0000000000..d58be42697 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/ExecutionWrapper.html @@ -0,0 +1,368 @@ +--- +title: ActiveSupport::ExecutionWrapper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + active
+ + + + +

Class Public methods

+ +
+

+ + register_hook(hook, outer: false) + +

+ + +
+

Register an object to be invoked during both the run and complete steps.

+ +

hook.complete will be passed the value returned from hook.run, and will only be invoked if run has previously been called. (Mostly, this means it won't be invoked if an exception occurs in a preceding to_run block; all ordinary to_complete blocks are invoked in that situation.)

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/execution_wrapper.rb, line 49
+def self.register_hook(hook, outer: false)
+  if outer
+    to_run RunHook.new(hook), prepend: true
+    to_complete :after, CompleteHook.new(hook)
+  else
+    to_run RunHook.new(hook)
+    to_complete CompleteHook.new(hook)
+  end
+end
+
+
+ +
+ +
+

+ + run!() + +

+ + +
+

Run this execution.

+ +

Returns an instance, whose complete! method must be invoked after the work has been performed.

+ +

Where possible, prefer wrap.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/execution_wrapper.rb, line 65
+def self.run!
+  if active?
+    Null
+  else
+    new.tap do |instance|
+      success = nil
+      begin
+        instance.run!
+        success = true
+      ensure
+        instance.complete! unless success
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + to_complete(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/execution_wrapper.rb, line 20
+def self.to_complete(*args, &block)
+  set_callback(:complete, *args, &block)
+end
+
+
+ +
+ +
+

+ + to_run(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/execution_wrapper.rb, line 16
+def self.to_run(*args, &block)
+  set_callback(:run, *args, &block)
+end
+
+
+ +
+ +
+

+ + wrap() + +

+ + +
+

Perform the work in the supplied block as an execution.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/execution_wrapper.rb, line 82
+def self.wrap
+  return yield if active?
+
+  instance = run!
+  begin
+    yield
+  ensure
+    instance.complete!
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + complete!() + +

+ + +
+

Complete this in-flight execution. This method must be called exactly once on the result of any call to run!.

+ +

Where possible, prefer wrap.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/execution_wrapper.rb, line 117
+def complete!
+  run_callbacks(:complete)
+ensure
+  self.class.active.delete Thread.current
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Executor.html b/src/5.2/classes/ActiveSupport/Executor.html new file mode 100644 index 0000000000..ae34578bc8 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Executor.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Executor +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/FileUpdateChecker.html b/src/5.2/classes/ActiveSupport/FileUpdateChecker.html new file mode 100644 index 0000000000..68fe256f70 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/FileUpdateChecker.html @@ -0,0 +1,293 @@ +--- +title: ActiveSupport::FileUpdateChecker +layout: default +--- +
+ +
+
+ +
+ +

FileUpdateChecker specifies the API used by Rails to watch files and control reloading. The API depends on four methods:

+
  • +

    initialize which expects two parameters and one block as described below.

    +
  • +

    updated? which returns a boolean if there were updates in the filesystem or not.

    +
  • +

    execute which executes the given block on initialization and updates the latest watched files and timestamp.

    +
  • +

    execute_if_updated which just executes the block if it was updated.

    +
+ +

After initialization, a call to execute_if_updated must execute the block only if there was really a change in the filesystem.

+ +

This class is used by Rails to reload the I18n framework whenever they are changed upon a new request.

+ +
i18n_reloader = ActiveSupport::FileUpdateChecker.new(paths) do
+  I18n.reload!
+end
+
+ActiveSupport::Reloader.to_prepare do
+  i18n_reloader.execute_if_updated
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(files, dirs = {}, &block) + +

+ + +
+

It accepts two parameters on initialization. The first is an array of files and the second is an optional hash of directories. The hash must have directories as keys and the value is an array of extensions to be watched under that directory.

+ +

This method must also receive a block that will be called once a path changes. The array of files and list of directories cannot be changed after FileUpdateChecker has been initialized.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/file_update_checker.rb, line 42
+def initialize(files, dirs = {}, &block)
+  unless block
+    raise ArgumentError, "A block is required to initialize a FileUpdateChecker"
+  end
+
+  @files = files.freeze
+  @glob  = compile_glob(dirs)
+  @block = block
+
+  @watched    = nil
+  @updated_at = nil
+
+  @last_watched   = watched
+  @last_update_at = updated_at(@last_watched)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + execute() + +

+ + +
+

Executes the given block and updates the latest watched files and timestamp.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/file_update_checker.rb, line 80
+def execute
+  @last_watched   = watched
+  @last_update_at = updated_at(@last_watched)
+  @block.call
+ensure
+  @watched = nil
+  @updated_at = nil
+end
+
+
+ +
+ +
+

+ + execute_if_updated() + +

+ + +
+

Execute the block given if updated.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/file_update_checker.rb, line 90
+def execute_if_updated
+  if updated?
+    yield if block_given?
+    execute
+    true
+  else
+    false
+  end
+end
+
+
+ +
+ +
+

+ + updated?() + +

+ + +
+

Check if any of the entries were updated. If so, the watched and/or updated_at values are cached until the block is executed via execute or execute_if_updated.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/file_update_checker.rb, line 61
+def updated?
+  current_watched = watched
+  if @last_watched.size != current_watched.size
+    @watched = current_watched
+    true
+  else
+    current_updated_at = updated_at(current_watched)
+    if @last_update_at < current_updated_at
+      @watched    = current_watched
+      @updated_at = current_updated_at
+      true
+    else
+      false
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Gzip.html b/src/5.2/classes/ActiveSupport/Gzip.html new file mode 100644 index 0000000000..95ae2ed656 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Gzip.html @@ -0,0 +1,170 @@ +--- +title: ActiveSupport::Gzip +layout: default +--- +
+ +
+
+ +
+ +

A convenient wrapper for the zlib standard library that allows compression/decompression of strings with gzip.

+ +
gzip = ActiveSupport::Gzip.compress('compress me!')
+# => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
+
+ActiveSupport::Gzip.decompress(gzip)
+# => "compress me!"
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + compress(source, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY) + +

+ + +
+

Compresses a string using gzip.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/gzip.rb, line 30
+def self.compress(source, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY)
+  output = Stream.new
+  gz = Zlib::GzipWriter.new(output, level, strategy)
+  gz.write(source)
+  gz.close
+  output.string
+end
+
+
+ +
+ +
+

+ + decompress(source) + +

+ + +
+

Decompresses a gzipped string.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/gzip.rb, line 25
+def self.decompress(source)
+  Zlib::GzipReader.wrap(StringIO.new(source), &:read)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Gzip/Stream.html b/src/5.2/classes/ActiveSupport/Gzip/Stream.html new file mode 100644 index 0000000000..1a4c167dd4 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Gzip/Stream.html @@ -0,0 +1,148 @@ +--- +title: ActiveSupport::Gzip::Stream +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/gzip.rb, line 17
+def initialize(*)
+  super
+  set_encoding "BINARY"
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/gzip.rb, line 21
+def close; rewind; end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/HashWithIndifferentAccess.html b/src/5.2/classes/ActiveSupport/HashWithIndifferentAccess.html new file mode 100644 index 0000000000..0dab1e55c3 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/HashWithIndifferentAccess.html @@ -0,0 +1,2134 @@ +--- +title: ActiveSupport::HashWithIndifferentAccess +layout: default +--- +
+ +
+
+ +
+ +

Implements a hash where keys :foo and "foo" are considered to be the same.

+ +
rgb = ActiveSupport::HashWithIndifferentAccess.new
+
+rgb[:black] = '#000000'
+rgb[:black]  # => '#000000'
+rgb['black'] # => '#000000'
+
+rgb['white'] = '#FFFFFF'
+rgb[:white]  # => '#FFFFFF'
+rgb['white'] # => '#FFFFFF'
+
+ +

Internally symbols are mapped to strings when used as keys in the entire writing interface (calling []=, merge, etc). This mapping belongs to the public interface. For example, given:

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
+
+ +

You are guaranteed that the key is returned as a string:

+ +
hash.keys # => ["a"]
+
+ +

Technically other types of keys are accepted:

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
+hash[0] = 0
+hash # => {"a"=>1, 0=>0}
+
+ +

but this class is intended for use cases where strings or symbols are the expected keys and it is convenient to understand both as the same. For example the params hash in Ruby on Rails.

+ +

Note that core extensions define Hash#with_indifferent_access:

+ +
rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
+
+ +

which may be handy.

+ +

To access this class outside of Rails, require the core extension with:

+ +
require "active_support/core_ext/hash/indifferent_access"
+
+ +

which will, in turn, require this file.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + [](*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 79
+def self.[](*args)
+  new.merge!(Hash[*args])
+end
+
+
+ +
+ +
+

+ + new(constructor = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 66
+def initialize(constructor = {})
+  if constructor.respond_to?(:to_hash)
+    super()
+    update(constructor)
+
+    hash = constructor.to_hash
+    self.default = hash.default if hash.default
+    self.default_proc = hash.default_proc if hash.default_proc
+  else
+    super(constructor)
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](key) + +

+ + +
+

Same as Hash#[] where the key passed as argument can be either a string or a symbol:

+ +
counters = ActiveSupport::HashWithIndifferentAccess.new
+counters[:foo] = 1
+
+counters['foo'] # => 1
+counters[:foo]  # => 1
+counters[:zoo]  # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 162
+def [](key)
+  super(convert_key(key))
+end
+
+
+ +
+ +
+

+ + []=(key, value) + +

+ + +
+

Assigns a new value to the hash:

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new
+hash[:key] = 'value'
+
+ +

This value can be later fetched using either :key or 'key'.

+
+ + + +
+ Also aliased as: regular_writer, store +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 92
+def []=(key, value)
+  regular_writer(convert_key(key), convert_value(value, for: :assignment))
+end
+
+
+ +
+ +
+

+ + assoc(key) + +

+ + +
+

Same as Hash#assoc where the key passed as argument can be either a string or a symbol:

+ +
counters = ActiveSupport::HashWithIndifferentAccess.new
+counters[:foo] = 1
+
+counters.assoc('foo') # => ["foo", 1]
+counters.assoc(:foo)  # => ["foo", 1]
+counters.assoc(:zoo)  # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 175
+def assoc(key)
+  super(convert_key(key))
+end
+
+
+ +
+ +
+

+ + compact() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 346
+def compact
+  dup.tap(&:compact!)
+end
+
+
+ +
+ +
+

+ + deep_stringify_keys() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 300
+def deep_stringify_keys; dup end
+
+
+ +
+ +
+

+ + deep_stringify_keys!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 298
+def deep_stringify_keys!; self end
+
+
+ +
+ +
+

+ + deep_symbolize_keys() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 305
+def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
+
+
+ +
+ +
+

+ + default(*args) + +

+ + +
+

Same as Hash#default where the key passed as argument can be either a string or a symbol:

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new(1)
+hash.default                   # => 1
+
+hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
+hash.default                   # => nil
+hash.default('foo')            # => 'foo'
+hash.default(:foo)             # => 'foo'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 219
+def default(*args)
+  super(*args.map { |arg| convert_key(arg) })
+end
+
+
+ +
+ +
+

+ + delete(key) + +

+ + +
+

Removes the specified key from the hash.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 293
+def delete(key)
+  super(convert_key(key))
+end
+
+
+ +
+ +
+

+ + dig(*args) + +

+ + +
+

Same as Hash#dig where the key passed as argument can be either a string or a symbol:

+ +
counters = ActiveSupport::HashWithIndifferentAccess.new
+counters[:foo] = { bar: 1 }
+
+counters.dig('foo', 'bar')     # => 1
+counters.dig(:foo, :bar)       # => 1
+counters.dig(:zoo)             # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 203
+def dig(*args)
+  args[0] = convert_key(args[0]) if args.size > 0
+  super(*args)
+end
+
+
+ +
+ +
+

+ + dup() + +

+ + +
+

Returns a shallow copy of the hash.

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
+dup  = hash.dup
+dup[:a][:c] = 'c'
+
+hash[:a][:c] # => "c"
+dup[:a][:c]  # => "c"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 254
+def dup
+  self.class.new(self).tap do |new_hash|
+    set_defaults(new_hash)
+  end
+end
+
+
+ +
+ +
+

+ + extractable_options?() + +

+ + +
+

Returns true so that Array#extract_options! finds members of this class.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 54
+def extractable_options?
+  true
+end
+
+
+ +
+ +
+

+ + fetch(key, *extras) + +

+ + +
+

Same as Hash#fetch where the key passed as argument can be either a string or a symbol:

+ +
counters = ActiveSupport::HashWithIndifferentAccess.new
+counters[:foo] = 1
+
+counters.fetch('foo')          # => 1
+counters.fetch(:bar, 0)        # => 0
+counters.fetch(:bar) { |key| 0 } # => 0
+counters.fetch(:zoo)           # => KeyError: key not found: "zoo"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 189
+def fetch(key, *extras)
+  super(convert_key(key), *extras)
+end
+
+
+ +
+ +
+

+ + fetch_values(*indices, &block) + +

+ + +
+

Returns an array of the values at the specified indices, but also raises an exception when one of the keys can't be found.

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new
+hash[:a] = 'x'
+hash[:b] = 'y'
+hash.fetch_values('a', 'b') # => ["x", "y"]
+hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
+hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 242
+def fetch_values(*indices, &block)
+  indices.collect { |key| fetch(key, &block) }
+end
+
+
+ +
+ +
+

+ + has_key?(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: key? +
+ + + +
+ +
+

+ + include?(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: key? +
+ + + +
+ +
+

+ + key?(key) + +

+ + +
+

Checks the hash for a key matching the argument passed in:

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new
+hash['key'] = 'value'
+hash.key?(:key)  # => true
+hash.key?('key') # => true
+
+
+ + + +
+ Also aliased as: include?, has_key?, member? +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 145
+def key?(key)
+  super(convert_key(key))
+end
+
+
+ +
+ +
+

+ + member?(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: key? +
+ + + +
+ +
+

+ + merge(hash, &block) + +

+ + +
+

This method has the same semantics of update, except it does not modify the receiver but rather returns a new hash with indifferent access with the result of the merge.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 263
+def merge(hash, &block)
+  dup.update(hash, &block)
+end
+
+
+ +
+ +
+

+ + merge!(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: update +
+ + + +
+ +
+

+ + nested_under_indifferent_access() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 62
+def nested_under_indifferent_access
+  self
+end
+
+
+ +
+ +
+

+ + regular_update(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: update +
+ + + +
+ +
+

+ + regular_writer(key, value) + +

+ + +
+ +
+ + + + + +
+ Alias for: []= +
+ + + +
+ +
+

+ + reject(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 313
+def reject(*args, &block)
+  return to_enum(:reject) unless block_given?
+  dup.tap { |hash| hash.reject!(*args, &block) }
+end
+
+
+ +
+ +
+

+ + replace(other_hash) + +

+ + +
+

Replaces the contents of this hash with other_hash.

+ +
h = { "a" => 100, "b" => 200 }
+h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 288
+def replace(other_hash)
+  super(self.class.new(other_hash))
+end
+
+
+ +
+ +
+

+ + reverse_merge(other_hash) + +

+ + +
+

Like merge but the other way around: Merges the receiver into the argument and returns a new hash with indifferent access as result:

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new
+hash['a'] = nil
+hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
+
+
+ + + +
+ Also aliased as: with_defaults +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 273
+def reverse_merge(other_hash)
+  super(self.class.new(other_hash))
+end
+
+
+ +
+ +
+

+ + reverse_merge!(other_hash) + +

+ + +
+

Same semantics as reverse_merge but modifies the receiver in-place.

+
+ + + +
+ Also aliased as: with_defaults! +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 279
+def reverse_merge!(other_hash)
+  super(self.class.new(other_hash))
+end
+
+
+ +
+ +
+

+ + select(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 308
+def select(*args, &block)
+  return to_enum(:select) unless block_given?
+  dup.tap { |hash| hash.select!(*args, &block) }
+end
+
+
+ +
+ +
+

+ + slice(*keys) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 336
+def slice(*keys)
+  keys.map! { |key| convert_key(key) }
+  self.class.new(super)
+end
+
+
+ +
+ +
+

+ + slice!(*keys) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 341
+def slice!(*keys)
+  keys.map! { |key| convert_key(key) }
+  super
+end
+
+
+ +
+ +
+

+ + store(key, value) + +

+ + +
+ +
+ + + + + +
+ Alias for: []= +
+ + + +
+ +
+

+ + stringify_keys() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 299
+def stringify_keys; dup end
+
+
+ +
+ +
+

+ + stringify_keys!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 297
+def stringify_keys!; self end
+
+
+ +
+ +
+

+ + symbolize_keys() + +

+ + +
+ +
+ + + +
+ Also aliased as: to_options +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 303
+def symbolize_keys; to_hash.symbolize_keys! end
+
+
+ +
+ +
+

+ + to_hash() + +

+ + +
+

Convert to a regular hash with string keys.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 351
+def to_hash
+  _new_hash = Hash.new
+  set_defaults(_new_hash)
+
+  each do |key, value|
+    _new_hash[key] = convert_value(value, for: :to_hash)
+  end
+  _new_hash
+end
+
+
+ +
+ +
+

+ + to_options() + +

+ + +
+ +
+ + + + + +
+ Alias for: symbolize_keys +
+ + + +
+ +
+

+ + to_options!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 306
+def to_options!; self end
+
+
+ +
+ +
+

+ + transform_keys(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 323
+def transform_keys(*args, &block)
+  return to_enum(:transform_keys) unless block_given?
+  dup.tap { |hash| hash.transform_keys!(*args, &block) }
+end
+
+
+ +
+ +
+

+ + transform_keys!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 328
+def transform_keys!
+  return enum_for(:transform_keys!) { size } unless block_given?
+  keys.each do |key|
+    self[yield(key)] = delete(key)
+  end
+  self
+end
+
+
+ +
+ +
+

+ + transform_values(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 318
+def transform_values(*args, &block)
+  return to_enum(:transform_values) unless block_given?
+  dup.tap { |hash| hash.transform_values!(*args, &block) }
+end
+
+
+ +
+ +
+

+ + update(other_hash) + +

+ + +
+

Updates the receiver in-place, merging in the hash passed as argument:

+ +
hash_1 = ActiveSupport::HashWithIndifferentAccess.new
+hash_1[:key] = 'value'
+
+hash_2 = ActiveSupport::HashWithIndifferentAccess.new
+hash_2[:key] = 'New Value!'
+
+hash_1.update(hash_2) # => {"key"=>"New Value!"}
+
+ +

The argument can be either an ActiveSupport::HashWithIndifferentAccess or a regular Hash. In either case the merge respects the semantics of indifferent access.

+ +

If the argument is a regular hash with keys :key and +“key”+ only one of the values end up in the receiver, but which one is unspecified.

+ +

When given a block, the value for duplicated keys will be determined by the result of invoking the block with the duplicated key, the value in the receiver, and the value in other_hash. The rules for duplicated keys follow the semantics of indifferent access:

+ +
hash_1[:key] = 10
+hash_2['key'] = 12
+hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
+
+
+ + + +
+ Also aliased as: regular_update, merge! +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 123
+def update(other_hash)
+  if other_hash.is_a? HashWithIndifferentAccess
+    super(other_hash)
+  else
+    other_hash.to_hash.each_pair do |key, value|
+      if block_given? && key?(key)
+        value = yield(convert_key(key), self[key], value)
+      end
+      regular_writer(convert_key(key), convert_value(value))
+    end
+    self
+  end
+end
+
+
+ +
+ +
+

+ + values_at(*indices) + +

+ + +
+

Returns an array of the values at the specified indices:

+ +
hash = ActiveSupport::HashWithIndifferentAccess.new
+hash[:a] = 'x'
+hash[:b] = 'y'
+hash.values_at('a', 'b') # => ["x", "y"]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 229
+def values_at(*indices)
+  indices.collect { |key| self[convert_key(key)] }
+end
+
+
+ +
+ +
+

+ + with_defaults(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge +
+ + + +
+ +
+

+ + with_defaults!(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge! +
+ + + +
+ +
+

+ + with_indifferent_access() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 58
+def with_indifferent_access
+  dup
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + convert_key(key) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 362
+def convert_key(key) # :doc:
+  key.kind_of?(Symbol) ? key.to_s : key
+end
+
+
+ +
+ +
+

+ + convert_value(value, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 366
+def convert_value(value, options = {}) # :doc:
+  if value.is_a? Hash
+    if options[:for] == :to_hash
+      value.to_hash
+    else
+      value.nested_under_indifferent_access
+    end
+  elsif value.is_a?(Array)
+    if options[:for] != :assignment || value.frozen?
+      value = value.dup
+    end
+    value.map! { |e| convert_value(e, options) }
+  else
+    value
+  end
+end
+
+
+ +
+ +
+

+ + set_defaults(target) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 383
+def set_defaults(target) # :doc:
+  if default_proc
+    target.default_proc = default_proc.dup
+  else
+    target.default = default
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Inflector.html b/src/5.2/classes/ActiveSupport/Inflector.html new file mode 100644 index 0000000000..0913a81a03 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Inflector.html @@ -0,0 +1,1243 @@ +--- +title: ActiveSupport::Inflector +layout: default +--- +
+ +
+
+ +
+ +

The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without, and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept in inflections.rb.

+ +

The Rails core team has stated patches for the inflections library will not be accepted in order to avoid breaking legacy applications which may be relying on errant inflections. If you discover an incorrect inflection and require it for your application or wish to define rules for languages other than English, please correct or add them yourself (explained below).

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + camelize(term, uppercase_first_letter = true) + +

+ + +
+

Converts strings to UpperCamelCase. If the uppercase_first_letter parameter is set to false, then produces lowerCamelCase.

+ +

Also converts '/' to '::' which is useful for converting paths to namespaces.

+ +
camelize('active_model')                # => "ActiveModel"
+camelize('active_model', false)         # => "activeModel"
+camelize('active_model/errors')         # => "ActiveModel::Errors"
+camelize('active_model/errors', false)  # => "activeModel::Errors"
+
+ +

As a rule of thumb you can think of camelize as the inverse of underscore, though there are cases where that does not hold:

+ +
camelize(underscore('SSLError'))        # => "SslError"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 69
+def camelize(term, uppercase_first_letter = true)
+  string = term.to_s
+  if uppercase_first_letter
+    string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize }
+  else
+    string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase }
+  end
+  string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
+  string.gsub!("/".freeze, "::".freeze)
+  string
+end
+
+
+ +
+ +
+

+ + classify(table_name) + +

+ + +
+

Creates a class name from a plural table name like Rails does for table names to models. Note that this returns a string and not a Class (To convert to an actual class follow classify with constantize).

+ +
classify('ham_and_eggs') # => "HamAndEgg"
+classify('posts')        # => "Post"
+
+ +

Singular names are not handled correctly:

+ +
classify('calculus')     # => "Calculus"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 201
+def classify(table_name)
+  # strip out any leading schema name
+  camelize(singularize(table_name.to_s.sub(/.*\./, "".freeze)))
+end
+
+
+ +
+ +
+

+ + constantize(camel_cased_word) + +

+ + +
+

Tries to find a constant with the name specified in the argument string.

+ +
constantize('Module')   # => Module
+constantize('Foo::Bar') # => Foo::Bar
+
+ +

The name is assumed to be the one of a top-level constant, no matter whether it starts with “::” or not. No lexical context is taken into account:

+ +
C = 'outside'
+module M
+  C = 'inside'
+  C                # => 'inside'
+  constantize('C') # => 'outside', same as ::C
+end
+
+ +

NameError is raised when the name is not in CamelCase or the constant is unknown.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 272
+def constantize(camel_cased_word)
+  names = camel_cased_word.split("::".freeze)
+
+  # Trigger a built-in NameError exception including the ill-formed constant in the message.
+  Object.const_get(camel_cased_word) if names.empty?
+
+  # Remove the first blank element in case of '::ClassName' notation.
+  names.shift if names.size > 1 && names.first.empty?
+
+  names.inject(Object) do |constant, name|
+    if constant == Object
+      constant.const_get(name)
+    else
+      candidate = constant.const_get(name)
+      next candidate if constant.const_defined?(name, false)
+      next candidate unless Object.const_defined?(name)
+
+      # Go down the ancestors to check if it is owned directly. The check
+      # stops when we reach Object or the end of ancestors tree.
+      constant = constant.ancestors.inject(constant) do |const, ancestor|
+        break const    if ancestor == Object
+        break ancestor if ancestor.const_defined?(name, false)
+        const
+      end
+
+      # owner is in Object, so raise
+      constant.const_get(name, false)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + dasherize(underscored_word) + +

+ + +
+

Replaces underscores with dashes in the string.

+ +
dasherize('puni_puni') # => "puni-puni"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 209
+def dasherize(underscored_word)
+  underscored_word.tr("_".freeze, "-".freeze)
+end
+
+
+ +
+ +
+

+ + deconstantize(path) + +

+ + +
+

Removes the rightmost segment from the constant expression in the string.

+ +
deconstantize('Net::HTTP')   # => "Net"
+deconstantize('::Net::HTTP') # => "::Net"
+deconstantize('String')      # => ""
+deconstantize('::String')    # => ""
+deconstantize('')            # => ""
+
+ +

See also demodulize.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 239
+def deconstantize(path)
+  path.to_s[0, path.rindex("::") || 0] # implementation based on the one in facets' Module#spacename
+end
+
+
+ +
+ +
+

+ + demodulize(path) + +

+ + +
+

Removes the module part from the expression in the string.

+ +
demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections"
+demodulize('Inflections')                           # => "Inflections"
+demodulize('::Inflections')                         # => "Inflections"
+demodulize('')                                      # => ""
+
+ +

See also deconstantize.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 221
+def demodulize(path)
+  path = path.to_s
+  if i = path.rindex("::")
+    path[(i + 2)..-1]
+  else
+    path
+  end
+end
+
+
+ +
+ +
+

+ + foreign_key(class_name, separate_class_name_and_id_with_underscore = true) + +

+ + +
+

Creates a foreign key name from a class name. separate_class_name_and_id_with_underscore sets whether the method should put '_' between the name and 'id'.

+ +
foreign_key('Message')        # => "message_id"
+foreign_key('Message', false) # => "messageid"
+foreign_key('Admin::Post')    # => "post_id"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 250
+def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
+  underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
+end
+
+
+ +
+ +
+

+ + humanize(lower_case_and_underscored_word, capitalize: true, keep_id_suffix: false) + +

+ + +
+

Tweaks an attribute name for display to end users.

+ +

Specifically, performs these transformations:

+
  • +

    Applies human inflection rules to the argument.

    +
  • +

    Deletes leading underscores, if any.

    +
  • +

    Removes a “_id” suffix if present.

    +
  • +

    Replaces underscores with spaces, if any.

    +
  • +

    Downcases all words except acronyms.

    +
  • +

    Capitalizes the first word.

    +
+ +

The capitalization of the first word can be turned off by setting the :capitalize option to false (default is true).

+ +

The trailing '_id' can be kept and capitalized by setting the optional parameter keep_id_suffix to true (default is false).

+ +
humanize('employee_salary')                  # => "Employee salary"
+humanize('author_id')                        # => "Author"
+humanize('author_id', capitalize: false)     # => "author"
+humanize('_id')                              # => "Id"
+humanize('author_id', keep_id_suffix: true)  # => "Author Id"
+
+ +

If “SSL” was defined to be an acronym:

+ +
humanize('ssl_error') # => "SSL error"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 129
+def humanize(lower_case_and_underscored_word, capitalize: true, keep_id_suffix: false)
+  result = lower_case_and_underscored_word.to_s.dup
+
+  inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
+
+  result.sub!(/\A_+/, "".freeze)
+  unless keep_id_suffix
+    result.sub!(/_id\z/, "".freeze)
+  end
+  result.tr!("_".freeze, " ".freeze)
+
+  result.gsub!(/([a-z\d]*)/i) do |match|
+    "#{inflections.acronyms[match.downcase] || match.downcase}"
+  end
+
+  if capitalize
+    result.sub!(/\A\w/) { |match| match.upcase }
+  end
+
+  result
+end
+
+
+ +
+ +
+

+ + inflections(locale = :en) + +

+ + +
+

Yields a singleton instance of Inflector::Inflections so you can specify additional inflector rules. If passed an optional locale, rules for other languages can be specified. If not specified, defaults to :en. Only rules for English are provided.

+ +
ActiveSupport::Inflector.inflections(:en) do |inflect|
+  inflect.uncountable 'rails'
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 252
+def inflections(locale = :en)
+  if block_given?
+    yield Inflections.instance(locale)
+  else
+    Inflections.instance(locale)
+  end
+end
+
+
+ +
+ +
+

+ + ordinal(number) + +

+ + +
+

Returns the suffix that should be added to a number to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.

+ +
ordinal(1)     # => "st"
+ordinal(2)     # => "nd"
+ordinal(1002)  # => "nd"
+ordinal(1003)  # => "rd"
+ordinal(-11)   # => "th"
+ordinal(-1021) # => "st"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 345
+def ordinal(number)
+  abs_number = number.to_i.abs
+
+  if (11..13).include?(abs_number % 100)
+    "th"
+  else
+    case abs_number % 10
+    when 1; "st"
+    when 2; "nd"
+    when 3; "rd"
+    else    "th"
+    end
+  end
+end
+
+
+ +
+ +
+

+ + ordinalize(number) + +

+ + +
+

Turns a number into an ordinal string used to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.

+ +
ordinalize(1)     # => "1st"
+ordinalize(2)     # => "2nd"
+ordinalize(1002)  # => "1002nd"
+ordinalize(1003)  # => "1003rd"
+ordinalize(-11)   # => "-11th"
+ordinalize(-1021) # => "-1021st"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 369
+def ordinalize(number)
+  "#{number}#{ordinal(number)}"
+end
+
+
+ +
+ +
+

+ + parameterize(string, separator: "-", preserve_case: false) + +

+ + +
+

Replaces special characters in a string so that it may be used as part of a 'pretty' URL.

+ +
parameterize("Donald E. Knuth") # => "donald-e-knuth"
+parameterize("^très|Jolie-- ")  # => "tres-jolie"
+
+ +

To use a custom separator, override the separator argument.

+ +
parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
+parameterize("^très|Jolie__ ", separator: '_')  # => "tres_jolie"
+
+ +

To preserve the case of the characters in a string, use the preserve_case argument.

+ +
parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
+parameterize("^très|Jolie-- ", preserve_case: true) # => "tres-Jolie"
+
+ +

It preserves dashes and underscores unless they are used as separators:

+ +
parameterize("^très|Jolie__ ")                 # => "tres-jolie__"
+parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
+parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/transliterate.rb, line 92
+def parameterize(string, separator: "-", preserve_case: false)
+  # Replace accented chars with their ASCII equivalents.
+  parameterized_string = transliterate(string)
+
+  # Turn unwanted chars into the separator.
+  parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
+
+  unless separator.nil? || separator.empty?
+    if separator == "-".freeze
+      re_duplicate_separator        = /-{2,}/
+      re_leading_trailing_separator = /^-|-$/i
+    else
+      re_sep = Regexp.escape(separator)
+      re_duplicate_separator        = /#{re_sep}{2,}/
+      re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/i
+    end
+    # No more than one of the separator in a row.
+    parameterized_string.gsub!(re_duplicate_separator, separator)
+    # Remove leading/trailing separator.
+    parameterized_string.gsub!(re_leading_trailing_separator, "".freeze)
+  end
+
+  parameterized_string.downcase! unless preserve_case
+  parameterized_string
+end
+
+
+ +
+ +
+

+ + pluralize(word, locale = :en) + +

+ + +
+

Returns the plural form of the word in the string.

+ +

If passed an optional locale parameter, the word will be pluralized using rules defined for that language. By default, this parameter is set to :en.

+ +
pluralize('post')             # => "posts"
+pluralize('octopus')          # => "octopi"
+pluralize('sheep')            # => "sheep"
+pluralize('words')            # => "words"
+pluralize('CamelOctopus')     # => "CamelOctopi"
+pluralize('ley', :es)         # => "leyes"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 32
+def pluralize(word, locale = :en)
+  apply_inflections(word, inflections(locale).plurals, locale)
+end
+
+
+ +
+ +
+

+ + safe_constantize(camel_cased_word) + +

+ + +
+

Tries to find a constant with the name specified in the argument string.

+ +
safe_constantize('Module')   # => Module
+safe_constantize('Foo::Bar') # => Foo::Bar
+
+ +

The name is assumed to be the one of a top-level constant, no matter whether it starts with “::” or not. No lexical context is taken into account:

+ +
C = 'outside'
+module M
+  C = 'inside'
+  C                     # => 'inside'
+  safe_constantize('C') # => 'outside', same as ::C
+end
+
+ +

nil is returned when the name is not in CamelCase or the constant (or part of it) is unknown.

+ +
safe_constantize('blargle')                  # => nil
+safe_constantize('UnknownModule')            # => nil
+safe_constantize('UnknownModule::Foo::Bar')  # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 325
+def safe_constantize(camel_cased_word)
+  constantize(camel_cased_word)
+rescue NameError => e
+  raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) ||
+    e.name.to_s == camel_cased_word.to_s)
+rescue ArgumentError => e
+  raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message)
+rescue LoadError => e
+  raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(e.message)
+end
+
+
+ +
+ +
+

+ + singularize(word, locale = :en) + +

+ + +
+

The reverse of pluralize, returns the singular form of a word in a string.

+ +

If passed an optional locale parameter, the word will be singularized using rules defined for that language. By default, this parameter is set to :en.

+ +
singularize('posts')            # => "post"
+singularize('octopi')           # => "octopus"
+singularize('sheep')            # => "sheep"
+singularize('word')             # => "word"
+singularize('CamelOctopi')      # => "CamelOctopus"
+singularize('leyes', :es)       # => "ley"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 49
+def singularize(word, locale = :en)
+  apply_inflections(word, inflections(locale).singulars, locale)
+end
+
+
+ +
+ +
+

+ + tableize(class_name) + +

+ + +
+

Creates the name of a table like Rails does for models to table names. This method uses the pluralize method on the last word in the string.

+ +
tableize('RawScaledScorer') # => "raw_scaled_scorers"
+tableize('ham_and_egg')     # => "ham_and_eggs"
+tableize('fancyCategory')   # => "fancy_categories"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 187
+def tableize(class_name)
+  pluralize(underscore(class_name))
+end
+
+
+ +
+ +
+

+ + titleize(word, keep_id_suffix: false) + +

+ + +
+

Capitalizes all the words and replaces some characters in the string to create a nicer looking title. titleize is meant for creating pretty output. It is not used in the Rails internals.

+ +

The trailing '_id','Id'.. can be kept and capitalized by setting the optional parameter keep_id_suffix to true. By default, this parameter is false.

+ +

titleize is also aliased as titlecase.

+ +
titleize('man from the boondocks')                       # => "Man From The Boondocks"
+titleize('x-men: the last stand')                        # => "X Men: The Last Stand"
+titleize('TheManWithoutAPast')                           # => "The Man Without A Past"
+titleize('raiders_of_the_lost_ark')                      # => "Raiders Of The Lost Ark"
+titleize('string_ending_with_id', keep_id_suffix: true)  # => "String Ending With Id"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 175
+def titleize(word, keep_id_suffix: false)
+  humanize(underscore(word), keep_id_suffix: keep_id_suffix).gsub(/\b(?<!\w['’`])[a-z]/) do |match|
+    match.capitalize
+  end
+end
+
+
+ +
+ +
+

+ + transliterate(string, replacement = "?".freeze) + +

+ + +
+

Replaces non-ASCII characters with an ASCII approximation, or if none exists, a replacement character which defaults to “?”.

+ +
transliterate('Ærøskøbing')
+# => "AEroskobing"
+
+ +

Default approximations are provided for Western/Latin characters, e.g, “ø”, “ñ”, “é”, “ß”, etc.

+ +

This method is I18n aware, so you can set up custom approximations for a locale. This can be useful, for example, to transliterate German's “ü” and “ö” to “ue” and “oe”, or to add support for transliterating Russian to ASCII.

+ +

In order to make your custom transliterations available, you must set them as the i18n.transliterate.rule i18n key:

+ +
# Store the transliterations in locales/de.yml
+i18n:
+  transliterate:
+    rule:
+      ü: "ue"
+      ö: "oe"
+
+# Or set them using Ruby
+I18n.backend.store_translations(:de, i18n: {
+  transliterate: {
+    rule: {
+      'ü' => 'ue',
+      'ö' => 'oe'
+    }
+  }
+})
+
+ +

The value for i18n.transliterate.rule can be a simple Hash that maps characters to ASCII approximations as shown above, or, for more complex requirements, a Proc:

+ +
I18n.backend.store_translations(:de, i18n: {
+  transliterate: {
+    rule: ->(string) { MyTransliterator.transliterate(string) }
+  }
+})
+
+ +

Now you can have different transliterations for each locale:

+ +
I18n.locale = :en
+transliterate('Jürgen')
+# => "Jurgen"
+
+I18n.locale = :de
+transliterate('Jürgen')
+# => "Juergen"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/transliterate.rb, line 61
+def transliterate(string, replacement = "?".freeze)
+  raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
+
+  I18n.transliterate(
+    ActiveSupport::Multibyte::Unicode.normalize(
+      ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
+    replacement: replacement)
+end
+
+
+ +
+ +
+

+ + underscore(camel_cased_word) + +

+ + +
+

Makes an underscored, lowercase form from the expression in the string.

+ +

Changes '::' to '/' to convert namespaces to paths.

+ +
underscore('ActiveModel')         # => "active_model"
+underscore('ActiveModel::Errors') # => "active_model/errors"
+
+ +

As a rule of thumb you can think of underscore as the inverse of camelize, though there are cases where that does not hold:

+ +
camelize(underscore('SSLError'))  # => "SslError"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 92
+def underscore(camel_cased_word)
+  return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
+  word = camel_cased_word.to_s.gsub("::".freeze, "/".freeze)
+  word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_'.freeze }#{$2.downcase}" }
+  word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
+  word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
+  word.tr!("-".freeze, "_".freeze)
+  word.downcase!
+  word
+end
+
+
+ +
+ +
+

+ + upcase_first(string) + +

+ + +
+

Converts just the first character to uppercase.

+ +
upcase_first('what a Lovely Day') # => "What a Lovely Day"
+upcase_first('w')                 # => "W"
+upcase_first('')                  # => ""
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/methods.rb, line 156
+def upcase_first(string)
+  string.length > 0 ? string[0].upcase.concat(string[1..-1]) : ""
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Inflector/Inflections.html b/src/5.2/classes/ActiveSupport/Inflector/Inflections.html new file mode 100644 index 0000000000..a4cd09856e --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Inflector/Inflections.html @@ -0,0 +1,601 @@ +--- +title: ActiveSupport::Inflector::Inflections +layout: default +--- +
+ +
+
+ +
+ +

A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional inflection rules. If passed an optional locale, rules for other languages can be specified. The default locale is :en. Only rules for English are provided.

+ +
ActiveSupport::Inflector.inflections(:en) do |inflect|
+  inflect.plural /^(ox)$/i, '\1\2en'
+  inflect.singular /^(ox)en/i, '\1'
+
+  inflect.irregular 'octopus', 'octopi'
+
+  inflect.uncountable 'equipment'
+end
+
+ +

New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may already have been loaded.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + acronym_regex
+ [R] + acronyms
+ [R] + humans
+ [R] + plurals
+ [R] + singulars
+ [R] + uncountables
+ + + + +

Class Public methods

+ +
+

+ + instance(locale = :en) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 66
+def self.instance(locale = :en)
+  @__instance__[locale] ||= new
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 75
+def initialize
+  @plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
+  define_acronym_regex_patterns
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + acronym(word) + +

+ + +
+

Specifies a new acronym. An acronym must be specified as it will appear in a camelized string. An underscore string that contains the acronym will retain the acronym when passed to camelize, humanize, or titleize. A camelized string that contains the acronym will maintain the acronym when titleized or humanized, and will convert the acronym into a non-delimited single lowercase word when passed to underscore.

+ +
acronym 'HTML'
+titleize 'html'     # => 'HTML'
+camelize 'html'     # => 'HTML'
+underscore 'MyHTML' # => 'my_html'
+
+ +

The acronym, however, must occur as a delimited unit and not be part of another word for conversions to recognize it:

+ +
acronym 'HTTP'
+camelize 'my_http_delimited' # => 'MyHTTPDelimited'
+camelize 'https'             # => 'Https', not 'HTTPs'
+underscore 'HTTPS'           # => 'http_s', not 'https'
+
+acronym 'HTTPS'
+camelize 'https'   # => 'HTTPS'
+underscore 'HTTPS' # => 'https'
+
+ +

Note: Acronyms that are passed to pluralize will no longer be recognized, since the acronym will not occur as a delimited unit in the pluralized result. To work around this, you must specify the pluralized form as an acronym as well:

+ +
acronym 'API'
+camelize(pluralize('api')) # => 'Apis'
+
+acronym 'APIs'
+camelize(pluralize('api')) # => 'APIs'
+
+ +

acronym may be used to specify any word that contains an acronym or otherwise needs to maintain a non-standard capitalization. The only restriction is that the word must begin with a capital letter.

+ +
acronym 'RESTful'
+underscore 'RESTful'           # => 'restful'
+underscore 'RESTfulController' # => 'restful_controller'
+titleize 'RESTfulController'   # => 'RESTful Controller'
+camelize 'restful'             # => 'RESTful'
+camelize 'restful_controller'  # => 'RESTfulController'
+
+acronym 'McDonald'
+underscore 'McDonald' # => 'mcdonald'
+camelize 'mcdonald'   # => 'McDonald'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 137
+def acronym(word)
+  @acronyms[word.downcase] = word
+  define_acronym_regex_patterns
+end
+
+
+ +
+ +
+

+ + clear(scope = :all) + +

+ + +
+

Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type, the options are: :plurals, :singulars, :uncountables, :humans.

+ +
clear :all
+clear :plurals
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 226
+def clear(scope = :all)
+  case scope
+  when :all
+    @plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
+  else
+    instance_variable_set "@#{scope}", []
+  end
+end
+
+
+ +
+ +
+

+ + human(rule, replacement) + +

+ + +
+

Specifies a humanized form of a string by a regular expression rule or by a string mapping. When using a regular expression based replacement, the normal humanize formatting is called after the replacement. When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name').

+ +
human /_cnt$/i, '\1_count'
+human 'legacy_col_person_name', 'Name'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 215
+def human(rule, replacement)
+  @humans.prepend([rule, replacement])
+end
+
+
+ +
+ +
+

+ + irregular(singular, plural) + +

+ + +
+

Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used for strings, not regular expressions. You simply pass the irregular in singular and plural form.

+ +
irregular 'octopus', 'octopi'
+irregular 'person', 'people'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 169
+def irregular(singular, plural)
+  @uncountables.delete(singular)
+  @uncountables.delete(plural)
+
+  s0 = singular[0]
+  srest = singular[1..-1]
+
+  p0 = plural[0]
+  prest = plural[1..-1]
+
+  if s0.upcase == p0.upcase
+    plural(/(#{s0})#{srest}$/i, '\1' + prest)
+    plural(/(#{p0})#{prest}$/i, '\1' + prest)
+
+    singular(/(#{s0})#{srest}$/i, '\1' + srest)
+    singular(/(#{p0})#{prest}$/i, '\1' + srest)
+  else
+    plural(/#{s0.upcase}(?i)#{srest}$/,   p0.upcase   + prest)
+    plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest)
+    plural(/#{p0.upcase}(?i)#{prest}$/,   p0.upcase   + prest)
+    plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest)
+
+    singular(/#{s0.upcase}(?i)#{srest}$/,   s0.upcase   + srest)
+    singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest)
+    singular(/#{p0.upcase}(?i)#{prest}$/,   s0.upcase   + srest)
+    singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest)
+  end
+end
+
+
+ +
+ +
+

+ + plural(rule, replacement) + +

+ + +
+

Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression. The replacement should always be a string that may include references to the matched data from the rule.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 146
+def plural(rule, replacement)
+  @uncountables.delete(rule) if rule.is_a?(String)
+  @uncountables.delete(replacement)
+  @plurals.prepend([rule, replacement])
+end
+
+
+ +
+ +
+

+ + singular(rule, replacement) + +

+ + +
+

Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression. The replacement should always be a string that may include references to the matched data from the rule.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 156
+def singular(rule, replacement)
+  @uncountables.delete(rule) if rule.is_a?(String)
+  @uncountables.delete(replacement)
+  @singulars.prepend([rule, replacement])
+end
+
+
+ +
+ +
+

+ + uncountable(*words) + +

+ + +
+

Specifies words that are uncountable and should not be inflected.

+ +
uncountable 'money'
+uncountable 'money', 'information'
+uncountable %w( money information rice )
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 203
+def uncountable(*words)
+  @uncountables.add(words)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Inflector/Inflections/Uncountables.html b/src/5.2/classes/ActiveSupport/Inflector/Inflections/Uncountables.html new file mode 100644 index 0000000000..89806d7ec0 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Inflector/Inflections/Uncountables.html @@ -0,0 +1,271 @@ +--- +title: ActiveSupport::Inflector::Inflections::Uncountables +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 35
+def initialize
+  @regex_array = []
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(*word) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 45
+def <<(*word)
+  add(word)
+end
+
+
+ +
+ +
+

+ + add(words) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 49
+def add(words)
+  words = words.flatten.map(&:downcase)
+  concat(words)
+  @regex_array += words.map { |word| to_regex(word) }
+  self
+end
+
+
+ +
+ +
+

+ + delete(entry) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 40
+def delete(entry)
+  super entry
+  @regex_array.delete(to_regex(entry))
+end
+
+
+ +
+ +
+

+ + uncountable?(str) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/inflector/inflections.rb, line 56
+def uncountable?(str)
+  @regex_array.any? { |regex| regex.match? str }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/InheritableOptions.html b/src/5.2/classes/ActiveSupport/InheritableOptions.html new file mode 100644 index 0000000000..d91ca6c633 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/InheritableOptions.html @@ -0,0 +1,169 @@ +--- +title: ActiveSupport::InheritableOptions +layout: default +--- +
+ +
+
+ +
+ +

InheritableOptions provides a constructor to build an OrderedOptions hash inherited from another hash.

+ +

Use this if you already have some hash and you want to create a new one based on it.

+ +
h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' })
+h.girl # => 'Mary'
+h.boy  # => 'John'
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(parent = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_options.rb, line 70
+def initialize(parent = nil)
+  if parent.kind_of?(OrderedOptions)
+    # use the faster _get when dealing with OrderedOptions
+    super() { |h, k| parent._get(k) }
+  elsif parent
+    super() { |h, k| parent[k] }
+  else
+    super()
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + inheritable_copy() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_options.rb, line 81
+def inheritable_copy
+  self.class.new(self)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/JSON.html b/src/5.2/classes/ActiveSupport/JSON.html new file mode 100644 index 0000000000..06e6a25ead --- /dev/null +++ b/src/5.2/classes/ActiveSupport/JSON.html @@ -0,0 +1,234 @@ +--- +title: ActiveSupport::JSON +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DATETIME_REGEX=/^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/
 
DATE_REGEX=/^\d{4}-\d{2}-\d{2}$/
 

matches YAML-formatted dates

+ + + + + + +

Class Public methods

+ +
+

+ + decode(json) + +

+ + +
+

Parses a JSON string (JavaScript Object Notation) into a hash. See www.json.org for more info.

+ +
ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
+=> {"team" => "rails", "players" => "36"}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/json/decoding.rb, line 22
+def decode(json)
+  data = ::JSON.parse(json, quirks_mode: true)
+
+  if ActiveSupport.parse_json_times
+    convert_dates_from(data)
+  else
+    data
+  end
+end
+
+
+ +
+ +
+

+ + encode(value, options = nil) + +

+ + +
+

Dumps objects in JSON (JavaScript Object Notation). See www.json.org for more info.

+ +
ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
+# => "{\"team\":\"rails\",\"players\":\"36\"}"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/json/encoding.rb, line 21
+def self.encode(value, options = nil)
+  Encoding.json_encoder.new(options).encode(value)
+end
+
+
+ +
+ +
+

+ + parse_error() + +

+ + +
+

Returns the class of the error that will be raised when there is an error in decoding JSON. Using this method means you won't directly depend on the ActiveSupport's JSON implementation, in case it changes in the future.

+ +
begin
+  obj = ActiveSupport::JSON.decode(some_string)
+rescue ActiveSupport::JSON.parse_error
+  Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}")
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/json/decoding.rb, line 42
+def parse_error
+  ::JSON::ParserError
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/KeyGenerator.html b/src/5.2/classes/ActiveSupport/KeyGenerator.html new file mode 100644 index 0000000000..c81e1bea0f --- /dev/null +++ b/src/5.2/classes/ActiveSupport/KeyGenerator.html @@ -0,0 +1,158 @@ +--- +title: ActiveSupport::KeyGenerator +layout: default +--- +
+ +
+
+ +
+ +

KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2. It can be used to derive a number of keys for various purposes from a given secret. This lets Rails applications have a single secure secret, but avoid reusing that key in multiple incompatible contexts.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(secret, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/key_generator.rb, line 12
+def initialize(secret, options = {})
+  @secret = secret
+  # The default iterations are higher than required for our key derivation uses
+  # on the off chance someone uses this for password storage
+  @iterations = options[:iterations] || 2**16
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + generate_key(salt, key_size = 64) + +

+ + +
+

Returns a derived key suitable for use. The default key_size is chosen to be compatible with the default settings of ActiveSupport::MessageVerifier. i.e. OpenSSL::Digest::SHA1#block_length

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/key_generator.rb, line 22
+def generate_key(salt, key_size = 64)
+  OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/LazyLoadHooks.html b/src/5.2/classes/ActiveSupport/LazyLoadHooks.html new file mode 100644 index 0000000000..2462625509 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/LazyLoadHooks.html @@ -0,0 +1,175 @@ +--- +title: ActiveSupport::LazyLoadHooks +layout: default +--- +
+ +
+
+ +
+ +

lazy_load_hooks allows Rails to lazily load a lot of components and thus making the app boot faster. Because of this feature now there is no need to require ActiveRecord::Base at boot time purely to apply configuration. Instead a hook is registered that applies configuration once ActiveRecord::Base is loaded. Here ActiveRecord::Base is used as example but this feature can be applied elsewhere too.

+ +

Here is an example where on_load method is called to register a hook.

+ +
initializer 'active_record.initialize_timezone' do
+  ActiveSupport.on_load(:active_record) do
+    self.time_zone_aware_attributes = true
+    self.default_timezone = :utc
+  end
+end
+
+ +

When the entirety of ActiveRecord::Base has been evaluated then run_load_hooks is invoked. The very last line of ActiveRecord::Base is:

+ +
ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + on_load(name, options = {}, &block) + +

+ + +
+

Declares a block that will be executed when a Rails component is fully loaded.

+ +

Options:

+
  • +

    :yield - Yields the object that run_load_hooks to block.

    +
  • +

    :run_once - Given block will run only once.

    +
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/lazy_load_hooks.rb, line 41
+def on_load(name, options = {}, &block)
+  @loaded[name].each do |base|
+    execute_hook(name, base, options, block)
+  end
+
+  @load_hooks[name] << [block, options]
+end
+
+
+ +
+ +
+

+ + run_load_hooks(name, base = Object) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/lazy_load_hooks.rb, line 49
+def run_load_hooks(name, base = Object)
+  @loaded[name] << base
+  @load_hooks[name].each do |hook, options|
+    execute_hook(name, base, options, hook)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/LogSubscriber.html b/src/5.2/classes/ActiveSupport/LogSubscriber.html new file mode 100644 index 0000000000..154cb596a2 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/LogSubscriber.html @@ -0,0 +1,539 @@ +--- +title: ActiveSupport::LogSubscriber +layout: default +--- +
+ +
+
+ +
+ +

ActiveSupport::LogSubscriber is an object set to consume ActiveSupport::Notifications with the sole purpose of logging them. The log subscriber dispatches notifications to a registered object based on its given namespace.

+ +

An example would be Active Record log subscriber responsible for logging queries:

+ +
module ActiveRecord
+  class LogSubscriber < ActiveSupport::LogSubscriber
+    def sql(event)
+      "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
+    end
+  end
+end
+
+ +

And it's finally registered as:

+ +
ActiveRecord::LogSubscriber.attach_to :active_record
+
+ +

Since we need to know all instance methods before attaching the log subscriber, the line above should be called after your ActiveRecord::LogSubscriber definition.

+ +

After configured, whenever a “sql.active_record” notification is published, it will properly dispatch the event (ActiveSupport::Notifications::Event) to the sql method.

+ +

Log subscriber also has some helpers to deal with logging and automatically flushes all logs when the request finishes (via action_dispatch.callback notification) in a Rails environment.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BLACK="\e[30m"
 

Colors

BLUE="\e[34m"
 
BOLD="\e[1m"
 
CLEAR="\e[0m"
 

Embed in a String to clear all previous ANSI sequences.

CYAN="\e[36m"
 
GREEN="\e[32m"
 
MAGENTA="\e[35m"
 
RED="\e[31m"
 
WHITE="\e[37m"
 
YELLOW="\e[33m"
 
+ + + + +

Attributes

+ + + + + + + + +
+ [W] + logger
+ + + + +

Class Public methods

+ +
+

+ + flush_all!() + +

+ + +
+

Flush all log_subscribers' logger.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber.rb, line 70
+def flush_all!
+  logger.flush if logger.respond_to?(:flush)
+end
+
+
+ +
+ +
+

+ + log_subscribers() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber.rb, line 65
+def log_subscribers
+  subscribers
+end
+
+
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber.rb, line 57
+def logger
+  @logger ||= if defined?(Rails) && Rails.respond_to?(:logger)
+    Rails.logger
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + finish(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber.rb, line 83
+def finish(name, id, payload)
+  super if logger
+rescue => e
+  if logger
+    logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
+  end
+end
+
+
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber.rb, line 75
+def logger
+  LogSubscriber.logger
+end
+
+
+ +
+ +
+

+ + start(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber.rb, line 79
+def start(name, id, payload)
+  super if logger
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + color(text, color, bold = false) + +

+ + +
+

Set color by using a symbol or one of the defined constants. If a third option is set to true, it also adds bold to the string. This is based on the Highline implementation and will automatically append CLEAR to the end of the returned String.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber.rb, line 105
+def color(text, color, bold = false) # :doc:
+  return text unless colorize_logging
+  color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
+  bold  = bold ? BOLD : ""
+  "#{bold}#{color}#{text}#{CLEAR}"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper.html b/src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper.html new file mode 100644 index 0000000000..f1ccf412a1 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper.html @@ -0,0 +1,185 @@ +--- +title: ActiveSupport::LogSubscriber::TestHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides some helpers to deal with testing log subscribers by setting up notifications. Take for instance Active Record subscriber tests:

+ +
class SyncLogSubscriberTest < ActiveSupport::TestCase
+  include ActiveSupport::LogSubscriber::TestHelper
+
+  setup do
+    ActiveRecord::LogSubscriber.attach_to(:active_record)
+  end
+
+  def test_basic_query_logging
+    Developer.all.to_a
+    wait
+    assert_equal 1, @logger.logged(:debug).size
+    assert_match(/Developer Load/, @logger.logged(:debug).last)
+    assert_match(/SELECT \* FROM "developers"/, @logger.logged(:debug).last)
+  end
+end
+
+ +

All you need to do is to ensure that your log subscriber is added to Rails::Subscriber, as in the second line of the code above. The test helpers are responsible for setting up the queue, subscriptions and turning colors in logs off.

+ +

The messages are available in the @logger instance, which is a logger with limited powers (it actually does not send anything to your output), and you can collect them doing @logger.logged(level), where level is the level used in logging, like info, debug, warn and so on.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + set_logger(logger) + +

+ + +
+

Overwrite if you use another logger in your log subscriber.

+ +
def logger
+  ActiveRecord::Base.logger = @logger
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 101
+def set_logger(logger)
+  ActiveSupport::LogSubscriber.logger = logger
+end
+
+
+ +
+ +
+

+ + wait() + +

+ + +
+

Wait notifications to be published.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 92
+def wait
+  @notifier.wait
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper/MockLogger.html b/src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper/MockLogger.html new file mode 100644 index 0000000000..e6605fcd46 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/LogSubscriber/TestHelper/MockLogger.html @@ -0,0 +1,267 @@ +--- +title: ActiveSupport::LogSubscriber::TestHelper::MockLogger +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + ActiveSupport::Logger::Severity + +
  • + +
+ + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + flush_count
+ [RW] + level
+ + + + +

Class Public methods

+ +
+

+ + new(level = DEBUG) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 60
+def initialize(level = DEBUG)
+  @flush_count = 0
+  @level = level
+  @logged = Hash.new { |h, k| h[k] = [] }
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + flush() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 78
+def flush
+  @flush_count += 1
+end
+
+
+ +
+ +
+

+ + logged(level) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 74
+def logged(level)
+  @logged[level].compact.map { |l| l.to_s.strip }
+end
+
+
+ +
+ +
+

+ + method_missing(level, message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 66
+def method_missing(level, message = nil)
+  if block_given?
+    @logged[level] << yield
+  else
+    @logged[level] << message
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Logger.html b/src/5.2/classes/ActiveSupport/Logger.html new file mode 100644 index 0000000000..2c07d8a92a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Logger.html @@ -0,0 +1,231 @@ +--- +title: ActiveSupport::Logger +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + logger_outputs_to?(logger, *sources) + +

+ + +
+

Returns true if the logger destination matches one of the sources

+ +
logger = Logger.new(STDOUT)
+ActiveSupport::Logger.logger_outputs_to?(logger, STDOUT)
+# => true
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/logger.rb, line 17
+def self.logger_outputs_to?(logger, *sources)
+  logdev = logger.instance_variable_get("@logdev")
+  logger_source = logdev.dev if logdev.respond_to?(:dev)
+  sources.any? { |source| source == logger_source }
+end
+
+
+ +
+ +
+

+ + new(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/logger.rb, line 81
+def initialize(*args)
+  super
+  @formatter = SimpleFormatter.new
+  after_initialize if respond_to? :after_initialize
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(severity, message = nil, progname = nil, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/logger.rb, line 87
+def add(severity, message = nil, progname = nil, &block)
+  return true if @logdev.nil? || (severity || UNKNOWN) < level
+  super
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Logger/SimpleFormatter.html b/src/5.2/classes/ActiveSupport/Logger/SimpleFormatter.html new file mode 100644 index 0000000000..04cbdeea1b --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Logger/SimpleFormatter.html @@ -0,0 +1,113 @@ +--- +title: ActiveSupport::Logger::SimpleFormatter +layout: default +--- +
+ +
+
+ +
+ +

Simple formatter which only displays the message.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + call(severity, timestamp, progname, msg) + +

+ + +
+

This method is invoked when a log event occurs

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/logger.rb, line 103
+def call(severity, timestamp, progname, msg)
+  "#{String === msg ? msg : msg.inspect}\n"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/MessageEncryptor.html b/src/5.2/classes/ActiveSupport/MessageEncryptor.html new file mode 100644 index 0000000000..fce6b40dd7 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/MessageEncryptor.html @@ -0,0 +1,350 @@ +--- +title: ActiveSupport::MessageEncryptor +layout: default +--- +
+ +
+
+ +
+ +

MessageEncryptor is a simple way to encrypt values which get stored somewhere you don't trust.

+ +

The cipher text and initialization vector are base64 encoded and returned to you.

+ +

This can be used in situations similar to the MessageVerifier, but where you don't want users to be able to determine the value of the payload.

+ +
len   = ActiveSupport::MessageEncryptor.key_len
+salt  = SecureRandom.random_bytes(len)
+key   = ActiveSupport::KeyGenerator.new('password').generate_key(salt, len) # => "\x89\xE0\x156\xAC..."
+crypt = ActiveSupport::MessageEncryptor.new(key)                            # => #<ActiveSupport::MessageEncryptor ...>
+encrypted_data = crypt.encrypt_and_sign('my secret data')                   # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
+crypt.decrypt_and_verify(encrypted_data)                                    # => "my secret data"
+
+ +

Confining messages to a specific purpose

+ +

By default any message can be used throughout your app. But they can also be confined to a specific :purpose.

+ +
token = crypt.encrypt_and_sign("this is the chair", purpose: :login)
+
+ +

Then that same purpose must be passed when verifying to get the data back out:

+ +
crypt.decrypt_and_verify(token, purpose: :login)    # => "this is the chair"
+crypt.decrypt_and_verify(token, purpose: :shipping) # => nil
+crypt.decrypt_and_verify(token)                     # => nil
+
+ +

Likewise, if a message has no purpose it won't be returned when verifying with a specific purpose.

+ +
token = crypt.encrypt_and_sign("the conversation is lively")
+crypt.decrypt_and_verify(token, purpose: :scare_tactics) # => nil
+crypt.decrypt_and_verify(token)                          # => "the conversation is lively"
+
+ +

Making messages expire

+ +

By default messages last forever and verifying one year from now will still return the original value. But messages can be set to expire at a given time with :expires_in or :expires_at.

+ +
crypt.encrypt_and_sign(parcel, expires_in: 1.month)
+crypt.encrypt_and_sign(doowad, expires_at: Time.now.end_of_year)
+
+ +

Then the messages can be verified and returned upto the expire time. Thereafter, verifying returns nil.

+ +

Rotating keys

+ +

MessageEncryptor also supports rotating out old configurations by falling back to a stack of encryptors. Call rotate to build and add an encryptor so decrypt_and_verify will also try the fallback.

+ +

By default any rotated encryptors use the values of the primary encryptor unless specified otherwise.

+ +

You'd give your encryptor the new defaults:

+ +
crypt = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm")
+
+ +

Then gradually rotate the old values out by adding them as fallbacks. Any message generated with the old values will then work until the rotation is removed.

+ +
crypt.rotate old_secret            # Fallback to an old secret instead of @secret.
+crypt.rotate cipher: "aes-256-cbc" # Fallback to an old cipher instead of aes-256-gcm.
+
+ +

Though if both the secret and the cipher was changed at the same time, the above should be combined into:

+ +
crypt.rotate old_secret, cipher: "aes-256-cbc"
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
OpenSSLCipherError=OpenSSL::Cipher::CipherError
 
+ + + + + + +

Class Public methods

+ +
+

+ + key_len(cipher = default_cipher) + +

+ + +
+

Given a cipher, returns the key length of the cipher to help generate the key of desired size

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_encryptor.rb, line 161
+def self.key_len(cipher = default_cipher)
+  OpenSSL::Cipher.new(cipher).key_len
+end
+
+
+ +
+ +
+

+ + new(secret, *signature_key_or_options) + +

+ + +
+

Initialize a new MessageEncryptor. secret must be at least as long as the cipher key size. For the default 'aes-256-gcm' cipher, this is 256 bits. If you are using a user-entered secret, you can generate a suitable key by using ActiveSupport::KeyGenerator or a similar key derivation function.

+ +

First additional parameter is used as the signature key for MessageVerifier. This allows you to specify keys to encrypt and sign data.

+ +
ActiveSupport::MessageEncryptor.new('secret', 'signature_secret')
+
+ +

Options:

+
  • +

    :cipher - Cipher to use. Can be any cipher returned by OpenSSL::Cipher.ciphers. Default is 'aes-256-gcm'.

    +
  • +

    :digest - String of digest to use for signing. Default is SHA1. Ignored when using an AEAD cipher like 'aes-256-gcm'.

    +
  • +

    :serializer - Object serializer to use. Default is Marshal.

    +
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_encryptor.rb, line 137
+def initialize(secret, *signature_key_or_options)
+  options = signature_key_or_options.extract_options!
+  sign_secret = signature_key_or_options.first
+  @secret = secret
+  @sign_secret = sign_secret
+  @cipher = options[:cipher] || self.class.default_cipher
+  @digest = options[:digest] || "SHA1" unless aead_mode?
+  @verifier = resolve_verifier
+  @serializer = options[:serializer] || Marshal
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + decrypt_and_verify(data, purpose: nil, **) + +

+ + +
+

Decrypt and verify a message. We need to verify the message in order to avoid padding attacks. Reference: www.limited-entropy.com/padding-oracle-attacks/.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_encryptor.rb, line 156
+def decrypt_and_verify(data, purpose: nil, **)
+  _decrypt(verifier.verify(data), purpose)
+end
+
+
+ +
+ +
+

+ + encrypt_and_sign(value, expires_at: nil, expires_in: nil, purpose: nil) + +

+ + +
+

Encrypt and sign a message. We need to sign the message in order to avoid padding attacks. Reference: www.limited-entropy.com/padding-oracle-attacks/.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_encryptor.rb, line 150
+def encrypt_and_sign(value, expires_at: nil, expires_in: nil, purpose: nil)
+  verifier.generate(_encrypt(value, expires_at: expires_at, expires_in: expires_in, purpose: purpose))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/MessageEncryptor/InvalidMessage.html b/src/5.2/classes/ActiveSupport/MessageEncryptor/InvalidMessage.html new file mode 100644 index 0000000000..9e7353e8cc --- /dev/null +++ b/src/5.2/classes/ActiveSupport/MessageEncryptor/InvalidMessage.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::MessageEncryptor::InvalidMessage +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/MessageVerifier.html b/src/5.2/classes/ActiveSupport/MessageVerifier.html new file mode 100644 index 0000000000..f6486fa040 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/MessageVerifier.html @@ -0,0 +1,437 @@ +--- +title: ActiveSupport::MessageVerifier +layout: default +--- +
+ +
+
+ +
+ +

MessageVerifier makes it easy to generate and verify messages which are signed to prevent tampering.

+ +

This is useful for cases like remember-me tokens and auto-unsubscribe links where the session store isn't suitable or available.

+ +

Remember Me:

+ +
cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
+
+ +

In the authentication filter:

+ +
id, time = @verifier.verify(cookies[:remember_me])
+if Time.now < time
+  self.current_user = User.find(id)
+end
+
+ +

By default it uses Marshal to serialize the message. If you want to use another serialization method, you can set the serializer in the options hash upon initialization:

+ +
@verifier = ActiveSupport::MessageVerifier.new('s3Krit', serializer: YAML)
+
+ +

MessageVerifier creates HMAC signatures using SHA1 hash algorithm by default. If you want to use a different hash algorithm, you can change it by providing :digest key as an option while initializing the verifier:

+ +
@verifier = ActiveSupport::MessageVerifier.new('s3Krit', digest: 'SHA256')
+
+ +

Confining messages to a specific purpose

+ +

By default any message can be used throughout your app. But they can also be confined to a specific :purpose.

+ +
token = @verifier.generate("this is the chair", purpose: :login)
+
+ +

Then that same purpose must be passed when verifying to get the data back out:

+ +
@verifier.verified(token, purpose: :login)    # => "this is the chair"
+@verifier.verified(token, purpose: :shipping) # => nil
+@verifier.verified(token)                     # => nil
+
+@verifier.verify(token, purpose: :login)      # => "this is the chair"
+@verifier.verify(token, purpose: :shipping)   # => ActiveSupport::MessageVerifier::InvalidSignature
+@verifier.verify(token)                       # => ActiveSupport::MessageVerifier::InvalidSignature
+
+ +

Likewise, if a message has no purpose it won't be returned when verifying with a specific purpose.

+ +
token = @verifier.generate("the conversation is lively")
+@verifier.verified(token, purpose: :scare_tactics) # => nil
+@verifier.verified(token)                          # => "the conversation is lively"
+
+@verifier.verify(token, purpose: :scare_tactics)   # => ActiveSupport::MessageVerifier::InvalidSignature
+@verifier.verify(token)                            # => "the conversation is lively"
+
+ +

Making messages expire

+ +

By default messages last forever and verifying one year from now will still return the original value. But messages can be set to expire at a given time with :expires_in or :expires_at.

+ +
@verifier.generate(parcel, expires_in: 1.month)
+@verifier.generate(doowad, expires_at: Time.now.end_of_year)
+
+ +

Then the messages can be verified and returned upto the expire time. Thereafter, the verified method returns nil while verify raises ActiveSupport::MessageVerifier::InvalidSignature.

+ +

Rotating keys

+ +

MessageVerifier also supports rotating out old configurations by falling back to a stack of verifiers. Call rotate to build and add a verifier to so either verified or verify will also try verifying with the fallback.

+ +

By default any rotated verifiers use the values of the primary verifier unless specified otherwise.

+ +

You'd give your verifier the new defaults:

+ +
verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA512", serializer: JSON)
+
+ +

Then gradually rotate the old values out by adding them as fallbacks. Any message generated with the old values will then work until the rotation is removed.

+ +
verifier.rotate old_secret          # Fallback to an old secret instead of @secret.
+verifier.rotate digest: "SHA256"    # Fallback to an old digest instead of SHA512.
+verifier.rotate serializer: Marshal # Fallback to an old serializer instead of JSON.
+
+ +

Though the above would most likely be combined into one rotation:

+ +
verifier.rotate old_secret, digest: "SHA256", serializer: Marshal
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(secret, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_verifier.rb, line 106
+def initialize(secret, options = {})
+  raise ArgumentError, "Secret should not be nil." unless secret
+  @secret = secret
+  @digest = options[:digest] || "SHA1"
+  @serializer = options[:serializer] || Marshal
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + generate(value, expires_at: nil, expires_in: nil, purpose: nil) + +

+ + +
+

Generates a signed message for the provided value.

+ +

The message is signed with the MessageVerifier's secret. Without knowing the secret, the original value cannot be extracted from the message.

+ +
verifier = ActiveSupport::MessageVerifier.new 's3Krit'
+verifier.generate 'a private message' # => "BAhJIhRwcml2YXRlLW1lc3NhZ2UGOgZFVA==--e2d724331ebdee96a10fb99b089508d1c72bd772"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_verifier.rb, line 186
+def generate(value, expires_at: nil, expires_in: nil, purpose: nil)
+  data = encode(Messages::Metadata.wrap(@serializer.dump(value), expires_at: expires_at, expires_in: expires_in, purpose: purpose))
+  "#{data}--#{generate_digest(data)}"
+end
+
+
+ +
+ +
+

+ + valid_message?(signed_message) + +

+ + +
+

Checks if a signed message could have been generated by signing an object with the MessageVerifier's secret.

+ +
verifier = ActiveSupport::MessageVerifier.new 's3Krit'
+signed_message = verifier.generate 'a private message'
+verifier.valid_message?(signed_message) # => true
+
+tampered_message = signed_message.chop # editing the message invalidates the signature
+verifier.valid_message?(tampered_message) # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_verifier.rb, line 122
+def valid_message?(signed_message)
+  return if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank?
+
+  data, digest = signed_message.split("--".freeze)
+  data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data))
+end
+
+
+ +
+ +
+

+ + verified(signed_message, purpose: nil, **) + +

+ + +
+

Decodes the signed message using the MessageVerifier's secret.

+ +
verifier = ActiveSupport::MessageVerifier.new 's3Krit'
+
+signed_message = verifier.generate 'a private message'
+verifier.verified(signed_message) # => 'a private message'
+
+ +

Returns nil if the message was not signed with the same secret.

+ +
other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
+other_verifier.verified(signed_message) # => nil
+
+ +

Returns nil if the message is not Base64-encoded.

+ +
invalid_message = "f--46a0120593880c733a53b6dad75b42ddc1c8996d"
+verifier.verified(invalid_message) # => nil
+
+ +

Raises any error raised while decoding the signed message.

+ +
incompatible_message = "test--dad7b06c94abba8d46a15fafaef56c327665d5ff"
+verifier.verified(incompatible_message) # => TypeError: incompatible marshal file format
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_verifier.rb, line 150
+def verified(signed_message, purpose: nil, **)
+  if valid_message?(signed_message)
+    begin
+      data = signed_message.split("--".freeze)[0]
+      message = Messages::Metadata.verify(decode(data), purpose)
+      @serializer.load(message) if message
+    rescue ArgumentError => argument_error
+      return if argument_error.message.include?("invalid base64")
+      raise
+    end
+  end
+end
+
+
+ +
+ +
+

+ + verify(*args) + +

+ + +
+

Decodes the signed message using the MessageVerifier's secret.

+ +
verifier = ActiveSupport::MessageVerifier.new 's3Krit'
+signed_message = verifier.generate 'a private message'
+
+verifier.verify(signed_message) # => 'a private message'
+
+ +

Raises InvalidSignature if the message was not signed with the same secret or was not Base64-encoded.

+ +
other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
+other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/message_verifier.rb, line 175
+def verify(*args)
+  verified(*args) || raise(InvalidSignature)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/MessageVerifier/InvalidSignature.html b/src/5.2/classes/ActiveSupport/MessageVerifier/InvalidSignature.html new file mode 100644 index 0000000000..bbbebb7b47 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/MessageVerifier/InvalidSignature.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::MessageVerifier::InvalidSignature +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Messages.html b/src/5.2/classes/ActiveSupport/Messages.html new file mode 100644 index 0000000000..d0d09e2871 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Messages.html @@ -0,0 +1,71 @@ +--- +title: ActiveSupport::Messages +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Messages/Rotator.html b/src/5.2/classes/ActiveSupport/Messages/Rotator.html new file mode 100644 index 0000000000..358e4e5d93 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Messages/Rotator.html @@ -0,0 +1,69 @@ +--- +title: ActiveSupport::Messages::Rotator +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Messages/Rotator/Encryptor.html b/src/5.2/classes/ActiveSupport/Messages/Rotator/Encryptor.html new file mode 100644 index 0000000000..ddf7d9e8c1 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Messages/Rotator/Encryptor.html @@ -0,0 +1,117 @@ +--- +title: ActiveSupport::Messages::Rotator::Encryptor +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + decrypt_and_verify(*args, on_rotation: nil, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/messages/rotator.rb, line 20
+def decrypt_and_verify(*args, on_rotation: nil, **options)
+  super
+rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
+  run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, options) } || raise
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Messages/Rotator/Verifier.html b/src/5.2/classes/ActiveSupport/Messages/Rotator/Verifier.html new file mode 100644 index 0000000000..125ba997b4 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Messages/Rotator/Verifier.html @@ -0,0 +1,115 @@ +--- +title: ActiveSupport::Messages::Rotator::Verifier +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + verified(*args, on_rotation: nil, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/messages/rotator.rb, line 35
+def verified(*args, on_rotation: nil, **options)
+  super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, options) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Multibyte.html b/src/5.2/classes/ActiveSupport/Multibyte.html new file mode 100644 index 0000000000..4bf8993f47 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Multibyte.html @@ -0,0 +1,167 @@ +--- +title: ActiveSupport::Multibyte +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + proxy_class() + +

+ + +
+

Returns the current proxy class.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte.rb, line 19
+def self.proxy_class
+  @proxy_class ||= ActiveSupport::Multibyte::Chars
+end
+
+
+ +
+ +
+

+ + proxy_class=(klass) + +

+ + +
+

The proxy class returned when calling mb_chars. You can use this accessor to configure your own proxy class so you can support other encodings. See the ActiveSupport::Multibyte::Chars implementation for an example how to do this.

+ +
ActiveSupport::Multibyte.proxy_class = CharsForUTF32
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte.rb, line 14
+def self.proxy_class=(klass)
+  @proxy_class = klass
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Multibyte/Chars.html b/src/5.2/classes/ActiveSupport/Multibyte/Chars.html new file mode 100644 index 0000000000..7eb3c8516c --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Multibyte/Chars.html @@ -0,0 +1,937 @@ +--- +title: ActiveSupport::Multibyte::Chars +layout: default +--- +
+ +
+
+ +
+ +

Chars enables you to work transparently with UTF-8 encoding in the Ruby String class without having extensive knowledge about the encoding. A Chars object accepts a string upon initialization and proxies String methods in an encoding safe manner. All the normal String methods are also implemented on the proxy.

+ +

String methods are proxied through the Chars object, and can be accessed through the mb_chars method. Methods which would normally return a String object now return a Chars object so methods can be chained.

+ +
'The Perfect String  '.mb_chars.downcase.strip.normalize
+# => #<ActiveSupport::Multibyte::Chars:0x007fdc434ccc10 @wrapped_string="the perfect string">
+
+ +

Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made. If certain methods do explicitly check the class, call to_s before you pass chars objects to them.

+ +
bad.explicit_checking_method 'T'.mb_chars.downcase.to_s
+
+ +

The default Chars implementation assumes that the encoding of the string is UTF-8, if you want to handle different encodings you can write your own multibyte string handler and configure it through ActiveSupport::Multibyte.proxy_class.

+ +
class CharsForUTF32
+  def size
+    @wrapped_string.size / 4
+  end
+
+  def self.accepts?(string)
+    string.length % 4 == 0
+  end
+end
+
+ActiveSupport::Multibyte.proxy_class = CharsForUTF32
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Comparable + +
  • + +
+ + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + to_s
+ [R] + to_str
+ [R] + wrapped_string
+ + + + +

Class Public methods

+ +
+

+ + consumes?(string) + +

+ + +
+

Returns true when the proxy class can handle the string. Returns false otherwise.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 79
+def self.consumes?(string)
+  string.encoding == Encoding::UTF_8
+end
+
+
+ +
+ +
+

+ + new(string) + +

+ + +
+

Creates a new Chars instance by wrapping string.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 55
+def initialize(string)
+  @wrapped_string = string
+  @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + capitalize() + +

+ + +
+

Converts the first character to uppercase and the remainder to lowercase.

+ +
'über'.mb_chars.capitalize.to_s # => "Über"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 148
+def capitalize
+  (slice(0) || chars("")).upcase + (slice(1..-1) || chars("")).downcase
+end
+
+
+ +
+ +
+

+ + compose() + +

+ + +
+

Performs composition on all the characters.

+ +
'é'.length                       # => 3
+'é'.mb_chars.compose.to_s.length # => 2
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 184
+def compose
+  chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack("U*"))
+end
+
+
+ +
+ +
+

+ + decompose() + +

+ + +
+

Performs canonical decomposition on all the characters.

+ +
'é'.length                         # => 2
+'é'.mb_chars.decompose.to_s.length # => 3
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 176
+def decompose
+  chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack("U*"))
+end
+
+
+ +
+ +
+

+ + downcase() + +

+ + +
+

Converts characters in the string to lowercase.

+ +
'VĚDA A VÝZKUM'.mb_chars.downcase.to_s # => "věda a výzkum"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 134
+def downcase
+  chars Unicode.downcase(@wrapped_string)
+end
+
+
+ +
+ +
+

+ + grapheme_length() + +

+ + +
+

Returns the number of grapheme clusters in the string.

+ +
'क्षि'.mb_chars.length   # => 4
+'क्षि'.mb_chars.grapheme_length # => 3
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 192
+def grapheme_length
+  Unicode.unpack_graphemes(@wrapped_string).length
+end
+
+
+ +
+ +
+

+ + limit(limit) + +

+ + +
+

Limits the byte size of the string to a number of bytes without breaking characters. Usable when the storage for a string is limited for some reason.

+ +
'こんにちは'.mb_chars.limit(7).to_s # => "こん"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 120
+def limit(limit)
+  slice(0...translate_offset(limit))
+end
+
+
+ +
+ +
+

+ + method_missing(method, *args, &block) + +

+ + +
+

Forward all undefined methods to the wrapped string.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 61
+def method_missing(method, *args, &block)
+  result = @wrapped_string.__send__(method, *args, &block)
+  if /!$/.match?(method)
+    self if result
+  else
+    result.kind_of?(String) ? chars(result) : result
+  end
+end
+
+
+ +
+ +
+

+ + normalize(form = nil) + +

+ + +
+

Returns the KC normalization of the string by default. NFKC is considered the best normalization form for passing strings to databases and validations.

+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 168
+def normalize(form = nil)
+  chars(Unicode.normalize(@wrapped_string, form))
+end
+
+
+ +
+ +
+

+ + respond_to_missing?(method, include_private) + +

+ + +
+

Returns true if obj responds to the given method. Private methods are included in the search only if the optional second parameter evaluates to true.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 73
+def respond_to_missing?(method, include_private)
+  @wrapped_string.respond_to?(method, include_private)
+end
+
+
+ +
+ +
+

+ + reverse() + +

+ + +
+

Reverses all characters in the string.

+ +
'Café'.mb_chars.reverse.to_s # => 'éfaC'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 111
+def reverse
+  chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack("U*"))
+end
+
+
+ +
+ +
+

+ + slice!(*args) + +

+ + +
+

Works like String#slice!, but returns an instance of Chars, or nil if the string was not modified. The string will not be modified if the range given is out of bounds

+ +
string = 'Welcome'
+string.mb_chars.slice!(3)    # => #<ActiveSupport::Multibyte::Chars:0x000000038109b8 @wrapped_string="c">
+string # => 'Welome'
+string.mb_chars.slice!(0..3) # => #<ActiveSupport::Multibyte::Chars:0x00000002eb80a0 @wrapped_string="Welo">
+string # => 'me'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 101
+def slice!(*args)
+  string_sliced = @wrapped_string.slice!(*args)
+  if string_sliced
+    chars(string_sliced)
+  end
+end
+
+
+ +
+ +
+

+ + split(*args) + +

+ + +
+

Works just like String#split, with the exception that the items in the resulting list are Chars instances instead of String. This makes chaining methods easier.

+ +
'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 88
+def split(*args)
+  @wrapped_string.split(*args).map { |i| self.class.new(i) }
+end
+
+
+ +
+ +
+

+ + swapcase() + +

+ + +
+

Converts characters in the string to the opposite case.

+ +
'El Cañón'.mb_chars.swapcase.to_s # => "eL cAÑÓN"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 141
+def swapcase
+  chars Unicode.swapcase(@wrapped_string)
+end
+
+
+ +
+ +
+

+ + tidy_bytes(force = false) + +

+ + +
+

Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.

+ +

Passing true will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 201
+def tidy_bytes(force = false)
+  chars(Unicode.tidy_bytes(@wrapped_string, force))
+end
+
+
+ +
+ +
+

+ + titlecase() + +

+ + +
+ +
+ + + + + +
+ Alias for: titleize +
+ + + +
+ +
+

+ + titleize() + +

+ + +
+

Capitalizes the first letter of every word, when possible.

+ +
"ÉL QUE SE ENTERÓ".mb_chars.titleize.to_s    # => "Él Que Se Enteró"
+"日本語".mb_chars.titleize.to_s               # => "日本語"
+
+
+ + + +
+ Also aliased as: titlecase +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 156
+def titleize
+  chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1) })
+end
+
+
+ +
+ +
+

+ + upcase() + +

+ + +
+

Converts characters in the string to uppercase.

+ +
'Laurent, où sont les tests ?'.mb_chars.upcase.to_s # => "LAURENT, OÙ SONT LES TESTS ?"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/chars.rb, line 127
+def upcase
+  chars Unicode.upcase(@wrapped_string)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Multibyte/Unicode.html b/src/5.2/classes/ActiveSupport/Multibyte/Unicode.html new file mode 100644 index 0000000000..dfb25082f7 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Multibyte/Unicode.html @@ -0,0 +1,847 @@ +--- +title: ActiveSupport::Multibyte::Unicode +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HANGUL_LBASE=0x1100
 
HANGUL_LCOUNT=19
 
HANGUL_NCOUNT=HANGUL_VCOUNT * HANGUL_TCOUNT
 
HANGUL_SBASE=0xAC00
 

Hangul character boundaries and properties

HANGUL_SCOUNT=11172
 
HANGUL_SLAST=HANGUL_SBASE + HANGUL_SCOUNT
 
HANGUL_TBASE=0x11A7
 
HANGUL_TCOUNT=28
 
HANGUL_VBASE=0x1161
 
HANGUL_VCOUNT=21
 
NORMALIZATION_FORMS=[:c, :kc, :d, :kd]
 

A list of all available normalization forms. See www.unicode.org/reports/tr15/tr15-29.html for more information about normalization.

UNICODE_VERSION="9.0.0"
 

The Unicode version that is supported by the implementation

+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + default_normalization_form

The default normalization used for operations that require normalization. It can be set to any of the normalizations in NORMALIZATION_FORMS.

+ +
ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
+
+ + + + + +

Instance Public methods

+ +
+

+ + compose(codepoints) + +

+ + +
+

Compose decomposed characters to the composed form.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 161
+def compose(codepoints)
+  pos = 0
+  eoa = codepoints.length - 1
+  starter_pos = 0
+  starter_char = codepoints[0]
+  previous_combining_class = -1
+  while pos < eoa
+    pos += 1
+    lindex = starter_char - HANGUL_LBASE
+    # -- Hangul
+    if 0 <= lindex && lindex < HANGUL_LCOUNT
+      vindex = codepoints[starter_pos + 1] - HANGUL_VBASE rescue vindex = -1
+      if 0 <= vindex && vindex < HANGUL_VCOUNT
+        tindex = codepoints[starter_pos + 2] - HANGUL_TBASE rescue tindex = -1
+        if 0 <= tindex && tindex < HANGUL_TCOUNT
+          j = starter_pos + 2
+          eoa -= 2
+        else
+          tindex = 0
+          j = starter_pos + 1
+          eoa -= 1
+        end
+        codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE
+      end
+      starter_pos += 1
+      starter_char = codepoints[starter_pos]
+    # -- Other characters
+    else
+      current_char = codepoints[pos]
+      current = database.codepoints[current_char]
+      if current.combining_class > previous_combining_class
+        if ref = database.composition_map[starter_char]
+          composition = ref[current_char]
+        else
+          composition = nil
+        end
+        unless composition.nil?
+          codepoints[starter_pos] = composition
+          starter_char = composition
+          codepoints.delete_at pos
+          eoa -= 1
+          pos -= 1
+          previous_combining_class = -1
+        else
+          previous_combining_class = current.combining_class
+        end
+      else
+        previous_combining_class = current.combining_class
+      end
+      if current.combining_class == 0
+        starter_pos = pos
+        starter_char = codepoints[pos]
+      end
+    end
+  end
+  codepoints
+end
+
+
+ +
+ +
+

+ + decompose(type, codepoints) + +

+ + +
+

Decompose composed characters to the decomposed form.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 140
+def decompose(type, codepoints)
+  codepoints.inject([]) do |decomposed, cp|
+    # if it's a hangul syllable starter character
+    if HANGUL_SBASE <= cp && cp < HANGUL_SLAST
+      sindex = cp - HANGUL_SBASE
+      ncp = [] # new codepoints
+      ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
+      ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
+      tindex = sindex % HANGUL_TCOUNT
+      ncp << (HANGUL_TBASE + tindex) unless tindex == 0
+      decomposed.concat ncp
+    # if the codepoint is decomposable in with the current decomposition type
+    elsif (ncp = database.codepoints[cp].decomp_mapping) && (!database.codepoints[cp].decomp_type || type == :compatibility)
+      decomposed.concat decompose(type, ncp.dup)
+    else
+      decomposed << cp
+    end
+  end
+end
+
+
+ +
+ +
+

+ + downcase(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 284
+def downcase(string)
+  apply_mapping string, :lowercase_mapping
+end
+
+
+ +
+ +
+

+ + in_char_class?(codepoint, classes) + +

+ + +
+

Detect whether the codepoint is in a certain character class. Returns true when it's in the specified character class and false otherwise. Valid character classes are: :cr, :lf, :l, :v, :lv, :lvt and :t.

+ +

Primarily used by the grapheme cluster support.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 42
+def in_char_class?(codepoint, classes)
+  classes.detect { |c| database.boundary[c] === codepoint } ? true : false
+end
+
+
+ +
+ +
+

+ + normalize(string, form = nil) + +

+ + +
+

Returns the KC normalization of the string by default. NFKC is considered the best normalization form for passing strings to databases and validations.

+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 266
+def normalize(string, form = nil)
+  form ||= @default_normalization_form
+  # See http://www.unicode.org/reports/tr15, Table 1
+  codepoints = string.codepoints.to_a
+  case form
+  when :d
+    reorder_characters(decompose(:canonical, codepoints))
+  when :c
+    compose(reorder_characters(decompose(:canonical, codepoints)))
+  when :kd
+    reorder_characters(decompose(:compatibility, codepoints))
+  when :kc
+    compose(reorder_characters(decompose(:compatibility, codepoints)))
+  else
+    raise ArgumentError, "#{form} is not a valid normalization variant", caller
+  end.pack("U*".freeze)
+end
+
+
+ +
+ +
+

+ + pack_graphemes(unpacked) + +

+ + +
+

Reverse operation of unpack_graphemes.

+ +
Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 119
+def pack_graphemes(unpacked)
+  unpacked.flatten.pack("U*")
+end
+
+
+ +
+ +
+

+ + reorder_characters(codepoints) + +

+ + +
+

Re-order codepoints so the string becomes canonical.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 124
+def reorder_characters(codepoints)
+  length = codepoints.length - 1
+  pos = 0
+  while pos < length do
+    cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos + 1]]
+    if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
+      codepoints[pos..pos + 1] = cp2.code, cp1.code
+      pos += (pos > 0 ? -1 : 1)
+    else
+      pos += 1
+    end
+  end
+  codepoints
+end
+
+
+ +
+ +
+

+ + swapcase(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 292
+def swapcase(string)
+  apply_mapping string, :swapcase_mapping
+end
+
+
+ +
+ +
+

+ + tidy_bytes(string, force = false) + +

+ + +
+

Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.

+ +

Passing true will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 226
+def tidy_bytes(string, force = false)
+  return string if string.empty?
+  return recode_windows1252_chars(string) if force
+  string.scrub { |bad| recode_windows1252_chars(bad) }
+end
+
+
+ +
+ +
+

+ + unpack_graphemes(string) + +

+ + +
+

Unpack the string at grapheme boundaries. Returns a list of character lists.

+ +
Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
+Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 51
+def unpack_graphemes(string)
+  codepoints = string.codepoints.to_a
+  unpacked = []
+  pos = 0
+  marker = 0
+  eoc = codepoints.length
+  while (pos < eoc)
+    pos += 1
+    previous = codepoints[pos - 1]
+    current = codepoints[pos]
+
+    # See http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
+    should_break =
+      if pos == eoc
+        true
+      # GB3. CR X LF
+      elsif previous == database.boundary[:cr] && current == database.boundary[:lf]
+        false
+      # GB4. (Control|CR|LF) ÷
+      elsif previous && in_char_class?(previous, [:control, :cr, :lf])
+        true
+      # GB5. ÷ (Control|CR|LF)
+      elsif in_char_class?(current, [:control, :cr, :lf])
+        true
+      # GB6. L X (L|V|LV|LVT)
+      elsif database.boundary[:l] === previous && in_char_class?(current, [:l, :v, :lv, :lvt])
+        false
+      # GB7. (LV|V) X (V|T)
+      elsif in_char_class?(previous, [:lv, :v]) && in_char_class?(current, [:v, :t])
+        false
+      # GB8. (LVT|T) X (T)
+      elsif in_char_class?(previous, [:lvt, :t]) && database.boundary[:t] === current
+        false
+      # GB9. X (Extend | ZWJ)
+      elsif in_char_class?(current, [:extend, :zwj])
+        false
+      # GB9a. X SpacingMark
+      elsif database.boundary[:spacingmark] === current
+        false
+      # GB9b. Prepend X
+      elsif database.boundary[:prepend] === previous
+        false
+      # GB10. (E_Base | EBG) Extend* X E_Modifier
+      elsif (marker...pos).any? { |i| in_char_class?(codepoints[i], [:e_base, :e_base_gaz]) && codepoints[i + 1...pos].all? { |c| database.boundary[:extend] === c } } && database.boundary[:e_modifier] === current
+        false
+      # GB11. ZWJ X (Glue_After_Zwj | EBG)
+      elsif database.boundary[:zwj] === previous && in_char_class?(current, [:glue_after_zwj, :e_base_gaz])
+        false
+      # GB12. ^ (RI RI)* RI X RI
+      # GB13. [^RI] (RI RI)* RI X RI
+      elsif codepoints[marker..pos].all? { |c| database.boundary[:regional_indicator] === c } && codepoints[marker..pos].count { |c| database.boundary[:regional_indicator] === c }.even?
+        false
+      # GB999. Any ÷ Any
+      else
+        true
+      end
+
+    if should_break
+      unpacked << codepoints[marker..pos - 1]
+      marker = pos
+    end
+  end
+  unpacked
+end
+
+
+ +
+ +
+

+ + upcase(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 288
+def upcase(string)
+  apply_mapping string, :uppercase_mapping
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Multibyte/Unicode/Codepoint.html b/src/5.2/classes/ActiveSupport/Multibyte/Unicode/Codepoint.html new file mode 100644 index 0000000000..6a88e70e94 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Multibyte/Unicode/Codepoint.html @@ -0,0 +1,211 @@ +--- +title: ActiveSupport::Multibyte::Unicode::Codepoint +layout: default +--- +
+ +
+
+ +
+ +

Holds data about a codepoint in the Unicode database.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + code
+ [RW] + combining_class
+ [RW] + decomp_mapping
+ [RW] + decomp_type
+ [RW] + lowercase_mapping
+ [RW] + uppercase_mapping
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+

Initializing Codepoint object with default values

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 301
+def initialize
+  @combining_class = 0
+  @uppercase_mapping = 0
+  @lowercase_mapping = 0
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + swapcase_mapping() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 307
+def swapcase_mapping
+  uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Multibyte/Unicode/UnicodeDatabase.html b/src/5.2/classes/ActiveSupport/Multibyte/Unicode/UnicodeDatabase.html new file mode 100644 index 0000000000..f25bacee20 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Multibyte/Unicode/UnicodeDatabase.html @@ -0,0 +1,312 @@ +--- +title: ActiveSupport::Multibyte::Unicode::UnicodeDatabase +layout: default +--- +
+ +
+
+ +
+ +

Holds static data from the Unicode database.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ATTRIBUTES=:codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
 
+ + + + + + +

Class Public methods

+ +
+

+ + dirname() + +

+ + +
+

Returns the directory in which the data files are stored.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 361
+def self.dirname
+  File.expand_path("../values", __dir__)
+end
+
+
+ +
+ +
+

+ + filename() + +

+ + +
+

Returns the filename for the data file for this version.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 366
+def self.filename
+  File.expand_path File.join(dirname, "unicode_tables.dat")
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 318
+def initialize
+  @codepoints = Hash.new(Codepoint.new)
+  @composition_exclusion = []
+  @composition_map = {}
+  @boundary = {}
+  @cp1252 = {}
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ===(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 348
+def ===(other)
+  detect { |i| i === other } ? true : false
+end
+
+
+ +
+ +
+

+ + load() + +

+ + +
+

Loads the Unicode database and returns all the internal objects of UnicodeDatabase.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/multibyte/unicode.rb, line 338
+def load
+  begin
+    @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, "rb") { |f| Marshal.load f.read }
+  rescue => e
+    raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
+  end
+
+  # Redefine the === method so we can write shorter rules for grapheme cluster breaks
+  @boundary.each_key do |k|
+    @boundary[k].instance_eval do
+      def ===(other)
+        detect { |i| i === other } ? true : false
+      end
+    end if @boundary[k].kind_of?(Array)
+  end
+
+  # define attr_reader methods for the instance variables
+  class << self
+    attr_reader(*ATTRIBUTES)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Notifications.html b/src/5.2/classes/ActiveSupport/Notifications.html new file mode 100644 index 0000000000..f767711b6e --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Notifications.html @@ -0,0 +1,479 @@ +--- +title: ActiveSupport::Notifications +layout: default +--- +
+ +
+
+ +
+ +

Notifications

+ +

ActiveSupport::Notifications provides an instrumentation API for Ruby.

+ +

Instrumenters

+ +

To instrument an event you just need to do:

+ +
ActiveSupport::Notifications.instrument('render', extra: :information) do
+  render plain: 'Foo'
+end
+
+ +

That first executes the block and then notifies all subscribers once done.

+ +

In the example above render is the name of the event, and the rest is called the payload. The payload is a mechanism that allows instrumenters to pass extra information to subscribers. Payloads consist of a hash whose contents are arbitrary and generally depend on the event.

+ +

Subscribers

+ +

You can consume those events and the information they provide by registering a subscriber.

+ +
ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload|
+  name    # => String, name of the event (such as 'render' from above)
+  start   # => Time, when the instrumented block started execution
+  finish  # => Time, when the instrumented block ended execution
+  id      # => String, unique ID for this notification
+  payload # => Hash, the payload
+end
+
+ +

For instance, let's store all “render” events in an array:

+ +
events = []
+
+ActiveSupport::Notifications.subscribe('render') do |*args|
+  events << ActiveSupport::Notifications::Event.new(*args)
+end
+
+ +

That code returns right away, you are just subscribing to “render” events. The block is saved and will be called whenever someone instruments “render”:

+ +
ActiveSupport::Notifications.instrument('render', extra: :information) do
+  render plain: 'Foo'
+end
+
+event = events.first
+event.name      # => "render"
+event.duration  # => 10 (in milliseconds)
+event.payload   # => { extra: :information }
+
+ +

The block in the subscribe call gets the name of the event, start timestamp, end timestamp, a string with a unique identifier for that event (something like “535801666f04d0298cd6”), and a hash with the payload, in that order.

+ +

If an exception happens during that particular instrumentation the payload will have a key :exception with an array of two elements as value: a string with the name of the exception class, and the exception message. The :exception_object key of the payload will have the exception itself as the value.

+ +

As the previous example depicts, the class ActiveSupport::Notifications::Event is able to take the arguments as they come and provide an object-oriented interface to that data.

+ +

It is also possible to pass an object which responds to call method as the second parameter to the subscribe method instead of a block:

+ +
module ActionController
+  class PageRequest
+    def call(name, started, finished, unique_id, payload)
+      Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
+    end
+  end
+end
+
+ActiveSupport::Notifications.subscribe('process_action.action_controller', ActionController::PageRequest.new)
+
+ +

resulting in the following output within the logs including a hash with the payload:

+ +
notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 {
+   controller: "Devise::SessionsController",
+   action: "new",
+   params: {"action"=>"new", "controller"=>"devise/sessions"},
+   format: :html,
+   method: "GET",
+   path: "/login/sign_in",
+   status: 200,
+   view_runtime: 279.3080806732178,
+   db_runtime: 40.053
+ }
+
+ +

You can also subscribe to all events whose name matches a certain regexp:

+ +
ActiveSupport::Notifications.subscribe(/render/) do |*args|
+  ...
+end
+
+ +

and even pass no argument to subscribe, in which case you are subscribing to all events.

+ +

Temporary Subscriptions

+ +

Sometimes you do not want to subscribe to an event for the entire life of the application. There are two ways to unsubscribe.

+ +

WARNING: The instrumentation framework is designed for long-running subscribers, use this feature sparingly because it wipes some internal caches and that has a negative impact on performance.

+ +

Subscribe While a Block Runs

+ +

You can subscribe to some event temporarily while some block runs. For example, in

+ +
callback = lambda {|*args| ... }
+ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
+  ...
+end
+
+ +

the callback will be called for all “sql.active_record” events instrumented during the execution of the block. The callback is unsubscribed automatically after that.

+ +

Manual Unsubscription

+ +

The subscribe method returns a subscriber object:

+ +
subscriber = ActiveSupport::Notifications.subscribe("render") do |*args|
+  ...
+end
+
+ +

To prevent that block from being called anymore, just unsubscribe passing that reference:

+ +
ActiveSupport::Notifications.unsubscribe(subscriber)
+
+ +

You can also unsubscribe by passing the name of the subscriber object. Note that this will unsubscribe all subscriptions with the given name:

+ +
ActiveSupport::Notifications.unsubscribe("render")
+
+ +

Default Queue

+ +

Notifications ships with a queue implementation that consumes and publishes events to all log subscribers. You can use any queue implementation you want.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + notifier
+ + + + +

Class Public methods

+ +
+

+ + instrument(name, payload = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications.rb, line 166
+def instrument(name, payload = {})
+  if notifier.listening?(name)
+    instrumenter.instrument(name, payload) { yield payload if block_given? }
+  else
+    yield payload if block_given?
+  end
+end
+
+
+ +
+ +
+

+ + instrumenter() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications.rb, line 189
+def instrumenter
+  InstrumentationRegistry.instance.instrumenter_for(notifier)
+end
+
+
+ +
+ +
+

+ + publish(name, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications.rb, line 162
+def publish(name, *args)
+  notifier.publish(name, *args)
+end
+
+
+ +
+ +
+

+ + subscribe(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications.rb, line 174
+def subscribe(*args, &block)
+  notifier.subscribe(*args, &block)
+end
+
+
+ +
+ +
+

+ + subscribed(callback, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications.rb, line 178
+def subscribed(callback, *args, &block)
+  subscriber = subscribe(*args, &callback)
+  yield
+ensure
+  unsubscribe(subscriber)
+end
+
+
+ +
+ +
+

+ + unsubscribe(subscriber_or_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications.rb, line 185
+def unsubscribe(subscriber_or_name)
+  notifier.unsubscribe(subscriber_or_name)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Notifications/Event.html b/src/5.2/classes/ActiveSupport/Notifications/Event.html new file mode 100644 index 0000000000..b487f0d762 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Notifications/Event.html @@ -0,0 +1,298 @@ +--- +title: ActiveSupport::Notifications::Event +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + children
+ [RW] + end
+ [R] + name
+ [R] + payload
+ [R] + time
+ [R] + transaction_id
+ + + + +

Class Public methods

+ +
+

+ + new(name, start, ending, transaction_id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 58
+def initialize(name, start, ending, transaction_id, payload)
+  @name           = name
+  @payload        = payload.dup
+  @time           = start
+  @transaction_id = transaction_id
+  @end            = ending
+  @children       = []
+  @duration       = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 84
+def <<(event)
+  @children << event
+end
+
+
+ +
+ +
+

+ + duration() + +

+ + +
+

Returns the difference in milliseconds between when the execution of the event started and when it ended.

+ +
ActiveSupport::Notifications.subscribe('wait') do |*args|
+  @event = ActiveSupport::Notifications::Event.new(*args)
+end
+
+ActiveSupport::Notifications.instrument('wait') do
+  sleep 1
+end
+
+@event.duration # => 1000.138
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 80
+def duration
+  @duration ||= 1000.0 * (self.end - time)
+end
+
+
+ +
+ +
+

+ + parent_of?(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 88
+def parent_of?(event)
+  @children.include? event
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Notifications/Fanout.html b/src/5.2/classes/ActiveSupport/Notifications/Fanout.html new file mode 100644 index 0000000000..8ddbc20ede --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Notifications/Fanout.html @@ -0,0 +1,461 @@ +--- +title: ActiveSupport::Notifications::Fanout +layout: default +--- +
+ +
+
+ +
+ +

This is a default queue implementation that ships with Notifications. It just pushes events to all registered log subscribers.

+ +

This class is thread safe. All methods are reentrant.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Mutex_m + +
  • + +
+ + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 15
+def initialize
+  @subscribers = []
+  @listeners_for = Concurrent::Map.new
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + finish(name, id, payload, listeners = listeners_for(name)) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 47
+def finish(name, id, payload, listeners = listeners_for(name))
+  listeners.each { |s| s.finish(name, id, payload) }
+end
+
+
+ +
+ +
+

+ + listeners_for(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 55
+def listeners_for(name)
+  # this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
+  @listeners_for[name] || synchronize do
+    # use synchronisation when accessing @subscribers
+    @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
+  end
+end
+
+
+ +
+ +
+

+ + listening?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 63
+def listening?(name)
+  listeners_for(name).any?
+end
+
+
+ +
+ +
+

+ + publish(name, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 51
+def publish(name, *args)
+  listeners_for(name).each { |s| s.publish(name, *args) }
+end
+
+
+ +
+ +
+

+ + start(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 43
+def start(name, id, payload)
+  listeners_for(name).each { |s| s.start(name, id, payload) }
+end
+
+
+ +
+ +
+

+ + subscribe(pattern = nil, callable = nil, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 21
+def subscribe(pattern = nil, callable = nil, &block)
+  subscriber = Subscribers.new(pattern, callable || block)
+  synchronize do
+    @subscribers << subscriber
+    @listeners_for.clear
+  end
+  subscriber
+end
+
+
+ +
+ +
+

+ + unsubscribe(subscriber_or_name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 30
+def unsubscribe(subscriber_or_name)
+  synchronize do
+    case subscriber_or_name
+    when String
+      @subscribers.reject! { |s| s.matches?(subscriber_or_name) }
+    else
+      @subscribers.delete(subscriber_or_name)
+    end
+
+    @listeners_for.clear
+  end
+end
+
+
+ +
+ +
+

+ + wait() + +

+ + +
+

This is a sync queue, so there is no waiting.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/fanout.rb, line 68
+def wait
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Notifications/Instrumenter.html b/src/5.2/classes/ActiveSupport/Notifications/Instrumenter.html new file mode 100644 index 0000000000..4a9ac7a80c --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Notifications/Instrumenter.html @@ -0,0 +1,297 @@ +--- +title: ActiveSupport::Notifications::Instrumenter +layout: default +--- +
+ +
+
+ +
+ +

Instrumenters are stored in a thread local.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + id
+ + + + +

Class Public methods

+ +
+

+ + new(notifier) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 11
+def initialize(notifier)
+  @id       = unique_id
+  @notifier = notifier
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + finish(name, payload) + +

+ + +
+

Send a finish notification with name and payload.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 39
+def finish(name, payload)
+  @notifier.finish name, @id, payload
+end
+
+
+ +
+ +
+

+ + finish_with_state(listeners_state, name, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 43
+def finish_with_state(listeners_state, name, payload)
+  @notifier.finish name, @id, payload, listeners_state
+end
+
+
+ +
+ +
+

+ + instrument(name, payload = {}) + +

+ + +
+

Instrument the given block by measuring the time taken to execute it and publish it. Notice that events get sent even if an error occurs in the passed-in block.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 19
+def instrument(name, payload = {})
+  # some of the listeners might have state
+  listeners_state = start name, payload
+  begin
+    yield payload
+  rescue Exception => e
+    payload[:exception] = [e.class.name, e.message]
+    payload[:exception_object] = e
+    raise e
+  ensure
+    finish_with_state listeners_state, name, payload
+  end
+end
+
+
+ +
+ +
+

+ + start(name, payload) + +

+ + +
+

Send a start notification with name and payload.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 34
+def start(name, payload)
+  @notifier.start name, @id, payload
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/NumberHelper.html b/src/5.2/classes/ActiveSupport/NumberHelper.html new file mode 100644 index 0000000000..d80c85e34a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/NumberHelper.html @@ -0,0 +1,639 @@ +--- +title: ActiveSupport::NumberHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + number_to_currency(number, options = {}) + +

+ + +
+

Formats a number into a currency string (e.g., $13.65). You can customize the format in the options hash.

+ +

The currency unit and number formatting of the current locale will be used unless otherwise specified in the provided options. No currency conversion is performed. If the user is given a way to change their locale, they will also be able to change the relative value of the currency displayed with this helper. If your application will ever support multiple locales, you may want to specify a constant :locale option or consider using a library capable of currency conversion.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the level of precision (defaults to 2).

    +
  • +

    :unit - Sets the denomination of the currency (defaults to “$”).

    +
  • +

    :separator - Sets the separator between the units (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “,”).

    +
  • +

    :format - Sets the format for non-negative numbers (defaults to “%u%n”). Fields are %u for the currency, and %n for the number.

    +
  • +

    :negative_format - Sets the format for negative numbers (defaults to prepending a hyphen to the formatted number given by :format). Accepts the same fields than :format, except %n is here the absolute value of the number.

    +
+ +

Examples

+ +
number_to_currency(1234567890.50)                # => "$1,234,567,890.50"
+number_to_currency(1234567890.506)               # => "$1,234,567,890.51"
+number_to_currency(1234567890.506, precision: 3) # => "$1,234,567,890.506"
+number_to_currency(1234567890.506, locale: :fr)  # => "1 234 567 890,51 €"
+number_to_currency('123a456')                    # => "$123a456"
+
+number_to_currency(-1234567890.50, negative_format: '(%u%n)')
+# => "($1,234,567,890.50)"
+number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '')
+# => "&pound;1234567890,50"
+number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
+# => "1234567890,50 &pound;"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/number_helper.rb, line 103
+def number_to_currency(number, options = {})
+  NumberToCurrencyConverter.convert(number, options)
+end
+
+
+ +
+ +
+

+ + number_to_delimited(number, options = {}) + +

+ + +
+

Formats a number with grouped thousands using delimiter (e.g., 12,324). You can customize the format in the options hash.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “,”).

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter_pattern - Sets a custom regular expression used for deriving the placement of delimiter. Helpful when using currency formats like INR.

    +
+ +

Examples

+ +
number_to_delimited(12345678)                    # => "12,345,678"
+number_to_delimited('123456')                    # => "123,456"
+number_to_delimited(12345678.05)                 # => "12,345,678.05"
+number_to_delimited(12345678, delimiter: '.')    # => "12.345.678"
+number_to_delimited(12345678, delimiter: ',')    # => "12,345,678"
+number_to_delimited(12345678.05, separator: ' ') # => "12,345,678 05"
+number_to_delimited(12345678.05, locale: :fr)    # => "12 345 678,05"
+number_to_delimited('112a')                      # => "112a"
+number_to_delimited(98765432.98, delimiter: ' ', separator: ',')
+                                                 # => "98 765 432,98"
+number_to_delimited("123456.78",
+  delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/)
+                                                 # => "1,23,456.78"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/number_helper.rb, line 175
+def number_to_delimited(number, options = {})
+  NumberToDelimitedConverter.convert(number, options)
+end
+
+
+ +
+ +
+

+ + number_to_human(number, options = {}) + +

+ + +
+

Pretty prints (formats and approximates) a number in a way it is more readable by humans (eg.: 1200000000 becomes “1.2 Billion”). This is useful for numbers that can get very large (and too hard to read).

+ +

See number_to_human_size if you want to print a file size.

+ +

You can also define your own unit-quantifier names if you want to use other decimal units (eg.: 1500 becomes “1.5 kilometers”, 0.150 becomes “150 milliliters”, etc). You may define a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3).

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to true)

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to true)

    +
  • +

    :units - A Hash of unit quantifier names. Or a string containing an i18n scope where to find this hash. It might have the following keys:

    +
    • +

      integers: :unit, :ten, :hundred, :thousand, :million, :billion, :trillion, :quadrillion

      +
    • +

      fractionals: :deci, :centi, :mili, :micro, :nano, :pico, :femto

      +
    +
  • +

    :format - Sets the format of the output string (defaults to “%n %u”). The field types are:

    +
    • +

      %u - The quantifier (ex.: 'thousand')

      +
    • +

      %n - The number

      +
    +
+ +

Examples

+ +
number_to_human(123)                         # => "123"
+number_to_human(1234)                        # => "1.23 Thousand"
+number_to_human(12345)                       # => "12.3 Thousand"
+number_to_human(1234567)                     # => "1.23 Million"
+number_to_human(1234567890)                  # => "1.23 Billion"
+number_to_human(1234567890123)               # => "1.23 Trillion"
+number_to_human(1234567890123456)            # => "1.23 Quadrillion"
+number_to_human(1234567890123456789)         # => "1230 Quadrillion"
+number_to_human(489939, precision: 2)        # => "490 Thousand"
+number_to_human(489939, precision: 4)        # => "489.9 Thousand"
+number_to_human(1234567, precision: 4,
+                         significant: false) # => "1.2346 Million"
+number_to_human(1234567, precision: 1,
+                         separator: ',',
+                         significant: false) # => "1,2 Million"
+
+number_to_human(500000000, precision: 5)           # => "500 Million"
+number_to_human(12345012345, significant: false)   # => "12.345 Billion"
+
+ +

Non-significant zeros after the decimal separator are stripped out by default (set :strip_insignificant_zeros to false to change that):

+ +

number_to_human(12.00001) # => “12” number_to_human(12.00001, strip_insignificant_zeros: false) # => “12.0”

+ +

Custom Unit Quantifiers

+ +

You can also use your own custom unit quantifiers:

+ +
number_to_human(500000, units: { unit: 'ml', thousand: 'lt' })  # => "500 lt"
+
+ +

If in your I18n locale you have:

+ +
distance:
+  centi:
+    one: "centimeter"
+    other: "centimeters"
+  unit:
+    one: "meter"
+    other: "meters"
+  thousand:
+    one: "kilometer"
+    other: "kilometers"
+  billion: "gazillion-distance"
+
+ +

Then you could do:

+ +
number_to_human(543934, units: :distance)            # => "544 kilometers"
+number_to_human(54393498, units: :distance)          # => "54400 kilometers"
+number_to_human(54393498000, units: :distance)       # => "54.4 gazillion-distance"
+number_to_human(343, units: :distance, precision: 1) # => "300 meters"
+number_to_human(1, units: :distance)                 # => "1 meter"
+number_to_human(0.34, units: :distance)              # => "34 centimeters"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/number_helper.rb, line 367
+def number_to_human(number, options = {})
+  NumberToHumanConverter.convert(number, options)
+end
+
+
+ +
+ +
+

+ + number_to_human_size(number, options = {}) + +

+ + +
+

Formats the bytes in number into a more understandable representation (e.g., giving it 1500 yields 1.5 KB). This method is useful for reporting file sizes to users. You can customize the format in the options hash.

+ +

See number_to_human if you want to pretty-print a generic number.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3).

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to true)

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to true)

    +
+ +

Examples

+ +
number_to_human_size(123)                                    # => "123 Bytes"
+number_to_human_size(1234)                                   # => "1.21 KB"
+number_to_human_size(12345)                                  # => "12.1 KB"
+number_to_human_size(1234567)                                # => "1.18 MB"
+number_to_human_size(1234567890)                             # => "1.15 GB"
+number_to_human_size(1234567890123)                          # => "1.12 TB"
+number_to_human_size(1234567890123456)                       # => "1.1 PB"
+number_to_human_size(1234567890123456789)                    # => "1.07 EB"
+number_to_human_size(1234567, precision: 2)                  # => "1.2 MB"
+number_to_human_size(483989, precision: 2)                   # => "470 KB"
+number_to_human_size(1234567, precision: 2, separator: ',')  # => "1,2 MB"
+number_to_human_size(1234567890123, precision: 5)            # => "1.1228 TB"
+number_to_human_size(524288000, precision: 5)                # => "500 MB"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/number_helper.rb, line 263
+def number_to_human_size(number, options = {})
+  NumberToHumanSizeConverter.convert(number, options)
+end
+
+
+ +
+ +
+

+ + number_to_percentage(number, options = {}) + +

+ + +
+

Formats a number as a percentage string (e.g., 65%). You can customize the format in the options hash.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3). Keeps the number's precision if nil.

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to false).

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to false).

    +
  • +

    :format - Specifies the format of the percentage string The number field is %n (defaults to “%n%”).

    +
+ +

Examples

+ +
number_to_percentage(100)                                  # => "100.000%"
+number_to_percentage('98')                                 # => "98.000%"
+number_to_percentage(100, precision: 0)                    # => "100%"
+number_to_percentage(1000, delimiter: '.', separator: ',') # => "1.000,000%"
+number_to_percentage(302.24398923423, precision: 5)        # => "302.24399%"
+number_to_percentage(1000, locale: :fr)                    # => "1000,000%"
+number_to_percentage(1000, precision: nil)                 # => "1000%"
+number_to_percentage('98a')                                # => "98a%"
+number_to_percentage(100, format: '%n  %')                 # => "100.000  %"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/number_helper.rb, line 140
+def number_to_percentage(number, options = {})
+  NumberToPercentageConverter.convert(number, options)
+end
+
+
+ +
+ +
+

+ + number_to_phone(number, options = {}) + +

+ + +
+

Formats a number into a phone number (US by default e.g., (555) 123-9876). You can customize the format in the options hash.

+ +

Options

+
  • +

    :area_code - Adds parentheses around the area code.

    +
  • +

    :delimiter - Specifies the delimiter to use (defaults to “-”).

    +
  • +

    :extension - Specifies an extension to add to the end of the generated number.

    +
  • +

    :country_code - Sets the country code for the phone number.

    +
  • +

    :pattern - Specifies how the number is divided into three groups with the custom regexp to override the default format.

    +
+ +

Examples

+ +
number_to_phone(5551234)                                     # => "555-1234"
+number_to_phone('5551234')                                   # => "555-1234"
+number_to_phone(1235551234)                                  # => "123-555-1234"
+number_to_phone(1235551234, area_code: true)                 # => "(123) 555-1234"
+number_to_phone(1235551234, delimiter: ' ')                  # => "123 555 1234"
+number_to_phone(1235551234, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
+number_to_phone(1235551234, country_code: 1)                 # => "+1-123-555-1234"
+number_to_phone('123a456')                                   # => "123a456"
+
+number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
+# => "+1.123.555.1234 x 1343"
+
+number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
+# => "(755) 6123-4567"
+number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/)
+# => "133-1234-5678"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/number_helper.rb, line 53
+def number_to_phone(number, options = {})
+  NumberToPhoneConverter.convert(number, options)
+end
+
+
+ +
+ +
+

+ + number_to_rounded(number, options = {}) + +

+ + +
+

Formats a number with the specified level of :precision (e.g., 112.32 has a precision of 2 if :significant is false, and 5 if :significant is true). You can customize the format in the options hash.

+ +

Options

+
  • +

    :locale - Sets the locale to be used for formatting (defaults to current locale).

    +
  • +

    :precision - Sets the precision of the number (defaults to 3). Keeps the number's precision if nil.

    +
  • +

    :significant - If true, precision will be the number of significant_digits. If false, the number of fractional digits (defaults to false).

    +
  • +

    :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

    +
  • +

    :delimiter - Sets the thousands delimiter (defaults to “”).

    +
  • +

    :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to false).

    +
+ +

Examples

+ +
number_to_rounded(111.2345)                                  # => "111.235"
+number_to_rounded(111.2345, precision: 2)                    # => "111.23"
+number_to_rounded(13, precision: 5)                          # => "13.00000"
+number_to_rounded(389.32314, precision: 0)                   # => "389"
+number_to_rounded(111.2345, significant: true)               # => "111"
+number_to_rounded(111.2345, precision: 1, significant: true) # => "100"
+number_to_rounded(13, precision: 5, significant: true)       # => "13.000"
+number_to_rounded(13, precision: nil)                        # => "13"
+number_to_rounded(111.234, locale: :fr)                      # => "111,234"
+
+number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
+# => "13"
+
+number_to_rounded(389.32314, precision: 4, significant: true) # => "389.3"
+number_to_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.')
+# => "1.111,23"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/number_helper.rb, line 219
+def number_to_rounded(number, options = {})
+  NumberToRoundedConverter.convert(number, options)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/NumericWithFormat.html b/src/5.2/classes/ActiveSupport/NumericWithFormat.html new file mode 100644 index 0000000000..87feaf6700 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/NumericWithFormat.html @@ -0,0 +1,218 @@ +--- +title: ActiveSupport::NumericWithFormat +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + to_s(format = nil, options = nil) + +

+ + +
+

Provides options for converting numbers into formatted strings. Options are provided for phone numbers, currency, percentage, precision, positional notation, file size and pretty printing.

+ +

Options

+ +

For details on which formats use which options, see ActiveSupport::NumberHelper

+ +

Examples

+ +
Phone Numbers:
+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"
+1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
+# => "+1.123.555.1234 x 1343"
+
+Currency:
+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"
+1234567890.506.to_s(:currency, locale: :fr)   # => "1 234 567 890,51 €"
+-1234567890.50.to_s(:currency, negative_format: '(%u%n)')
+# => "($1,234,567,890.50)"
+1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
+# => "&pound;1234567890,50"
+1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
+# => "1234567890,50 &pound;"
+
+Percentage:
+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%"
+1000.to_s(:percentage, locale: :fr)                    # => "1 000,000%"
+100.to_s(:percentage, format: '%n  %')                 # => "100.000  %"
+
+Delimited:
+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"
+12345678.05.to_s(:delimited, locale: :fr)     # => "12 345 678,05"
+98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
+# => "98 765 432,98"
+
+Rounded:
+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"
+111.2345.to_s(:rounded, precision: 1, significant: true)     # => "100"
+13.to_s(:rounded, precision: 5, significant: true)           # => "13.000"
+111.234.to_s(:rounded, locale: :fr)                          # => "111,234"
+13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
+# => "13"
+389.32314.to_s(:rounded, precision: 4, significant: true)    # => "389.3"
+1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
+# => "1.111,23"
+
+Human-friendly size in Bytes:
+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"
+1234567.to_s(:human_size, precision: 2)                 # => "1.2 MB"
+483989.to_s(:human_size, precision: 2)                  # => "470 KB"
+1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
+1234567890123.to_s(:human_size, precision: 5)           # => "1.1228 TB"
+524288000.to_s(:human_size, precision: 5)               # => "500 MB"
+
+Human-friendly format:
+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"
+1234567890123456789.to_s(:human)                       # => "1230 Quadrillion"
+489939.to_s(:human, precision: 2)                      # => "490 Thousand"
+489939.to_s(:human, precision: 4)                      # => "489.9 Thousand"
+1234567.to_s(:human, precision: 4,
+                 significant: false)                   # => "1.2346 Million"
+1234567.to_s(:human, precision: 1,
+                 separator: ',',
+                 significant: false)                   # => "1,2 Million"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/conversions.rb, line 104
+def to_s(format = nil, options = nil)
+  case format
+  when nil
+    super()
+  when Integer, String
+    super(format)
+  when :phone
+    ActiveSupport::NumberHelper.number_to_phone(self, options || {})
+  when :currency
+    ActiveSupport::NumberHelper.number_to_currency(self, options || {})
+  when :percentage
+    ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
+  when :delimited
+    ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
+  when :rounded
+    ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
+  when :human
+    ActiveSupport::NumberHelper.number_to_human(self, options || {})
+  when :human_size
+    ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
+  when Symbol
+    super()
+  else
+    super(format)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/OrderedHash.html b/src/5.2/classes/ActiveSupport/OrderedHash.html new file mode 100644 index 0000000000..87af8bf249 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/OrderedHash.html @@ -0,0 +1,318 @@ +--- +title: ActiveSupport::OrderedHash +layout: default +--- +
+ +
+
+ +
+ +

DEPRECATED: ActiveSupport::OrderedHash implements a hash that preserves insertion order.

+ +
oh = ActiveSupport::OrderedHash.new
+oh[:a] = 1
+oh[:b] = 2
+oh.keys # => [:a, :b], this order is guaranteed
+
+ +

Also, maps the omap feature for YAML files (See yaml.org/type/omap.html) to support ordered items when loading from yaml.

+ +

ActiveSupport::OrderedHash is namespaced to prevent conflicts with other implementations.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + encode_with(coder) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_hash.rb, line 29
+def encode_with(coder)
+  coder.represent_seq "!omap", map { |k, v| { k => v } }
+end
+
+
+ +
+ +
+

+ + extractable_options?() + +

+ + +
+

Returns true to make sure that this hash is extractable via Array#extract_options!

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_hash.rb, line 46
+def extractable_options?
+  true
+end
+
+
+ +
+ +
+

+ + nested_under_indifferent_access() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_hash.rb, line 41
+def nested_under_indifferent_access
+  self
+end
+
+
+ +
+ +
+

+ + reject(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_hash.rb, line 37
+def reject(*args, &block)
+  dup.tap { |hash| hash.reject!(*args, &block) }
+end
+
+
+ +
+ +
+

+ + select(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_hash.rb, line 33
+def select(*args, &block)
+  dup.tap { |hash| hash.select!(*args, &block) }
+end
+
+
+ +
+ +
+

+ + to_yaml_type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_hash.rb, line 25
+def to_yaml_type
+  "!tag:yaml.org,2002:omap"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/OrderedOptions.html b/src/5.2/classes/ActiveSupport/OrderedOptions.html new file mode 100644 index 0000000000..72770a52e4 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/OrderedOptions.html @@ -0,0 +1,296 @@ +--- +title: ActiveSupport::OrderedOptions +layout: default +--- +
+ +
+
+ +
+ +

Usually key value pairs are handled something like this:

+ +
h = {}
+h[:boy] = 'John'
+h[:girl] = 'Mary'
+h[:boy]  # => 'John'
+h[:girl] # => 'Mary'
+h[:dog]  # => nil
+
+ +

Using OrderedOptions, the above code could be reduced to:

+ +
h = ActiveSupport::OrderedOptions.new
+h.boy = 'John'
+h.girl = 'Mary'
+h.boy  # => 'John'
+h.girl # => 'Mary'
+h.dog  # => nil
+
+ +

To raise an exception when the value is blank, append a bang to the key name, like:

+ +
h.dog! # => raises KeyError: :dog is blank
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + [](key) + +

+ + +
+ +
+ + + +
+ Also aliased as: _get +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_options.rb, line 37
+def [](key)
+  super(key.to_sym)
+end
+
+
+ +
+ +
+

+ + []=(key, value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_options.rb, line 33
+def []=(key, value)
+  super(key.to_sym, value)
+end
+
+
+ +
+ +
+

+ + _get(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: [] +
+ + + +
+ +
+

+ + method_missing(name, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_options.rb, line 41
+def method_missing(name, *args)
+  name_string = name.to_s.dup
+  if name_string.chomp!("=")
+    self[name_string] = args.first
+  else
+    bangs = name_string.chomp!("!")
+
+    if bangs
+      self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
+    else
+      self[name_string]
+    end
+  end
+end
+
+
+ +
+ +
+

+ + respond_to_missing?(name, include_private) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/ordered_options.rb, line 56
+def respond_to_missing?(name, include_private)
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/PerThreadRegistry.html b/src/5.2/classes/ActiveSupport/PerThreadRegistry.html new file mode 100644 index 0000000000..72f223a108 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/PerThreadRegistry.html @@ -0,0 +1,183 @@ +--- +title: ActiveSupport::PerThreadRegistry +layout: default +--- +
+ +
+
+ +
+ +

NOTE: This approach has been deprecated for end-user code in favor of thread_mattr_accessor and friends. Please use that approach instead.

+ +

This module is used to encapsulate access to thread local variables.

+ +

Instead of polluting the thread locals namespace:

+ +
Thread.current[:connection_handler]
+
+ +

you define a class that extends this module:

+ +
module ActiveRecord
+  class RuntimeRegistry
+    extend ActiveSupport::PerThreadRegistry
+
+    attr_accessor :connection_handler
+  end
+end
+
+ +

and invoke the declared instance accessors as class methods. So

+ +
ActiveRecord::RuntimeRegistry.connection_handler = connection_handler
+
+ +

sets a connection handler local to the current thread, and

+ +
ActiveRecord::RuntimeRegistry.connection_handler
+
+ +

returns a connection handler local to the current thread.

+ +

This feature is accomplished by instantiating the class and storing the instance as a thread local keyed by the class name. In the example above a key “ActiveRecord::RuntimeRegistry” is stored in Thread.current. The class methods proxy to said thread local instance.

+ +

If the class has an initializer, it must accept no arguments.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + extended(object) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/per_thread_registry.rb, line 42
+def self.extended(object)
+  object.instance_variable_set "@per_thread_registry_key", object.name.freeze
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + instance() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/per_thread_registry.rb, line 46
+def instance
+  Thread.current[@per_thread_registry_key] ||= new
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/ProxyObject.html b/src/5.2/classes/ActiveSupport/ProxyObject.html new file mode 100644 index 0000000000..96f85fe7e6 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/ProxyObject.html @@ -0,0 +1,113 @@ +--- +title: ActiveSupport::ProxyObject +layout: default +--- +
+ +
+
+ +
+ +

A class with no predefined methods that behaves similarly to Builder's BlankSlate. Used for proxy classes.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + raise(*args) + +

+ + +
+

Let ActiveSupport::ProxyObject at least raise exceptions.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/proxy_object.rb, line 11
+def raise(*args)
+  ::Object.send(:raise, *args)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/RangeWithFormat.html b/src/5.2/classes/ActiveSupport/RangeWithFormat.html new file mode 100644 index 0000000000..dcc8ef3684 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/RangeWithFormat.html @@ -0,0 +1,205 @@ +--- +title: ActiveSupport::RangeWithFormat +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RANGE_FORMATS={ +db: -> (start, stop) do +case start +when String then "BETWEEN '#{start}' AND '#{stop}'" +else +"BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" +end +end +}
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + to_default_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_s(format = :default) + +

+ + +
+

Convert range to a formatted string. See RANGE_FORMATS for predefined formats.

+ +
range = (1..100)           # => 1..100
+
+range.to_s                 # => "1..100"
+range.to_s(:db)            # => "BETWEEN '1' AND '100'"
+
+ +

Adding your own range formats to to_s

+ +

You can add your own formats to the Range::RANGE_FORMATS hash. Use the format name as the hash key and a Proc instance.

+ +
# config/initializers/range_formats.rb
+Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
+
+
+ + + +
+ Also aliased as: to_default_s, to_formatted_s +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/range/conversions.rb, line 27
+def to_s(format = :default)
+  if formatter = RANGE_FORMATS[format]
+    formatter.call(first, last)
+  else
+    super()
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Reloader.html b/src/5.2/classes/ActiveSupport/Reloader.html new file mode 100644 index 0000000000..f484d5d46b --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Reloader.html @@ -0,0 +1,401 @@ +--- +title: ActiveSupport::Reloader +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + after_class_unload(*args, &block) + +

+ + +
+

Registers a callback that will run immediately after the classes are unloaded.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 42
+def self.after_class_unload(*args, &block)
+  set_callback(:class_unload, :after, *args, &block)
+end
+
+
+ +
+ +
+

+ + before_class_unload(*args, &block) + +

+ + +
+

Registers a callback that will run immediately before the classes are unloaded.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 37
+def self.before_class_unload(*args, &block)
+  set_callback(:class_unload, *args, &block)
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 92
+def initialize
+  super
+  @locked = false
+end
+
+
+ +
+ +
+

+ + reload!() + +

+ + +
+

Initiate a manual reload

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 49
+def self.reload!
+  executor.wrap do
+    new.tap do |instance|
+      begin
+        instance.run!
+      ensure
+        instance.complete!
+      end
+    end
+  end
+  prepare!
+end
+
+
+ +
+ +
+

+ + to_prepare(*args, &block) + +

+ + +
+

Registers a callback that will run once at application startup and every time the code is reloaded.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 32
+def self.to_prepare(*args, &block)
+  set_callback(:prepare, *args, &block)
+end
+
+
+ +
+ +
+

+ + wrap() + +

+ + +
+

Run the supplied block as a work unit, reloading code as needed

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 71
+def self.wrap
+  executor.wrap do
+    super
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + release_unload_lock!() + +

+ + +
+

Release the unload lock if it has been previously obtained

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 107
+def release_unload_lock!
+  if @locked
+    @locked = false
+    ActiveSupport::Dependencies.interlock.done_unloading
+  end
+end
+
+
+ +
+ +
+

+ + require_unload_lock!() + +

+ + +
+

Acquire the ActiveSupport::Dependencies::Interlock unload lock, ensuring it will be released automatically

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/reloader.rb, line 99
+def require_unload_lock!
+  unless @locked
+    ActiveSupport::Dependencies.interlock.start_unloading
+    @locked = true
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Rescuable.html b/src/5.2/classes/ActiveSupport/Rescuable.html new file mode 100644 index 0000000000..1af2f9d91b --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Rescuable.html @@ -0,0 +1,120 @@ +--- +title: ActiveSupport::Rescuable +layout: default +--- +
+ +
+
+ +
+ +

Rescuable module adds support for easier exception handling.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + rescue_with_handler(exception) + +

+ + +
+

Delegates to the class method, but uses the instance as the subject for rescue_from handlers (method calls, instance_exec blocks).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/rescuable.rb, line 164
+def rescue_with_handler(exception)
+  self.class.rescue_with_handler exception, object: self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Rescuable/ClassMethods.html b/src/5.2/classes/ActiveSupport/Rescuable/ClassMethods.html new file mode 100644 index 0000000000..6290d2325a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Rescuable/ClassMethods.html @@ -0,0 +1,208 @@ +--- +title: ActiveSupport::Rescuable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + rescue_from(*klasses, with: nil, &block) + +

+ + +
+

Rescue exceptions raised in controller actions.

+ +

rescue_from receives a series of exception classes or class names, and a trailing :with option with the name of a method or a Proc object to be called to handle them. Alternatively a block can be given.

+ +

Handlers that take one argument will be called with the exception, so that the exception can be inspected when dealing with it.

+ +

Handlers are inherited. They are searched from right to left, from bottom to top, and up the hierarchy. The handler of the first class for which exception.is_a?(klass) holds true is the one invoked, if any.

+ +
class ApplicationController < ActionController::Base
+  rescue_from User::NotAuthorized, with: :deny_access # self defined exception
+  rescue_from ActiveRecord::RecordInvalid, with: :show_errors
+
+  rescue_from 'MyAppError::Base' do |exception|
+    render xml: exception, status: 500
+  end
+
+  private
+    def deny_access
+      ...
+    end
+
+    def show_errors(exception)
+      exception.record.new_record? ? ...
+    end
+end
+
+ +

Exceptions raised inside exception handlers are not propagated up.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/rescuable.rb, line 51
+def rescue_from(*klasses, with: nil, &block)
+  unless with
+    if block_given?
+      with = block
+    else
+      raise ArgumentError, "Need a handler. Pass the with: keyword argument or provide a block."
+    end
+  end
+
+  klasses.each do |klass|
+    key = if klass.is_a?(Module) && klass.respond_to?(:===)
+      klass.name
+    elsif klass.is_a?(String)
+      klass
+    else
+      raise ArgumentError, "#{klass.inspect} must be an Exception class or a String referencing an Exception class"
+    end
+
+    # Put the new handler at the end because the list is read in reverse.
+    self.rescue_handlers += [[key, with]]
+  end
+end
+
+
+ +
+ +
+

+ + rescue_with_handler(exception, object: self, visited_exceptions: []) + +

+ + +
+

Matches an exception to a handler based on the exception class.

+ +

If no handler matches the exception, check for a handler matching the (optional) exception.cause. If no handler matches the exception or its cause, this returns nil, so you can deal with unhandled exceptions. Be sure to re-raise unhandled exceptions if this is what you expect.

+ +
begin
+  …
+rescue => exception
+  rescue_with_handler(exception) || raise
+end
+
+ +

Returns the exception if it was handled and nil if it was not.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/rescuable.rb, line 88
+def rescue_with_handler(exception, object: self, visited_exceptions: [])
+  visited_exceptions << exception
+
+  if handler = handler_for_rescue(exception, object: object)
+    handler.call exception
+    exception
+  elsif exception
+    if visited_exceptions.include?(exception.cause)
+      nil
+    else
+      rescue_with_handler(exception.cause, object: object, visited_exceptions: visited_exceptions)
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/SafeBuffer.html b/src/5.2/classes/ActiveSupport/SafeBuffer.html new file mode 100644 index 0000000000..6666f63b18 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/SafeBuffer.html @@ -0,0 +1,694 @@ +--- +title: ActiveSupport::SafeBuffer +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
UNSAFE_STRING_METHODS=%w( +capitalize chomp chop delete downcase gsub lstrip next reverse rstrip +slice squeeze strip sub succ swapcase tr tr_s upcase +)
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(str = "") + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 172
+def initialize(str = "")
+  @html_safe = true
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + %(args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 199
+def %(args)
+  case args
+  when Hash
+    escaped_args = Hash[args.map { |k, arg| [k, html_escape_interpolated_argument(arg)] }]
+  else
+    escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
+  end
+
+  self.class.new(super(escaped_args))
+end
+
+
+ +
+ +
+

+ + +(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 195
+def +(other)
+  dup.concat(other)
+end
+
+
+ +
+ +
+

+ + <<(value) + +

+ + +
+ +
+ + + + + +
+ Alias for: concat +
+ + + +
+ +
+

+ + [](*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 151
+def [](*args)
+  if args.size < 2
+    super
+  elsif html_safe?
+    new_safe_buffer = super
+
+    if new_safe_buffer
+      new_safe_buffer.instance_variable_set :@html_safe, true
+    end
+
+    new_safe_buffer
+  else
+    to_str[*args]
+  end
+end
+
+
+ +
+ +
+

+ + clone_empty() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 182
+def clone_empty
+  self[0, 0]
+end
+
+
+ +
+ +
+

+ + concat(value) + +

+ + +
+ +
+ + + +
+ Also aliased as: original_concat, << +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 186
+def concat(value)
+  super(html_escape_interpolated_argument(value))
+end
+
+
+ +
+ +
+

+ + encode_with(coder) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 222
+def encode_with(coder)
+  coder.represent_object nil, to_str
+end
+
+
+ +
+ +
+

+ + html_safe?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 210
+def html_safe?
+  defined?(@html_safe) && @html_safe
+end
+
+
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 177
+def initialize_copy(other)
+  super
+  @html_safe = other.html_safe?
+end
+
+
+ +
+ +
+

+ + original_concat(value) + +

+ + +
+ +
+ + + + + +
+ Alias for: concat +
+ + + +
+ +
+

+ + prepend(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 191
+def prepend(value)
+  super(html_escape_interpolated_argument(value))
+end
+
+
+ +
+ +
+

+ + safe_concat(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 167
+def safe_concat(value)
+  raise SafeConcatError unless html_safe?
+  original_concat(value)
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 218
+def to_param
+  to_str
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 214
+def to_s
+  self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/SafeBuffer/SafeConcatError.html b/src/5.2/classes/ActiveSupport/SafeBuffer/SafeConcatError.html new file mode 100644 index 0000000000..2b838bb117 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/SafeBuffer/SafeConcatError.html @@ -0,0 +1,113 @@ +--- +title: ActiveSupport::SafeBuffer::SafeConcatError +layout: default +--- +
+ +
+
+ +
+ +

Raised when ActiveSupport::SafeBuffer#safe_concat is called on unsafe buffers.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 146
+def initialize
+  super "Could not concatenate to the buffer because it is not html safe."
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/SecurityUtils.html b/src/5.2/classes/ActiveSupport/SecurityUtils.html new file mode 100644 index 0000000000..66f519b534 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/SecurityUtils.html @@ -0,0 +1,150 @@ +--- +title: ActiveSupport::SecurityUtils +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + fixed_length_secure_compare(a, b) + +

+ + +
+

Constant time string comparison, for fixed length strings.

+ +

The values compared should be of fixed length, such as strings that have already been processed by HMAC. Raises in case of length mismatch.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/security_utils.rb, line 11
+def fixed_length_secure_compare(a, b)
+  raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
+
+  l = a.unpack "C#{a.bytesize}"
+
+  res = 0
+  b.each_byte { |byte| res |= byte ^ l.shift }
+  res == 0
+end
+
+
+ +
+ +
+

+ + secure_compare(a, b) + +

+ + +
+

Constant time string comparison, for variable length strings.

+ +

The values are first processed by SHA256, so that we don't leak length info via timing attacks.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/security_utils.rb, line 26
+def secure_compare(a, b)
+  fixed_length_secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b)) && a == b
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/StringInquirer.html b/src/5.2/classes/ActiveSupport/StringInquirer.html new file mode 100644 index 0000000000..4c69efd8bb --- /dev/null +++ b/src/5.2/classes/ActiveSupport/StringInquirer.html @@ -0,0 +1,81 @@ +--- +title: ActiveSupport::StringInquirer +layout: default +--- +
+ +
+
+ +
+ +

Wrapping a string in this class gives you a prettier way to test for equality. The value returned by Rails.env is wrapped in a StringInquirer object, so instead of calling this:

+ +
Rails.env == 'production'
+
+ +

you can call this:

+ +
Rails.env.production?
+
+ +

Instantiating a new StringInquirer

+ +
vehicle = ActiveSupport::StringInquirer.new('car')
+vehicle.car?   # => true
+vehicle.bike?  # => false
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Subscriber.html b/src/5.2/classes/ActiveSupport/Subscriber.html new file mode 100644 index 0000000000..08772b603a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Subscriber.html @@ -0,0 +1,432 @@ +--- +title: ActiveSupport::Subscriber +layout: default +--- +
+ +
+
+ +
+ +

ActiveSupport::Subscriber is an object set to consume ActiveSupport::Notifications. The subscriber dispatches notifications to a registered object based on its given namespace.

+ +

An example would be an Active Record subscriber responsible for collecting statistics about queries:

+ +
module ActiveRecord
+  class StatsSubscriber < ActiveSupport::Subscriber
+    attach_to :active_record
+
+    def sql(event)
+      Statsd.timing("sql.#{event.payload[:name]}", event.duration)
+    end
+  end
+end
+
+ +

After configured, whenever a “sql.active_record” notification is published, it will properly dispatch the event (ActiveSupport::Notifications::Event) to the sql method.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + namespace

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ [R] + notifier

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ [R] + subscriber

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ + + + +

Class Public methods

+ +
+

+ + attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications) + +

+ + +
+

Attach the subscriber to a namespace.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/subscriber.rb, line 30
+def attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications)
+  @namespace  = namespace
+  @subscriber = subscriber
+  @notifier   = notifier
+
+  subscribers << subscriber
+
+  # Add event subscribers for all existing methods on the class.
+  subscriber.public_methods(false).each do |event|
+    add_event_subscriber(event)
+  end
+end
+
+
+ +
+ +
+

+ + method_added(event) + +

+ + +
+

Adds event subscribers for all new methods added to the class.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/subscriber.rb, line 44
+def method_added(event)
+  # Only public methods are added as subscribers, and only if a notifier
+  # has been set up. This means that subscribers will only be set up for
+  # classes that call #attach_to.
+  if public_method_defined?(event) && notifier
+    add_event_subscriber(event)
+  end
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/subscriber.rb, line 80
+def initialize
+  @queue_key = [self.class.name, object_id].join "-"
+  @patterns  = []
+  super
+end
+
+
+ +
+ +
+

+ + subscribers() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/subscriber.rb, line 53
+def subscribers
+  @@subscribers ||= []
+end
+
+
+ +
+ + +

Class Private methods

+ +
+

+ + add_event_subscriber(event) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/subscriber.rb, line 65
+def add_event_subscriber(event) # :doc:
+  return if %w{ start finish }.include?(event.to_s)
+
+  pattern = "#{event}.#{namespace}"
+
+  # Don't add multiple subscribers (eg. if methods are redefined).
+  return if subscriber.patterns.include?(pattern)
+
+  subscriber.patterns << pattern
+  notifier.subscribe(pattern, subscriber)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + finish(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/subscriber.rb, line 94
+def finish(name, id, payload)
+  finished  = now
+  event     = event_stack.pop
+  event.end = finished
+  event.payload.merge!(payload)
+
+  method = name.split(".".freeze).first
+  send(method, event)
+end
+
+
+ +
+ +
+

+ + start(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/subscriber.rb, line 86
+def start(name, id, payload)
+  e = ActiveSupport::Notifications::Event.new(name, now, nil, id, payload)
+  parent = event_stack.last
+  parent << e if parent
+
+  event_stack.push e
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/TaggedLogging.html b/src/5.2/classes/ActiveSupport/TaggedLogging.html new file mode 100644 index 0000000000..1caaeecaad --- /dev/null +++ b/src/5.2/classes/ActiveSupport/TaggedLogging.html @@ -0,0 +1,200 @@ +--- +title: ActiveSupport::TaggedLogging +layout: default +--- +
+ +
+
+ +
+ +

Wraps any standard Logger object 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"
+
+ +

This is used by the default Rails.logger as configured by Railties to make it easy to stamp log lines with subdomains, request ids, and anything else to aid debugging of multi-user production applications.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(logger) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/tagged_logging.rb, line 61
+def self.new(logger)
+  # Ensure we set a default formatter so we aren't extending nil!
+  logger.formatter ||= ActiveSupport::Logger::SimpleFormatter.new
+  logger.formatter.extend Formatter
+  logger.extend(self)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + flush() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/tagged_logging.rb, line 74
+def flush
+  clear_tags!
+  super if defined?(super)
+end
+
+
+ +
+ +
+

+ + tagged(*tags) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/tagged_logging.rb, line 70
+def tagged(*tags)
+  formatter.tagged(*tags) { yield self }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/TestCase.html b/src/5.2/classes/ActiveSupport/TestCase.html new file mode 100644 index 0000000000..6b533c00d3 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/TestCase.html @@ -0,0 +1,223 @@ +--- +title: ActiveSupport::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
Assertion=Minitest::Assertion
 
+ + + + + + +

Class Public methods

+ +
+

+ + test_order() + +

+ + +
+

Returns the order in which test cases are run.

+ +
ActiveSupport::TestCase.test_order # => :random
+
+ +

Possible values are :random, :parallel, :alpha, :sorted. Defaults to :random.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/test_case.rb, line 39
+def test_order
+  ActiveSupport.test_order ||= :random
+end
+
+
+ +
+ +
+

+ + test_order=(new_order) + +

+ + +
+

Sets the order in which test cases are run.

+ +
ActiveSupport::TestCase.test_order = :random # => :random
+
+ +

Valid values are:

+
  • +

    :random (to run tests in random order)

    +
  • +

    :parallel (to run tests in parallel)

    +
  • +

    :sorted (to run tests alphabetically by method name)

    +
  • +

    :alpha (equivalent to :sorted)

    +
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/test_case.rb, line 29
+def test_order=(new_order)
+  ActiveSupport.test_order = new_order
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing.html b/src/5.2/classes/ActiveSupport/Testing.html new file mode 100644 index 0000000000..a3fb6c91f5 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing.html @@ -0,0 +1,99 @@ +--- +title: ActiveSupport::Testing +layout: default +--- + diff --git a/src/5.2/classes/ActiveSupport/Testing/Assertions.html b/src/5.2/classes/ActiveSupport/Testing/Assertions.html new file mode 100644 index 0000000000..123cc2bd47 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/Assertions.html @@ -0,0 +1,479 @@ +--- +title: ActiveSupport::Testing::Assertions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) + +

+ + +
+

Assertion that the result of evaluating an expression is changed before and after invoking the passed in block.

+ +
assert_changes 'Status.all_good?' do
+  post :create, params: { status: { ok: false } }
+end
+
+ +

You can pass the block as a string to be evaluated in the context of the block. A lambda can be passed for the block as well.

+ +
assert_changes -> { Status.all_good? } do
+  post :create, params: { status: { ok: false } }
+end
+
+ +

The assertion is useful to test side effects. The passed block can be anything that can be converted to string with to_s.

+ +
assert_changes :@object do
+  @object = 42
+end
+
+ +

The keyword arguments :from and :to can be given to specify the expected initial value and the expected value after the block was executed.

+ +
assert_changes :@object, from: nil, to: :foo do
+  @object = :foo
+end
+
+ +

An error message can be specified.

+ +
assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do
+  post :create, params: { status: { incident: true } }
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/assertions.rb, line 159
+def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block)
+  exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
+
+  before = exp.call
+  retval = yield
+
+  unless from == UNTRACKED
+    error = "#{expression.inspect} isn't #{from.inspect}"
+    error = "#{message}.\n#{error}" if message
+    assert from === before, error
+  end
+
+  after = exp.call
+
+  error = "#{expression.inspect} didn't change"
+  error = "#{error}. It was already #{to}" if before == to
+  error = "#{message}.\n#{error}" if message
+  assert before != after, error
+
+  unless to == UNTRACKED
+    error = "#{expression.inspect} didn't change to #{to}"
+    error = "#{message}.\n#{error}" if message
+    assert to === after, error
+  end
+
+  retval
+end
+
+
+ +
+ +
+

+ + assert_difference(expression, *args, &block) + +

+ + +
+

Test numeric difference between the return value of an expression as a result of what is evaluated in the yielded block.

+ +
assert_difference 'Article.count' do
+  post :create, params: { article: {...} }
+end
+
+ +

An arbitrary expression is passed in and evaluated.

+ +
assert_difference 'Article.last.comments(:reload).size' do
+  post :create, params: { comment: {...} }
+end
+
+ +

An arbitrary positive or negative difference can be specified. The default is 1.

+ +
assert_difference 'Article.count', -1 do
+  post :delete, params: { id: ... }
+end
+
+ +

An array of expressions can also be passed in and evaluated.

+ +
assert_difference [ 'Article.count', 'Post.count' ], 2 do
+  post :create, params: { article: {...} }
+end
+
+ +

A hash of expressions/numeric differences can also be passed in and evaluated.

+ +
assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do
+  post :create, params: { article: {...} }
+end
+
+ +

A lambda or a list of lambdas can be passed in and evaluated:

+ +
assert_difference ->{ Article.count }, 2 do
+  post :create, params: { article: {...} }
+end
+
+assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
+  post :create, params: { article: {...} }
+end
+
+ +

An error message can be specified.

+ +
assert_difference 'Article.count', -1, 'An Article should be destroyed' do
+  post :delete, params: { id: ... }
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/assertions.rb, line 82
+def assert_difference(expression, *args, &block)
+  expressions =
+    if expression.is_a?(Hash)
+      message = args[0]
+      expression
+    else
+      difference = args[0] || 1
+      message = args[1]
+      Hash[Array(expression).map { |e| [e, difference] }]
+    end
+
+  exps = expressions.keys.map { |e|
+    e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
+  }
+  before = exps.map(&:call)
+
+  retval = yield
+
+  expressions.zip(exps, before) do |(code, diff), exp, before_value|
+    error  = "#{code.inspect} didn't change by #{diff}"
+    error  = "#{message}.\n#{error}" if message
+    assert_equal(before_value + diff, exp.call, error)
+  end
+
+  retval
+end
+
+
+ +
+ +
+

+ + assert_no_changes(expression, message = nil, &block) + +

+ + +
+

Assertion that the result of evaluating an expression is not changed before and after invoking the passed in block.

+ +
assert_no_changes 'Status.all_good?' do
+  post :create, params: { status: { ok: true } }
+end
+
+ +

An error message can be specified.

+ +
assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do
+  post :create, params: { status: { ok: false } }
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/assertions.rb, line 199
+def assert_no_changes(expression, message = nil, &block)
+  exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
+
+  before = exp.call
+  retval = yield
+  after = exp.call
+
+  error = "#{expression.inspect} did change to #{after}"
+  error = "#{message}.\n#{error}" if message
+  assert before == after, error
+
+  retval
+end
+
+
+ +
+ +
+

+ + assert_no_difference(expression, message = nil, &block) + +

+ + +
+

Assertion that the numeric result of evaluating an expression is not changed before and after invoking the passed in block.

+ +
assert_no_difference 'Article.count' do
+  post :create, params: { article: invalid_attributes }
+end
+
+ +

An error message can be specified.

+ +
assert_no_difference 'Article.count', 'An Article should not be created' do
+  post :create, params: { article: invalid_attributes }
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/assertions.rb, line 121
+def assert_no_difference(expression, message = nil, &block)
+  assert_difference expression, 0, message, &block
+end
+
+
+ +
+ +
+

+ + assert_not(object, message = nil) + +

+ + +
+

Asserts that an expression is not truthy. Passes if object is nil or false. “Truthy” means “considered true in a conditional” like if foo.

+ +
assert_not nil    # => true
+assert_not false  # => true
+assert_not 'foo'  # => Expected "foo" to be nil or false
+
+ +

An error message can be specified.

+ +
assert_not foo, 'foo should be false'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/assertions.rb, line 19
+def assert_not(object, message = nil)
+  message ||= "Expected #{mu_pp(object)} to be nil or false"
+  assert !object, message
+end
+
+
+ +
+ +
+

+ + assert_nothing_raised() + +

+ + +
+

Assertion that the block should not raise an exception.

+ +

Passes if evaluated code in the yielded block raises no exception.

+ +
assert_nothing_raised do
+  perform_service(param: 'no_exception')
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/assertions.rb, line 31
+def assert_nothing_raised
+  yield
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/ConstantLookup.html b/src/5.2/classes/ActiveSupport/Testing/ConstantLookup.html new file mode 100644 index 0000000000..7794889a85 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/ConstantLookup.html @@ -0,0 +1,85 @@ +--- +title: ActiveSupport::Testing::ConstantLookup +layout: default +--- +
+ +
+
+ +
+ +

Resolves a constant from a minitest spec name.

+ +

Given the following spec-style test:

+ +
describe WidgetsController, :index do
+  describe "authenticated user" do
+    describe "returns widgets" do
+      it "has a controller that exists" do
+        assert_kind_of WidgetsController, @controller
+      end
+    end
+  end
+end
+
+ +

The test will have the following name:

+ +
"WidgetsController::index::authenticated user::returns widgets"
+
+ +

The constant WidgetsController can be resolved from the name. The following code will resolve the constant:

+ +
controller = determine_constant_from_test_name(name) do |constant|
+  Class === constant && constant < ::ActionController::Metal
+end
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/Declarative.html b/src/5.2/classes/ActiveSupport/Testing/Declarative.html new file mode 100644 index 0000000000..50bb6c07c6 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/Declarative.html @@ -0,0 +1,115 @@ +--- +title: ActiveSupport::Testing::Declarative +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + test(name, &block) + +

+ + +
+

Helper to define a test method using a String. Under the hood, it replaces spaces with underscores and defines the test method.

+ +
test "verify something" do
+  ...
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/declarative.rb, line 13
+def test(name, &block)
+  test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
+  defined = method_defined? test_name
+  raise "#{test_name} is already defined in #{self}" if defined
+  if block_given?
+    define_method(test_name, &block)
+  else
+    define_method(test_name) do
+      flunk "No implementation provided for #{name}"
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/FileFixtures.html b/src/5.2/classes/ActiveSupport/Testing/FileFixtures.html new file mode 100644 index 0000000000..5ee422cefc --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/FileFixtures.html @@ -0,0 +1,122 @@ +--- +title: ActiveSupport::Testing::FileFixtures +layout: default +--- +
+ +
+
+ +
+ +

Adds simple access to sample files called file fixtures. File fixtures are normal files stored in ActiveSupport::TestCase.file_fixture_path.

+ +

File fixtures are represented as Pathname objects. This makes it easy to extract specific information:

+ +
file_fixture("example.txt").read # get the file's content
+file_fixture("example.mp3").size # get the file size
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + file_fixture(fixture_name) + +

+ + +
+

Returns a Pathname to the fixture file named fixture_name.

+ +

Raises ArgumentError if fixture_name can't be found.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/file_fixtures.rb, line 24
+def file_fixture(fixture_name)
+  path = Pathname.new(File.join(file_fixture_path, fixture_name))
+
+  if path.exist?
+    path
+  else
+    msg = "the directory '%s' does not contain a file named '%s'"
+    raise ArgumentError, msg % [file_fixture_path, fixture_name]
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/Isolation.html b/src/5.2/classes/ActiveSupport/Testing/Isolation.html new file mode 100644 index 0000000000..1e7524f721 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/Isolation.html @@ -0,0 +1,162 @@ +--- +title: ActiveSupport::Testing::Isolation +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + forking_env?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/isolation.rb, line 14
+def self.forking_env?
+  !ENV["NO_FORK"] && Process.respond_to?(:fork)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/isolation.rb, line 18
+def run
+  serialized = run_in_isolation do
+    super
+  end
+
+  Marshal.load(serialized)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/Isolation/Forking.html b/src/5.2/classes/ActiveSupport/Testing/Isolation/Forking.html new file mode 100644 index 0000000000..49cda9937a --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/Isolation/Forking.html @@ -0,0 +1,132 @@ +--- +title: ActiveSupport::Testing::Isolation::Forking +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + run_in_isolation(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/isolation.rb, line 27
+def run_in_isolation(&blk)
+  read, write = IO.pipe
+  read.binmode
+  write.binmode
+
+  pid = fork do
+    read.close
+    yield
+    begin
+      if error?
+        failures.map! { |e|
+          begin
+            Marshal.dump e
+            e
+          rescue TypeError
+            ex = Exception.new e.message
+            ex.set_backtrace e.backtrace
+            Minitest::UnexpectedError.new ex
+          end
+        }
+      end
+      test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
+      result = Marshal.dump(test_result)
+    end
+
+    write.puts [result].pack("m")
+    exit!
+  end
+
+  write.close
+  result = read.read
+  Process.wait2(pid)
+  result.unpack("m")[0]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/Isolation/Subprocess.html b/src/5.2/classes/ActiveSupport/Testing/Isolation/Subprocess.html new file mode 100644 index 0000000000..67393b319c --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/Isolation/Subprocess.html @@ -0,0 +1,153 @@ +--- +title: ActiveSupport::Testing::Isolation::Subprocess +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ORIG_ARGV=ARGV.dup unless defined?(ORIG_ARGV)
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + run_in_isolation(&blk) + +

+ + +
+

Crazy H4X to get this working in windows / jruby with no forking.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/isolation.rb, line 68
+def run_in_isolation(&blk)
+  require "tempfile"
+
+  if ENV["ISOLATION_TEST"]
+    yield
+    test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
+    File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
+      file.puts [Marshal.dump(test_result)].pack("m")
+    end
+    exit!
+  else
+    Tempfile.open("isolation") do |tmpfile|
+      env = {
+        "ISOLATION_TEST" => self.class.name,
+        "ISOLATION_OUTPUT" => tmpfile.path
+      }
+
+      test_opts = "-n#{self.class.name}##{name}"
+
+      load_path_args = []
+      $-I.each do |p|
+        load_path_args << "-I"
+        load_path_args << File.expand_path(p)
+      end
+
+      child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts])
+
+      begin
+        Process.wait(child.pid)
+      rescue Errno::ECHILD # The child process may exit before we wait
+        nil
+      end
+
+      return tmpfile.read.unpack("m")[0]
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown.html b/src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown.html new file mode 100644 index 0000000000..9abf76dcd2 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown.html @@ -0,0 +1,147 @@ +--- +title: ActiveSupport::Testing::SetupAndTeardown +layout: default +--- +
+ +
+
+ +
+ +

Adds support for setup and teardown callbacks. These callbacks serve as a replacement to overwriting the #setup and #teardown methods of your TestCase.

+ +
class ExampleTest < ActiveSupport::TestCase
+  setup do
+    # ...
+  end
+
+  teardown do
+    # ...
+  end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + prepended(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/setup_and_teardown.rb, line 21
+def self.prepended(klass)
+  klass.include ActiveSupport::Callbacks
+  klass.define_callbacks :setup, :teardown
+  klass.extend ClassMethods
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown/ClassMethods.html b/src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown/ClassMethods.html new file mode 100644 index 0000000000..c0ef97f567 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/SetupAndTeardown/ClassMethods.html @@ -0,0 +1,140 @@ +--- +title: ActiveSupport::Testing::SetupAndTeardown::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + setup(*args, &block) + +

+ + +
+

Add a callback, which runs before TestCase#setup.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/setup_and_teardown.rb, line 29
+def setup(*args, &block)
+  set_callback(:setup, :before, *args, &block)
+end
+
+
+ +
+ +
+

+ + teardown(*args, &block) + +

+ + +
+

Add a callback, which runs after TestCase#teardown.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/setup_and_teardown.rb, line 34
+def teardown(*args, &block)
+  set_callback(:teardown, :after, *args, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/Testing/TimeHelpers.html b/src/5.2/classes/ActiveSupport/Testing/TimeHelpers.html new file mode 100644 index 0000000000..bd1ec4512e --- /dev/null +++ b/src/5.2/classes/ActiveSupport/Testing/TimeHelpers.html @@ -0,0 +1,367 @@ +--- +title: ActiveSupport::Testing::TimeHelpers +layout: default +--- +
+ +
+
+ +
+ +

Contains helpers that help you test passage of time.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + after_teardown() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/time_helpers.rb, line 55
+def after_teardown
+  travel_back
+  super
+end
+
+
+ +
+ +
+

+ + freeze_time(&block) + +

+ + +
+

Calls travel_to with Time.now.

+ +
Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
+freeze_time
+sleep(1)
+Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
+
+ +

This method also accepts a block, which will return the current time back to its original state at the end of the block:

+ +
Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
+freeze_time do
+  sleep(1)
+  User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
+end
+Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/time_helpers.rb, line 189
+def freeze_time(&block)
+  travel_to Time.now, &block
+end
+
+
+ +
+ +
+

+ + travel(duration, &block) + +

+ + +
+

Changes current time to the time in the future or in the past by a given time difference by stubbing Time.now, Date.today, and DateTime.now. The stubs are automatically removed at the end of the test.

+ +
Time.current     # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+travel 1.day
+Time.current     # => Sun, 10 Nov 2013 15:34:49 EST -05:00
+Date.current     # => Sun, 10 Nov 2013
+DateTime.current # => Sun, 10 Nov 2013 15:34:49 -0500
+
+ +

This method also accepts a block, which will return the current time back to its original state at the end of the block:

+ +
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+travel 1.day do
+  User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
+end
+Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/time_helpers.rb, line 78
+def travel(duration, &block)
+  travel_to Time.now + duration, &block
+end
+
+
+ +
+ +
+

+ + travel_back() + +

+ + +
+

Returns the current time back to its original state, by removing the stubs added by travel and travel_to.

+ +
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
+Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+travel_back
+Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/time_helpers.rb, line 169
+def travel_back
+  simple_stubs.unstub_all!
+end
+
+
+ +
+ +
+

+ + travel_to(date_or_time) + +

+ + +
+

Changes current time to the given time by stubbing Time.now, Date.today, and DateTime.now to return the time or date passed into this method. The stubs are automatically removed at the end of the test.

+ +
Time.current     # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
+Time.current     # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+Date.current     # => Wed, 24 Nov 2004
+DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
+
+ +

Dates are taken as their timestamp at the beginning of the day in the application time zone. Time.current returns said timestamp, and Time.now its equivalent in the system time zone. Similarly, Date.current returns a date equal to the argument, and Date.today the date according to Time.now, which may be different. (Note that you rarely want to deal with Time.now, or Date.today, in order to honor the application time zone please always use Time.current and Date.current.)

+ +

Note that the usec for the time passed will be set to 0 to prevent rounding errors with external services, like MySQL (which will round instead of floor, leading to off-by-one-second errors).

+ +

This method also accepts a block, which will return the current time back to its original state at the end of the block:

+ +
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+travel_to Time.zone.local(2004, 11, 24, 01, 04, 44) do
+  Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+end
+Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/testing/time_helpers.rb, line 113
+      def travel_to(date_or_time)
+        if block_given? && simple_stubs.stubbing(Time, :now)
+          travel_to_nested_block_call = <<-MSG.strip_heredoc
+
+      Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
+
+      Instead of:
+
+         travel_to 2.days.from_now do
+           # 2 days from today
+           travel_to 3.days.from_now do
+             # 5 days from today
+           end
+         end
+
+      preferred way to achieve above is:
+
+         travel 2.days do
+           # 2 days from today
+         end
+
+         travel 5.days do
+           # 5 days from today
+         end
+
+          MSG
+          raise travel_to_nested_block_call
+        end
+
+        if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
+          now = date_or_time.midnight.to_time
+        else
+          now = date_or_time.to_time.change(usec: 0)
+        end
+
+        simple_stubs.stub_object(Time, :now) { at(now.to_i) }
+        simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
+        simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
+
+        if block_given?
+          begin
+            yield
+          ensure
+            travel_back
+          end
+        end
+      end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/TimeWithZone.html b/src/5.2/classes/ActiveSupport/TimeWithZone.html new file mode 100644 index 0000000000..d31d1b672d --- /dev/null +++ b/src/5.2/classes/ActiveSupport/TimeWithZone.html @@ -0,0 +1,2637 @@ +--- +title: ActiveSupport::TimeWithZone +layout: default +--- +
+ +
+
+ +
+ +

A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are limited to UTC and the system's ENV['TZ'] zone.

+ +

You shouldn't ever need to create a TimeWithZone instance directly via new. Instead use methods local, parse, at and now on TimeZone instances, and in_time_zone on Time and DateTime instances.

+ +
Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
+Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+Time.zone.at(1171139445)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
+Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00
+
+ +

See Time and TimeZone for further documentation of these methods.

+ +

TimeWithZone instances implement the same API as Ruby Time instances, so that Time and TimeWithZone instances are interchangeable.

+ +
t = Time.zone.now                     # => Sun, 18 May 2008 13:27:25 EDT -04:00
+t.hour                                # => 13
+t.dst?                                # => true
+t.utc_offset                          # => -14400
+t.zone                                # => "EDT"
+t.to_s(:rfc822)                       # => "Sun, 18 May 2008 13:27:25 -0400"
+t + 1.day                             # => Mon, 19 May 2008 13:27:25 EDT -04:00
+t.beginning_of_year                   # => Tue, 01 Jan 2008 00:00:00 EST -05:00
+t > Time.utc(1999)                    # => true
+t.is_a?(Time)                         # => true
+t.is_a?(ActiveSupport::TimeWithZone)  # => true
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
PRECISIONS=Hash.new { |h, n| h[n] = "%FT%T.%#{n}N".freeze }
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + time_zone
+ + + + +

Class Public methods

+ +
+

+ + name() + +

+ + +
+

Report class name as 'Time' to thwart type checking.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 42
+def self.name
+  "Time"
+end
+
+
+ +
+ +
+

+ + new(utc_time, time_zone, local_time = nil, period = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 52
+def initialize(utc_time, time_zone, local_time = nil, period = nil)
+  @utc = utc_time ? transfer_time_values_to_utc_constructor(utc_time) : nil
+  @time_zone, @time = time_zone, local_time
+  @period = @utc ? period : get_period_and_ensure_valid_local_time(period)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + +(other) + +

+ + +
+

Adds an interval of time to the current object's time and returns that value as a new TimeWithZone object.

+ +
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
+now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
+now + 1000          # => Sun, 02 Nov 2014 01:43:08 EDT -04:00
+
+ +

If we're adding a Duration of variable length (i.e., years, months, days), move forward from time, otherwise move forward from utc, for accuracy when moving across DST boundaries.

+ +

For instance, a time + 24.hours will advance exactly 24 hours, while a time + 1.day will advance 23-25 hours, depending on the day.

+ +
now + 24.hours      # => Mon, 03 Nov 2014 00:26:28 EST -05:00
+now + 1.day         # => Mon, 03 Nov 2014 01:26:28 EST -05:00
+
+
+ + + +
+ Also aliased as: since, in +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 276
+def +(other)
+  if duration_of_variable_length?(other)
+    method_missing(:+, other)
+  else
+    result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other)
+    result.in_time_zone(time_zone)
+  end
+end
+
+
+ +
+ +
+

+ + -(other) + +

+ + +
+

Returns a new TimeWithZone object that represents the difference between the current object's time and the other time.

+ +
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
+now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
+now - 1000          # => Mon, 03 Nov 2014 00:09:48 EST -05:00
+
+ +

If subtracting a Duration of variable length (i.e., years, months, days), move backward from time, otherwise move backward from utc, for accuracy when moving across DST boundaries.

+ +

For instance, a time - 24.hours will go subtract exactly 24 hours, while a time - 1.day will subtract 23-25 hours, depending on the day.

+ +
now - 24.hours      # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
+now - 1.day         # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 303
+def -(other)
+  if other.acts_like?(:time)
+    to_time - other.to_time
+  elsif duration_of_variable_length?(other)
+    method_missing(:-, other)
+  else
+    result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other)
+    result.in_time_zone(time_zone)
+  end
+end
+
+
+ +
+ +
+

+ + <=>(other) + +

+ + +
+

Use the time in UTC for comparisons.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 225
+def <=>(other)
+  utc <=> other
+end
+
+
+ +
+ +
+

+ + acts_like_time?() + +

+ + +
+

So that self acts_like?(:time).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 464
+def acts_like_time?
+  true
+end
+
+
+ +
+ +
+

+ + advance(options) + +

+ + +
+

Uses Date to provide precise Time calculations for years, months, and days according to the proleptic Gregorian calendar. The result is returned as a new TimeWithZone object.

+ +

The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.

+ +

If advancing by a value of variable length (i.e., years, weeks, months, days), move forward from time, otherwise move forward from utc, for accuracy when moving across DST boundaries.

+ +
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
+now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
+now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29 EDT -04:00
+now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28 EDT -04:00
+now.advance(hours: 1)   # => Sun, 02 Nov 2014 01:26:28 EST -05:00
+now.advance(days: 1)    # => Mon, 03 Nov 2014 01:26:28 EST -05:00
+now.advance(weeks: 1)   # => Sun, 09 Nov 2014 01:26:28 EST -05:00
+now.advance(months: 1)  # => Tue, 02 Dec 2014 01:26:28 EST -05:00
+now.advance(years: 1)   # => Mon, 02 Nov 2015 01:26:28 EST -05:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 392
+def advance(options)
+  # If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
+  # otherwise advance from #utc, for accuracy when moving across DST boundaries
+  if options.values_at(:years, :weeks, :months, :days).any?
+    method_missing(:advance, options)
+  else
+    utc.advance(options).in_time_zone(time_zone)
+  end
+end
+
+
+ +
+ +
+

+ + ago(other) + +

+ + +
+

Subtracts an interval of time from the current object's time and returns the result as a new TimeWithZone object.

+ +
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
+now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
+now.ago(1000)       # => Mon, 03 Nov 2014 00:09:48 EST -05:00
+
+ +

If we're subtracting a Duration of variable length (i.e., years, months, days), move backward from time, otherwise move backward from utc, for accuracy when moving across DST boundaries.

+ +

For instance, time.ago(24.hours) will move back exactly 24 hours, while time.ago(1.day) will move back 23-25 hours, depending on the day.

+ +
now.ago(24.hours)   # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
+now.ago(1.day)      # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 331
+def ago(other)
+  since(-other)
+end
+
+
+ +
+ +
+

+ + as_json(options = nil) + +

+ + +
+

Coerces time to a string for JSON encoding. The default format is ISO 8601. You can get %Y/%m/%d %H:%M:%S +offset style by setting ActiveSupport::JSON::Encoding.use_standard_json_time_format to false.

+ +
# With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
+Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
+# => "2005-02-01T05:15:10.000-10:00"
+
+# With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
+Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").to_json
+# => "2005/02/01 05:15:10 -1000"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 167
+def as_json(options = nil)
+  if ActiveSupport::JSON::Encoding.use_standard_json_time_format
+    xmlschema(ActiveSupport::JSON::Encoding.time_precision)
+  else
+    %(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
+  end
+end
+
+
+ +
+ +
+

+ + between?(min, max) + +

+ + +
+

Returns true if the current object's time is within the specified min and max time.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 231
+def between?(min, max)
+  utc.between?(min, max)
+end
+
+
+ +
+ +
+

+ + blank?() + +

+ + +
+

An instance of ActiveSupport::TimeWithZone is never blank

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 475
+def blank?
+  false
+end
+
+
+ +
+ +
+

+ + change(options) + +

+ + +
+

Returns a new ActiveSupport::TimeWithZone where one or more of the elements have been changed according to the options parameter. The time options (:hour, :min, :sec, :usec, :nsec) reset cascadingly, so if only the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour and minute is passed, then sec, usec and nsec is set to 0. The options parameter takes a hash with any of these keys: :year, :month, :day, :hour, :min, :sec, :usec, :nsec, :offset, :zone. Pass either :usec or :nsec, not both. Similarly, pass either :zone or :offset, not both.

+ +
t = Time.zone.now          # => Fri, 14 Apr 2017 11:45:15 EST -05:00
+t.change(year: 2020)       # => Tue, 14 Apr 2020 11:45:15 EST -05:00
+t.change(hour: 12)         # => Fri, 14 Apr 2017 12:00:00 EST -05:00
+t.change(min: 30)          # => Fri, 14 Apr 2017 11:30:00 EST -05:00
+t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15 HST -10:00
+t.change(zone: "Hawaii")   # => Fri, 14 Apr 2017 11:45:15 HST -10:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 352
+def change(options)
+  if options[:zone] && options[:offset]
+    raise ArgumentError, "Can't change both :offset and :zone at the same time: #{options.inspect}"
+  end
+
+  new_time = time.change(options)
+
+  if options[:zone]
+    new_zone = ::Time.find_zone(options[:zone])
+  elsif options[:offset]
+    new_zone = ::Time.find_zone(new_time.utc_offset)
+  end
+
+  new_zone ||= time_zone
+  periods = new_zone.periods_for_local(new_time)
+
+  self.class.new(nil, new_zone, new_time, periods.include?(period) ? period : nil)
+end
+
+
+ +
+ +
+

+ + comparable_time() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc +
+ + + +
+ +
+

+ + dst?() + +

+ + +
+

Returns true if the current time is within Daylight Savings Time for the specified time zone.

+ +
Time.zone = 'Eastern Time (US & Canada)'    # => 'Eastern Time (US & Canada)'
+Time.zone.parse("2012-5-30").dst?           # => true
+Time.zone.parse("2012-11-30").dst?          # => false
+
+
+ + + +
+ Also aliased as: isdst +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 95
+def dst?
+  period.dst?
+end
+
+
+ +
+ +
+

+ + eql?(other) + +

+ + +
+

Returns true if other is equal to current object.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 252
+def eql?(other)
+  other.eql?(utc)
+end
+
+
+ +
+ +
+

+ + formatted_offset(colon = true, alternate_utc_string = nil) + +

+ + +
+

Returns a formatted string of the offset from UTC, or an alternative string if the time zone is already UTC.

+ +
Time.zone = 'Eastern Time (US & Canada)'   # => "Eastern Time (US & Canada)"
+Time.zone.now.formatted_offset(true)       # => "-05:00"
+Time.zone.now.formatted_offset(false)      # => "-0500"
+Time.zone = 'UTC'                          # => "UTC"
+Time.zone.now.formatted_offset(true, "0")  # => "0"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 126
+def formatted_offset(colon = true, alternate_utc_string = nil)
+  utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon)
+end
+
+
+ +
+ +
+

+ + freeze() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 479
+def freeze
+  # preload instance variables before freezing
+  period; utc; time; to_datetime; to_time
+  super
+end
+
+
+ +
+ +
+

+ + future?() + +

+ + +
+

Returns true if the current object's time is in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 247
+def future?
+  utc.future?
+end
+
+
+ +
+ +
+

+ + getgm() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc +
+ + + +
+ +
+

+ + getlocal(utc_offset = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: localtime +
+ + + +
+ +
+

+ + getutc() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc +
+ + + +
+ +
+

+ + gmt?() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc? +
+ + + +
+ +
+

+ + gmt_offset() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc_offset +
+ + + +
+ +
+

+ + gmtime() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc +
+ + + +
+ +
+

+ + gmtoff() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc_offset +
+ + + +
+ +
+

+ + hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 256
+def hash
+  utc.hash
+end
+
+
+ +
+ +
+

+ + httpdate() + +

+ + +
+

Returns a string of the object's date and time in the format used by HTTP requests.

+ +
Time.zone.now.httpdate  # => "Tue, 01 Jan 2013 04:39:43 GMT"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 188
+def httpdate
+  utc.httpdate
+end
+
+
+ +
+ +
+

+ + in(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: + +
+ + + +
+ +
+

+ + in_time_zone(new_zone = ::Time.zone) + +

+ + +
+

Returns the simultaneous time in Time.zone, or the specified zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 78
+def in_time_zone(new_zone = ::Time.zone)
+  return self if time_zone == new_zone
+  utc.in_time_zone(new_zone)
+end
+
+
+ +
+ +
+

+ + inspect() + +

+ + +
+

Returns a string of the object's date, time, zone, and offset from UTC.

+ +
Time.zone.now.inspect # => "Thu, 04 Dec 2014 11:00:25 EST -05:00"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 141
+def inspect
+  "#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
+end
+
+
+ +
+ +
+

+ + is_a?(klass) + +

+ + +
+

Say we're a Time to thwart type checking.

+
+ + + +
+ Also aliased as: kind_of? +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 469
+def is_a?(klass)
+  klass == ::Time || super
+end
+
+
+ +
+ +
+

+ + isdst() + +

+ + +
+ +
+ + + + + +
+ Alias for: dst? +
+ + + +
+ +
+

+ + iso8601(fraction_digits = 0) + +

+ + +
+ +
+ + + + + +
+ Alias for: xmlschema +
+ + + +
+ +
+

+ + kind_of?(klass) + +

+ + +
+ +
+ + + + + +
+ Alias for: is_a? +
+ + + +
+ +
+

+ + localtime(utc_offset = nil) + +

+ + +
+

Returns a Time instance of the simultaneous time in the system timezone.

+
+ + + +
+ Also aliased as: getlocal +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 84
+def localtime(utc_offset = nil)
+  utc.getlocal(utc_offset)
+end
+
+
+ +
+ +
+

+ + marshal_dump() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 485
+def marshal_dump
+  [utc, time_zone.name, time]
+end
+
+
+ +
+ +
+

+ + marshal_load(variables) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 489
+def marshal_load(variables)
+  initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc)
+end
+
+
+ +
+ +
+

+ + method_missing(sym, *args, &block) + +

+ + +
+

Send the missing method to time instance, and wrap result in a new TimeWithZone with the existing time_zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 510
+def method_missing(sym, *args, &block)
+  wrap_with_time_zone time.__send__(sym, *args, &block)
+rescue NoMethodError => e
+  raise e, e.message.sub(time.inspect, inspect), e.backtrace
+end
+
+
+ +
+ +
+

+ + past?() + +

+ + +
+

Returns true if the current object's time is in the past.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 236
+def past?
+  utc.past?
+end
+
+
+ +
+ +
+

+ + period() + +

+ + +
+

Returns the underlying TZInfo::TimezonePeriod.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 73
+def period
+  @period ||= time_zone.period_for_utc(@utc)
+end
+
+
+ +
+ +
+

+ + respond_to?(sym, include_priv = false) + +

+ + +
+

respond_to_missing? is not called in some cases, such as when type conversion is performed with Kernel#String

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 495
+def respond_to?(sym, include_priv = false)
+  # ensure that we're not going to throw and rescue from NoMethodError in method_missing which is slow
+  return false if sym.to_sym == :to_str
+  super
+end
+
+
+ +
+ +
+

+ + respond_to_missing?(sym, include_priv) + +

+ + +
+

Ensure proxy class responds to all methods that underlying time instance responds to.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 503
+def respond_to_missing?(sym, include_priv)
+  return false if sym.to_sym == :acts_like_date?
+  time.respond_to?(sym, include_priv)
+end
+
+
+ +
+ +
+

+ + rfc2822() + +

+ + +
+

Returns a string of the object's date and time in the RFC 2822 standard format.

+ +
Time.zone.now.rfc2822  # => "Tue, 01 Jan 2013 04:51:39 +0000"
+
+
+ + + +
+ Also aliased as: rfc822 +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 196
+def rfc2822
+  to_s(:rfc822)
+end
+
+
+ +
+ +
+

+ + rfc3339(fraction_digits = 0) + +

+ + +
+ +
+ + + + + +
+ Alias for: xmlschema +
+ + + +
+ +
+

+ + rfc822() + +

+ + +
+ +
+ + + + + +
+ Alias for: rfc2822 +
+ + + +
+ +
+

+ + since(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: + +
+ + + +
+ +
+

+ + strftime(format) + +

+ + +
+

Replaces %Z directive with +zone before passing to Time#strftime, so that zone information is correct.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 219
+def strftime(format)
+  format = format.gsub(/((?:\A|[^%])(?:%%)*)%Z/, "\\1#{zone}")
+  getlocal(utc_offset).strftime(format)
+end
+
+
+ +
+ +
+

+ + time() + +

+ + +
+

Returns a Time instance that represents the time in time_zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 59
+def time
+  @time ||= period.to_local(@utc)
+end
+
+
+ +
+ +
+

+ + to_a() + +

+ + +
+

Returns Array of parts of Time in sequence of [seconds, minutes, hours, day, month, year, weekday, yearday, dst?, zone].

+ +
now = Time.zone.now     # => Tue, 18 Aug 2015 02:29:27 UTC +00:00
+now.to_a                # => [27, 29, 2, 18, 8, 2015, 2, 230, false, "UTC"]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 415
+def to_a
+  [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
+end
+
+
+ +
+ +
+

+ + to_datetime() + +

+ + +
+

Returns an instance of DateTime with the timezone's UTC offset

+ +
Time.zone.now.to_datetime                         # => Tue, 18 Aug 2015 02:32:20 +0000
+Time.current.in_time_zone('Hawaii').to_datetime   # => Mon, 17 Aug 2015 16:32:20 -1000
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 448
+def to_datetime
+  @to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
+end
+
+
+ +
+ +
+

+ + to_f() + +

+ + +
+

Returns the object's date and time as a floating point number of seconds since the Epoch (January 1, 1970 00:00 UTC).

+ +
Time.zone.now.to_f # => 1417709320.285418
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 423
+def to_f
+  utc.to_f
+end
+
+
+ +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_i() + +

+ + +
+

Returns the object's date and time as an integer number of seconds since the Epoch (January 1, 1970 00:00 UTC).

+ +
Time.zone.now.to_i # => 1417709320
+
+
+ + + +
+ Also aliased as: tv_sec +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 431
+def to_i
+  utc.to_i
+end
+
+
+ +
+ +
+

+ + to_r() + +

+ + +
+

Returns the object's date and time as a rational number of seconds since the Epoch (January 1, 1970 00:00 UTC).

+ +
Time.zone.now.to_r # => (708854548642709/500000)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 440
+def to_r
+  utc.to_r
+end
+
+
+ +
+ +
+

+ + to_s(format = :default) + +

+ + +
+

Returns a string of the object's date and time. Accepts an optional format:

+
  • +

    :default - default value, mimics Ruby Time#to_s format.

    +
  • +

    :db - format outputs time in UTC :db time. See Time#to_formatted_s(:db).

    +
  • +

    Any key in Time::DATE_FORMATS can be used. See active_support/core_ext/time/conversions.rb.

    +
+
+ + + +
+ Also aliased as: to_formatted_s +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 206
+def to_s(format = :default)
+  if format == :db
+    utc.to_s(format)
+  elsif formatter = ::Time::DATE_FORMATS[format]
+    formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+  else
+    "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
+  end
+end
+
+
+ +
+ +
+

+ + to_time() + +

+ + +
+

Returns an instance of Time, either with the same UTC offset as self or in the local system timezone depending on the setting of ActiveSupport.to_time_preserves_timezone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 455
+def to_time
+  if preserve_timezone
+    @to_time_with_instance_offset ||= getlocal(utc_offset)
+  else
+    @to_time_with_system_offset ||= getlocal
+  end
+end
+
+
+ +
+ +
+

+ + today?() + +

+ + +
+

Returns true if the current object's time falls within the current day.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 242
+def today?
+  time.today?
+end
+
+
+ +
+ +
+

+ + tv_sec() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_i +
+ + + +
+ +
+

+ + utc() + +

+ + +
+

Returns a Time instance of the simultaneous time in the UTC timezone.

+
+ + + +
+ Also aliased as: comparable_time, getgm, getutc, gmtime +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 64
+def utc
+  @utc ||= period.to_utc(@time)
+end
+
+
+ +
+ +
+

+ + utc?() + +

+ + +
+

Returns true if the current time zone is set to UTC.

+ +
Time.zone = 'UTC'                           # => 'UTC'
+Time.zone.now.utc?                          # => true
+Time.zone = 'Eastern Time (US & Canada)'    # => 'Eastern Time (US & Canada)'
+Time.zone.now.utc?                          # => false
+
+
+ + + +
+ Also aliased as: gmt? +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 106
+def utc?
+  period.offset.abbreviation == :UTC || period.offset.abbreviation == :UCT
+end
+
+
+ +
+ +
+

+ + utc_offset() + +

+ + +
+

Returns the offset from current time to UTC time in seconds.

+
+ + + +
+ Also aliased as: gmt_offset, gmtoff +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 112
+def utc_offset
+  period.utc_total_offset
+end
+
+
+ +
+ +
+

+ + xmlschema(fraction_digits = 0) + +

+ + +
+

Returns a string of the object's date and time in the ISO 8601 standard format.

+ +
Time.zone.now.xmlschema  # => "2014-12-04T11:02:37-05:00"
+
+
+ + + +
+ Also aliased as: iso8601, rfc3339 +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 149
+def xmlschema(fraction_digits = 0)
+  "#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z'.freeze)}"
+end
+
+
+ +
+ +
+

+ + zone() + +

+ + +
+

Returns the time zone abbreviation.

+ +
Time.zone = 'Eastern Time (US & Canada)'   # => "Eastern Time (US & Canada)"
+Time.zone.now.zone # => "EST"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/time_with_zone.rb, line 134
+def zone
+  period.zone_identifier.to_s
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/TimeZone.html b/src/5.2/classes/ActiveSupport/TimeZone.html new file mode 100644 index 0000000000..7f34c9e403 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/TimeZone.html @@ -0,0 +1,1547 @@ +--- +title: ActiveSupport::TimeZone +layout: default +--- +
+ +
+
+ +
+ +

The TimeZone class serves as a wrapper around TZInfo::Timezone instances. It allows us to do the following:

+
  • +

    Limit the set of zones provided by TZInfo to a meaningful subset of 134 zones.

    +
  • +

    Retrieve and display zones with a friendlier name (e.g., “Eastern Time (US & Canada)” instead of “America/New_York”).

    +
  • +

    Lazily load TZInfo::Timezone instances only when they're needed.

    +
  • +

    Create ActiveSupport::TimeWithZone instances via TimeZone's local, parse, at and now methods.

    +
+ +

If you set config.time_zone in the Rails Application, you can access this TimeZone object via Time.zone:

+ +
# application.rb:
+class Application < Rails::Application
+  config.time_zone = 'Eastern Time (US & Canada)'
+end
+
+Time.zone      # => #<ActiveSupport::TimeZone:0x514834...>
+Time.zone.name # => "Eastern Time (US & Canada)"
+Time.zone.now  # => Sun, 18 May 2008 14:30:44 EDT -04:00
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Comparable + +
  • + +
+ + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAPPING={ +"International Date Line West" => "Etc/GMT+12", +"Midway Island" => "Pacific/Midway", +"American Samoa" => "Pacific/Pago_Pago", +"Hawaii" => "Pacific/Honolulu", +"Alaska" => "America/Juneau", +"Pacific Time (US & Canada)" => "America/Los_Angeles", +"Tijuana" => "America/Tijuana", +"Mountain Time (US & Canada)" => "America/Denver", +"Arizona" => "America/Phoenix", +"Chihuahua" => "America/Chihuahua", +"Mazatlan" => "America/Mazatlan", +"Central Time (US & Canada)" => "America/Chicago", +"Saskatchewan" => "America/Regina", +"Guadalajara" => "America/Mexico_City", +"Mexico City" => "America/Mexico_City", +"Monterrey" => "America/Monterrey", +"Central America" => "America/Guatemala", +"Eastern Time (US & Canada)" => "America/New_York", +"Indiana (East)" => "America/Indiana/Indianapolis", +"Bogota" => "America/Bogota", +"Lima" => "America/Lima", +"Quito" => "America/Lima", +"Atlantic Time (Canada)" => "America/Halifax", +"Caracas" => "America/Caracas", +"La Paz" => "America/La_Paz", +"Santiago" => "America/Santiago", +"Newfoundland" => "America/St_Johns", +"Brasilia" => "America/Sao_Paulo", +"Buenos Aires" => "America/Argentina/Buenos_Aires", +"Montevideo" => "America/Montevideo", +"Georgetown" => "America/Guyana", +"Puerto Rico" => "America/Puerto_Rico", +"Greenland" => "America/Godthab", +"Mid-Atlantic" => "Atlantic/South_Georgia", +"Azores" => "Atlantic/Azores", +"Cape Verde Is." => "Atlantic/Cape_Verde", +"Dublin" => "Europe/Dublin", +"Edinburgh" => "Europe/London", +"Lisbon" => "Europe/Lisbon", +"London" => "Europe/London", +"Casablanca" => "Africa/Casablanca", +"Monrovia" => "Africa/Monrovia", +"UTC" => "Etc/UTC", +"Belgrade" => "Europe/Belgrade", +"Bratislava" => "Europe/Bratislava", +"Budapest" => "Europe/Budapest", +"Ljubljana" => "Europe/Ljubljana", +"Prague" => "Europe/Prague", +"Sarajevo" => "Europe/Sarajevo", +"Skopje" => "Europe/Skopje", +"Warsaw" => "Europe/Warsaw", +"Zagreb" => "Europe/Zagreb", +"Brussels" => "Europe/Brussels", +"Copenhagen" => "Europe/Copenhagen", +"Madrid" => "Europe/Madrid", +"Paris" => "Europe/Paris", +"Amsterdam" => "Europe/Amsterdam", +"Berlin" => "Europe/Berlin", +"Bern" => "Europe/Zurich", +"Zurich" => "Europe/Zurich", +"Rome" => "Europe/Rome", +"Stockholm" => "Europe/Stockholm", +"Vienna" => "Europe/Vienna", +"West Central Africa" => "Africa/Algiers", +"Bucharest" => "Europe/Bucharest", +"Cairo" => "Africa/Cairo", +"Helsinki" => "Europe/Helsinki", +"Kyiv" => "Europe/Kiev", +"Riga" => "Europe/Riga", +"Sofia" => "Europe/Sofia", +"Tallinn" => "Europe/Tallinn", +"Vilnius" => "Europe/Vilnius", +"Athens" => "Europe/Athens", +"Istanbul" => "Europe/Istanbul", +"Minsk" => "Europe/Minsk", +"Jerusalem" => "Asia/Jerusalem", +"Harare" => "Africa/Harare", +"Pretoria" => "Africa/Johannesburg", +"Kaliningrad" => "Europe/Kaliningrad", +"Moscow" => "Europe/Moscow", +"St. Petersburg" => "Europe/Moscow", +"Volgograd" => "Europe/Volgograd", +"Samara" => "Europe/Samara", +"Kuwait" => "Asia/Kuwait", +"Riyadh" => "Asia/Riyadh", +"Nairobi" => "Africa/Nairobi", +"Baghdad" => "Asia/Baghdad", +"Tehran" => "Asia/Tehran", +"Abu Dhabi" => "Asia/Muscat", +"Muscat" => "Asia/Muscat", +"Baku" => "Asia/Baku", +"Tbilisi" => "Asia/Tbilisi", +"Yerevan" => "Asia/Yerevan", +"Kabul" => "Asia/Kabul", +"Ekaterinburg" => "Asia/Yekaterinburg", +"Islamabad" => "Asia/Karachi", +"Karachi" => "Asia/Karachi", +"Tashkent" => "Asia/Tashkent", +"Chennai" => "Asia/Kolkata", +"Kolkata" => "Asia/Kolkata", +"Mumbai" => "Asia/Kolkata", +"New Delhi" => "Asia/Kolkata", +"Kathmandu" => "Asia/Kathmandu", +"Astana" => "Asia/Dhaka", +"Dhaka" => "Asia/Dhaka", +"Sri Jayawardenepura" => "Asia/Colombo", +"Almaty" => "Asia/Almaty", +"Novosibirsk" => "Asia/Novosibirsk", +"Rangoon" => "Asia/Rangoon", +"Bangkok" => "Asia/Bangkok", +"Hanoi" => "Asia/Bangkok", +"Jakarta" => "Asia/Jakarta", +"Krasnoyarsk" => "Asia/Krasnoyarsk", +"Beijing" => "Asia/Shanghai", +"Chongqing" => "Asia/Chongqing", +"Hong Kong" => "Asia/Hong_Kong", +"Urumqi" => "Asia/Urumqi", +"Kuala Lumpur" => "Asia/Kuala_Lumpur", +"Singapore" => "Asia/Singapore", +"Taipei" => "Asia/Taipei", +"Perth" => "Australia/Perth", +"Irkutsk" => "Asia/Irkutsk", +"Ulaanbaatar" => "Asia/Ulaanbaatar", +"Seoul" => "Asia/Seoul", +"Osaka" => "Asia/Tokyo", +"Sapporo" => "Asia/Tokyo", +"Tokyo" => "Asia/Tokyo", +"Yakutsk" => "Asia/Yakutsk", +"Darwin" => "Australia/Darwin", +"Adelaide" => "Australia/Adelaide", +"Canberra" => "Australia/Melbourne", +"Melbourne" => "Australia/Melbourne", +"Sydney" => "Australia/Sydney", +"Brisbane" => "Australia/Brisbane", +"Hobart" => "Australia/Hobart", +"Vladivostok" => "Asia/Vladivostok", +"Guam" => "Pacific/Guam", +"Port Moresby" => "Pacific/Port_Moresby", +"Magadan" => "Asia/Magadan", +"Srednekolymsk" => "Asia/Srednekolymsk", +"Solomon Is." => "Pacific/Guadalcanal", +"New Caledonia" => "Pacific/Noumea", +"Fiji" => "Pacific/Fiji", +"Kamchatka" => "Asia/Kamchatka", +"Marshall Is." => "Pacific/Majuro", +"Auckland" => "Pacific/Auckland", +"Wellington" => "Pacific/Auckland", +"Nuku'alofa" => "Pacific/Tongatapu", +"Tokelau Is." => "Pacific/Fakaofo", +"Chatham Is." => "Pacific/Chatham", +"Samoa" => "Pacific/Apia" +}
 

Keys are Rails TimeZone names, values are TZInfo identifiers.

UTC_OFFSET_WITHOUT_COLON=UTC_OFFSET_WITH_COLON.tr(":", "")
 
UTC_OFFSET_WITH_COLON="%s%02d:%02d"
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + name
+ [R] + tzinfo
+ + + + +

Class Public methods

+ +
+

+ + [](arg) + +

+ + +
+

Locate a specific time zone object. If the argument is a string, it is interpreted to mean the name of the timezone to locate. If it is a numeric value it is either the hour offset, or the second offset, of the timezone to find. (The first one with that offset will be returned.) Returns nil if no such time zone is known to the system.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 230
+def [](arg)
+  case arg
+  when String
+    begin
+      @lazy_zones_map[arg] ||= create(arg)
+    rescue TZInfo::InvalidTimezoneIdentifier
+      nil
+    end
+  when Numeric, ActiveSupport::Duration
+    arg *= 3600 if arg.abs <= 13
+    all.find { |z| z.utc_offset == arg.to_i }
+  else
+    raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
+  end
+end
+
+
+ +
+ +
+

+ + all() + +

+ + +
+

Returns an array of all TimeZone objects. There are multiple TimeZone objects per time zone, in many cases, to make it easier for users to find their own time zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 221
+def all
+  @zones ||= zones_map.values.sort
+end
+
+
+ +
+ +
+

+ + country_zones(country_code) + +

+ + +
+

A convenience method for returning a collection of TimeZone objects for time zones in the country specified by its ISO 3166-1 Alpha2 code.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 254
+def country_zones(country_code)
+  code = country_code.to_s.upcase
+  @country_zones[code] ||= load_country_zones(code)
+end
+
+
+ +
+ +
+

+ + create(name) + +

+ + +
+ +
+ + + + + +
+ Alias for: new +
+ + + +
+ +
+

+ + find_tzinfo(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 205
+def find_tzinfo(name)
+  TZInfo::Timezone.new(MAPPING[name] || name)
+end
+
+
+ +
+ +
+

+ + new(name) + +

+ + +
+

Returns a TimeZone instance with the given name, or nil if no such TimeZone instance exists. (This exists to support the use of this class with the composed_of macro.)

+
+ + + +
+ Also aliased as: create +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 214
+def new(name)
+  self[name]
+end
+
+
+ +
+ +
+

+ + new(name, utc_offset = nil, tzinfo = nil) + +

+ + +
+

Create a new TimeZone object with the given name and offset. The offset is the number of seconds that this time zone is offset from UTC (GMT). Seconds were chosen as the offset unit because that is the unit that Ruby uses to represent time zone offsets (see Time#utc_offset).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 297
+def initialize(name, utc_offset = nil, tzinfo = nil)
+  @name = name
+  @utc_offset = utc_offset
+  @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
+end
+
+
+ +
+ +
+

+ + seconds_to_utc_offset(seconds, colon = true) + +

+ + +
+

Assumes self represents an offset from UTC in seconds (as returned from Time#utc_offset) and turns this into an +HH:MM formatted string.

+ +
ActiveSupport::TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 197
+def seconds_to_utc_offset(seconds, colon = true)
+  format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON
+  sign = (seconds < 0 ? "-" : "+")
+  hours = seconds.abs / 3600
+  minutes = (seconds.abs % 3600) / 60
+  format % [sign, hours, minutes]
+end
+
+
+ +
+ +
+

+ + us_zones() + +

+ + +
+

A convenience method for returning a collection of TimeZone objects for time zones in the USA.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 248
+def us_zones
+  country_zones(:us)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(zone) + +

+ + +
+

Compare this time zone to the parameter. The two are compared first on their offsets, and then by name.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 324
+def <=>(zone)
+  return unless zone.respond_to? :utc_offset
+  result = (utc_offset <=> zone.utc_offset)
+  result = (name <=> zone.name) if result == 0
+  result
+end
+
+
+ +
+ +
+

+ + =~(re) + +

+ + +
+

Compare name and TZInfo identifier to a supplied regexp, returning true if a match is found.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 333
+def =~(re)
+  re === name || re === MAPPING[name]
+end
+
+
+ +
+ +
+

+ + at(secs) + +

+ + +
+

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from number of seconds since the Unix epoch.

+ +
Time.zone = 'Hawaii'        # => "Hawaii"
+Time.utc(2000).to_f         # => 946684800.0
+Time.zone.at(946684800.0)   # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 358
+def at(secs)
+  Time.at(secs).utc.in_time_zone(self)
+end
+
+
+ +
+ +
+

+ + formatted_offset(colon = true, alternate_utc_string = nil) + +

+ + +
+

Returns a formatted string of the offset from UTC, or an alternative string if the time zone is already UTC.

+ +
zone = ActiveSupport::TimeZone['Central Time (US & Canada)']
+zone.formatted_offset        # => "-06:00"
+zone.formatted_offset(false) # => "-0600"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 318
+def formatted_offset(colon = true, alternate_utc_string = nil)
+  utc_offset == 0 && alternate_utc_string || self.class.seconds_to_utc_offset(utc_offset, colon)
+end
+
+
+ +
+ +
+

+ + iso8601(str) + +

+ + +
+

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from an ISO 8601 string.

+ +
Time.zone = 'Hawaii'                     # => "Hawaii"
+Time.zone.iso8601('1999-12-31T14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+
+ +

If the time components are missing then they will be set to zero.

+ +
Time.zone = 'Hawaii'            # => "Hawaii"
+Time.zone.iso8601('1999-12-31') # => Fri, 31 Dec 1999 00:00:00 HST -10:00
+
+ +

If the string is invalid then an ArgumentError will be raised unlike parse which usually returns nil when given an invalid date string.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 375
+def iso8601(str)
+  parts = Date._iso8601(str)
+
+  raise ArgumentError, "invalid date" if parts.empty?
+
+  time = Time.new(
+    parts.fetch(:year),
+    parts.fetch(:mon),
+    parts.fetch(:mday),
+    parts.fetch(:hour, 0),
+    parts.fetch(:min, 0),
+    parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
+    parts.fetch(:offset, 0)
+  )
+
+  if parts[:offset]
+    TimeWithZone.new(time.utc, self)
+  else
+    TimeWithZone.new(nil, self, time)
+  end
+end
+
+
+ +
+ +
+

+ + local(*args) + +

+ + +
+

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from given values.

+ +
Time.zone = 'Hawaii'                    # => "Hawaii"
+Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 347
+def local(*args)
+  time = Time.utc(*args)
+  ActiveSupport::TimeWithZone.new(nil, self, time)
+end
+
+
+ +
+ +
+

+ + local_to_utc(time, dst = true) + +

+ + +
+

Adjust the given time to the simultaneous time in UTC. Returns a Time.utc() instance.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 506
+def local_to_utc(time, dst = true)
+  tzinfo.local_to_utc(time, dst)
+end
+
+
+ +
+ +
+

+ + now() + +

+ + +
+

Returns an ActiveSupport::TimeWithZone instance representing the current time in the time zone represented by self.

+ +
Time.zone = 'Hawaii'  # => "Hawaii"
+Time.zone.now         # => Wed, 23 Jan 2008 20:24:27 HST -10:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 478
+def now
+  time_now.utc.in_time_zone(self)
+end
+
+
+ +
+ +
+

+ + parse(str, now = now()) + +

+ + +
+

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from parsed string.

+ +
Time.zone = 'Hawaii'                   # => "Hawaii"
+Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+
+ +

If upper components are missing from the string, they are supplied from TimeZone#now:

+ +
Time.zone.now               # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
+
+ +

However, if the date component is not provided, but any other upper components are supplied, then the day of the month defaults to 1:

+ +
Time.zone.parse('Mar 2000') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
+
+ +

If the string is invalid then an ArgumentError could be raised.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 415
+def parse(str, now = now())
+  parts_to_time(Date._parse(str, false), now)
+end
+
+
+ +
+ +
+

+ + period_for_local(time, dst = true) + +

+ + +
+

Available so that TimeZone instances respond like TZInfo::Timezone instances.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 518
+def period_for_local(time, dst = true)
+  tzinfo.period_for_local(time, dst) { |periods| periods.last }
+end
+
+
+ +
+ +
+

+ + period_for_utc(time) + +

+ + +
+

Available so that TimeZone instances respond like TZInfo::Timezone instances.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 512
+def period_for_utc(time)
+  tzinfo.period_for_utc(time)
+end
+
+
+ +
+ +
+

+ + rfc3339(str) + +

+ + +
+

Method for creating new ActiveSupport::TimeWithZone instance in time zone of self from an RFC 3339 string.

+ +
Time.zone = 'Hawaii'                     # => "Hawaii"
+Time.zone.rfc3339('2000-01-01T00:00:00Z') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+
+ +

If the time or zone components are missing then an ArgumentError will be raised. This is much stricter than either parse or iso8601 which allow for missing components.

+ +
Time.zone = 'Hawaii'            # => "Hawaii"
+Time.zone.rfc3339('1999-12-31') # => ArgumentError: invalid date
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 431
+def rfc3339(str)
+  parts = Date._rfc3339(str)
+
+  raise ArgumentError, "invalid date" if parts.empty?
+
+  time = Time.new(
+    parts.fetch(:year),
+    parts.fetch(:mon),
+    parts.fetch(:mday),
+    parts.fetch(:hour),
+    parts.fetch(:min),
+    parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
+    parts.fetch(:offset)
+  )
+
+  TimeWithZone.new(time.utc, self)
+end
+
+
+ +
+ +
+

+ + strptime(str, format, now = now()) + +

+ + +
+

Parses str according to format and returns an ActiveSupport::TimeWithZone.

+ +

Assumes that str is a time in the time zone self, unless format includes an explicit time zone. (This is the same behavior as parse.) In either case, the returned TimeWithZone has the timezone of self.

+ +
Time.zone = 'Hawaii'                   # => "Hawaii"
+Time.zone.strptime('1999-12-31 14:00:00', '%Y-%m-%d %H:%M:%S') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+
+ +

If upper components are missing from the string, they are supplied from TimeZone#now:

+ +
Time.zone.now                              # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+Time.zone.strptime('22:30:00', '%H:%M:%S') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
+
+ +

However, if the date component is not provided, but any other upper components are supplied, then the day of the month defaults to 1:

+ +
Time.zone.strptime('Mar 2000', '%b %Y') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 469
+def strptime(str, format, now = now())
+  parts_to_time(DateTime._strptime(str, format), now)
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+

Returns a textual representation of this time zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 338
+def to_s
+  "(GMT#{formatted_offset}) #{name}"
+end
+
+
+ +
+ +
+

+ + today() + +

+ + +
+

Returns the current date in this time zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 483
+def today
+  tzinfo.now.to_date
+end
+
+
+ +
+ +
+

+ + tomorrow() + +

+ + +
+

Returns the next date in this time zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 488
+def tomorrow
+  today + 1
+end
+
+
+ +
+ +
+

+ + utc_offset() + +

+ + +
+

Returns the offset of this time zone from UTC in seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 304
+def utc_offset
+  if @utc_offset
+    @utc_offset
+  else
+    tzinfo.current_period.utc_offset if tzinfo && tzinfo.current_period
+  end
+end
+
+
+ +
+ +
+

+ + utc_to_local(time) + +

+ + +
+

Adjust the given time to the simultaneous time in the time zone represented by self. Returns a Time.utc() instance – if you want an ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 500
+def utc_to_local(time)
+  tzinfo.utc_to_local(time)
+end
+
+
+ +
+ +
+

+ + yesterday() + +

+ + +
+

Returns the previous date in this time zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/values/time_zone.rb, line 493
+def yesterday
+  today - 1
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/VERSION.html b/src/5.2/classes/ActiveSupport/VERSION.html new file mode 100644 index 0000000000..426447eb03 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/VERSION.html @@ -0,0 +1,120 @@ +--- +title: ActiveSupport::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/XMLConverter.html b/src/5.2/classes/ActiveSupport/XMLConverter.html new file mode 100644 index 0000000000..ea6091e238 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/XMLConverter.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::XMLConverter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/XMLConverter/DisallowedType.html b/src/5.2/classes/ActiveSupport/XMLConverter/DisallowedType.html new file mode 100644 index 0000000000..2ada899d25 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/XMLConverter/DisallowedType.html @@ -0,0 +1,113 @@ +--- +title: ActiveSupport::XMLConverter::DisallowedType +layout: default +--- +
+ +
+
+ +
+ +

Raised if the XML contains attributes with type=“yaml” or type=“symbol”. Read Hash#from_xml for more details.

+ +
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 145
+def initialize(type)
+  super "Disallowed type attribute: #{type.inspect}"
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/XmlMini.html b/src/5.2/classes/ActiveSupport/XmlMini.html new file mode 100644 index 0000000000..37728c847d --- /dev/null +++ b/src/5.2/classes/ActiveSupport/XmlMini.html @@ -0,0 +1,421 @@ +--- +title: ActiveSupport::XmlMini +layout: default +--- +
+ +
+
+ +
+ +

XmlMini

+ +

To use the much faster libxml parser:

+ +
gem 'libxml-ruby', '=0.9.7'
+XmlMini.backend = 'LibXML'
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_ENCODINGS={ +"binary" => "base64" +} unless defined?(DEFAULT_ENCODINGS)
 
FORMATTING={ +"symbol" => Proc.new { |symbol| symbol.to_s }, +"date" => Proc.new { |date| date.to_s(:db) }, +"dateTime" => Proc.new { |time| time.xmlschema }, +"binary" => Proc.new { |binary| ::Base64.encode64(binary) }, +"yaml" => Proc.new { |yaml| yaml.to_yaml } +} unless defined?(FORMATTING)
 
PARSING={ +"symbol" => Proc.new { |symbol| symbol.to_s.to_sym }, +"date" => Proc.new { |date| ::Date.parse(date) }, +"datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc }, +"integer" => Proc.new { |integer| integer.to_i }, +"float" => Proc.new { |float| float.to_f }, +"decimal" => Proc.new do |number| +if String === number +begin +BigDecimal(number) +rescue ArgumentError +BigDecimal(number.to_f.to_s) +end +else +BigDecimal(number) +end +end, +"boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) }, +"string" => Proc.new { |string| string.to_s }, +"yaml" => Proc.new { |yaml| YAML.load(yaml) rescue yaml }, +"base64Binary" => Proc.new { |bin| ::Base64.decode64(bin) }, +"binary" => Proc.new { |bin, entity| _parse_binary(bin, entity) }, +"file" => Proc.new { |file, entity| _parse_file(file, entity) } +}
 
TYPE_NAMES={ +"Symbol" => "symbol", +"Integer" => "integer", +"BigDecimal" => "decimal", +"Float" => "float", +"TrueClass" => "boolean", +"FalseClass" => "boolean", +"Date" => "date", +"DateTime" => "dateTime", +"Time" => "dateTime", +"Array" => "array", +"Hash" => "hash" +}
 
+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + depth
+ + + + + +

Instance Public methods

+ +
+

+ + backend() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini.rb, line 103
+def backend
+  current_thread_backend || @backend
+end
+
+
+ +
+ +
+

+ + backend=(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini.rb, line 107
+def backend=(name)
+  backend = name && cast_backend_name_to_module(name)
+  self.current_thread_backend = backend if current_thread_backend
+  @backend = backend
+end
+
+
+ +
+ +
+

+ + rename_key(key, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini.rb, line 154
+def rename_key(key, options = {})
+  camelize  = options[:camelize]
+  dasherize = !options.has_key?(:dasherize) || options[:dasherize]
+  if camelize
+    key = true == camelize ? key.camelize : key.camelize(camelize)
+  end
+  key = _dasherize(key) if dasherize
+  key
+end
+
+
+ +
+ +
+

+ + to_tag(key, value, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini.rb, line 121
+def to_tag(key, value, options)
+  type_name = options.delete(:type)
+  merged_options = options.merge(root: key, skip_instruct: true)
+
+  if value.is_a?(::Method) || value.is_a?(::Proc)
+    if value.arity == 1
+      value.call(merged_options)
+    else
+      value.call(merged_options, key.to_s.singularize)
+    end
+  elsif value.respond_to?(:to_xml)
+    value.to_xml(merged_options)
+  else
+    type_name ||= TYPE_NAMES[value.class.name]
+    type_name ||= value.class.name if value && !value.respond_to?(:to_str)
+    type_name   = type_name.to_s   if type_name
+    type_name   = "dateTime" if type_name == "datetime"
+
+    key = rename_key(key.to_s, options)
+
+    attributes = options[:skip_types] || type_name.nil? ? {} : { type: type_name }
+    attributes[:nil] = true if value.nil?
+
+    encoding = options[:encoding] || DEFAULT_ENCODINGS[type_name]
+    attributes[:encoding] = encoding if encoding
+
+    formatted_value = FORMATTING[type_name] && !value.nil? ?
+      FORMATTING[type_name].call(value) : value
+
+    options[:builder].tag!(key, formatted_value, attributes)
+  end
+end
+
+
+ +
+ +
+

+ + with_backend(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini.rb, line 113
+def with_backend(name)
+  old_backend = current_thread_backend
+  self.current_thread_backend = name && cast_backend_name_to_module(name)
+  yield
+ensure
+  self.current_thread_backend = old_backend
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX.html b/src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX.html new file mode 100644 index 0000000000..aeadd3a275 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::XmlMini_LibXMLSAX +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX/HashBuilder.html b/src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX/HashBuilder.html new file mode 100644 index 0000000000..47f6c5c679 --- /dev/null +++ b/src/5.2/classes/ActiveSupport/XmlMini_LibXMLSAX/HashBuilder.html @@ -0,0 +1,410 @@ +--- +title: ActiveSupport::XmlMini_LibXMLSAX::HashBuilder +layout: default +--- +
+ +
+
+ +
+ +

Class that will build the hash while the XML document is being parsed using SAX events.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + LibXML::XML::SaxParser::Callbacks + +
  • + +
+ + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CONTENT_KEY="__content__".freeze
 
HASH_SIZE_KEY="__hash_size__".freeze
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + hash
+ + + + + +

Instance Public methods

+ +
+

+ + current_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 21
+def current_hash
+  @hash_stack.last
+end
+
+
+ +
+ +
+

+ + on_cdata_block(string) + +

+ + +
+ +
+ + + + + +
+ Alias for: on_characters +
+ + + +
+ +
+

+ + on_characters(string) + +

+ + +
+ +
+ + + +
+ Also aliased as: on_cdata_block +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 55
+def on_characters(string)
+  current_hash[CONTENT_KEY] << string
+end
+
+
+ +
+ +
+

+ + on_end_document() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 30
+def on_end_document
+  @hash = @hash_stack.pop
+  @hash.delete(CONTENT_KEY)
+end
+
+
+ +
+ +
+

+ + on_end_element(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 48
+def on_end_element(name)
+  if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == ""
+    current_hash.delete(CONTENT_KEY)
+  end
+  @hash_stack.pop
+end
+
+
+ +
+ +
+

+ + on_start_document() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 25
+def on_start_document
+  @hash = { CONTENT_KEY => "".dup }
+  @hash_stack = [@hash]
+end
+
+
+ +
+ +
+

+ + on_start_element(name, attrs = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 35
+def on_start_element(name, attrs = {})
+  new_hash = { CONTENT_KEY => "".dup }.merge!(attrs)
+  new_hash[HASH_SIZE_KEY] = new_hash.size + 1
+
+  case current_hash[name]
+  when Array then current_hash[name] << new_hash
+  when Hash  then current_hash[name] = [current_hash[name], new_hash]
+  when nil   then current_hash[name] = new_hash
+  end
+
+  @hash_stack.push(new_hash)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX.html b/src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX.html new file mode 100644 index 0000000000..3300ff159b --- /dev/null +++ b/src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::XmlMini_NokogiriSAX +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX/HashBuilder.html b/src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX/HashBuilder.html new file mode 100644 index 0000000000..e73770950d --- /dev/null +++ b/src/5.2/classes/ActiveSupport/XmlMini_NokogiriSAX/HashBuilder.html @@ -0,0 +1,436 @@ +--- +title: ActiveSupport::XmlMini_NokogiriSAX::HashBuilder +layout: default +--- +
+ +
+
+ +
+ +

Class that will build the hash while the XML document is being parsed using SAX events.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CONTENT_KEY="__content__".freeze
 
HASH_SIZE_KEY="__hash_size__".freeze
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + hash
+ + + + + +

Instance Public methods

+ +
+

+ + cdata_block(string) + +

+ + +
+ +
+ + + + + +
+ Alias for: characters +
+ + + +
+ +
+

+ + characters(string) + +

+ + +
+ +
+ + + +
+ Also aliased as: cdata_block +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 61
+def characters(string)
+  current_hash[CONTENT_KEY] << string
+end
+
+
+ +
+ +
+

+ + current_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 24
+def current_hash
+  @hash_stack.last
+end
+
+
+ +
+ +
+

+ + end_document() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 33
+def end_document
+  raise "Parse stack not empty!" if @hash_stack.size > 1
+end
+
+
+ +
+ +
+

+ + end_element(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 54
+def end_element(name)
+  if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == ""
+    current_hash.delete(CONTENT_KEY)
+  end
+  @hash_stack.pop
+end
+
+
+ +
+ +
+

+ + error(error_message) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 37
+def error(error_message)
+  raise error_message
+end
+
+
+ +
+ +
+

+ + start_document() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 28
+def start_document
+  @hash = {}
+  @hash_stack = [@hash]
+end
+
+
+ +
+ +
+

+ + start_element(name, attrs = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 41
+def start_element(name, attrs = [])
+  new_hash = { CONTENT_KEY => "".dup }.merge!(Hash[attrs])
+  new_hash[HASH_SIZE_KEY] = new_hash.size + 1
+
+  case current_hash[name]
+  when Array then current_hash[name] << new_hash
+  when Hash  then current_hash[name] = [current_hash[name], new_hash]
+  when nil   then current_hash[name] = new_hash
+  end
+
+  @hash_stack.push(new_hash)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Array.html b/src/5.2/classes/Array.html new file mode 100644 index 0000000000..fe73283579 --- /dev/null +++ b/src/5.2/classes/Array.html @@ -0,0 +1,1420 @@ +--- +title: Array +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + wrap(object) + +

+ + +
+

Wraps its argument in an array unless it is already an array (or array-like).

+ +

Specifically:

+
  • +

    If the argument is nil an empty array is returned.

    +
  • +

    Otherwise, if the argument responds to to_ary it is invoked, and its result returned.

    +
  • +

    Otherwise, returns an array with the argument as its single element.

    + +
    Array.wrap(nil)       # => []
    +Array.wrap([1, 2, 3]) # => [1, 2, 3]
    +Array.wrap(0)         # => [0]
    +
    +
+ +

This method is similar in purpose to Kernel#Array, but there are some differences:

+
  • +

    If the argument responds to to_ary the method is invoked. Kernel#Array moves on to try to_a if the returned value is nil, but Array.wrap returns an array with the argument as its single element right away.

    +
  • +

    If the returned value from to_ary is neither nil nor an Array object, Kernel#Array raises an exception, while Array.wrap does not, it just returns the value.

    +
  • +

    It does not call to_a on the argument, if the argument does not respond to to_ary it returns an array with the argument as its single element.

    +
+ +

The last point is easily explained with some enumerables:

+ +
Array(foo: :bar)      # => [[:foo, :bar]]
+Array.wrap(foo: :bar) # => [{:foo=>:bar}]
+
+ +

There's also a related idiom that uses the splat operator:

+ +
[*object]
+
+ +

which returns [] for nil, but calls to Array(object) otherwise.

+ +

The differences with Kernel#Array explained above apply to the rest of objects.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/wrap.rb, line 39
+def self.wrap(object)
+  if object.nil?
+    []
+  elsif object.respond_to?(:to_ary)
+    object.to_ary || [object]
+  else
+    [object]
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + deep_dup() + +

+ + +
+

Returns a deep copy of array.

+ +
array = [1, [2, 3]]
+dup   = array.deep_dup
+dup[1][2] = 4
+
+array[1][2] # => nil
+dup[1][2]   # => 4
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 29
+def deep_dup
+  map(&:deep_dup)
+end
+
+
+ +
+ +
+

+ + extract_options!() + +

+ + +
+

Extracts options from a set of arguments. Removes and returns the last element in the array if it's a hash, otherwise returns a blank hash.

+ +
def options(*args)
+  args.extract_options!
+end
+
+options(1, 2)        # => {}
+options(1, 2, a: :b) # => {:a=>:b}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/extract_options.rb, line 24
+def extract_options!
+  if last.is_a?(Hash) && last.extractable_options?
+    pop
+  else
+    {}
+  end
+end
+
+
+ +
+ +
+

+ + fifth() + +

+ + +
+

Equal to self[4].

+ +
%w( a b c d e ).fifth # => "e"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 68
+def fifth
+  self[4]
+end
+
+
+ +
+ +
+

+ + forty_two() + +

+ + +
+

Equal to self[41]. Also known as accessing “the reddit”.

+ +
(1..42).to_a.forty_two # => 42
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 75
+def forty_two
+  self[41]
+end
+
+
+ +
+ +
+

+ + fourth() + +

+ + +
+

Equal to self[3].

+ +
%w( a b c d e ).fourth # => "d"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 61
+def fourth
+  self[3]
+end
+
+
+ +
+ +
+

+ + from(position) + +

+ + +
+

Returns the tail of the array from position.

+ +
%w( a b c d ).from(0)  # => ["a", "b", "c", "d"]
+%w( a b c d ).from(2)  # => ["c", "d"]
+%w( a b c d ).from(10) # => []
+%w().from(0)           # => []
+%w( a b c d ).from(-2) # => ["c", "d"]
+%w( a b c ).from(-10)  # => []
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 12
+def from(position)
+  self[position, length] || []
+end
+
+
+ +
+ +
+

+ + in_groups(number, fill_with = nil) + +

+ + +
+

Splits or iterates over the array in number of groups, padding any remaining slots with fill_with unless it is false.

+ +
%w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
+["1", "2", "3", "4"]
+["5", "6", "7", nil]
+["8", "9", "10", nil]
+
+%w(1 2 3 4 5 6 7 8 9 10).in_groups(3, '&nbsp;') {|group| p group}
+["1", "2", "3", "4"]
+["5", "6", "7", "&nbsp;"]
+["8", "9", "10", "&nbsp;"]
+
+%w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
+["1", "2", "3"]
+["4", "5"]
+["6", "7"]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 62
+def in_groups(number, fill_with = nil)
+  # size.div number gives minor group size;
+  # size % number gives how many objects need extra accommodation;
+  # each group hold either division or division + 1 items.
+  division = size.div number
+  modulo = size % number
+
+  # create a new array avoiding dup
+  groups = []
+  start = 0
+
+  number.times do |index|
+    length = division + (modulo > 0 && modulo > index ? 1 : 0)
+    groups << last_group = slice(start, length)
+    last_group << fill_with if fill_with != false &&
+      modulo > 0 && length == division
+    start += length
+  end
+
+  if block_given?
+    groups.each { |g| yield(g) }
+  else
+    groups
+  end
+end
+
+
+ +
+ +
+

+ + in_groups_of(number, fill_with = nil) + +

+ + +
+

Splits or iterates over the array in groups of size number, padding any remaining slots with fill_with unless it is false.

+ +
%w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
+["1", "2", "3"]
+["4", "5", "6"]
+["7", "8", "9"]
+["10", nil, nil]
+
+%w(1 2 3 4 5).in_groups_of(2, '&nbsp;') {|group| p group}
+["1", "2"]
+["3", "4"]
+["5", "&nbsp;"]
+
+%w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
+["1", "2"]
+["3", "4"]
+["5"]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 22
+def in_groups_of(number, fill_with = nil)
+  if number.to_i <= 0
+    raise ArgumentError,
+      "Group size must be a positive integer, was #{number.inspect}"
+  end
+
+  if fill_with == false
+    collection = self
+  else
+    # size % number gives how many extra we have;
+    # subtracting from number gives how many to add;
+    # modulo number ensures we don't add group of just fill.
+    padding = (number - size % number) % number
+    collection = dup.concat(Array.new(padding, fill_with))
+  end
+
+  if block_given?
+    collection.each_slice(number) { |slice| yield(slice) }
+  else
+    collection.each_slice(number).to_a
+  end
+end
+
+
+ +
+ +
+

+ + inquiry() + +

+ + +
+

Wraps the array in an ArrayInquirer object, which gives a friendlier way to check its string-like contents.

+ +
pets = [:cat, :dog].inquiry
+
+pets.cat?     # => true
+pets.ferret?  # => false
+
+pets.any?(:cat, :ferret)  # => true
+pets.any?(:ferret, :alligator)  # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/inquiry.rb, line 16
+def inquiry
+  ActiveSupport::ArrayInquirer.new(self)
+end
+
+
+ +
+ +
+

+ + second() + +

+ + +
+

Equal to self[1].

+ +
%w( a b c d e ).second # => "b"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 47
+def second
+  self[1]
+end
+
+
+ +
+ +
+

+ + second_to_last() + +

+ + +
+

Equal to self[-2].

+ +
%w( a b c d e ).second_to_last # => "d"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 89
+def second_to_last
+  self[-2]
+end
+
+
+ +
+ +
+

+ + split(value = nil) + +

+ + +
+

Divides the array into one or more subarrays based on a delimiting value or the result of an optional block.

+ +
[1, 2, 3, 4, 5].split(3)              # => [[1, 2], [4, 5]]
+(1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 93
+def split(value = nil)
+  arr = dup
+  result = []
+  if block_given?
+    while (idx = arr.index { |i| yield i })
+      result << arr.shift(idx)
+      arr.shift
+    end
+  else
+    while (idx = arr.index(value))
+      result << arr.shift(idx)
+      arr.shift
+    end
+  end
+  result << arr
+end
+
+
+ +
+ +
+

+ + third() + +

+ + +
+

Equal to self[2].

+ +
%w( a b c d e ).third # => "c"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 54
+def third
+  self[2]
+end
+
+
+ +
+ +
+

+ + third_to_last() + +

+ + +
+

Equal to self[-3].

+ +
%w( a b c d e ).third_to_last # => "c"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 82
+def third_to_last
+  self[-3]
+end
+
+
+ +
+ +
+

+ + to(position) + +

+ + +
+

Returns the beginning of the array up to position.

+ +
%w( a b c d ).to(0)  # => ["a"]
+%w( a b c d ).to(2)  # => ["a", "b", "c"]
+%w( a b c d ).to(10) # => ["a", "b", "c", "d"]
+%w().to(0)           # => []
+%w( a b c d ).to(-2) # => ["a", "b", "c"]
+%w( a b c ).to(-10)  # => []
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 24
+def to(position)
+  if position >= 0
+    take position + 1
+  else
+    self[0..position]
+  end
+end
+
+
+ +
+ +
+

+ + to_default_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+

Extends Array#to_s to convert a collection of elements into a comma separated id list if :db argument is given as the format.

+ +
Blog.all.to_formatted_s(:db)  # => "1,2,3"
+Blog.none.to_formatted_s(:db) # => "null"
+[1,2].to_formatted_s          # => "[1, 2]"
+
+
+ + + +
+ Also aliased as: to_s +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 93
+def to_formatted_s(format = :default)
+  case format
+  when :db
+    if empty?
+      "null"
+    else
+      collect(&:id).join(",")
+    end
+  else
+    to_default_s
+  end
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+

Calls to_param on all its elements and joins the result with slashes. This is used by url_for in Action Pack.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 42
+def to_param
+  collect(&:to_param).join "/"
+end
+
+
+ +
+ +
+

+ + to_query(key) + +

+ + +
+

Converts an array into a string suitable for use as a URL query string, using the given key as the param name.

+ +
['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 50
+def to_query(key)
+  prefix = "#{key}[]"
+
+  if empty?
+    nil.to_query(prefix)
+  else
+    collect { |value| value.to_query(prefix) }.join "&"
+  end
+end
+
+
+ +
+ +
+

+ + to_s(format = :default) + +

+ + +
+ +
+ + + +
+ Also aliased as: to_default_s +
+ + + +
+ Alias for: to_formatted_s +
+ + + +
+ +
+

+ + to_sentence(options = {}) + +

+ + +
+

Converts the array to a comma-separated sentence where the last element is joined by the connector word.

+ +

You can pass the following options to change the default behavior. If you pass an option key that doesn't exist in the list below, it will raise an ArgumentError.

+ +

Options

+
  • +

    :words_connector - The sign or word used to join the elements in arrays with two or more elements (default: “, ”).

    +
  • +

    :two_words_connector - The sign or word used to join the elements in arrays with two elements (default: “ and ”).

    +
  • +

    :last_word_connector - The sign or word used to join the last element in arrays with three or more elements (default: “, and ”).

    +
  • +

    :locale - If i18n is available, you can set a locale and use the connector options defined on the 'support.array' namespace in the corresponding dictionary file.

    +
+ +

Examples

+ +
[].to_sentence                      # => ""
+['one'].to_sentence                 # => "one"
+['one', 'two'].to_sentence          # => "one and two"
+['one', 'two', 'three'].to_sentence # => "one, two, and three"
+
+['one', 'two'].to_sentence(passing: 'invalid option')
+# => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale
+
+['one', 'two'].to_sentence(two_words_connector: '-')
+# => "one-two"
+
+['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
+# => "one or two or at least three"
+
+ +

Using :locale option:

+ +
# Given this locale dictionary:
+#
+#   es:
+#     support:
+#       array:
+#         words_connector: " o "
+#         two_words_connector: " y "
+#         last_word_connector: " o al menos "
+
+['uno', 'dos'].to_sentence(locale: :es)
+# => "uno y dos"
+
+['uno', 'dos', 'tres'].to_sentence(locale: :es)
+# => "uno o dos o al menos tres"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 61
+def to_sentence(options = {})
+  options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
+
+  default_connectors = {
+    words_connector: ", ",
+    two_words_connector: " and ",
+    last_word_connector: ", and "
+  }
+  if defined?(I18n)
+    i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
+    default_connectors.merge!(i18n_connectors)
+  end
+  options = default_connectors.merge!(options)
+
+  case length
+  when 0
+    ""
+  when 1
+    "#{self[0]}"
+  when 2
+    "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
+  else
+    "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
+  end
+end
+
+
+ +
+ +
+

+ + to_xml(options = {}) + +

+ + +
+

Returns a string that represents the array in XML by invoking to_xml on each element. Active Record collections delegate their representation in XML to this method.

+ +

All elements are expected to respond to to_xml, if any of them does not then an exception is raised.

+ +

The root node reflects the class name of the first element in plural if all elements belong to the same type and that's not Hash:

+ +
customer.projects.to_xml
+
+<?xml version="1.0" encoding="UTF-8"?>
+<projects type="array">
+  <project>
+    <amount type="decimal">20000.0</amount>
+    <customer-id type="integer">1567</customer-id>
+    <deal-date type="date">2008-04-09</deal-date>
+    ...
+  </project>
+  <project>
+    <amount type="decimal">57230.0</amount>
+    <customer-id type="integer">1567</customer-id>
+    <deal-date type="date">2008-04-15</deal-date>
+    ...
+  </project>
+</projects>
+
+ +

Otherwise the root element is “objects”:

+ +
[{ foo: 1, bar: 2}, { baz: 3}].to_xml
+
+<?xml version="1.0" encoding="UTF-8"?>
+<objects type="array">
+  <object>
+    <bar type="integer">2</bar>
+    <foo type="integer">1</foo>
+  </object>
+  <object>
+    <baz type="integer">3</baz>
+  </object>
+</objects>
+
+ +

If the collection is empty the root element is “nil-classes” by default:

+ +
[].to_xml
+
+<?xml version="1.0" encoding="UTF-8"?>
+<nil-classes type="array"/>
+
+ +

To ensure a meaningful root element use the :root option:

+ +
customer_with_no_projects.projects.to_xml(root: 'projects')
+
+<?xml version="1.0" encoding="UTF-8"?>
+<projects type="array"/>
+
+ +

By default name of the node for the children of root is root.singularize. You can change it with the :children option.

+ +

The options hash is passed downwards:

+ +
Message.all.to_xml(skip_types: true)
+
+<?xml version="1.0" encoding="UTF-8"?>
+<messages>
+  <message>
+    <created-at>2008-03-07T09:58:18+01:00</created-at>
+    <id>1</id>
+    <name>1</name>
+    <updated-at>2008-03-07T09:58:18+01:00</updated-at>
+    <user-id>1</user-id>
+  </message>
+</messages>
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 183
+def to_xml(options = {})
+  require "active_support/builder" unless defined?(Builder)
+
+  options = options.dup
+  options[:indent]  ||= 2
+  options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
+  options[:root]    ||= \
+    if first.class != Hash && all? { |e| e.is_a?(first.class) }
+      underscored = ActiveSupport::Inflector.underscore(first.class.name)
+      ActiveSupport::Inflector.pluralize(underscored).tr("/", "_")
+    else
+      "objects"
+    end
+
+  builder = options[:builder]
+  builder.instruct! unless options.delete(:skip_instruct)
+
+  root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
+  children = options.delete(:children) || root.singularize
+  attributes = options[:skip_types] ? {} : { type: "array" }
+
+  if empty?
+    builder.tag!(root, attributes)
+  else
+    builder.tag!(root, attributes) do
+      each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
+      yield builder if block_given?
+    end
+  end
+end
+
+
+ +
+ +
+

+ + without(*elements) + +

+ + +
+

Returns a copy of the Array without the specified elements.

+ +
people = ["David", "Rafael", "Aaron", "Todd"]
+people.without "Aaron", "Todd"
+# => ["David", "Rafael"]
+
+ +

Note: This is an optimization of Enumerable#without that uses Array#- instead of Array#reject for performance reasons.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/access.rb, line 40
+def without(*elements)
+  self - elements
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Benchmark.html b/src/5.2/classes/Benchmark.html new file mode 100644 index 0000000000..442584fb29 --- /dev/null +++ b/src/5.2/classes/Benchmark.html @@ -0,0 +1,108 @@ +--- +title: Benchmark +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + ms +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + ms() + +

+ + +
+

Benchmark realtime in milliseconds.

+ +
Benchmark.realtime { User.all }
+# => 8.0e-05
+
+Benchmark.ms { User.all }
+# => 0.074
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/benchmark.rb, line 13
+def ms
+  1000 * realtime { yield }
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/BigDecimal.html b/src/5.2/classes/BigDecimal.html new file mode 100644 index 0000000000..139be17464 --- /dev/null +++ b/src/5.2/classes/BigDecimal.html @@ -0,0 +1,113 @@ +--- +title: BigDecimal +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + duplicable?() + +

+ + +
+

BigDecimals are duplicable:

+ +
BigDecimal("1.2").duplicable? # => true
+BigDecimal("1.2").dup         # => #<BigDecimal:...,'0.12E1',18(18)>
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 113
+def duplicable?
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Class.html b/src/5.2/classes/Class.html new file mode 100644 index 0000000000..2bef555652 --- /dev/null +++ b/src/5.2/classes/Class.html @@ -0,0 +1,354 @@ +--- +title: Class +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + class_attribute(*attrs) + +

+ + +
+

Declare a class-level attribute whose value is inheritable by subclasses. Subclasses can change their own value and it will not impact parent class.

+ +

Options

+
  • +

    :instance_reader - Sets the instance reader method (defaults to true).

    +
  • +

    :instance_writer - Sets the instance writer method (defaults to true).

    +
  • +

    :instance_accessor - Sets both instance methods (defaults to true).

    +
  • +

    :instance_predicate - Sets a predicate method (defaults to true).

    +
  • +

    :default - Sets a default value for the attribute (defaults to nil).

    +
+ +

Examples

+ +
class Base
+  class_attribute :setting
+end
+
+class Subclass < Base
+end
+
+Base.setting = true
+Subclass.setting            # => true
+Subclass.setting = false
+Subclass.setting            # => false
+Base.setting                # => true
+
+ +

In the above case as long as Subclass does not assign a value to setting by performing Subclass.setting = something, Subclass.setting would read value assigned to parent class. Once Subclass assigns a value then the value assigned by Subclass would be returned.

+ +

This matches normal Ruby method inheritance: think of writing an attribute on a subclass as overriding the reader method. However, you need to be aware when using class_attribute with mutable structures as Array or Hash. In such cases, you don't want to do changes in place. Instead use setters:

+ +
Base.setting = []
+Base.setting                # => []
+Subclass.setting            # => []
+
+# Appending in child changes both parent and child because it is the same object:
+Subclass.setting << :foo
+Base.setting               # => [:foo]
+Subclass.setting           # => [:foo]
+
+# Use setters to not propagate changes:
+Base.setting = []
+Subclass.setting += [:foo]
+Base.setting               # => []
+Subclass.setting           # => [:foo]
+
+ +

For convenience, an instance predicate method is defined as well. To skip it, pass instance_predicate: false.

+ +
Subclass.setting?       # => false
+
+ +

Instances may overwrite the class value in the same way:

+ +
Base.setting = true
+object = Base.new
+object.setting          # => true
+object.setting = false
+object.setting          # => false
+Base.setting            # => true
+
+ +

To opt out of the instance reader method, pass instance_reader: false.

+ +
object.setting          # => NoMethodError
+object.setting?         # => NoMethodError
+
+ +

To opt out of the instance writer method, pass instance_writer: false.

+ +
object.setting = false  # => NoMethodError
+
+ +

To opt out of both instance methods, pass instance_accessor: false.

+ +

To set a default value for the attribute, pass default:, like so:

+ +
class_attribute :settings, default: {}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/class/attribute.rb, line 87
+def class_attribute(*attrs)
+  options = attrs.extract_options!
+  instance_reader    = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
+  instance_writer    = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
+  instance_predicate = options.fetch(:instance_predicate, true)
+  default_value      = options.fetch(:default, nil)
+
+  attrs.each do |name|
+    singleton_class.silence_redefinition_of_method(name)
+    define_singleton_method(name) { nil }
+
+    singleton_class.silence_redefinition_of_method("#{name}?")
+    define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
+
+    ivar = "@#{name}"
+
+    singleton_class.silence_redefinition_of_method("#{name}=")
+    define_singleton_method("#{name}=") do |val|
+      singleton_class.class_eval do
+        redefine_method(name) { val }
+      end
+
+      if singleton_class?
+        class_eval do
+          redefine_method(name) do
+            if instance_variable_defined? ivar
+              instance_variable_get ivar
+            else
+              singleton_class.send name
+            end
+          end
+        end
+      end
+      val
+    end
+
+    if instance_reader
+      redefine_method(name) do
+        if instance_variable_defined?(ivar)
+          instance_variable_get ivar
+        else
+          self.class.public_send name
+        end
+      end
+
+      redefine_method("#{name}?") { !!public_send(name) } if instance_predicate
+    end
+
+    if instance_writer
+      redefine_method("#{name}=") do |val|
+        instance_variable_set ivar, val
+      end
+    end
+
+    unless default_value.nil?
+      self.send("#{name}=", default_value)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + descendants() + +

+ + +
+

Returns an array with all classes that are < than its receiver.

+ +
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]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/class/subclasses.rb, line 21
+def descendants
+  descendants = []
+  ObjectSpace.each_object(singleton_class) do |k|
+    next if k.singleton_class?
+    descendants.unshift k unless k == self
+  end
+  descendants
+end
+
+
+ +
+ +
+

+ + subclasses() + +

+ + +
+

Returns an array with the direct children of self.

+ +
class Foo; end
+class Bar < Foo; end
+class Baz < Bar; end
+
+Foo.subclasses # => [Bar]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/class/subclasses.rb, line 47
+def subclasses
+  subclasses, chain = [], descendants
+  chain.each do |k|
+    subclasses << k unless chain.any? { |c| c > k }
+  end
+  subclasses
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Complex.html b/src/5.2/classes/Complex.html new file mode 100644 index 0000000000..f5c8874938 --- /dev/null +++ b/src/5.2/classes/Complex.html @@ -0,0 +1,113 @@ +--- +title: Complex +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + duplicable?() + +

+ + +
+

Complexes are not duplicable:

+ +
Complex(1).duplicable? # => false
+Complex(1).dup         # => TypeError: can't copy Complex
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 137
+def duplicable?
+  false
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Date.html b/src/5.2/classes/Date.html new file mode 100644 index 0000000000..85c6f4c8b3 --- /dev/null +++ b/src/5.2/classes/Date.html @@ -0,0 +1,1446 @@ +--- +title: Date +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DATE_FORMATS={ +short: "%d %b", +long: "%B %d, %Y", +db: "%Y-%m-%d", +number: "%Y%m%d", +long_ordinal: lambda { |date| +day_format = ActiveSupport::Inflector.ordinalize(date.day) +date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007" +}, +rfc822: "%d %b %Y", +iso8601: lambda { |date| date.iso8601 } +}
 
+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + beginning_of_week_default
+ + + + +

Class Public methods

+ +
+

+ + beginning_of_week() + +

+ + +
+

Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=). If Date.beginning_of_week has not been set for the current request, returns the week start specified in config.beginning_of_week. If no config.beginning_of_week was specified, returns :monday.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 19
+def beginning_of_week
+  Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
+end
+
+
+ +
+ +
+

+ + beginning_of_week=(week_start) + +

+ + +
+

Sets Date.beginning_of_week to a week start (e.g. :monday) for current request/thread.

+ +

This method accepts any of the following day symbols: :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 27
+def beginning_of_week=(week_start)
+  Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
+end
+
+
+ +
+ +
+

+ + current() + +

+ + +
+

Returns Time.zone.today when Time.zone or config.time_zone are set, otherwise just returns Date.today.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 48
+def current
+  ::Time.zone ? ::Time.zone.today : ::Date.today
+end
+
+
+ +
+ +
+

+ + find_beginning_of_week!(week_start) + +

+ + +
+

Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 32
+def find_beginning_of_week!(week_start)
+  raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
+  week_start
+end
+
+
+ +
+ +
+

+ + tomorrow() + +

+ + +
+

Returns a new Date representing the date 1 day after today (i.e. tomorrow's date).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 43
+def tomorrow
+  ::Date.current.tomorrow
+end
+
+
+ +
+ +
+

+ + yesterday() + +

+ + +
+

Returns a new Date representing the date 1 day ago (i.e. yesterday's date).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 38
+def yesterday
+  ::Date.current.yesterday
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(other) + +

+ + +
+ +
+ + + +
+ Also aliased as: compare_without_coercion +
+ + + +
+ Alias for: compare_with_coercion +
+ + + +
+ +
+

+ + acts_like_date?() + +

+ + +
+

Duck-types as a Date-like class. See Object#acts_like?.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/acts_like.rb, line 7
+def acts_like_date?
+  true
+end
+
+
+ +
+ +
+

+ + advance(options) + +

+ + +
+

Provides precise Date calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 112
+def advance(options)
+  options = options.dup
+  d = self
+  d = d >> options.delete(:years) * 12 if options[:years]
+  d = d >> options.delete(:months)     if options[:months]
+  d = d +  options.delete(:weeks) * 7  if options[:weeks]
+  d = d +  options.delete(:days)       if options[:days]
+  d
+end
+
+
+ +
+ +
+

+ + ago(seconds) + +

+ + +
+

Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) and then subtracts the specified number of seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 55
+def ago(seconds)
+  in_time_zone.since(-seconds)
+end
+
+
+ +
+ +
+

+ + at_beginning_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + at_end_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_day +
+ + + +
+ +
+

+ + at_midday() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + at_middle_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + at_midnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + at_noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + beginning_of_day() + +

+ + +
+

Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)

+
+ + + +
+ Also aliased as: midnight, at_midnight, at_beginning_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 67
+def beginning_of_day
+  in_time_zone
+end
+
+
+ +
+ +
+

+ + change(options) + +

+ + +
+

Returns a new Date where one or more of the elements have been changed according to the options parameter. The options parameter is a hash with a combination of these keys: :year, :month, :day.

+ +
Date.new(2007, 5, 12).change(day: 1)               # => Date.new(2007, 5, 1)
+Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 127
+def change(options)
+  ::Date.new(
+    options.fetch(:year, year),
+    options.fetch(:month, month),
+    options.fetch(:day, day)
+  )
+end
+
+
+ +
+ +
+

+ + compare_with_coercion(other) + +

+ + +
+

Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.

+
+ + + +
+ Also aliased as: <=> +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 136
+def compare_with_coercion(other)
+  if other.is_a?(Time)
+    to_datetime <=> other
+  else
+    compare_without_coercion(other)
+  end
+end
+
+
+ +
+ +
+

+ + compare_without_coercion(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: <=> +
+ + + +
+ +
+

+ + default_inspect() + +

+ + +
+ +
+ + + + + +
+ Alias for: inspect +
+ + + +
+ +
+

+ + end_of_day() + +

+ + +
+

Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)

+
+ + + +
+ Also aliased as: at_end_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 85
+def end_of_day
+  in_time_zone.end_of_day
+end
+
+
+ +
+ +
+

+ + in(seconds) + +

+ + +
+ +
+ + + + + +
+ Alias for: since +
+ + + +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + +
+ Also aliased as: default_inspect +
+ + + +
+ Alias for: readable_inspect +
+ + + +
+ +
+

+ + midday() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + middle_of_day() + +

+ + +
+

Converts Date to a Time (or DateTime if necessary) with the time portion set to the middle of the day (12:00)

+
+ + + +
+ Also aliased as: midday, noon, at_midday, at_noon, at_middle_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 75
+def middle_of_day
+  in_time_zone.middle_of_day
+end
+
+
+ +
+ +
+

+ + midnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + readable_inspect() + +

+ + +
+

Overrides the default inspect method with a human readable one, e.g., “Mon, 21 Feb 2005”

+
+ + + +
+ Also aliased as: inspect +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/conversions.rb, line 61
+def readable_inspect
+  strftime("%a, %d %b %Y")
+end
+
+
+ +
+ +
+

+ + since(seconds) + +

+ + +
+

Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) and then adds the specified number of seconds

+
+ + + +
+ Also aliased as: in +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 61
+def since(seconds)
+  in_time_zone.since(seconds)
+end
+
+
+ +
+ +
+

+ + to_default_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+

Convert to a formatted string. See DATE_FORMATS for predefined formats.

+ +

This method is aliased to to_s.

+ +
date = Date.new(2007, 11, 10)       # => Sat, 10 Nov 2007
+
+date.to_formatted_s(:db)            # => "2007-11-10"
+date.to_s(:db)                      # => "2007-11-10"
+
+date.to_formatted_s(:short)         # => "10 Nov"
+date.to_formatted_s(:number)        # => "20071110"
+date.to_formatted_s(:long)          # => "November 10, 2007"
+date.to_formatted_s(:long_ordinal)  # => "November 10th, 2007"
+date.to_formatted_s(:rfc822)        # => "10 Nov 2007"
+date.to_formatted_s(:iso8601)       # => "2007-11-10"
+
+ +

Adding your own date formats to to_formatted_s

+ +

You can add your own formats to the Date::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a date argument as the value.

+ +
# config/initializers/date_formats.rb
+Date::DATE_FORMATS[:month_and_year] = '%B %Y'
+Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") }
+
+
+ + + +
+ Also aliased as: to_s +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/conversions.rb, line 46
+def to_formatted_s(format = :default)
+  if formatter = DATE_FORMATS[format]
+    if formatter.respond_to?(:call)
+      formatter.call(self).to_s
+    else
+      strftime(formatter)
+    end
+  else
+    to_default_s
+  end
+end
+
+
+ +
+ +
+

+ + to_s(format = :default) + +

+ + +
+ +
+ + + +
+ Also aliased as: to_default_s +
+ + + +
+ Alias for: to_formatted_s +
+ + + +
+ +
+

+ + to_time(form = :local) + +

+ + +
+

Converts a Date instance to a Time, where the time is set to the beginning of the day. The timezone can be either :local or :utc (default :local).

+ +
date = Date.new(2007, 11, 10)  # => Sat, 10 Nov 2007
+
+date.to_time                   # => 2007-11-10 00:00:00 0800
+date.to_time(:local)           # => 2007-11-10 00:00:00 0800
+
+date.to_time(:utc)             # => 2007-11-10 00:00:00 UTC
+
+ +

NOTE: The :local timezone is Ruby's process timezone, i.e. ENV.

+ +
If the *application's* timezone is needed, then use +in_time_zone+ instead.
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/conversions.rb, line 81
+def to_time(form = :local)
+  raise ArgumentError, "Expected :local or :utc, got #{form.inspect}." unless [:local, :utc].include?(form)
+  ::Time.send(form, year, month, day)
+end
+
+
+ +
+ +
+

+ + xmlschema() + +

+ + +
+

Returns a string which represents the time in used time zone as DateTime defined by XML Schema:

+ +
date = Date.new(2015, 05, 23)  # => Sat, 23 May 2015
+date.xmlschema                 # => "2015-05-23T00:00:00+04:00"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date/conversions.rb, line 93
+def xmlschema
+  in_time_zone.xmlschema
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/DateAndTime.html b/src/5.2/classes/DateAndTime.html new file mode 100644 index 0000000000..9f2dc2d02f --- /dev/null +++ b/src/5.2/classes/DateAndTime.html @@ -0,0 +1,75 @@ +--- +title: DateAndTime +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/DateAndTime/Calculations.html b/src/5.2/classes/DateAndTime/Calculations.html new file mode 100644 index 0000000000..388fc15e63 --- /dev/null +++ b/src/5.2/classes/DateAndTime/Calculations.html @@ -0,0 +1,2373 @@ +--- +title: DateAndTime::Calculations +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DAYS_INTO_WEEK={ +monday: 0, +tuesday: 1, +wednesday: 2, +thursday: 3, +friday: 4, +saturday: 5, +sunday: 6 +}
 
WEEKEND_DAYS=[ 6, 0 ]
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + all_day() + +

+ + +
+

Returns a Range representing the whole day of the current date/time.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 308
+def all_day
+  beginning_of_day..end_of_day
+end
+
+
+ +
+ +
+

+ + all_month() + +

+ + +
+

Returns a Range representing the whole month of the current date/time.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 319
+def all_month
+  beginning_of_month..end_of_month
+end
+
+
+ +
+ +
+

+ + all_quarter() + +

+ + +
+

Returns a Range representing the whole quarter of the current date/time.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 324
+def all_quarter
+  beginning_of_quarter..end_of_quarter
+end
+
+
+ +
+ +
+

+ + all_week(start_day = Date.beginning_of_week) + +

+ + +
+

Returns a Range representing the whole week of the current date/time. Week starts on start_day, default is Date.beginning_of_week or config.beginning_of_week when set.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 314
+def all_week(start_day = Date.beginning_of_week)
+  beginning_of_week(start_day)..end_of_week(start_day)
+end
+
+
+ +
+ +
+

+ + all_year() + +

+ + +
+

Returns a Range representing the whole year of the current date/time.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 329
+def all_year
+  beginning_of_year..end_of_year
+end
+
+
+ +
+ +
+

+ + at_beginning_of_month() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_month +
+ + + +
+ +
+

+ + at_beginning_of_quarter() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_quarter +
+ + + +
+ +
+

+ + at_beginning_of_week(start_day = Date.beginning_of_week) + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_week +
+ + + +
+ +
+

+ + at_beginning_of_year() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_year +
+ + + +
+ +
+

+ + at_end_of_month() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_month +
+ + + +
+ +
+

+ + at_end_of_quarter() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_quarter +
+ + + +
+ +
+

+ + at_end_of_week(start_day = Date.beginning_of_week) + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_week +
+ + + +
+ +
+

+ + at_end_of_year() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_year +
+ + + +
+ +
+

+ + beginning_of_month() + +

+ + +
+

Returns a new date/time at the start of the month.

+ +
today = Date.today # => Thu, 18 Jun 2015
+today.beginning_of_month # => Mon, 01 Jun 2015
+
+ +

DateTime objects will have a time set to 0:00.

+ +
now = DateTime.current # => Thu, 18 Jun 2015 15:23:13 +0000
+now.beginning_of_month # => Mon, 01 Jun 2015 00:00:00 +0000
+
+
+ + + +
+ Also aliased as: at_beginning_of_month +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 112
+def beginning_of_month
+  first_hour(change(day: 1))
+end
+
+
+ +
+ +
+

+ + beginning_of_quarter() + +

+ + +
+

Returns a new date/time at the start of the quarter.

+ +
today = Date.today # => Fri, 10 Jul 2015
+today.beginning_of_quarter # => Wed, 01 Jul 2015
+
+ +

DateTime objects will have a time set to 0:00.

+ +
now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
+now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000
+
+
+ + + +
+ Also aliased as: at_beginning_of_quarter +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 126
+def beginning_of_quarter
+  first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
+  beginning_of_month.change(month: first_quarter_month)
+end
+
+
+ +
+ +
+

+ + beginning_of_week(start_day = Date.beginning_of_week) + +

+ + +
+

Returns a new date/time representing the start of this week on the given day. Week is assumed to start on start_day, default is Date.beginning_of_week or config.beginning_of_week when set. DateTime objects have their time set to 0:00.

+
+ + + +
+ Also aliased as: at_beginning_of_week +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 265
+def beginning_of_week(start_day = Date.beginning_of_week)
+  result = days_ago(days_to_week_start(start_day))
+  acts_like?(:time) ? result.midnight : result
+end
+
+
+ +
+ +
+

+ + beginning_of_year() + +

+ + +
+

Returns a new date/time at the beginning of the year.

+ +
today = Date.today # => Fri, 10 Jul 2015
+today.beginning_of_year # => Thu, 01 Jan 2015
+
+ +

DateTime objects will have a time set to 0:00.

+ +
now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
+now.beginning_of_year # => Thu, 01 Jan 2015 00:00:00 +0000
+
+
+ + + +
+ Also aliased as: at_beginning_of_year +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 156
+def beginning_of_year
+  change(month: 1).beginning_of_month
+end
+
+
+ +
+ +
+

+ + days_ago(days) + +

+ + +
+

Returns a new date/time the specified number of days ago.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 64
+def days_ago(days)
+  advance(days: -days)
+end
+
+
+ +
+ +
+

+ + days_since(days) + +

+ + +
+

Returns a new date/time the specified number of days in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 69
+def days_since(days)
+  advance(days: days)
+end
+
+
+ +
+ +
+

+ + days_to_week_start(start_day = Date.beginning_of_week) + +

+ + +
+

Returns the number of days to the start of the week on the given day. Week is assumed to start on start_day, default is Date.beginning_of_week or config.beginning_of_week when set.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 255
+def days_to_week_start(start_day = Date.beginning_of_week)
+  start_day_number = DAYS_INTO_WEEK[start_day]
+  current_day_number = wday != 0 ? wday - 1 : 6
+  (current_day_number - start_day_number) % 7
+end
+
+
+ +
+ +
+

+ + end_of_month() + +

+ + +
+

Returns a new date/time representing the end of the month. DateTime objects will have a time set to 23:59:59.

+
+ + + +
+ Also aliased as: at_end_of_month +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 294
+def end_of_month
+  last_day = ::Time.days_in_month(month, year)
+  last_hour(days_since(last_day - day))
+end
+
+
+ +
+ +
+

+ + end_of_quarter() + +

+ + +
+

Returns a new date/time at the end of the quarter.

+ +
today = Date.today # => Fri, 10 Jul 2015
+today.end_of_quarter # => Wed, 30 Sep 2015
+
+ +

DateTime objects will have a time set to 23:59:59.

+ +
now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
+now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000
+
+
+ + + +
+ Also aliased as: at_end_of_quarter +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 141
+def end_of_quarter
+  last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
+  beginning_of_month.change(month: last_quarter_month).end_of_month
+end
+
+
+ +
+ +
+

+ + end_of_week(start_day = Date.beginning_of_week) + +

+ + +
+

Returns a new date/time representing the end of this week on the given day. Week is assumed to start on start_day, default is Date.beginning_of_week or config.beginning_of_week when set. DateTime objects have their time set to 23:59:59.

+
+ + + +
+ Also aliased as: at_end_of_week +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 281
+def end_of_week(start_day = Date.beginning_of_week)
+  last_hour(days_since(6 - days_to_week_start(start_day)))
+end
+
+
+ +
+ +
+

+ + end_of_year() + +

+ + +
+

Returns a new date/time representing the end of the year. DateTime objects will have a time set to 23:59:59.

+
+ + + +
+ Also aliased as: at_end_of_year +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 302
+def end_of_year
+  change(month: 12).end_of_month
+end
+
+
+ +
+ +
+

+ + future?() + +

+ + +
+

Returns true if the date/time is in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 49
+def future?
+  self > self.class.current
+end
+
+
+ +
+ +
+

+ + last_month() + +

+ + +
+

Short-hand for months_ago(1).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 232
+def last_month
+  months_ago(1)
+end
+
+
+ +
+ +
+

+ + last_quarter() + +

+ + +
+ +
+ + + + + +
+ Alias for: prev_quarter +
+ + + +
+ +
+

+ + last_week(start_day = Date.beginning_of_week, same_time: false) + +

+ + +
+ +
+ + + + + +
+ Alias for: prev_week +
+ + + +
+ +
+

+ + last_weekday() + +

+ + +
+ +
+ + + + + +
+ Alias for: prev_weekday +
+ + + +
+ +
+

+ + last_year() + +

+ + +
+

Short-hand for years_ago(1).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 248
+def last_year
+  years_ago(1)
+end
+
+
+ +
+ +
+

+ + monday() + +

+ + +
+

Returns Monday of this week assuming that week starts on Monday. DateTime objects have their time set to 0:00.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 273
+def monday
+  beginning_of_week(:monday)
+end
+
+
+ +
+ +
+

+ + months_ago(months) + +

+ + +
+

Returns a new date/time the specified number of months ago.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 84
+def months_ago(months)
+  advance(months: -months)
+end
+
+
+ +
+ +
+

+ + months_since(months) + +

+ + +
+

Returns a new date/time the specified number of months in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 89
+def months_since(months)
+  advance(months: months)
+end
+
+
+ +
+ +
+

+ + next_day(days = 1) + +

+ + +
+

Returns a new date/time the specified number of days in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 34
+def next_day(days = 1)
+  advance(days: days)
+end
+
+
+ +
+ +
+

+ + next_month(months = 1) + +

+ + +
+

Returns a new date/time the specified number of months in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 192
+def next_month(months = 1)
+  advance(months: months)
+end
+
+
+ +
+ +
+

+ + next_occurring(day_of_week) + +

+ + +
+

Returns a new date/time representing the next occurrence of the specified day of week.

+ +
today = Date.today               # => Thu, 14 Dec 2017
+today.next_occurring(:monday)    # => Mon, 18 Dec 2017
+today.next_occurring(:thursday)  # => Thu, 21 Dec 2017
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 338
+def next_occurring(day_of_week)
+  current_day_number = wday != 0 ? wday - 1 : 6
+  from_now = DAYS_INTO_WEEK.fetch(day_of_week) - current_day_number
+  from_now += 7 unless from_now > 0
+  advance(days: from_now)
+end
+
+
+ +
+ +
+

+ + next_quarter() + +

+ + +
+

Short-hand for months_since(3)

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 197
+def next_quarter
+  months_since(3)
+end
+
+
+ +
+ +
+

+ + next_week(given_day_in_next_week = Date.beginning_of_week, same_time: false) + +

+ + +
+

Returns a new date/time representing the given day in the next week.

+ +
today = Date.today # => Thu, 07 May 2015
+today.next_week    # => Mon, 11 May 2015
+
+ +

The given_day_in_next_week defaults to the beginning of the week which is determined by Date.beginning_of_week or config.beginning_of_week when set.

+ +
today = Date.today       # => Thu, 07 May 2015
+today.next_week(:friday) # => Fri, 15 May 2015
+
+ +

DateTime objects have their time set to 0:00 unless same_time is true.

+ +
now = DateTime.current # => Thu, 07 May 2015 13:31:16 +0000
+now.next_week      # => Mon, 11 May 2015 00:00:00 +0000
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 177
+def next_week(given_day_in_next_week = Date.beginning_of_week, same_time: false)
+  result = first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
+  same_time ? copy_time_to(result) : result
+end
+
+
+ +
+ +
+

+ + next_weekday() + +

+ + +
+

Returns a new date/time representing the next weekday.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 183
+def next_weekday
+  if next_day.on_weekend?
+    next_week(:monday, same_time: true)
+  else
+    next_day
+  end
+end
+
+
+ +
+ +
+

+ + next_year(years = 1) + +

+ + +
+

Returns a new date/time the specified number of years in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 202
+def next_year(years = 1)
+  advance(years: years)
+end
+
+
+ +
+ +
+

+ + on_weekday?() + +

+ + +
+

Returns true if the date/time does not fall on a Saturday or Sunday.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 59
+def on_weekday?
+  !WEEKEND_DAYS.include?(wday)
+end
+
+
+ +
+ +
+

+ + on_weekend?() + +

+ + +
+

Returns true if the date/time falls on a Saturday or Sunday.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 54
+def on_weekend?
+  WEEKEND_DAYS.include?(wday)
+end
+
+
+ +
+ +
+

+ + past?() + +

+ + +
+

Returns true if the date/time is in the past.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 44
+def past?
+  self < self.class.current
+end
+
+
+ +
+ +
+

+ + prev_day(days = 1) + +

+ + +
+

Returns a new date/time the specified number of days ago.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 24
+def prev_day(days = 1)
+  advance(days: -days)
+end
+
+
+ +
+ +
+

+ + prev_month(months = 1) + +

+ + +
+

Returns a new date/time the specified number of months ago.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 227
+def prev_month(months = 1)
+  advance(months: -months)
+end
+
+
+ +
+ +
+

+ + prev_occurring(day_of_week) + +

+ + +
+

Returns a new date/time representing the previous occurrence of the specified day of week.

+ +
today = Date.today               # => Thu, 14 Dec 2017
+today.prev_occurring(:monday)    # => Mon, 11 Dec 2017
+today.prev_occurring(:thursday)  # => Thu, 07 Dec 2017
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 350
+def prev_occurring(day_of_week)
+  current_day_number = wday != 0 ? wday - 1 : 6
+  ago = current_day_number - DAYS_INTO_WEEK.fetch(day_of_week)
+  ago += 7 unless ago > 0
+  advance(days: -ago)
+end
+
+
+ +
+ +
+

+ + prev_quarter() + +

+ + +
+

Short-hand for months_ago(3).

+
+ + + +
+ Also aliased as: last_quarter +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 237
+def prev_quarter
+  months_ago(3)
+end
+
+
+ +
+ +
+

+ + prev_week(start_day = Date.beginning_of_week, same_time: false) + +

+ + +
+

Returns a new date/time representing the given day in the previous week. Week is assumed to start on start_day, default is Date.beginning_of_week or config.beginning_of_week when set. DateTime objects have their time set to 0:00 unless same_time is true.

+
+ + + +
+ Also aliased as: last_week +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 210
+def prev_week(start_day = Date.beginning_of_week, same_time: false)
+  result = first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
+  same_time ? copy_time_to(result) : result
+end
+
+
+ +
+ +
+

+ + prev_weekday() + +

+ + +
+

Returns a new date/time representing the previous weekday.

+
+ + + +
+ Also aliased as: last_weekday +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 217
+def prev_weekday
+  if prev_day.on_weekend?
+    copy_time_to(beginning_of_week(:friday))
+  else
+    prev_day
+  end
+end
+
+
+ +
+ +
+

+ + prev_year(years = 1) + +

+ + +
+

Returns a new date/time the specified number of years ago.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 243
+def prev_year(years = 1)
+  advance(years: -years)
+end
+
+
+ +
+ +
+

+ + sunday() + +

+ + +
+

Returns Sunday of this week assuming that week starts on Monday. DateTime objects have their time set to 23:59:59.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 288
+def sunday
+  end_of_week(:monday)
+end
+
+
+ +
+ +
+

+ + today?() + +

+ + +
+

Returns true if the date/time is today.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 39
+def today?
+  to_date == ::Date.current
+end
+
+
+ +
+ +
+

+ + tomorrow() + +

+ + +
+

Returns a new date/time representing tomorrow.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 29
+def tomorrow
+  advance(days: 1)
+end
+
+
+ +
+ +
+

+ + weeks_ago(weeks) + +

+ + +
+

Returns a new date/time the specified number of weeks ago.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 74
+def weeks_ago(weeks)
+  advance(weeks: -weeks)
+end
+
+
+ +
+ +
+

+ + weeks_since(weeks) + +

+ + +
+

Returns a new date/time the specified number of weeks in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 79
+def weeks_since(weeks)
+  advance(weeks: weeks)
+end
+
+
+ +
+ +
+

+ + years_ago(years) + +

+ + +
+

Returns a new date/time the specified number of years ago.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 94
+def years_ago(years)
+  advance(years: -years)
+end
+
+
+ +
+ +
+

+ + years_since(years) + +

+ + +
+

Returns a new date/time the specified number of years in the future.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 99
+def years_since(years)
+  advance(years: years)
+end
+
+
+ +
+ +
+

+ + yesterday() + +

+ + +
+

Returns a new date/time representing yesterday.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 19
+def yesterday
+  advance(days: -1)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/DateAndTime/Compatibility.html b/src/5.2/classes/DateAndTime/Compatibility.html new file mode 100644 index 0000000000..6fd23ca5bc --- /dev/null +++ b/src/5.2/classes/DateAndTime/Compatibility.html @@ -0,0 +1,54 @@ +--- +title: DateAndTime::Compatibility +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/DateAndTime/Zones.html b/src/5.2/classes/DateAndTime/Zones.html new file mode 100644 index 0000000000..fe0aa6d949 --- /dev/null +++ b/src/5.2/classes/DateAndTime/Zones.html @@ -0,0 +1,121 @@ +--- +title: DateAndTime::Zones +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + in_time_zone(zone = ::Time.zone) + +

+ + +
+

Returns the simultaneous time in Time.zone if a zone is given or if Time.zone_default is set. Otherwise, it returns the current time.

+ +
Time.zone = 'Hawaii'        # => 'Hawaii'
+Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00
+
+ +

This method is similar to Time#localtime, except that it uses Time.zone as the local zone instead of the operating system's time zone.

+ +

You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, and the conversion will be based on that zone instead of Time.zone.

+ +
Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
+Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_and_time/zones.rb, line 20
+def in_time_zone(zone = ::Time.zone)
+  time_zone = ::Time.find_zone! zone
+  time = acts_like?(:time) ? self : nil
+
+  if time_zone
+    time_with_zone(time, time_zone)
+  else
+    time || to_time
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/DateTime.html b/src/5.2/classes/DateTime.html new file mode 100644 index 0000000000..f294316c64 --- /dev/null +++ b/src/5.2/classes/DateTime.html @@ -0,0 +1,2097 @@ +--- +title: DateTime +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + civil_from_format(utc_or_local, year, month = 1, day = 1, hour = 0, min = 0, sec = 0) + +

+ + +
+

Returns DateTime with local offset for given year if format is local else offset is zero.

+ +
DateTime.civil_from_format :local, 2012
+# => Sun, 01 Jan 2012 00:00:00 +0300
+DateTime.civil_from_format :local, 2012, 12, 17
+# => Mon, 17 Dec 2012 00:00:00 +0000
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 69
+def self.civil_from_format(utc_or_local, year, month = 1, day = 1, hour = 0, min = 0, sec = 0)
+  if utc_or_local.to_sym == :local
+    offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
+  else
+    offset = 0
+  end
+  civil(year, month, day, hour, min, sec, offset)
+end
+
+
+ +
+ +
+

+ + current() + +

+ + +
+

Returns Time.zone.now.to_datetime when Time.zone or config.time_zone are set, otherwise returns Time.now.to_datetime.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 10
+def current
+  ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(other) + +

+ + +
+

Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 204
+def <=>(other)
+  if other.respond_to? :to_datetime
+    super other.to_datetime rescue nil
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + acts_like_date?() + +

+ + +
+

Duck-types as a Date-like class. See Object#acts_like?.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/acts_like.rb, line 8
+def acts_like_date?
+  true
+end
+
+
+ +
+ +
+

+ + acts_like_time?() + +

+ + +
+

Duck-types as a Time-like class. See Object#acts_like?.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/acts_like.rb, line 13
+def acts_like_time?
+  true
+end
+
+
+ +
+ +
+

+ + advance(options) + +

+ + +
+

Uses Date to provide precise Time calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 78
+def advance(options)
+  unless options[:weeks].nil?
+    options[:weeks], partial_weeks = options[:weeks].divmod(1)
+    options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
+  end
+
+  unless options[:days].nil?
+    options[:days], partial_days = options[:days].divmod(1)
+    options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
+  end
+
+  d = to_date.advance(options)
+  datetime_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
+  seconds_to_advance = \
+    options.fetch(:seconds, 0) +
+    options.fetch(:minutes, 0) * 60 +
+    options.fetch(:hours, 0) * 3600
+
+  if seconds_to_advance.zero?
+    datetime_advanced_by_date
+  else
+    datetime_advanced_by_date.since(seconds_to_advance)
+  end
+end
+
+
+ +
+ +
+

+ + ago(seconds) + +

+ + +
+

Returns a new DateTime representing the time a number of seconds ago. Do not use this method in combination with x.months, use months_ago instead!

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 105
+def ago(seconds)
+  since(-seconds)
+end
+
+
+ +
+ +
+

+ + at_beginning_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + at_beginning_of_hour() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_hour +
+ + + +
+ +
+

+ + at_beginning_of_minute() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_minute +
+ + + +
+ +
+

+ + at_end_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_day +
+ + + +
+ +
+

+ + at_end_of_hour() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_hour +
+ + + +
+ +
+

+ + at_end_of_minute() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_minute +
+ + + +
+ +
+

+ + at_midday() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + at_middle_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + at_midnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + at_noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + beginning_of_day() + +

+ + +
+

Returns a new DateTime representing the start of the day (0:00).

+
+ + + +
+ Also aliased as: midnight, at_midnight, at_beginning_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 118
+def beginning_of_day
+  change(hour: 0)
+end
+
+
+ +
+ +
+

+ + beginning_of_hour() + +

+ + +
+

Returns a new DateTime representing the start of the hour (hh:00:00).

+
+ + + +
+ Also aliased as: at_beginning_of_hour +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 142
+def beginning_of_hour
+  change(min: 0)
+end
+
+
+ +
+ +
+

+ + beginning_of_minute() + +

+ + +
+

Returns a new DateTime representing the start of the minute (hh:mm:00).

+
+ + + +
+ Also aliased as: at_beginning_of_minute +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 154
+def beginning_of_minute
+  change(sec: 0)
+end
+
+
+ +
+ +
+

+ + change(options) + +

+ + +
+

Returns a new DateTime where one or more of the elements have been changed according to the options parameter. The time options (:hour, :min, :sec) reset cascadingly, so if only the hour is passed, then minute and sec is set to 0. If the hour and minute is passed, then sec is set to 0. The options parameter takes a hash with any of these keys: :year, :month, :day, :hour, :min, :sec, :offset, :start.

+ +
DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1)              # => DateTime.new(2012, 8, 1, 22, 35, 0)
+DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1)  # => DateTime.new(1981, 8, 1, 22, 35, 0)
+DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 51
+def change(options)
+  if new_nsec = options[:nsec]
+    raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
+    new_fraction = Rational(new_nsec, 1000000000)
+  else
+    new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
+    new_fraction = Rational(new_usec, 1000000)
+  end
+
+  raise ArgumentError, "argument out of range" if new_fraction >= 1
+
+  ::DateTime.civil(
+    options.fetch(:year, year),
+    options.fetch(:month, month),
+    options.fetch(:day, day),
+    options.fetch(:hour, hour),
+    options.fetch(:min, options[:hour] ? 0 : min),
+    options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + new_fraction,
+    options.fetch(:offset, offset),
+    options.fetch(:start, start)
+  )
+end
+
+
+ +
+ +
+

+ + default_inspect() + +

+ + +
+ +
+ + + + + +
+ Alias for: inspect +
+ + + +
+ +
+

+ + end_of_day() + +

+ + +
+

Returns a new DateTime representing the end of the day (23:59:59).

+
+ + + +
+ Also aliased as: at_end_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 136
+def end_of_day
+  change(hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000))
+end
+
+
+ +
+ +
+

+ + end_of_hour() + +

+ + +
+

Returns a new DateTime representing the end of the hour (hh:59:59).

+
+ + + +
+ Also aliased as: at_end_of_hour +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 148
+def end_of_hour
+  change(min: 59, sec: 59, usec: Rational(999999999, 1000))
+end
+
+
+ +
+ +
+

+ + end_of_minute() + +

+ + +
+

Returns a new DateTime representing the end of the minute (hh:mm:59).

+
+ + + +
+ Also aliased as: at_end_of_minute +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 160
+def end_of_minute
+  change(sec: 59, usec: Rational(999999999, 1000))
+end
+
+
+ +
+ +
+

+ + formatted_offset(colon = true, alternate_utc_string = nil) + +

+ + +
+

Returns a formatted string of the offset from UTC, or an alternative string if the time zone is already UTC.

+ +
datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
+datetime.formatted_offset         # => "-06:00"
+datetime.formatted_offset(false)  # => "-0600"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 51
+def formatted_offset(colon = true, alternate_utc_string = nil)
+  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
+end
+
+
+ +
+ +
+

+ + getgm() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc +
+ + + +
+ +
+

+ + getlocal(utc_offset = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: localtime +
+ + + +
+ +
+

+ + getutc() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc +
+ + + +
+ +
+

+ + gmtime() + +

+ + +
+ +
+ + + + + +
+ Alias for: utc +
+ + + +
+ +
+

+ + in(seconds) + +

+ + +
+ +
+ + + + + +
+ Alias for: since +
+ + + +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + +
+ Also aliased as: default_inspect +
+ + + +
+ Alias for: readable_inspect +
+ + + +
+ +
+

+ + localtime(utc_offset = nil) + +

+ + +
+

Returns a Time instance of the simultaneous time in the system timezone.

+
+ + + +
+ Also aliased as: getlocal +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 166
+def localtime(utc_offset = nil)
+  utc = new_offset(0)
+
+  Time.utc(
+    utc.year, utc.month, utc.day,
+    utc.hour, utc.min, utc.sec + utc.sec_fraction
+  ).getlocal(utc_offset)
+end
+
+
+ +
+ +
+

+ + midday() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + middle_of_day() + +

+ + +
+

Returns a new DateTime representing the middle of the day (12:00)

+
+ + + +
+ Also aliased as: midday, noon, at_midday, at_noon, at_middle_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 126
+def middle_of_day
+  change(hour: 12)
+end
+
+
+ +
+ +
+

+ + midnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + nsec() + +

+ + +
+

Returns the fraction of a second as nanoseconds

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 94
+def nsec
+  (sec_fraction * 1_000_000_000).to_i
+end
+
+
+ +
+ +
+

+ + readable_inspect() + +

+ + +
+

Overrides the default inspect method with a human readable one, e.g., “Mon, 21 Feb 2005 14:30:00 +0000”.

+
+ + + +
+ Also aliased as: inspect +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 56
+def readable_inspect
+  to_s(:rfc822)
+end
+
+
+ +
+ +
+

+ + seconds_since_midnight() + +

+ + +
+

Returns the number of seconds since 00:00:00.

+ +
DateTime.new(2012, 8, 29,  0,  0,  0).seconds_since_midnight # => 0
+DateTime.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296
+DateTime.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 20
+def seconds_since_midnight
+  sec + (min * 60) + (hour * 3600)
+end
+
+
+ +
+ +
+

+ + seconds_until_end_of_day() + +

+ + +
+

Returns the number of seconds until 23:59:59.

+ +
DateTime.new(2012, 8, 29,  0,  0,  0).seconds_until_end_of_day # => 86399
+DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
+DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 29
+def seconds_until_end_of_day
+  end_of_day.to_i - to_i
+end
+
+
+ +
+ +
+

+ + since(seconds) + +

+ + +
+

Returns a new DateTime representing the time a number of seconds since the instance time. Do not use this method in combination with x.months, use months_since instead!

+
+ + + +
+ Also aliased as: in +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 112
+def since(seconds)
+  self + Rational(seconds.round, 86400)
+end
+
+
+ +
+ +
+

+ + subsec() + +

+ + +
+

Returns the fraction of a second as a Rational

+ +
DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 36
+def subsec
+  sec_fraction
+end
+
+
+ +
+ +
+

+ + to_default_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_f() + +

+ + +
+

Converts self to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 79
+def to_f
+  seconds_since_unix_epoch.to_f + sec_fraction
+end
+
+
+ +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+

Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.

+ +

This method is aliased to to_s.

+ +

Examples

+ +
datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0)   # => Tue, 04 Dec 2007 00:00:00 +0000
+
+datetime.to_formatted_s(:db)            # => "2007-12-04 00:00:00"
+datetime.to_s(:db)                      # => "2007-12-04 00:00:00"
+datetime.to_s(:number)                  # => "20071204000000"
+datetime.to_formatted_s(:short)         # => "04 Dec 00:00"
+datetime.to_formatted_s(:long)          # => "December 04, 2007 00:00"
+datetime.to_formatted_s(:long_ordinal)  # => "December 4th, 2007 00:00"
+datetime.to_formatted_s(:rfc822)        # => "Tue, 04 Dec 2007 00:00:00 +0000"
+datetime.to_formatted_s(:iso8601)       # => "2007-12-04T00:00:00+00:00"
+
+ +

Adding your own datetime formats to to_formatted_s

+ +

DateTime formats are shared with Time. You can add your own to the Time::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a time or datetime argument as the value.

+ +
# config/initializers/time_formats.rb
+Time::DATE_FORMATS[:month_and_year] = '%B %Y'
+Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
+
+
+ + + +
+ Also aliased as: to_s +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 35
+def to_formatted_s(format = :default)
+  if formatter = ::Time::DATE_FORMATS[format]
+    formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+  else
+    to_default_s
+  end
+end
+
+
+ +
+ +
+

+ + to_i() + +

+ + +
+

Converts self to an integer number of seconds since the Unix epoch.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 84
+def to_i
+  seconds_since_unix_epoch.to_i
+end
+
+
+ +
+ +
+

+ + to_s(format = :default) + +

+ + +
+ +
+ + + +
+ Also aliased as: to_default_s +
+ + + +
+ Alias for: to_formatted_s +
+ + + +
+ +
+

+ + to_time() + +

+ + +
+

Either return an instance of Time with the same UTC offset as self or an instance of Time representing the same time in the local system timezone depending on the setting of on the setting of ActiveSupport.to_time_preserves_timezone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/compatibility.rb, line 15
+def to_time
+  preserve_timezone ? getlocal(utc_offset) : getlocal
+end
+
+
+ +
+ +
+

+ + usec() + +

+ + +
+

Returns the fraction of a second as microseconds

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 89
+def usec
+  (sec_fraction * 1_000_000).to_i
+end
+
+
+ +
+ +
+

+ + utc() + +

+ + +
+

Returns a Time instance of the simultaneous time in the UTC timezone.

+ +
DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24))     # => Mon, 21 Feb 2005 10:11:12 -0600
+DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
+
+
+ + + +
+ Also aliased as: getgm, getutc, gmtime +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 180
+def utc
+  utc = new_offset(0)
+
+  Time.utc(
+    utc.year, utc.month, utc.day,
+    utc.hour, utc.min, utc.sec + utc.sec_fraction
+  )
+end
+
+
+ +
+ +
+

+ + utc?() + +

+ + +
+

Returns true if offset == 0.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 193
+def utc?
+  offset == 0
+end
+
+
+ +
+ +
+

+ + utc_offset() + +

+ + +
+

Returns the offset value in seconds.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 198
+def utc_offset
+  (offset * 86400).to_i
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Delegator.html b/src/5.2/classes/Delegator.html new file mode 100644 index 0000000000..a901517979 --- /dev/null +++ b/src/5.2/classes/Delegator.html @@ -0,0 +1,144 @@ +--- +title: Delegator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + try(a*, &b) + + +

+ + +
+

See Object#try

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/try.rb, line 111
+  
+
+
+ +
+ +
+

+ + try!(a*, &b) + + +

+ + +
+

See Object#try!

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/try.rb, line 119
+
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Digest.html b/src/5.2/classes/Digest.html new file mode 100644 index 0000000000..38189a3893 --- /dev/null +++ b/src/5.2/classes/Digest.html @@ -0,0 +1,67 @@ +--- +title: Digest +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Digest/UUID.html b/src/5.2/classes/Digest/UUID.html new file mode 100644 index 0000000000..187907052e --- /dev/null +++ b/src/5.2/classes/Digest/UUID.html @@ -0,0 +1,238 @@ +--- +title: Digest::UUID +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + uuid_from_hash(hash_class, uuid_namespace, name) + +

+ + +
+

Generates a v5 non-random UUID (Universally Unique IDentifier).

+ +

Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs. uuid_from_hash always generates the same UUID for a given name and namespace combination.

+ +

See RFC 4122 for details of UUID at: www.ietf.org/rfc/rfc4122.txt

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 18
+def self.uuid_from_hash(hash_class, uuid_namespace, name)
+  if hash_class == Digest::MD5
+    version = 3
+  elsif hash_class == Digest::SHA1
+    version = 5
+  else
+    raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
+  end
+
+  hash = hash_class.new
+  hash.update(uuid_namespace)
+  hash.update(name)
+
+  ary = hash.digest.unpack("NnnnnN")
+  ary[2] = (ary[2] & 0x0FFF) | (version << 12)
+  ary[3] = (ary[3] & 0x3FFF) | 0x8000
+
+  "%08x-%04x-%04x-%04x-%04x%08x" % ary
+end
+
+
+ +
+ +
+

+ + uuid_v3(uuid_namespace, name) + +

+ + +
+

Convenience method for uuid_from_hash using Digest::MD5.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 39
+def self.uuid_v3(uuid_namespace, name)
+  uuid_from_hash(Digest::MD5, uuid_namespace, name)
+end
+
+
+ +
+ +
+

+ + uuid_v4() + +

+ + +
+

Convenience method for SecureRandom.uuid.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 49
+def self.uuid_v4
+  SecureRandom.uuid
+end
+
+
+ +
+ +
+

+ + uuid_v5(uuid_namespace, name) + +

+ + +
+

Convenience method for uuid_from_hash using Digest::SHA1.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 44
+def self.uuid_v5(uuid_namespace, name)
+  uuid_from_hash(Digest::SHA1, uuid_namespace, name)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/ERB.html b/src/5.2/classes/ERB.html new file mode 100644 index 0000000000..24bd568d8c --- /dev/null +++ b/src/5.2/classes/ERB.html @@ -0,0 +1,73 @@ +--- +title: ERB +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/ERB/Util.html b/src/5.2/classes/ERB/Util.html new file mode 100644 index 0000000000..e1be4b4d5c --- /dev/null +++ b/src/5.2/classes/ERB/Util.html @@ -0,0 +1,310 @@ +--- +title: ERB::Util +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HTML_ESCAPE={ "&" => "&amp;", ">" => "&gt;", "<" => "&lt;", '"' => "&quot;", "'" => "&#39;" }
 
HTML_ESCAPE_ONCE_REGEXP=/["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
 
JSON_ESCAPE={ "&" => '\u0026', ">" => '\u003e', "<" => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
 
JSON_ESCAPE_REGEXP=/[\u2028\u2029&><]/u
 
+ + + + + + +

Class Public methods

+ +
+

+ + h(s) + +

+ + +
+ +
+ + + + + +
+ Alias for: html_escape +
+ + + +
+ +
+

+ + html_escape(s) + +

+ + +
+

A utility method for escaping HTML tag characters. This method is also aliased as h.

+ +
puts html_escape('is a > 0 & a < 10?')
+# => is a &gt; 0 &amp; a &lt; 10?
+
+
+ + + +
+ Also aliased as: h +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 20
+def html_escape(s)
+  unwrapped_html_escape(s).html_safe
+end
+
+
+ +
+ +
+

+ + html_escape_once(s) + +

+ + +
+

A utility method for escaping HTML without affecting existing escaped entities.

+ +
html_escape_once('1 < 2 &amp; 3')
+# => "1 &lt; 2 &amp; 3"
+
+html_escape_once('&lt;&lt; Accept & Checkout')
+# => "&lt;&lt; Accept &amp; Checkout"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 51
+def html_escape_once(s)
+  result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
+  s.html_safe? ? result.html_safe : result
+end
+
+
+ +
+ +
+

+ + json_escape(s) + +

+ + +
+

A utility method for escaping HTML entities in JSON strings. Specifically, the &, > and < characters are replaced with their equivalent unicode escaped form - u0026, u003e, and u003c. The Unicode sequences u2028 and u2029 are also escaped as they are treated as newline characters in some JavaScript engines. These sequences have identical meaning as the original characters inside the context of a JSON string, so assuming the input is a valid and well-formed JSON value, the output will have equivalent meaning when parsed:

+ +
json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"})
+# => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}"
+
+json_escape(json)
+# => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}"
+
+JSON.parse(json) == JSON.parse(json_escape(json))
+# => true
+
+ +

The intended use case for this method is to escape JSON strings before including them inside a script tag to avoid XSS vulnerability:

+ +
<script>
+  var currentUser = <%= raw json_escape(current_user.to_json) %>;
+</script>
+
+ +

It is necessary to raw the result of json_escape, so that quotation marks don't get converted to &quot; entities. json_escape doesn't automatically flag the result as HTML safe, since the raw value is unsafe to use inside HTML attributes.

+ +

If your JSON is being used downstream for insertion into the DOM, be aware of whether or not it is being inserted via +html()+. Most jQuery plugins do this. If that is the case, be sure to html_escape or sanitize any user-generated content returned by your JSON.

+ +

If you need to output JSON elsewhere in your HTML, you can just do something like this, as any unsafe characters (including quotation marks) will be automatically escaped for you:

+ +
<div data-user-info="<%= current_user.to_json %>">...</div>
+
+ +

WARNING: this helper only works with valid JSON. Using this on non-JSON values will open up serious XSS vulnerabilities. For example, if you replace the current_user.to_json in the example above with user input instead, the browser will happily eval() that string as JavaScript.

+ +

The escaping performed in this method is identical to those performed in the Active Support JSON encoder when ActiveSupport.escape_html_entities_in_json is set to true. Because this transformation is idempotent, this helper can be applied even if ActiveSupport.escape_html_entities_in_json is already true.

+ +

Therefore, when you are unsure if ActiveSupport.escape_html_entities_in_json is enabled, or if you are unsure where your JSON string originated from, it is recommended that you always apply this helper (other libraries, such as the JSON gem, do not provide this kind of protection by default; also some gems might override to_json to bypass Active Support's encoder).

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 113
+def json_escape(s)
+  result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE)
+  s.html_safe? ? result.html_safe : result
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Enumerable.html b/src/5.2/classes/Enumerable.html new file mode 100644 index 0000000000..dc8afefa47 --- /dev/null +++ b/src/5.2/classes/Enumerable.html @@ -0,0 +1,363 @@ +--- +title: Enumerable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + exclude?(object) + +

+ + +
+

The negative of the Enumerable#include?. Returns true if the collection does not include the object.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 92
+def exclude?(object)
+  !include?(object)
+end
+
+
+ +
+ +
+

+ + index_by() + +

+ + +
+

Convert an enumerable to a hash.

+ +
people.index_by(&:login)
+# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
+people.index_by { |person| "#{person.first_name} #{person.last_name}" }
+# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 64
+def index_by
+  if block_given?
+    result = {}
+    each { |elem| result[yield(elem)] = elem }
+    result
+  else
+    to_enum(:index_by) { size if respond_to?(:size) }
+  end
+end
+
+
+ +
+ +
+

+ + many?() + +

+ + +
+

Returns true if the enumerable has more than 1 element. Functionally equivalent to enum.to_a.size > 1. Can be called with a block too, much like any?, so people.many? { |p| p.age > 26 } returns true if more than one person is over 26.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 78
+def many?
+  cnt = 0
+  if block_given?
+    any? do |element|
+      cnt += 1 if yield element
+      cnt > 1
+    end
+  else
+    any? { (cnt += 1) > 1 }
+  end
+end
+
+
+ +
+ +
+

+ + pluck(*keys) + +

+ + +
+

Convert an enumerable to an array based on the given key.

+ +
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
+# => ["David", "Rafael", "Aaron"]
+
+[{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
+# => [[1, "David"], [2, "Rafael"]]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 114
+def pluck(*keys)
+  if keys.many?
+    map { |element| keys.map { |key| element[key] } }
+  else
+    map { |element| element[keys.first] }
+  end
+end
+
+
+ +
+ +
+

+ + sum(identity = nil, &block) + +

+ + +
+

Calculates a sum from the elements.

+ +
payments.sum { |p| p.price * p.tax_rate }
+payments.sum(&:price)
+
+ +

The latter is a shortcut for:

+ +
payments.inject(0) { |sum, p| sum + p.price }
+
+ +

It can also calculate the sum without the use of a block.

+ +
[5, 15, 10].sum # => 30
+['foo', 'bar'].sum # => "foobar"
+[[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5]
+
+ +

The default sum of an empty list is zero. You can override this default:

+ +
[].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 38
+def sum(identity = nil, &block)
+  if identity
+    _original_sum_with_required_identity(identity, &block)
+  elsif block_given?
+    map(&block).sum(identity)
+  else
+    inject(:+) || 0
+  end
+end
+
+
+ +
+ +
+

+ + without(*elements) + +

+ + +
+

Returns a copy of the enumerable without the specified elements.

+ +
["David", "Rafael", "Aaron", "Todd"].without "Aaron", "Todd"
+# => ["David", "Rafael"]
+
+{foo: 1, bar: 2, baz: 3}.without :bar
+# => {foo: 1, baz: 3}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 103
+def without(*elements)
+  reject { |element| elements.include?(element) }
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Exception.html b/src/5.2/classes/Exception.html new file mode 100644 index 0000000000..0b32130787 --- /dev/null +++ b/src/5.2/classes/Exception.html @@ -0,0 +1,107 @@ +--- +title: Exception +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + as_json(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/json.rb, line 224
+def as_json(options = nil)
+  to_s
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/FalseClass.html b/src/5.2/classes/FalseClass.html new file mode 100644 index 0000000000..5d96470384 --- /dev/null +++ b/src/5.2/classes/FalseClass.html @@ -0,0 +1,200 @@ +--- +title: FalseClass +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+

false is blank:

+ +
false.blank? # => true
+
+ +

@return [true]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 68
+def blank?
+  true
+end
+
+
+ +
+ +
+

+ + duplicable?() + +

+ + +
+

false is not duplicable:

+ +
false.duplicable? # => false
+false.dup         # => TypeError: can't dup FalseClass
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 55
+def duplicable?
+  false
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns self.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 34
+def to_param
+  self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/File.html b/src/5.2/classes/File.html new file mode 100644 index 0000000000..b5b64920cb --- /dev/null +++ b/src/5.2/classes/File.html @@ -0,0 +1,153 @@ +--- +title: File +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + atomic_write(file_name, temp_dir = dirname(file_name)) + +

+ + +
+

Write to a file atomically. Useful for situations where you don't want other processes or threads to see half-written files.

+ +
File.atomic_write('important.file') do |file|
+  file.write('hello')
+end
+
+ +

This method needs to create a temporary file. By default it will create it in the same directory as the destination file. If you don't like this behavior you can provide a different directory but it must be on the same physical filesystem as the file you're trying to write.

+ +
File.atomic_write('/data/something.important', '/data/tmp') do |file|
+  file.write('hello')
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/file/atomic.rb, line 21
+def self.atomic_write(file_name, temp_dir = dirname(file_name))
+  require "tempfile" unless defined?(Tempfile)
+
+  Tempfile.open(".#{basename(file_name)}", temp_dir) do |temp_file|
+    temp_file.binmode
+    return_val = yield temp_file
+    temp_file.close
+
+    old_stat = if exist?(file_name)
+      # Get original file permissions
+      stat(file_name)
+    else
+      # If not possible, probe which are the default permissions in the
+      # destination directory.
+      probe_stat_in(dirname(file_name))
+    end
+
+    if old_stat
+      # Set correct permissions on new file
+      begin
+        chown(old_stat.uid, old_stat.gid, temp_file.path)
+        # This operation will affect filesystem ACL's
+        chmod(old_stat.mode, temp_file.path)
+      rescue Errno::EPERM, Errno::EACCES
+        # Changing file ownership failed, moving on.
+      end
+    end
+
+    # Overwrite original file with temp file
+    rename(temp_file.path, file_name)
+    return_val
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Float.html b/src/5.2/classes/Float.html new file mode 100644 index 0000000000..83b5c4bba6 --- /dev/null +++ b/src/5.2/classes/Float.html @@ -0,0 +1,60 @@ +--- +title: Float +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Hash.html b/src/5.2/classes/Hash.html new file mode 100644 index 0000000000..6ccac4cc74 --- /dev/null +++ b/src/5.2/classes/Hash.html @@ -0,0 +1,1923 @@ +--- +title: Hash +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + from_trusted_xml(xml) + +

+ + +
+

Builds a Hash from XML just like Hash.from_xml, but also allows Symbol and YAML.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 134
+def from_trusted_xml(xml)
+  from_xml xml, []
+end
+
+
+ +
+ +
+

+ + from_xml(xml, disallowed_types = nil) + +

+ + +
+

Returns a Hash containing a collection of pairs when the key is the node name and the value is its content

+ +
xml = <<-XML
+  <?xml version="1.0" encoding="UTF-8"?>
+    <hash>
+      <foo type="integer">1</foo>
+      <bar type="integer">2</bar>
+    </hash>
+XML
+
+hash = Hash.from_xml(xml)
+# => {"hash"=>{"foo"=>1, "bar"=>2}}
+
+ +

DisallowedType is raised if the XML contains attributes with type="yaml" or type="symbol". Use Hash.from_trusted_xml to parse this XML.

+ +

Custom disallowed_types can also be passed in the form of an array.

+ +
xml = <<-XML
+  <?xml version="1.0" encoding="UTF-8"?>
+    <hash>
+      <foo type="integer">1</foo>
+      <bar type="string">"David"</bar>
+    </hash>
+XML
+
+hash = Hash.from_xml(xml, ['integer'])
+# => ActiveSupport::XMLConverter::DisallowedType: Disallowed type attribute: "integer"
+
+ +

Note that passing custom disallowed types will override the default types, which are Symbol and YAML.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 129
+def from_xml(xml, disallowed_types = nil)
+  ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + assert_valid_keys(*valid_keys) + +

+ + +
+

Validates all keys in a hash match *valid_keys, raising ArgumentError on a mismatch.

+ +

Note that keys are treated differently than HashWithIndifferentAccess, meaning that string and symbol keys will not match.

+ +
{ name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
+{ name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
+{ name: 'Rob', age: '28' }.assert_valid_keys(:name, :age)   # => passes, raises nothing
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 77
+def assert_valid_keys(*valid_keys)
+  valid_keys.flatten!
+  each_key do |k|
+    unless valid_keys.include?(k)
+      raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
+    end
+  end
+end
+
+
+ +
+ +
+

+ + compact() + +

+ + +
+

Returns a hash with non nil values.

+ +
hash = { a: true, b: false, c: nil }
+hash.compact        # => { a: true, b: false }
+hash                # => { a: true, b: false, c: nil }
+{ c: nil }.compact  # => {}
+{ c: true }.compact # => { c: true }
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/compact.rb, line 12
+def compact
+  select { |_, value| !value.nil? }
+end
+
+
+ +
+ +
+

+ + compact!() + +

+ + +
+

Replaces current hash with non nil values. Returns nil if no changes were made, otherwise returns the hash.

+ +
hash = { a: true, b: false, c: nil }
+hash.compact!        # => { a: true, b: false }
+hash                 # => { a: true, b: false }
+{ c: true }.compact! # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/compact.rb, line 25
+def compact!
+  reject! { |_, value| value.nil? }
+end
+
+
+ +
+ +
+

+ + deep_dup() + +

+ + +
+

Returns a deep copy of hash.

+ +
hash = { a: { b: 'b' } }
+dup  = hash.deep_dup
+dup[:a][:c] = 'c'
+
+hash[:a][:c] # => nil
+dup[:a][:c]  # => "c"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 43
+def deep_dup
+  hash = dup
+  each_pair do |key, value|
+    if key.frozen? && ::String === key
+      hash[key] = value.deep_dup
+    else
+      hash.delete(key)
+      hash[key.deep_dup] = value.deep_dup
+    end
+  end
+  hash
+end
+
+
+ +
+ +
+

+ + deep_merge(other_hash, &block) + +

+ + +
+

Returns a new hash with self and other_hash merged recursively.

+ +
h1 = { a: true, b: { c: [1, 2, 3] } }
+h2 = { a: false, b: { x: [3, 4, 5] } }
+
+h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
+
+ +

Like with Hash#merge in the standard library, a block can be provided to merge values:

+ +
h1 = { a: 100, b: 200, c: { c1: 100 } }
+h2 = { b: 250, c: { c1: 200 } }
+h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
+# => { a: 100, b: 450, c: { c1: 300 } }
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 18
+def deep_merge(other_hash, &block)
+  dup.deep_merge!(other_hash, &block)
+end
+
+
+ +
+ +
+

+ + deep_merge!(other_hash, &block) + +

+ + +
+

Same as deep_merge, but modifies self.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 23
+def deep_merge!(other_hash, &block)
+  merge!(other_hash) do |key, this_val, other_val|
+    if this_val.is_a?(Hash) && other_val.is_a?(Hash)
+      this_val.deep_merge(other_val, &block)
+    elsif block_given?
+      block.call(key, this_val, other_val)
+    else
+      other_val
+    end
+  end
+end
+
+
+ +
+ +
+

+ + deep_stringify_keys() + +

+ + +
+

Returns a new hash with all keys converted to strings. This includes the keys from the root hash and from all nested hashes and arrays.

+ +
hash = { person: { name: 'Rob', age: '28' } }
+
+hash.deep_stringify_keys
+# => {"person"=>{"name"=>"Rob", "age"=>"28"}}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 113
+def deep_stringify_keys
+  deep_transform_keys(&:to_s)
+end
+
+
+ +
+ +
+

+ + deep_stringify_keys!() + +

+ + +
+

Destructively converts all keys to strings. This includes the keys from the root hash and from all nested hashes and arrays.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 120
+def deep_stringify_keys!
+  deep_transform_keys!(&:to_s)
+end
+
+
+ +
+ +
+

+ + deep_symbolize_keys() + +

+ + +
+

Returns a new hash with all keys converted to symbols, as long as they respond to to_sym. This includes the keys from the root hash and from all nested hashes and arrays.

+ +
hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
+
+hash.deep_symbolize_keys
+# => {:person=>{:name=>"Rob", :age=>"28"}}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 132
+def deep_symbolize_keys
+  deep_transform_keys { |key| key.to_sym rescue key }
+end
+
+
+ +
+ +
+

+ + deep_symbolize_keys!() + +

+ + +
+

Destructively converts all keys to symbols, as long as they respond to to_sym. This includes the keys from the root hash and from all nested hashes and arrays.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 139
+def deep_symbolize_keys!
+  deep_transform_keys! { |key| key.to_sym rescue key }
+end
+
+
+ +
+ +
+

+ + deep_transform_keys(&block) + +

+ + +
+

Returns a new hash with all keys converted by the block operation. This includes the keys from the root hash and from all nested hashes and arrays.

+ +
hash = { person: { name: 'Rob', age: '28' } }
+
+hash.deep_transform_keys{ |key| key.to_s.upcase }
+# => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 94
+def deep_transform_keys(&block)
+  _deep_transform_keys_in_object(self, &block)
+end
+
+
+ +
+ +
+

+ + deep_transform_keys!(&block) + +

+ + +
+

Destructively converts all keys by using the block operation. This includes the keys from the root hash and from all nested hashes and arrays.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 101
+def deep_transform_keys!(&block)
+  _deep_transform_keys_in_object!(self, &block)
+end
+
+
+ +
+ +
+

+ + except(*keys) + +

+ + +
+

Returns a hash that includes everything except given keys.

+ +
hash = { a: true, b: false, c: nil }
+hash.except(:c)     # => { a: true, b: false }
+hash.except(:a, :b) # => { c: nil }
+hash                # => { a: true, b: false, c: nil }
+
+ +

This is useful for limiting a set of parameters to everything but a few known toggles:

+ +
@person.update(params[:person].except(:admin))
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/except.rb, line 12
+def except(*keys)
+  dup.except!(*keys)
+end
+
+
+ +
+ +
+

+ + except!(*keys) + +

+ + +
+

Removes the given keys from hash and returns it.

+ +
hash = { a: true, b: false, c: nil }
+hash.except!(:c) # => { a: true, b: false }
+hash             # => { a: true, b: false }
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/except.rb, line 20
+def except!(*keys)
+  keys.each { |key| delete(key) }
+  self
+end
+
+
+ +
+ +
+

+ + extract!(*keys) + +

+ + +
+

Removes and returns the key/value pairs matching the given keys.

+ +
{ a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
+{ a: 1, b: 2 }.extract!(:a, :x)             # => {:a=>1}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 45
+def extract!(*keys)
+  keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
+end
+
+
+ +
+ +
+

+ + extractable_options?() + +

+ + +
+

By default, only instances of Hash itself are extractable. Subclasses of Hash may implement this method and return true to declare themselves as extractable. If a Hash is extractable, Array#extract_options! pops it from the Array when it is the last element of the Array.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/array/extract_options.rb, line 9
+def extractable_options?
+  instance_of?(Hash)
+end
+
+
+ +
+ +
+

+ + nested_under_indifferent_access() + +

+ + +
+

Called when object is nested under an object that receives with_indifferent_access. This method will be called on the current object by the enclosing object and is aliased to with_indifferent_access by default. Subclasses of Hash may overwrite this method to return self if converting to an ActiveSupport::HashWithIndifferentAccess would not be desirable.

+ +
b = { b: 1 }
+{ a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
+# => {"b"=>1}
+
+
+ + + + + +
+ Alias for: with_indifferent_access +
+ + + +
+ +
+

+ + reverse_merge(other_hash) + +

+ + +
+

Merges the caller into other_hash. For example,

+ +
options = options.reverse_merge(size: 25, velocity: 10)
+
+ +

is equivalent to

+ +
options = { size: 25, velocity: 10 }.merge(options)
+
+ +

This is particularly useful for initializing an options hash with default values.

+
+ + + +
+ Also aliased as: with_defaults +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 14
+def reverse_merge(other_hash)
+  other_hash.merge(self)
+end
+
+
+ +
+ +
+

+ + reverse_merge!(other_hash) + +

+ + +
+

Destructive reverse_merge.

+
+ + + +
+ Also aliased as: reverse_update, with_defaults! +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 20
+def reverse_merge!(other_hash)
+  replace(reverse_merge(other_hash))
+end
+
+
+ +
+ +
+

+ + reverse_update(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge! +
+ + + +
+ +
+

+ + slice(*keys) + +

+ + +
+

Slices a hash to include only the given keys. Returns a hash containing the given keys.

+ +
{ a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
+# => {:a=>1, :b=>2}
+
+ +

This is useful for limiting an options hash to valid keys before passing to a method:

+ +
def search(criteria = {})
+  criteria.assert_valid_keys(:mass, :velocity, :time)
+end
+
+search(options.slice(:mass, :velocity, :time))
+
+ +

If you have an array of keys you want to limit to, you should splat them:

+ +
valid_keys = [:mass, :velocity, :time]
+search(options.slice(*valid_keys))
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 23
+def slice(*keys)
+  keys.each_with_object(Hash.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
+end
+
+
+ +
+ +
+

+ + slice!(*keys) + +

+ + +
+

Replaces the hash with only the given keys. Returns a hash containing the removed key/value pairs.

+ +
{ a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
+# => {:c=>3, :d=>4}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 32
+def slice!(*keys)
+  omit = slice(*self.keys - keys)
+  hash = slice(*keys)
+  hash.default      = default
+  hash.default_proc = default_proc if default_proc
+  replace(hash)
+  omit
+end
+
+
+ +
+ +
+

+ + stringify_keys() + +

+ + +
+

Returns a new hash with all keys converted to strings.

+ +
hash = { name: 'Rob', age: '28' }
+
+hash.stringify_keys
+# => {"name"=>"Rob", "age"=>"28"}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 39
+def stringify_keys
+  transform_keys(&:to_s)
+end
+
+
+ +
+ +
+

+ + stringify_keys!() + +

+ + +
+

Destructively converts all keys to strings. Same as stringify_keys, but modifies self.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 45
+def stringify_keys!
+  transform_keys!(&:to_s)
+end
+
+
+ +
+ +
+

+ + symbolize_keys() + +

+ + +
+

Returns a new hash with all keys converted to symbols, as long as they respond to to_sym.

+ +
hash = { 'name' => 'Rob', 'age' => '28' }
+
+hash.symbolize_keys
+# => {:name=>"Rob", :age=>"28"}
+
+
+ + + +
+ Also aliased as: to_options +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 56
+def symbolize_keys
+  transform_keys { |key| key.to_sym rescue key }
+end
+
+
+ +
+ +
+

+ + symbolize_keys!() + +

+ + +
+

Destructively converts all keys to symbols, as long as they respond to to_sym. Same as symbolize_keys, but modifies self.

+
+ + + +
+ Also aliased as: to_options! +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 63
+def symbolize_keys!
+  transform_keys! { |key| key.to_sym rescue key }
+end
+
+
+ +
+ +
+

+ + to_options() + +

+ + +
+ +
+ + + + + +
+ Alias for: symbolize_keys +
+ + + +
+ +
+

+ + to_options!() + +

+ + +
+ +
+ + + + + +
+ Alias for: symbolize_keys! +
+ + + +
+ +
+

+ + to_param(namespace = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_query +
+ + + +
+ +
+

+ + to_query(namespace = nil) + +

+ + +
+

Returns a string representation of the receiver suitable for use as a URL query string:

+ +
{name: 'David', nationality: 'Danish'}.to_query
+# => "name=David&nationality=Danish"
+
+ +

An optional namespace can be passed to enclose key names:

+ +
{name: 'David', nationality: 'Danish'}.to_query('user')
+# => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
+
+ +

The string pairs “key=value” that conform the query string are sorted lexicographically in ascending order.

+ +

This method is also aliased as to_param.

+
+ + + +
+ Also aliased as: to_param +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 77
+def to_query(namespace = nil)
+  query = collect do |key, value|
+    unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
+      value.to_query(namespace ? "#{namespace}[#{key}]" : key)
+    end
+  end.compact
+
+  query.sort! unless namespace.to_s.include?("[]")
+  query.join("&")
+end
+
+
+ +
+ +
+

+ + to_xml(options = {}) + +

+ + +
+

Returns a string containing an XML representation of its receiver:

+ +
{ 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>
+
+ +

To do so, the method loops over the pairs and builds nodes that depend on the values. Given a pair key, value:

+
  • +

    If value is a hash there's a recursive call with key as :root.

    +
  • +

    If value is an array there's a recursive call with key as :root, and key singularized as :children.

    +
  • +

    If value is a callable object it must expect one or two arguments. Depending on the arity, the callable is invoked with the options hash as first argument with key as :root, and key singularized as second argument. The callable can add nodes by using options[:builder].

    + +
    {foo: lambda { |options, key| options[:builder].b(key) }}.to_xml
    +# => "<b>foo</b>"
    +
    +
  • +

    If value responds to to_xml the method is invoked with key as :root.

    + +
    class Foo
    +  def to_xml(options)
    +    options[:builder].bar 'fooing!'
    +  end
    +end
    +
    +{ foo: Foo.new }.to_xml(skip_instruct: true)
    +# =>
    +# <hash>
    +#   <bar>fooing!</bar>
    +# </hash>
    +
    +
  • +

    Otherwise, a node with key as tag is created with a string representation of value as text node. If value is nil an attribute “nil” set to “true” is added. Unless the option :skip_types exists and is true, an attribute “type” is added as well according to the following mapping:

    + +
    XML_TYPE_NAMES = {
    +  "Symbol"     => "symbol",
    +  "Integer"    => "integer",
    +  "BigDecimal" => "decimal",
    +  "Float"      => "float",
    +  "TrueClass"  => "boolean",
    +  "FalseClass" => "boolean",
    +  "Date"       => "date",
    +  "DateTime"   => "dateTime",
    +  "Time"       => "dateTime"
    +}
    +
    +
+ +

By default the root node is “hash”, but that's configurable via the :root option.

+ +

The default XML builder is a fresh instance of Builder::XmlMarkup. You can configure your own builder with the :builder option. The method also accepts options like :dasherize and friends, they are forwarded to the builder.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 75
+def to_xml(options = {})
+  require "active_support/builder" unless defined?(Builder)
+
+  options = options.dup
+  options[:indent]  ||= 2
+  options[:root]    ||= "hash"
+  options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
+
+  builder = options[:builder]
+  builder.instruct! unless options.delete(:skip_instruct)
+
+  root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
+
+  builder.tag!(root) do
+    each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, options) }
+    yield builder if block_given?
+  end
+end
+
+
+ +
+ +
+

+ + transform_keys() + +

+ + +
+

Returns a new hash with all keys converted using the block operation.

+ +
hash = { name: 'Rob', age: '28' }
+
+hash.transform_keys { |key| key.to_s.upcase } # => {"NAME"=>"Rob", "AGE"=>"28"}
+
+ +

If you do not provide a block, it will return an Enumerator for chaining with other methods:

+ +
hash.transform_keys.with_index { |k, i| [k, i].join } # => {"name0"=>"Rob", "age1"=>"28"}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 14
+def transform_keys
+  return enum_for(:transform_keys) { size } unless block_given?
+  result = {}
+  each_key do |key|
+    result[yield(key)] = self[key]
+  end
+  result
+end
+
+
+ +
+ +
+

+ + transform_keys!() + +

+ + +
+

Destructively converts all keys using the block operations. Same as transform_keys but modifies self.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 25
+def transform_keys!
+  return enum_for(:transform_keys!) { size } unless block_given?
+  keys.each do |key|
+    self[yield(key)] = delete(key)
+  end
+  self
+end
+
+
+ +
+ +
+

+ + transform_values() + +

+ + +
+

Returns a new hash with the results of running block once for every value. The keys are unchanged.

+ +
{ a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 } # => { a: 2, b: 4, c: 6 }
+
+ +

If you do not provide a block, it will return an Enumerator for chaining with other methods:

+ +
{ a: 1, b: 2 }.transform_values.with_index { |v, i| [v, i].join.to_i } # => { a: 10, b: 21 }
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/transform_values.rb, line 13
+def transform_values
+  return enum_for(:transform_values) { size } unless block_given?
+  return {} if empty?
+  result = self.class.new
+  each do |key, value|
+    result[key] = yield(value)
+  end
+  result
+end
+
+
+ +
+ +
+

+ + transform_values!() + +

+ + +
+

Destructively converts all values using the block operations. Same as transform_values but modifies self.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/transform_values.rb, line 25
+def transform_values!
+  return enum_for(:transform_values!) { size } unless block_given?
+  each do |key, value|
+    self[key] = yield(value)
+  end
+end
+
+
+ +
+ +
+

+ + with_defaults(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge +
+ + + +
+ +
+

+ + with_defaults!(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge! +
+ + + +
+ +
+

+ + with_indifferent_access() + +

+ + +
+

Returns an ActiveSupport::HashWithIndifferentAccess out of its receiver:

+ +
{ a: 1 }.with_indifferent_access['a'] # => 1
+
+
+ + + +
+ Also aliased as: nested_under_indifferent_access +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 9
+def with_indifferent_access
+  ActiveSupport::HashWithIndifferentAccess.new(self)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/IO.html b/src/5.2/classes/IO.html new file mode 100644 index 0000000000..e1006aa671 --- /dev/null +++ b/src/5.2/classes/IO.html @@ -0,0 +1,62 @@ +--- +title: IO +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Integer.html b/src/5.2/classes/Integer.html new file mode 100644 index 0000000000..338e5c05d3 --- /dev/null +++ b/src/5.2/classes/Integer.html @@ -0,0 +1,358 @@ +--- +title: Integer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + month() + +

+ + +
+ +
+ + + + + +
+ Alias for: months +
+ + + +
+ +
+

+ + months() + +

+ + +
+

Returns a Duration instance matching the number of months provided.

+ +
2.months # => 2 months
+
+
+ + + +
+ Also aliased as: month +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/integer/time.rb, line 10
+def months
+  ActiveSupport::Duration.months(self)
+end
+
+
+ +
+ +
+

+ + multiple_of?(number) + +

+ + +
+

Check whether the integer is evenly divisible by the argument.

+ +
0.multiple_of?(0)  # => true
+6.multiple_of?(5)  # => false
+10.multiple_of?(2) # => true
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/integer/multiple.rb, line 9
+def multiple_of?(number)
+  number != 0 ? self % number == 0 : zero?
+end
+
+
+ +
+ +
+

+ + ordinal() + +

+ + +
+

Ordinal returns the suffix used to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.

+ +
1.ordinal     # => "st"
+2.ordinal     # => "nd"
+1002.ordinal  # => "nd"
+1003.ordinal  # => "rd"
+-11.ordinal   # => "th"
+-1001.ordinal # => "st"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/integer/inflections.rb, line 28
+def ordinal
+  ActiveSupport::Inflector.ordinal(self)
+end
+
+
+ +
+ +
+

+ + ordinalize() + +

+ + +
+

Ordinalize turns a number into an ordinal string used to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.

+ +
1.ordinalize     # => "1st"
+2.ordinalize     # => "2nd"
+1002.ordinalize  # => "1002nd"
+1003.ordinalize  # => "1003rd"
+-11.ordinalize   # => "-11th"
+-1001.ordinalize # => "-1001st"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/integer/inflections.rb, line 15
+def ordinalize
+  ActiveSupport::Inflector.ordinalize(self)
+end
+
+
+ +
+ +
+

+ + year() + +

+ + +
+ +
+ + + + + +
+ Alias for: years +
+ + + +
+ +
+

+ + years() + +

+ + +
+

Returns a Duration instance matching the number of years provided.

+ +
2.years # => 2 years
+
+
+ + + +
+ Also aliased as: year +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/integer/time.rb, line 18
+def years
+  ActiveSupport::Duration.years(self)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Kernel.html b/src/5.2/classes/Kernel.html new file mode 100644 index 0000000000..1ea007bd09 --- /dev/null +++ b/src/5.2/classes/Kernel.html @@ -0,0 +1,321 @@ +--- +title: Kernel +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + class_eval(*args, &block) + +

+ + +
+

class_eval on an object acts like singleton_class.class_eval.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/kernel/singleton_class.rb, line 5
+def class_eval(*args, &block)
+  singleton_class.class_eval(*args, &block)
+end
+
+
+ +
+ +
+

+ + concern(topic, &module_definition) + +

+ + +
+

A shortcut to define a toplevel concern, not within a module.

+ +

See Module::Concerning for more.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/kernel/concern.rb, line 11
+def concern(topic, &module_definition)
+  Object.concern topic, &module_definition
+end
+
+
+ +
+ +
+

+ + enable_warnings() + +

+ + +
+

Sets $VERBOSE to true for the duration of the block and back to its original value afterwards.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 20
+def enable_warnings
+  with_warnings(true) { yield }
+end
+
+
+ +
+ +
+

+ + silence_warnings() + +

+ + +
+

Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.

+ +
silence_warnings do
+  value = noisy_call # no warning voiced
+end
+
+noisy_call # warning voiced
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 14
+def silence_warnings
+  with_warnings(nil) { yield }
+end
+
+
+ +
+ +
+

+ + suppress(*exception_classes) + +

+ + +
+

Blocks and ignores any exception passed as argument if raised within the block.

+ +
suppress(ZeroDivisionError) do
+  1/0
+  puts 'This code is NOT reached'
+end
+
+puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 41
+def suppress(*exception_classes)
+  yield
+rescue *exception_classes
+end
+
+
+ +
+ +
+

+ + with_warnings(flag) + +

+ + +
+

Sets $VERBOSE for the duration of the block and back to its original value afterwards.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 26
+def with_warnings(flag)
+  old_verbose, $VERBOSE = $VERBOSE, flag
+  yield
+ensure
+  $VERBOSE = old_verbose
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/LoadError.html b/src/5.2/classes/LoadError.html new file mode 100644 index 0000000000..a4d0464c09 --- /dev/null +++ b/src/5.2/classes/LoadError.html @@ -0,0 +1,107 @@ +--- +title: LoadError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + is_missing?(location) + +

+ + +
+

Returns true if the given path name (except perhaps for the “.rb” extension) is the missing file which caused the exception to be raised.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/load_error.rb, line 6
+def is_missing?(location)
+  location.sub(/\.rb$/, "".freeze) == path.sub(/\.rb$/, "".freeze)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/LoggerSilence.html b/src/5.2/classes/LoggerSilence.html new file mode 100644 index 0000000000..84139c2a64 --- /dev/null +++ b/src/5.2/classes/LoggerSilence.html @@ -0,0 +1,112 @@ +--- +title: LoggerSilence +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + silence(temporary_level = Logger::ERROR) + +

+ + +
+

Silences the logger for the duration of the block.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/logger_silence.rb, line 15
+def silence(temporary_level = Logger::ERROR)
+  if silencer
+    begin
+      old_local_level            = local_level
+      self.local_level           = temporary_level
+
+      yield self
+    ensure
+      self.local_level = old_local_level
+    end
+  else
+    yield self
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Method.html b/src/5.2/classes/Method.html new file mode 100644 index 0000000000..048f3a986f --- /dev/null +++ b/src/5.2/classes/Method.html @@ -0,0 +1,111 @@ +--- +title: Method +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + duplicable?() + +

+ + +
+

Methods are not duplicable:

+ +
method(:puts).duplicable? # => false
+method(:puts).dup         # => TypeError: allocator undefined for Method
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 123
+def duplicable?
+  false
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Mime.html b/src/5.2/classes/Mime.html new file mode 100644 index 0000000000..a2a0460f53 --- /dev/null +++ b/src/5.2/classes/Mime.html @@ -0,0 +1,221 @@ +--- +title: Mime +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ALL=AllType.instance
 

ALL isn't a real MIME type, so we don't register it for lookup with the other concrete types. It's a wildcard match that we use for `respond_to` negotiation internals.

EXTENSION_LOOKUP={}
 
LOOKUP={}
 
SET=Mimes.new
 
+ + + + + + +

Class Public methods

+ +
+

+ + [](type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 40
+def [](type)
+  return type if type.is_a?(Type)
+  Type.lookup_by_extension(type)
+end
+
+
+ +
+ +
+

+ + fetch(type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 45
+def fetch(type)
+  return type if type.is_a?(Type)
+  EXTENSION_LOOKUP.fetch(type.to_s) { |k| yield k }
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Mime/AllType.html b/src/5.2/classes/Mime/AllType.html new file mode 100644 index 0000000000..9dad44959c --- /dev/null +++ b/src/5.2/classes/Mime/AllType.html @@ -0,0 +1,196 @@ +--- +title: Mime::AllType +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Singleton + +
  • + +
+ + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 309
+def initialize
+  super "*/*", :all
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + all?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 313
+def all?; true; end
+
+
+ +
+ +
+

+ + html?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 314
+def html?; true; end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Mime/Mimes.html b/src/5.2/classes/Mime/Mimes.html new file mode 100644 index 0000000000..ef1aa9590b --- /dev/null +++ b/src/5.2/classes/Mime/Mimes.html @@ -0,0 +1,282 @@ +--- +title: Mime::Mimes +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 12
+def initialize
+  @mimes = []
+  @symbols = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 21
+def <<(type)
+  @mimes << type
+  @symbols = nil
+end
+
+
+ +
+ +
+

+ + delete_if() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 26
+def delete_if
+  @mimes.delete_if { |x| yield x }.tap { @symbols = nil }
+end
+
+
+ +
+ +
+

+ + each() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 17
+def each
+  @mimes.each { |x| yield x }
+end
+
+
+ +
+ +
+

+ + symbols() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 30
+def symbols
+  @symbols ||= map(&:to_sym)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Mime/NullType.html b/src/5.2/classes/Mime/NullType.html new file mode 100644 index 0000000000..d28de3bbe9 --- /dev/null +++ b/src/5.2/classes/Mime/NullType.html @@ -0,0 +1,156 @@ +--- +title: Mime::NullType +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Singleton + +
  • + +
+ + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + nil?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 325
+def nil?
+  true
+end
+
+
+ +
+ +
+

+ + ref() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 329
+def ref; end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Mime/Type.html b/src/5.2/classes/Mime/Type.html new file mode 100644 index 0000000000..a6224efe9a --- /dev/null +++ b/src/5.2/classes/Mime/Type.html @@ -0,0 +1,992 @@ +--- +title: Mime::Type +layout: default +--- +
+ +
+
+ +
+ +

Encapsulates the notion of a MIME type. Can be used at render time, for example, with:

+ +
class PostsController < ActionController::Base
+  def show
+    @post = Post.find(params[:id])
+
+    respond_to do |format|
+      format.html
+      format.ics { render body: @post.to_ics, mime_type: Mime::Type.lookup("text/calendar")  }
+      format.xml { render xml: @post }
+    end
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETER_SEPARATOR_REGEXP=/;\s*\w+="?\w+"?/
 
TRAILING_STAR_REGEXP=/^(text|application)\/\*/
 
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + hash
+ [R] + string

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ [R] + symbol
+ [R] + synonyms

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ + + + +

Class Public methods

+ +
+

+ + lookup(string) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 144
+def lookup(string)
+  LOOKUP[string] || Type.new(string)
+end
+
+
+ +
+ +
+

+ + lookup_by_extension(extension) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 148
+def lookup_by_extension(extension)
+  EXTENSION_LOOKUP[extension.to_s]
+end
+
+
+ +
+ +
+

+ + new(string, symbol = nil, synonyms = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 226
+def initialize(string, symbol = nil, synonyms = [])
+  @symbol, @synonyms = symbol, synonyms
+  @string = string
+  @hash = [@string, @synonyms, @symbol].hash
+end
+
+
+ +
+ +
+

+ + parse(accept_header) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 172
+def parse(accept_header)
+  if !accept_header.include?(",")
+    accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
+    parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact
+  else
+    list, index = [], 0
+    accept_header.split(",").each do |header|
+      params, q = header.split(PARAMETER_SEPARATOR_REGEXP)
+
+      next unless params
+      params.strip!
+      next if params.empty?
+
+      params = parse_trailing_star(params) || [params]
+
+      params.each do |m|
+        list << AcceptItem.new(index, m.to_s, q)
+        index += 1
+      end
+    end
+    AcceptList.sort! list
+  end
+end
+
+
+ +
+ +
+

+ + parse_data_with_trailing_star(type) + +

+ + +
+

For an input of 'text', returns [Mime[:json], Mime[:xml], Mime[:ics], Mime[:html], Mime[:css], Mime[:csv], Mime[:js], Mime[:yaml], Mime[:text].

+ +

For an input of 'application', returns [Mime[:html], Mime[:js], Mime[:xml], Mime[:yaml], Mime[:atom], Mime[:json], Mime[:rss], Mime[:url_encoded_form].

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 205
+def parse_data_with_trailing_star(type)
+  Mime::SET.select { |m| m =~ type }
+end
+
+
+ +
+ +
+

+ + parse_trailing_star(accept_header) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 196
+def parse_trailing_star(accept_header)
+  parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
+end
+
+
+ +
+ +
+

+ + register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 158
+def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)
+  new_mime = Type.new(string, symbol, mime_type_synonyms)
+
+  SET << new_mime
+
+  ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = new_mime } unless skip_lookup
+  ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = new_mime }
+
+  @register_callbacks.each do |callback|
+    callback.call(new_mime)
+  end
+  new_mime
+end
+
+
+ +
+ +
+

+ + register_alias(string, symbol, extension_synonyms = []) + +

+ + +
+

Registers an alias that's not used on MIME type lookup, but can be referenced directly. Especially useful for rendering different HTML versions depending on the user agent, like an iPhone.

+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 154
+def register_alias(string, symbol, extension_synonyms = [])
+  register(string, symbol, [], extension_synonyms, true)
+end
+
+
+ +
+ +
+

+ + register_callback(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 140
+def register_callback(&block)
+  @register_callbacks << block
+end
+
+
+ +
+ +
+

+ + unregister(symbol) + +

+ + +
+

This method is opposite of register method.

+ +

To unregister a MIME type:

+ +
Mime::Type.unregister(:mobile)
+
+
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 214
+def unregister(symbol)
+  symbol = symbol.downcase
+  if mime = Mime[symbol]
+    SET.delete_if { |v| v.eql?(mime) }
+    LOOKUP.delete_if { |_, v| v.eql?(mime) }
+    EXTENSION_LOOKUP.delete_if { |_, v| v.eql?(mime) }
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(mime_type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 256
+def ==(mime_type)
+  return false unless mime_type
+  (@synonyms + [ self ]).any? do |synonym|
+    synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
+  end
+end
+
+
+ +
+ +
+

+ + ===(list) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 248
+def ===(list)
+  if list.is_a?(Array)
+    (@synonyms + [ self ]).any? { |synonym| list.include?(synonym) }
+  else
+    super
+  end
+end
+
+
+ +
+ +
+

+ + =~(mime_type) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 270
+def =~(mime_type)
+  return false unless mime_type
+  regexp = Regexp.new(Regexp.quote(mime_type.to_s))
+  @synonyms.any? { |synonym| synonym.to_s =~ regexp } || @string =~ regexp
+end
+
+
+ +
+ +
+

+ + all?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 280
+def all?; false; end
+
+
+ +
+ +
+

+ + eql?(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 263
+def eql?(other)
+  super || (self.class == other.class &&
+            @string    == other.string &&
+            @synonyms  == other.synonyms &&
+            @symbol    == other.symbol)
+end
+
+
+ +
+ +
+

+ + html?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 276
+def html?
+  symbol == :html || @string =~ /html/
+end
+
+
+ +
+ +
+

+ + ref() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 244
+def ref
+  symbol || to_s
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 232
+def to_s
+  @string
+end
+
+
+ +
+ +
+

+ + to_str() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 236
+def to_str
+  to_s
+end
+
+
+ +
+ +
+

+ + to_sym() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 240
+def to_sym
+  @symbol
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Minitest.html b/src/5.2/classes/Minitest.html new file mode 100644 index 0000000000..69d39a2d3b --- /dev/null +++ b/src/5.2/classes/Minitest.html @@ -0,0 +1,224 @@ +--- +title: Minitest +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + plugin_rails_init(options) + +

+ + +
+

Owes great inspiration to test runner trailblazers like RSpec, minitest-reporters, maxitest and others.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/minitest/rails_plugin.rb, line 40
+def self.plugin_rails_init(options)
+  unless options[:full_backtrace] || ENV["BACKTRACE"]
+    # Plugin can run without Rails loaded, check before filtering.
+    Minitest.backtrace_filter = ::Rails.backtrace_cleaner if ::Rails.respond_to?(:backtrace_cleaner)
+  end
+
+  self.plugin_rails_replace_reporters(reporter, options)
+end
+
+
+ +
+ +
+

+ + plugin_rails_options(opts, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/minitest/rails_plugin.rb, line 15
+def self.plugin_rails_options(opts, options)
+  ::Rails::TestUnit::Runner.attach_before_load_options(opts)
+
+  opts.on("-b", "--backtrace", "Show the complete backtrace") do
+    options[:full_backtrace] = true
+  end
+
+  opts.on("-d", "--defer-output", "Output test failures and errors after the test run") do
+    options[:output_inline] = false
+  end
+
+  opts.on("-f", "--fail-fast", "Abort test run on first failure or error") do
+    options[:fail_fast] = true
+  end
+
+  opts.on("-c", "--[no-]color", "Enable color in the output") do |value|
+    options[:color] = value
+  end
+
+  options[:color] = true
+  options[:output_inline] = true
+end
+
+
+ +
+ +
+

+ + plugin_rails_replace_reporters(minitest_reporter, options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/minitest/rails_plugin.rb, line 49
+def self.plugin_rails_replace_reporters(minitest_reporter, options)
+  return unless minitest_reporter.kind_of?(Minitest::CompositeReporter)
+
+  # Replace progress reporter for colors.
+  if minitest_reporter.reporters.reject! { |reporter| reporter.kind_of?(SummaryReporter) } != nil
+    minitest_reporter << SuppressedSummaryReporter.new(options[:io], options)
+  end
+  if minitest_reporter.reporters.reject! { |reporter| reporter.kind_of?(ProgressReporter) } != nil
+    minitest_reporter << ::Rails::TestUnitReporter.new(options[:io], options)
+  end
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Minitest/SuppressedSummaryReporter.html b/src/5.2/classes/Minitest/SuppressedSummaryReporter.html new file mode 100644 index 0000000000..6a73c89f37 --- /dev/null +++ b/src/5.2/classes/Minitest/SuppressedSummaryReporter.html @@ -0,0 +1,107 @@ +--- +title: Minitest::SuppressedSummaryReporter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + aggregated_results(*) + +

+ + +
+

Disable extra failure output after a run if output is inline.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/minitest/rails_plugin.rb, line 10
+def aggregated_results(*)
+  super unless options[:output_inline]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Module.html b/src/5.2/classes/Module.html new file mode 100644 index 0000000000..8f0c864f14 --- /dev/null +++ b/src/5.2/classes/Module.html @@ -0,0 +1,1742 @@ +--- +title: Module +layout: default +--- +
+ +
+
+ +
+ +

Extends the module object with class/module and instance accessors for class/module attributes, just like the native attr* accessors for instance attributes.

+ +

Extends the module object with class/module and instance accessors for class/module attributes, just like the native attr* accessors for instance attributes, but does so on a per-thread basis.

+ +

So the values are scoped within the Thread.current space under the class name of the module.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DELEGATION_RESERVED_KEYWORDS=%w(_ arg args block)
 
DELEGATION_RESERVED_METHOD_NAMES=Set.new( +RUBY_RESERVED_KEYWORDS + DELEGATION_RESERVED_KEYWORDS +).freeze
 
RUBY_RESERVED_KEYWORDS=%w(alias and BEGIN begin break case class def defined? do +else elsif END end ensure false for if in module next nil not or redo rescue retry +return self super then true undef unless until when while yield)
 
+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + attr_internal_naming_format
+ + + + + +

Instance Public methods

+ +
+

+ + alias_attribute(new_name, old_name) + +

+ + +
+

Allows you to make aliases for attributes, which includes getter, setter, and a predicate.

+ +
class Content < ActiveRecord::Base
+  # has a title attribute
+end
+
+class Email < Content
+  alias_attribute :subject, :title
+end
+
+e = Email.find(1)
+e.title    # => "Superstars"
+e.subject  # => "Superstars"
+e.subject? # => true
+e.subject = "Megastars"
+e.title    # => "Megastars"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/aliasing.rb, line 21
+  def alias_attribute(new_name, old_name)
+    # The following reader methods use an explicit `self` receiver in order to
+    # support aliases that start with an uppercase letter. Otherwise, they would
+    # be resolved as constants instead.
+    module_eval <<-STR, __FILE__, __LINE__ + 1
+      def #{new_name}; self.#{old_name}; end          # def subject; self.title; end
+      def #{new_name}?; self.#{old_name}?; end        # def subject?; self.title?; end
+      def #{new_name}=(v); self.#{old_name} = v; end  # def subject=(v); self.title = v; end
+    STR
+  end
+
+
+ +
+ +
+

+ + anonymous?() + +

+ + +
+

A module may or may not have a name.

+ +
module M; end
+M.name # => "M"
+
+m = Module.new
+m.name # => nil
+
+ +

anonymous? method returns true if module does not have a name, false otherwise:

+ +
Module.new.anonymous? # => true
+
+module M; end
+M.anonymous?          # => false
+
+ +

A module gets a name when it is first assigned to a constant. Either via the module or class keyword or by an explicit assignment:

+ +
m = Module.new # creates an anonymous module
+m.anonymous?   # => true
+M = m          # m gets a name here as a side-effect
+m.name         # => "M"
+m.anonymous?   # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/anonymous.rb, line 27
+def anonymous?
+  name.nil?
+end
+
+
+ +
+ +
+

+ + attr_internal(*attrs) + +

+ + +
+ +
+ + + + + +
+ Alias for: attr_internal_accessor +
+ + + +
+ +
+

+ + attr_internal_accessor(*attrs) + +

+ + +
+

Declares an attribute reader and writer backed by an internally-named instance variable.

+
+ + + +
+ Also aliased as: attr_internal +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/attr_internal.rb, line 16
+def attr_internal_accessor(*attrs)
+  attr_internal_reader(*attrs)
+  attr_internal_writer(*attrs)
+end
+
+
+ +
+ +
+

+ + attr_internal_reader(*attrs) + +

+ + +
+

Declares an attribute reader backed by an internally-named instance variable.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/attr_internal.rb, line 5
+def attr_internal_reader(*attrs)
+  attrs.each { |attr_name| attr_internal_define(attr_name, :reader) }
+end
+
+
+ +
+ +
+

+ + attr_internal_writer(*attrs) + +

+ + +
+

Declares an attribute writer backed by an internally-named instance variable.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/attr_internal.rb, line 10
+def attr_internal_writer(*attrs)
+  attrs.each { |attr_name| attr_internal_define(attr_name, :writer) }
+end
+
+
+ +
+ +
+

+ + cattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk) + +

+ + +
+ +
+ + + + + +
+ Alias for: mattr_accessor +
+ + + +
+ +
+

+ + cattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: mattr_reader +
+ + + +
+ +
+

+ + cattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: mattr_writer +
+ + + +
+ +
+

+ + delegate(*methods, to: nil, prefix: nil, allow_nil: nil) + +

+ + +
+

Provides a delegate class method to easily expose contained objects' public methods as your own.

+ +

Options

+
  • +

    :to - Specifies the target object

    +
  • +

    :prefix - Prefixes the new method with the target name or a custom prefix

    +
  • +

    :allow_nil - if set to true, prevents a Module::DelegationError from being raised

    +
+ +

The macro receives one or more method names (specified as symbols or strings) and the name of the target object via the :to option (also a symbol or string).

+ +

Delegation is particularly useful with Active Record associations:

+ +
class Greeter < ActiveRecord::Base
+  def hello
+    'hello'
+  end
+
+  def goodbye
+    'goodbye'
+  end
+end
+
+class Foo < ActiveRecord::Base
+  belongs_to :greeter
+  delegate :hello, to: :greeter
+end
+
+Foo.new.hello   # => "hello"
+Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
+
+ +

Multiple delegates to the same target are allowed:

+ +
class Foo < ActiveRecord::Base
+  belongs_to :greeter
+  delegate :hello, :goodbye, to: :greeter
+end
+
+Foo.new.goodbye # => "goodbye"
+
+ +

Methods can be delegated to instance variables, class variables, or constants by providing them as a symbols:

+ +
class Foo
+  CONSTANT_ARRAY = [0,1,2,3]
+  @@class_array  = [4,5,6,7]
+
+  def initialize
+    @instance_array = [8,9,10,11]
+  end
+  delegate :sum, to: :CONSTANT_ARRAY
+  delegate :min, to: :@@class_array
+  delegate :max, to: :@instance_array
+end
+
+Foo.new.sum # => 6
+Foo.new.min # => 4
+Foo.new.max # => 11
+
+ +

It's also possible to delegate a method to the class by using :class:

+ +
class Foo
+  def self.hello
+    "world"
+  end
+
+  delegate :hello, to: :class
+end
+
+Foo.new.hello # => "world"
+
+ +

Delegates can optionally be prefixed using the :prefix option. If the value is true, the delegate methods are prefixed with the name of the object being delegated to.

+ +
Person = Struct.new(:name, :address)
+
+class Invoice < Struct.new(:client)
+  delegate :name, :address, to: :client, prefix: true
+end
+
+john_doe = Person.new('John Doe', 'Vimmersvej 13')
+invoice = Invoice.new(john_doe)
+invoice.client_name    # => "John Doe"
+invoice.client_address # => "Vimmersvej 13"
+
+ +

It is also possible to supply a custom prefix.

+ +
class Invoice < Struct.new(:client)
+  delegate :name, :address, to: :client, prefix: :customer
+end
+
+invoice = Invoice.new(john_doe)
+invoice.customer_name    # => 'John Doe'
+invoice.customer_address # => 'Vimmersvej 13'
+
+ +

If the target is nil and does not respond to the delegated method a Module::DelegationError is raised. If you wish to instead return nil, use the :allow_nil option.

+ +
class User < ActiveRecord::Base
+  has_one :profile
+  delegate :age, to: :profile
+end
+
+User.new.age
+# => Module::DelegationError: User#age delegated to profile.age, but profile is nil
+
+ +

But if not having a profile yet is fine and should not be an error condition:

+ +
class User < ActiveRecord::Base
+  has_one :profile
+  delegate :age, to: :profile, allow_nil: true
+end
+
+User.new.age # nil
+
+ +

Note that if the target is not nil then the call is attempted regardless of the :allow_nil option, and thus an exception is still raised if said object does not respond to the method:

+ +
class Foo
+  def initialize(bar)
+    @bar = bar
+  end
+
+  delegate :name, to: :@bar, allow_nil: true
+end
+
+Foo.new("Bar").name # raises NoMethodError: undefined method `name'
+
+ +

The target method must be public, otherwise it will raise NoMethodError.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/delegation.rb, line 154
+def delegate(*methods, to: nil, prefix: nil, allow_nil: nil)
+  unless to
+    raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter)."
+  end
+
+  if prefix == true && /^[^a-z_]/.match?(to)
+    raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
+  end
+
+  method_prefix = \
+    if prefix
+      "#{prefix == true ? to : prefix}_"
+    else
+      ""
+    end
+
+  location = caller_locations(1, 1).first
+  file, line = location.path, location.lineno
+
+  to = to.to_s
+  to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
+
+  methods.map do |method|
+    # Attribute writer methods only accept one argument. Makes sure []=
+    # methods still accept two arguments.
+    definition = /[^\]]=$/.match?(method) ? "arg" : "*args, &block"
+
+    # The following generated method calls the target exactly once, storing
+    # the returned value in a dummy variable.
+    #
+    # Reason is twofold: On one hand doing less calls is in general better.
+    # On the other hand it could be that the target has side-effects,
+    # whereas conceptually, from the user point of view, the delegator should
+    # be doing one call.
+    if allow_nil
+      method_def = [
+        "def #{method_prefix}#{method}(#{definition})",
+        "_ = #{to}",
+        "if !_.nil? || nil.respond_to?(:#{method})",
+        "  _.#{method}(#{definition})",
+        "end",
+      "end"
+      ].join ";"
+    else
+      exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
+
+      method_def = [
+        "def #{method_prefix}#{method}(#{definition})",
+        " _ = #{to}",
+        "  _.#{method}(#{definition})",
+        "rescue NoMethodError => e",
+        "  if _.nil? && e.name == :#{method}",
+        "    #{exception}",
+        "  else",
+        "    raise",
+        "  end",
+        "end"
+      ].join ";"
+    end
+
+    module_eval(method_def, file, line)
+  end
+end
+
+
+ +
+ +
+

+ + delegate_missing_to(target) + +

+ + +
+

When building decorators, a common pattern may emerge:

+ +
class Partition
+  def initialize(event)
+    @event = event
+  end
+
+  def person
+    @event.detail.person || @event.creator
+  end
+
+  private
+    def respond_to_missing?(name, include_private = false)
+      @event.respond_to?(name, include_private)
+    end
+
+    def method_missing(method, *args, &block)
+      @event.send(method, *args, &block)
+    end
+end
+
+ +

With Module#delegate_missing_to, the above is condensed to:

+ +
class Partition
+  delegate_missing_to :@event
+
+  def initialize(event)
+    @event = event
+  end
+
+  def person
+    @event.detail.person || @event.creator
+  end
+end
+
+ +

The target can be anything callable within the object, e.g. instance variables, methods, constants, etc.

+ +

The delegated method must be public on the target, otherwise it will raise NoMethodError.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/delegation.rb, line 258
+  def delegate_missing_to(target)
+    target = target.to_s
+    target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
+
+    module_eval <<-RUBY, __FILE__, __LINE__ + 1
+      def respond_to_missing?(name, include_private = false)
+        # It may look like an oversight, but we deliberately do not pass
+        # +include_private+, because they do not get delegated.
+
+        #{target}.respond_to?(name) || super
+      end
+
+      def method_missing(method, *args, &block)
+        if #{target}.respond_to?(method)
+          #{target}.public_send(method, *args, &block)
+        else
+          begin
+            super
+          rescue NoMethodError
+            if #{target}.nil?
+              raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil"
+            else
+              raise
+            end
+          end
+        end
+      end
+    RUBY
+  end
+
+
+ +
+ +
+

+ + deprecate(*method_names) + +

+ + +
+
deprecate :foo
+deprecate bar: 'message'
+deprecate :foo, :bar, baz: 'warning!', qux: 'gone!'
+
+ +

You can also use custom deprecator instance:

+ +
deprecate :foo, deprecator: MyLib::Deprecator.new
+deprecate :foo, bar: "warning!", deprecator: MyLib::Deprecator.new
+
+ +

Custom deprecators must respond to deprecation_warning(deprecated_method_name, message, caller_backtrace) method where you can implement your custom warning behavior.

+ +
class MyLib::Deprecator
+  def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
+    message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
+    Kernel.warn message
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/deprecation.rb, line 22
+def deprecate(*method_names)
+  ActiveSupport::Deprecation.deprecate_methods(self, *method_names)
+end
+
+
+ +
+ +
+

+ + mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk) + +

+ + +
+

Defines both class and instance accessors for class attributes. All class and instance methods created will be public, even if this method is called with a private or protected access modifier.

+ +
module HairColors
+  mattr_accessor :hair_colors
+end
+
+class Person
+  include HairColors
+end
+
+HairColors.hair_colors = [:brown, :black, :blonde, :red]
+HairColors.hair_colors # => [:brown, :black, :blonde, :red]
+Person.new.hair_colors # => [:brown, :black, :blonde, :red]
+
+ +

If a subclass changes the value then that would also change the value for parent class. Similarly if parent class changes the value then that would change the value of subclasses too.

+ +
class Male < Person
+end
+
+Male.new.hair_colors << :blue
+Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
+
+ +

To opt out of the instance writer method, pass instance_writer: false. To opt out of the instance reader method, pass instance_reader: false.

+ +
module HairColors
+  mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
+end
+
+class Person
+  include HairColors
+end
+
+Person.new.hair_colors = [:brown]  # => NoMethodError
+Person.new.hair_colors             # => NoMethodError
+
+ +

Or pass instance_accessor: false, to opt out both instance methods.

+ +
module HairColors
+  mattr_accessor :hair_colors, instance_accessor: false
+end
+
+class Person
+  include HairColors
+end
+
+Person.new.hair_colors = [:brown]  # => NoMethodError
+Person.new.hair_colors             # => NoMethodError
+
+ +

You can set a default value for the attribute.

+ +
module HairColors
+  mattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red]
+end
+
+class Person
+  include HairColors
+end
+
+Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
+
+
+ + + +
+ Also aliased as: cattr_accessor +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 210
+def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk)
+  mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, &blk)
+  mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default)
+end
+
+
+ +
+ +
+

+ + mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) + +

+ + +
+

Defines a class attribute and creates a class and instance reader methods. The underlying class variable is set to nil, if it is not previously defined. All class and instance methods created will be public, even if this method is called with a private or protected access modifier.

+ +
module HairColors
+  mattr_reader :hair_colors
+end
+
+HairColors.hair_colors # => nil
+HairColors.class_variable_set("@@hair_colors", [:brown, :black])
+HairColors.hair_colors # => [:brown, :black]
+
+ +

The attribute name must be a valid method name in Ruby.

+ +
module Foo
+  mattr_reader :"1_Badname"
+end
+# => NameError: invalid attribute name: 1_Badname
+
+ +

If you want to opt out the creation on the instance reader method, pass instance_reader: false or instance_accessor: false.

+ +
module HairColors
+  mattr_reader :hair_colors, instance_reader: false
+end
+
+class Person
+  include HairColors
+end
+
+Person.new.hair_colors # => NoMethodError
+
+ +

You can set a default value for the attribute.

+ +
module HairColors
+  mattr_reader :hair_colors, default: [:brown, :black, :blonde, :red]
+end
+
+class Person
+  include HairColors
+end
+
+Person.new.hair_colors # => [:brown, :black, :blonde, :red]
+
+
+ + + +
+ Also aliased as: cattr_reader +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 54
+  def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil)
+    syms.each do |sym|
+      raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
+      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+        @@#{sym} = nil unless defined? @@#{sym}
+
+        def self.#{sym}
+          @@#{sym}
+        end
+      EOS
+
+      if instance_reader && instance_accessor
+        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+          def #{sym}
+            @@#{sym}
+          end
+        EOS
+      end
+
+      sym_default_value = (block_given? && default.nil?) ? yield : default
+      class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil?
+    end
+  end
+
+
+ +
+ +
+

+ + mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil) + +

+ + +
+

Defines a class attribute and creates a class and instance writer methods to allow assignment to the attribute. All class and instance methods created will be public, even if this method is called with a private or protected access modifier.

+ +
module HairColors
+  mattr_writer :hair_colors
+end
+
+class Person
+  include HairColors
+end
+
+HairColors.hair_colors = [:brown, :black]
+Person.class_variable_get("@@hair_colors") # => [:brown, :black]
+Person.new.hair_colors = [:blonde, :red]
+HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red]
+
+ +

If you want to opt out the instance writer method, pass instance_writer: false or instance_accessor: false.

+ +
module HairColors
+  mattr_writer :hair_colors, instance_writer: false
+end
+
+class Person
+  include HairColors
+end
+
+Person.new.hair_colors = [:blonde, :red] # => NoMethodError
+
+ +

You can set a default value for the attribute.

+ +
module HairColors
+  mattr_writer :hair_colors, default: [:brown, :black, :blonde, :red]
+end
+
+class Person
+  include HairColors
+end
+
+Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
+
+
+ + + +
+ Also aliased as: cattr_writer +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 121
+  def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil)
+    syms.each do |sym|
+      raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
+      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+        @@#{sym} = nil unless defined? @@#{sym}
+
+        def self.#{sym}=(obj)
+          @@#{sym} = obj
+        end
+      EOS
+
+      if instance_writer && instance_accessor
+        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+          def #{sym}=(obj)
+            @@#{sym} = obj
+          end
+        EOS
+      end
+
+      sym_default_value = (block_given? && default.nil?) ? yield : default
+      send("#{sym}=", sym_default_value) unless sym_default_value.nil?
+    end
+  end
+
+
+ +
+ +
+

+ + parent() + +

+ + +
+

Returns the module which contains this one according to its name.

+ +
module M
+  module N
+  end
+end
+X = M::N
+
+M::N.parent # => M
+X.parent    # => M
+
+ +

The parent of top-level and anonymous modules is Object.

+ +
M.parent          # => Object
+Module.new.parent # => Object
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/introspection.rb, line 34
+def parent
+  parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
+end
+
+
+ +
+ +
+

+ + parent_name() + +

+ + +
+

Returns the name of the module containing this one.

+ +
M::N.parent_name # => "M"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/introspection.rb, line 9
+def parent_name
+  if defined?(@parent_name)
+    @parent_name
+  else
+    parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
+    @parent_name = parent_name unless frozen?
+    parent_name
+  end
+end
+
+
+ +
+ +
+

+ + parents() + +

+ + +
+

Returns all the parents of this module according to its name, ordered from nested outwards. The receiver is not contained within the result.

+ +
module M
+  module N
+  end
+end
+X = M::N
+
+M.parents    # => [Object]
+M::N.parents # => [M, Object]
+X.parents    # => [M, Object]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/introspection.rb, line 50
+def parents
+  parents = []
+  if parent_name
+    parts = parent_name.split("::")
+    until parts.empty?
+      parents << ActiveSupport::Inflector.constantize(parts * "::")
+      parts.pop
+    end
+  end
+  parents << Object unless parents.include? Object
+  parents
+end
+
+
+ +
+ +
+

+ + redefine_method(method, &block) + +

+ + +
+

Replaces the existing method definition, if there is one, with the passed block as its body.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/redefine_method.rb, line 26
+def redefine_method(method, &block)
+  visibility = method_visibility(method)
+  silence_redefinition_of_method(method)
+  define_method(method, &block)
+  send(visibility, method)
+end
+
+
+ +
+ +
+

+ + redefine_singleton_method(method, &block) + +

+ + +
+

Replaces the existing singleton method definition, if there is one, with the passed block as its body.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/redefine_method.rb, line 35
+def redefine_singleton_method(method, &block)
+  singleton_class.redefine_method(method, &block)
+end
+
+
+ +
+ +
+

+ + remove_possible_method(method) + +

+ + +
+

Removes the named method, if it exists.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/remove_method.rb, line 7
+def remove_possible_method(method)
+  if method_defined?(method) || private_method_defined?(method)
+    undef_method(method)
+  end
+end
+
+
+ +
+ +
+

+ + remove_possible_singleton_method(method) + +

+ + +
+

Removes the named singleton method, if it exists.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/remove_method.rb, line 14
+def remove_possible_singleton_method(method)
+  singleton_class.remove_possible_method(method)
+end
+
+
+ +
+ +
+

+ + silence_redefinition_of_method(method) + +

+ + +
+

Marks the named method as intended to be redefined, if it exists. Suppresses the Ruby method redefinition warning. Prefer redefine_method where possible.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/redefine_method.rb, line 8
+def silence_redefinition_of_method(method)
+  if method_defined?(method) || private_method_defined?(method)
+    # This suppresses the "method redefined" warning; the self-alias
+    # looks odd, but means we don't need to generate a unique name
+    alias_method method, method
+  end
+end
+
+
+ +
+ +
+

+ + thread_cattr_accessor(*syms) + +

+ + +
+ +
+ + + + + +
+ Alias for: thread_mattr_accessor +
+ + + +
+ +
+

+ + thread_mattr_accessor(*syms) + +

+ + +
+

Defines both class and instance accessors for class attributes.

+ +
class Account
+  thread_mattr_accessor :user
+end
+
+Account.user = "DHH"
+Account.user     # => "DHH"
+Account.new.user # => "DHH"
+
+ +

If a subclass changes the value, the parent class' value is not changed. Similarly, if the parent class changes the value, the value of subclasses is not changed.

+ +
class Customer < Account
+end
+
+Customer.user = "Rafael"
+Customer.user # => "Rafael"
+Account.user  # => "DHH"
+
+ +

To opt out of the instance writer method, pass instance_writer: false. To opt out of the instance reader method, pass instance_reader: false.

+ +
class Current
+  thread_mattr_accessor :user, instance_writer: false, instance_reader: false
+end
+
+Current.new.user = "DHH"  # => NoMethodError
+Current.new.user          # => NoMethodError
+
+ +

Or pass instance_accessor: false, to opt out both instance methods.

+ +
class Current
+  mattr_accessor :user, instance_accessor: false
+end
+
+Current.new.user = "DHH"  # => NoMethodError
+Current.new.user          # => NoMethodError
+
+
+ + + +
+ Also aliased as: thread_cattr_accessor +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb, line 145
+def thread_mattr_accessor(*syms)
+  thread_mattr_reader(*syms)
+  thread_mattr_writer(*syms)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Module/Concerning.html b/src/5.2/classes/Module/Concerning.html new file mode 100644 index 0000000000..bca3c4c3eb --- /dev/null +++ b/src/5.2/classes/Module/Concerning.html @@ -0,0 +1,260 @@ +--- +title: Module::Concerning +layout: default +--- +
+ +
+
+ +
+ +

Bite-sized separation of concerns

+ +

We often find ourselves with a medium-sized chunk of behavior that we'd like to extract, but only mix in to a single class.

+ +

Extracting a plain old Ruby object to encapsulate it and collaborate or delegate to the original object is often a good choice, but when there's no additional state to encapsulate or we're making DSL-style declarations about the parent class, introducing new collaborators can obfuscate rather than simplify.

+ +

The typical route is to just dump everything in a monolithic class, perhaps with a comment, as a least-bad alternative. Using modules in separate files means tedious sifting to get a big-picture view.

+ +

Dissatisfying ways to separate small concerns

+ +

Using comments:

+ +
class Todo < ApplicationRecord
+  # Other todo implementation
+  # ...
+
+  ## Event tracking
+  has_many :events
+
+  before_create :track_creation
+
+  private
+    def track_creation
+      # ...
+    end
+end
+
+ +

With an inline module:

+ +

Noisy syntax.

+ +
class Todo < ApplicationRecord
+  # Other todo implementation
+  # ...
+
+  module EventTracking
+    extend ActiveSupport::Concern
+
+    included do
+      has_many :events
+      before_create :track_creation
+    end
+
+    private
+      def track_creation
+        # ...
+      end
+  end
+  include EventTracking
+end
+
+ +

Mix-in noise exiled to its own file:

+ +

Once our chunk of behavior starts pushing the scroll-to-understand-it boundary, we give in and move it to a separate file. At this size, the increased overhead can be a reasonable tradeoff even if it reduces our at-a-glance perception of how things work.

+ +
class Todo < ApplicationRecord
+  # Other todo implementation
+  # ...
+
+  include TodoEventTracking
+end
+
+ +

Introducing Module#concerning

+ +

By quieting the mix-in noise, we arrive at a natural, low-ceremony way to separate bite-sized concerns.

+ +
class Todo < ApplicationRecord
+  # Other todo implementation
+  # ...
+
+  concerning :EventTracking do
+    included do
+      has_many :events
+      before_create :track_creation
+    end
+
+    private
+      def track_creation
+        # ...
+      end
+  end
+end
+
+Todo.ancestors
+# => [Todo, Todo::EventTracking, ApplicationRecord, Object]
+
+ +

This small step has some wonderful ripple effects. We can

+
  • +

    grok the behavior of our class in one glance,

    +
  • +

    clean up monolithic junk-drawer classes by separating their concerns, and

    +
  • +

    stop leaning on protected/private for crude “this is internal stuff” modularity.

    +
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + concern(topic, &module_definition) + +

+ + +
+

A low-cruft shortcut to define a concern.

+ +
concern :EventTracking do
+  ...
+end
+
+ +

is equivalent to

+ +
module EventTracking
+  extend ActiveSupport::Concern
+
+  ...
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/concerning.rb, line 126
+def concern(topic, &module_definition)
+  const_set topic, Module.new {
+    extend ::ActiveSupport::Concern
+    module_eval(&module_definition)
+  }
+end
+
+
+ +
+ +
+

+ + concerning(topic, &block) + +

+ + +
+

Define a new concern and mix it in.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/module/concerning.rb, line 109
+def concerning(topic, &block)
+  include concern(topic, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Module/DelegationError.html b/src/5.2/classes/Module/DelegationError.html new file mode 100644 index 0000000000..343c342f5c --- /dev/null +++ b/src/5.2/classes/Module/DelegationError.html @@ -0,0 +1,66 @@ +--- +title: Module::DelegationError +layout: default +--- +
+ +
+
+ +
+ +

Error generated by delegate when a method is called on nil and allow_nil option is not used.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/NameError.html b/src/5.2/classes/NameError.html new file mode 100644 index 0000000000..5b7e764515 --- /dev/null +++ b/src/5.2/classes/NameError.html @@ -0,0 +1,173 @@ +--- +title: NameError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + missing_name() + +

+ + +
+

Extract the name of the missing constant from the exception message.

+ +
begin
+  HelloWorld
+rescue NameError => e
+  e.missing_name
+end
+# => "HelloWorld"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/name_error.rb, line 12
+def missing_name
+  # Since ruby v2.3.0 `did_you_mean` gem is loaded by default.
+  # It extends NameError#message with spell corrections which are SLOW.
+  # We should use original_message message instead.
+  message = respond_to?(:original_message) ? original_message : self.message
+
+  if /undefined local variable or method/ !~ message
+    $1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
+  end
+end
+
+
+ +
+ +
+

+ + missing_name?(name) + +

+ + +
+

Was this exception raised because the given name was missing?

+ +
begin
+  HelloWorld
+rescue NameError => e
+  e.missing_name?("HelloWorld")
+end
+# => true
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/name_error.rb, line 31
+def missing_name?(name)
+  if name.is_a? Symbol
+    self.name == name
+  else
+    missing_name == name.to_s
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/NilClass.html b/src/5.2/classes/NilClass.html new file mode 100644 index 0000000000..1fbc9df829 --- /dev/null +++ b/src/5.2/classes/NilClass.html @@ -0,0 +1,296 @@ +--- +title: NilClass +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+

nil is blank:

+ +
nil.blank? # => true
+
+ +

@return [true]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 57
+def blank?
+  true
+end
+
+
+ +
+ +
+

+ + duplicable?() + +

+ + +
+

nil is not duplicable:

+ +
nil.duplicable? # => false
+nil.dup         # => TypeError: can't dup NilClass
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 40
+def duplicable?
+  false
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns self.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 20
+def to_param
+  self
+end
+
+
+ +
+ +
+

+ + try(*args) + +

+ + +
+

Calling try on nil always returns nil. It becomes especially helpful when navigating through associations that may return nil.

+ +
nil.try(:name) # => nil
+
+ +

Without try

+ +
@person && @person.children.any? && @person.children.first.name
+
+ +

With try

+ +
@person.try(:children).try(:first).try(:name)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/try.rb, line 138
+def try(*args)
+  nil
+end
+
+
+ +
+ +
+

+ + try!(*args) + +

+ + +
+

Calling try! on nil always returns nil.

+ +
nil.try!(:name) # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/try.rb, line 145
+def try!(*args)
+  nil
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Numeric.html b/src/5.2/classes/Numeric.html new file mode 100644 index 0000000000..3a286ded01 --- /dev/null +++ b/src/5.2/classes/Numeric.html @@ -0,0 +1,1333 @@ +--- +title: Numeric +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EXABYTE=PETABYTE * 1024
 
GIGABYTE=MEGABYTE * 1024
 
KILOBYTE=1024
 
MEGABYTE=KILOBYTE * 1024
 
PETABYTE=TERABYTE * 1024
 
TERABYTE=GIGABYTE * 1024
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + byte() + +

+ + +
+ +
+ + + + + +
+ Alias for: bytes +
+ + + +
+ +
+

+ + bytes() + +

+ + +
+

Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes

+ +
2.bytes # => 2
+
+
+ + + +
+ Also aliased as: byte +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 14
+def bytes
+  self
+end
+
+
+ +
+ +
+

+ + day() + +

+ + +
+ +
+ + + + + +
+ Alias for: days +
+ + + +
+ +
+

+ + days() + +

+ + +
+

Returns a Duration instance matching the number of days provided.

+ +
2.days # => 2 days
+
+
+ + + +
+ Also aliased as: day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 37
+def days
+  ActiveSupport::Duration.days(self)
+end
+
+
+ +
+ +
+

+ + duplicable?() + +

+ + +
+

Numbers are not duplicable:

+ +
3.duplicable? # => false
+3.dup         # => TypeError: can't dup Integer
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 101
+def duplicable?
+  false
+end
+
+
+ +
+ +
+

+ + exabyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: exabytes +
+ + + +
+ +
+

+ + exabytes() + +

+ + +
+

Returns the number of bytes equivalent to the exabytes provided.

+ +
2.exabytes # => 2_305_843_009_213_693_952
+
+
+ + + +
+ Also aliased as: exabyte +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 62
+def exabytes
+  self * EXABYTE
+end
+
+
+ +
+ +
+

+ + fortnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: fortnights +
+ + + +
+ +
+

+ + fortnights() + +

+ + +
+

Returns a Duration instance matching the number of fortnights provided.

+ +
2.fortnights # => 4 weeks
+
+
+ + + +
+ Also aliased as: fortnight +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 53
+def fortnights
+  ActiveSupport::Duration.weeks(self * 2)
+end
+
+
+ +
+ +
+

+ + gigabyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: gigabytes +
+ + + +
+ +
+

+ + gigabytes() + +

+ + +
+

Returns the number of bytes equivalent to the gigabytes provided.

+ +
2.gigabytes # => 2_147_483_648
+
+
+ + + +
+ Also aliased as: gigabyte +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 38
+def gigabytes
+  self * GIGABYTE
+end
+
+
+ +
+ +
+

+ + hour() + +

+ + +
+ +
+ + + + + +
+ Alias for: hours +
+ + + +
+ +
+

+ + hours() + +

+ + +
+

Returns a Duration instance matching the number of hours provided.

+ +
2.hours # => 2 hours
+
+
+ + + +
+ Also aliased as: hour +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 29
+def hours
+  ActiveSupport::Duration.hours(self)
+end
+
+
+ +
+ +
+

+ + html_safe?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 129
+def html_safe?
+  true
+end
+
+
+ +
+ +
+

+ + in_milliseconds() + +

+ + +
+

Returns the number of milliseconds equivalent to the seconds provided. Used with the standard time durations.

+ +
2.in_milliseconds # => 2000
+1.hour.in_milliseconds # => 3600000
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 63
+def in_milliseconds
+  self * 1000
+end
+
+
+ +
+ +
+

+ + kilobyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: kilobytes +
+ + + +
+ +
+

+ + kilobytes() + +

+ + +
+

Returns the number of bytes equivalent to the kilobytes provided.

+ +
2.kilobytes # => 2048
+
+
+ + + +
+ Also aliased as: kilobyte +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 22
+def kilobytes
+  self * KILOBYTE
+end
+
+
+ +
+ +
+

+ + megabyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: megabytes +
+ + + +
+ +
+

+ + megabytes() + +

+ + +
+

Returns the number of bytes equivalent to the megabytes provided.

+ +
2.megabytes # => 2_097_152
+
+
+ + + +
+ Also aliased as: megabyte +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 30
+def megabytes
+  self * MEGABYTE
+end
+
+
+ +
+ +
+

+ + minute() + +

+ + +
+ +
+ + + + + +
+ Alias for: minutes +
+ + + +
+ +
+

+ + minutes() + +

+ + +
+

Returns a Duration instance matching the number of minutes provided.

+ +
2.minutes # => 2 minutes
+
+
+ + + +
+ Also aliased as: minute +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 21
+def minutes
+  ActiveSupport::Duration.minutes(self)
+end
+
+
+ +
+ +
+

+ + negative?() + +

+ + +
+

Returns true if the number is negative.

+ +
-1.negative? # => true
+0.negative?  # => false
+1.negative?  # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/inquiry.rb, line 19
+def negative?
+  self < 0
+end
+
+
+ +
+ +
+

+ + petabyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: petabytes +
+ + + +
+ +
+

+ + petabytes() + +

+ + +
+

Returns the number of bytes equivalent to the petabytes provided.

+ +
2.petabytes # => 2_251_799_813_685_248
+
+
+ + + +
+ Also aliased as: petabyte +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 54
+def petabytes
+  self * PETABYTE
+end
+
+
+ +
+ +
+

+ + positive?() + +

+ + +
+

Returns true if the number is positive.

+ +
1.positive?  # => true
+0.positive?  # => false
+-1.positive? # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/inquiry.rb, line 10
+def positive?
+  self > 0
+end
+
+
+ +
+ +
+

+ + second() + +

+ + +
+ +
+ + + + + +
+ Alias for: seconds +
+ + + +
+ +
+

+ + seconds() + +

+ + +
+

Returns a Duration instance matching the number of seconds provided.

+ +
2.seconds # => 2 seconds
+
+
+ + + +
+ Also aliased as: second +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 13
+def seconds
+  ActiveSupport::Duration.seconds(self)
+end
+
+
+ +
+ +
+

+ + terabyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: terabytes +
+ + + +
+ +
+

+ + terabytes() + +

+ + +
+

Returns the number of bytes equivalent to the terabytes provided.

+ +
2.terabytes # => 2_199_023_255_552
+
+
+ + + +
+ Also aliased as: terabyte +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 46
+def terabytes
+  self * TERABYTE
+end
+
+
+ +
+ +
+

+ + week() + +

+ + +
+ +
+ + + + + +
+ Alias for: weeks +
+ + + +
+ +
+

+ + weeks() + +

+ + +
+

Returns a Duration instance matching the number of weeks provided.

+ +
2.weeks # => 2 weeks
+
+
+ + + +
+ Also aliased as: week +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 45
+def weeks
+  ActiveSupport::Duration.weeks(self)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Object.html b/src/5.2/classes/Object.html new file mode 100644 index 0000000000..5f6c6af77f --- /dev/null +++ b/src/5.2/classes/Object.html @@ -0,0 +1,1013 @@ +--- +title: Object +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Java + +
  • + +
+ + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
APP_PATH=File.expand_path("test/dummy/config/application", ENGINE_ROOT)
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + acts_like?(duck) + +

+ + +
+

A duck-type assistant method. For example, Active Support extends Date to define an acts_like_date? method, and extends Time to define acts_like_time?. As a result, we can do x.acts_like?(:time) and x.acts_like?(:date) to do duck-type-safe comparisons, since classes that we want to act like Time simply need to define an acts_like_time? method.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/acts_like.rb, line 9
+def acts_like?(duck)
+  case duck
+  when :time
+    respond_to? :acts_like_time?
+  when :date
+    respond_to? :acts_like_date?
+  when :string
+    respond_to? :acts_like_string?
+  else
+    respond_to? :"acts_like_#{duck}?"
+  end
+end
+
+
+ +
+ +
+

+ + blank?() + +

+ + +
+

An object is blank if it's false, empty, or a whitespace string. For example, false, '', ' ', nil, [], and {} are all blank.

+ +

This simplifies

+ +
!address || address.empty?
+
+ +

to

+ +
address.blank?
+
+ +

@return [true, false]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 19
+def blank?
+  respond_to?(:empty?) ? !!empty? : !self
+end
+
+
+ +
+ +
+

+ + deep_dup() + +

+ + +
+

Returns a deep copy of object if it's duplicable. If it's not duplicable, returns self.

+ +
object = Object.new
+dup    = object.deep_dup
+dup.instance_variable_set(:@a, 1)
+
+object.instance_variable_defined?(:@a) # => false
+dup.instance_variable_defined?(:@a)    # => true
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 15
+def deep_dup
+  duplicable? ? dup : self
+end
+
+
+ +
+ +
+

+ + duplicable?() + +

+ + +
+

Can you safely dup this object?

+ +

False for method objects; true otherwise.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 26
+def duplicable?
+  true
+end
+
+
+ +
+ +
+

+ + html_safe?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 123
+def html_safe?
+  false
+end
+
+
+ +
+ +
+

+ + in?(another_object) + +

+ + +
+

Returns true if this object is included in the argument. Argument must be any object which responds to #include?. Usage:

+ +
characters = ["Konata", "Kagami", "Tsukasa"]
+"Konata".in?(characters) # => true
+
+ +

This will throw an ArgumentError if the argument doesn't respond to #include?.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 12
+def in?(another_object)
+  another_object.include?(self)
+rescue NoMethodError
+  raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
+end
+
+
+ +
+ +
+

+ + instance_values() + +

+ + +
+

Returns a hash with string keys that maps instance variable names without “@” to their corresponding values.

+ +
class C
+  def initialize(x, y)
+    @x, @y = x, y
+  end
+end
+
+C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 14
+def instance_values
+  Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
+end
+
+
+ +
+ +
+

+ + instance_variable_names() + +

+ + +
+

Returns an array of instance variable names as strings including “@”.

+ +
class C
+  def initialize(x, y)
+    @x, @y = x, y
+  end
+end
+
+C.new(0, 1).instance_variable_names # => ["@y", "@x"]
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 27
+def instance_variable_names
+  instance_variables.map(&:to_s)
+end
+
+
+ +
+ +
+

+ + presence() + +

+ + +
+

Returns the receiver if it's present otherwise returns nil. object.presence is equivalent to

+ +
object.present? ? object : nil
+
+ +

For example, something like

+ +
state   = params[:state]   if params[:state].present?
+country = params[:country] if params[:country].present?
+region  = state || country || 'US'
+
+ +

becomes

+ +
region = params[:state].presence || params[:country].presence || 'US'
+
+ +

@return [Object]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 46
+def presence
+  self if present?
+end
+
+
+ +
+ +
+

+ + presence_in(another_object) + +

+ + +
+

Returns the receiver if it's included in the argument otherwise returns nil. Argument must be any object which responds to #include?. Usage:

+ +
params[:bucket_type].presence_in %w( project calendar )
+
+ +

This will throw an ArgumentError if the argument doesn't respond to #include?.

+ +

@return [Object]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 26
+def presence_in(another_object)
+  in?(another_object) ? self : nil
+end
+
+
+ +
+ +
+

+ + present?() + +

+ + +
+

An object is present if it's not blank.

+ +

@return [true, false]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 26
+def present?
+  !blank?
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+

Alias of to_s.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 7
+def to_param
+  to_s
+end
+
+
+ +
+ +
+

+ + to_query(key) + +

+ + +
+

Converts an object into a string suitable for use as a URL query string, using the given key as the param name.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 13
+def to_query(key)
+  "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
+end
+
+
+ +
+ +
+

+ + try(*a, &b) + + +

+ + +
+

Invokes the public method whose name goes as first argument just like public_send does, except that if the receiver does not respond to it the call returns nil rather than raising an exception.

+ +

This method is defined to be able to write

+ +
@person.try(:name)
+
+ +

instead of

+ +
@person.name if @person
+
+ +

try calls can be chained:

+ +
@person.try(:spouse).try(:name)
+
+ +

instead of

+ +
@person.spouse.name if @person && @person.spouse
+
+ +

try will also return nil if the receiver does not respond to the method:

+ +
@person.try(:non_existing_method) # => nil
+
+ +

instead of

+ +
@person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil
+
+ +

try returns nil when called on nil regardless of whether it responds to the method:

+ +
nil.try(:to_i) # => nil, rather than 0
+
+ +

Arguments and blocks are forwarded to the method if invoked:

+ +
@posts.try(:each_slice, 2) do |a, b|
+  ...
+end
+
+ +

The number of arguments in the signature must match. If the object responds to the method the call is attempted and ArgumentError is still raised in case of argument mismatch.

+ +

If try is called without arguments it yields the receiver to a given block unless it is nil:

+ +
@person.try do |p|
+  ...
+end
+
+ +

You can also call try with a block without accepting an argument, and the block will be instance_eval'ed instead:

+ +
@person.try { upcase.truncate(50) }
+
+ +

Please also note that try is defined on Object. Therefore, it won't work with instances of classes that do not have Object among their ancestors, like direct subclasses of BasicObject.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/try.rb, line 29
+  
+
+
+ +
+ +
+

+ + try!(*a, &b) + + +

+ + +
+

Same as try, but raises a NoMethodError exception if the receiver is not nil and does not implement the tried method.

+ +
"a".try!(:upcase) # => "A"
+nil.try!(:upcase) # => nil
+123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/try.rb, line 94
+
+
+
+ +
+ +
+

+ + unescape(str, escaped = /%[a-fA-F\d]{2}/) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/uri.rb, line 8
+def unescape(str, escaped = /%[a-fA-F\d]{2}/)
+  # TODO: Are we actually sure that ASCII == UTF-8?
+  # YK: My initial experiments say yes, but let's be sure please
+  enc = str.encoding
+  enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
+  str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
+end
+
+
+ +
+ +
+

+ + with_options(options, &block) + +

+ + +
+

An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. Each method called on the block variable must take an options hash as its final argument.

+ +

Without with_options, this code contains duplication:

+ +
class Account < ActiveRecord::Base
+  has_many :customers, dependent: :destroy
+  has_many :products,  dependent: :destroy
+  has_many :invoices,  dependent: :destroy
+  has_many :expenses,  dependent: :destroy
+end
+
+ +

Using with_options, we can remove the duplication:

+ +
class Account < ActiveRecord::Base
+  with_options dependent: :destroy do |assoc|
+    assoc.has_many :customers
+    assoc.has_many :products
+    assoc.has_many :invoices
+    assoc.has_many :expenses
+  end
+end
+
+ +

It can also be used with an explicit receiver:

+ +
I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
+  subject i18n.t :subject
+  body    i18n.t :body, user_name: user.name
+end
+
+ +

When you don't pass an explicit receiver, it executes the whole block in merging options context:

+ +
class Account < ActiveRecord::Base
+  with_options dependent: :destroy do
+    has_many :customers
+    has_many :products
+    has_many :invoices
+    has_many :expenses
+  end
+end
+
+ +

with_options can also be nested since the call is forwarded to its receiver.

+ +

NOTE: Each nesting level will merge inherited defaults in addition to their own.

+ +
class Post < ActiveRecord::Base
+  with_options if: :persisted?, length: { minimum: 50 } do
+    validates :content, if: -> { content.present? }
+  end
+end
+
+ +

The code is equivalent to:

+ +
validates :content, length: { minimum: 50 }, if: -> { content.present? }
+
+ +

Hence the inherited default for if key is ignored.

+ +

NOTE: You cannot call class methods implicitly inside of with_options. You can access these methods using the class name instead:

+ +
class Phone < ActiveRecord::Base
+  enum phone_number_type: [home: 0, office: 1, mobile: 2]
+
+  with_options presence: true do
+    validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/with_options.rb, line 78
+def with_options(options, &block)
+  option_merger = ActiveSupport::OptionMerger.new(self, options)
+  block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/PG.html b/src/5.2/classes/PG.html new file mode 100644 index 0000000000..e50c5a6587 --- /dev/null +++ b/src/5.2/classes/PG.html @@ -0,0 +1,69 @@ +--- +title: PG +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/PG/Connection.html b/src/5.2/classes/PG/Connection.html new file mode 100644 index 0000000000..ac8fd680c5 --- /dev/null +++ b/src/5.2/classes/PG/Connection.html @@ -0,0 +1,66 @@ +--- +title: PG::Connection +layout: default +--- +
+ +
+
+ +
+ +

Use async_exec instead of exec_params on pg versions before 1.1

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Process.html b/src/5.2/classes/Process.html new file mode 100644 index 0000000000..5717d1a131 --- /dev/null +++ b/src/5.2/classes/Process.html @@ -0,0 +1,56 @@ +--- +title: Process +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails.html b/src/5.2/classes/Rails.html new file mode 100644 index 0000000000..c440650298 --- /dev/null +++ b/src/5.2/classes/Rails.html @@ -0,0 +1,772 @@ +--- +title: Rails +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + app_class
+ [W] + application
+ [RW] + cache
+ [RW] + logger
+ + + + +

Class Public methods

+ +
+

+ + application() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 39
+def application
+  @application ||= (app_class.instance if app_class)
+end
+
+
+ +
+ +
+

+ + backtrace_cleaner() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 50
+def backtrace_cleaner
+  @backtrace_cleaner ||= begin
+    # Relies on Active Support, so we have to lazy load to postpone definition until Active Support has been loaded
+    require "rails/backtrace_cleaner"
+    Rails::BacktraceCleaner.new
+  end
+end
+
+
+ +
+ +
+

+ + configuration() + +

+ + +
+

The Configuration instance used to configure the Rails environment

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 46
+def configuration
+  application.config
+end
+
+
+ +
+ +
+

+ + env() + +

+ + +
+

Returns the current Rails environment.

+ +
Rails.env # => "development"
+Rails.env.development? # => true
+Rails.env.production? # => false
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 72
+def env
+  @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence || "development")
+end
+
+
+ +
+ +
+

+ + env=(environment) + +

+ + +
+

Sets the Rails environment.

+ +
Rails.env = "staging" # => "staging"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 79
+def env=(environment)
+  @_env = ActiveSupport::StringInquirer.new(environment)
+end
+
+
+ +
+ +
+

+ + gem_version() + +

+ + +
+

Returns the version of the currently loaded Rails as a Gem::Version

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/gem_version.rb, line 5
+def self.gem_version
+  Gem::Version.new VERSION::STRING
+end
+
+
+ +
+ +
+

+ + groups(*groups) + +

+ + +
+

Returns all Rails groups for loading based on:

+
  • +

    The Rails environment;

    +
  • +

    The environment variable RAILS_GROUPS;

    +
  • +

    The optional envs given as argument and the hash with group dependencies;

    + +

    groups assets: [:development, :test]

    + +

    # Returns # => [:default, “development”, :assets] for Rails.env == “development” # => [:default, “production”] for Rails.env == “production”

    +
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 94
+def groups(*groups)
+  hash = groups.extract_options!
+  env = Rails.env
+  groups.unshift(:default, env)
+  groups.concat ENV["RAILS_GROUPS"].to_s.split(",")
+  groups.concat hash.map { |k, v| k if v.map(&:to_s).include?(env) }
+  groups.compact!
+  groups.uniq!
+  groups
+end
+
+
+ +
+ +
+

+ + public_path() + +

+ + +
+

Returns a Pathname object of the public folder of the current Rails project, otherwise it returns nil if there is no project:

+ +
Rails.public_path
+  # => #<Pathname:/Users/someuser/some/path/project/public>
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 110
+def public_path
+  application && Pathname.new(application.paths["public"].first)
+end
+
+
+ +
+ +
+

+ + root() + +

+ + +
+

Returns a Pathname object of the current Rails project, otherwise it returns nil if there is no project:

+ +
Rails.root
+  # => #<Pathname:/Users/someuser/some/path/project>
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails.rb, line 63
+def root
+  application && application.config.root
+end
+
+
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the version of the currently loaded Rails as a string.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/version.rb, line 7
+def self.version
+  VERSION::STRING
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/API.html b/src/5.2/classes/Rails/API.html new file mode 100644 index 0000000000..211f1b2c71 --- /dev/null +++ b/src/5.2/classes/Rails/API.html @@ -0,0 +1,73 @@ +--- +title: Rails::API +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/API/EdgeTask.html b/src/5.2/classes/Rails/API/EdgeTask.html new file mode 100644 index 0000000000..3887bf89ae --- /dev/null +++ b/src/5.2/classes/Rails/API/EdgeTask.html @@ -0,0 +1,107 @@ +--- +title: Rails::API::EdgeTask +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + rails_version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 174
+def rails_version
+  "master@#{`git rev-parse HEAD`[0, 7]}"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/API/RepoTask.html b/src/5.2/classes/Rails/API/RepoTask.html new file mode 100644 index 0000000000..0af790501f --- /dev/null +++ b/src/5.2/classes/Rails/API/RepoTask.html @@ -0,0 +1,186 @@ +--- +title: Rails::API::RepoTask +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + api_dir() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 168
+def api_dir
+  "doc/rdoc"
+end
+
+
+ +
+ +
+

+ + component_root_dir(component) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 164
+def component_root_dir(component)
+  component
+end
+
+
+ +
+ +
+

+ + configure_sdoc() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 159
+def configure_sdoc
+  super
+  options << "-g" # link to GitHub, SDoc flag
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/API/StableTask.html b/src/5.2/classes/Rails/API/StableTask.html new file mode 100644 index 0000000000..789c0551f9 --- /dev/null +++ b/src/5.2/classes/Rails/API/StableTask.html @@ -0,0 +1,107 @@ +--- +title: Rails::API::StableTask +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + rails_version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 180
+def rails_version
+  File.read("RAILS_VERSION").strip
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/API/Task.html b/src/5.2/classes/Rails/API/Task.html new file mode 100644 index 0000000000..c41927c133 --- /dev/null +++ b/src/5.2/classes/Rails/API/Task.html @@ -0,0 +1,444 @@ +--- +title: Rails::API::Task +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
RDOC_FILES={ +"activesupport" => { +include: %w( +README.rdoc +lib/active_support/**/*.rb +) +}, + +"activerecord" => { +include: %w( +README.rdoc +lib/active_record/**/*.rb +) +}, + +"activemodel" => { +include: %w( +README.rdoc +lib/active_model/**/*.rb +) +}, + +"actionpack" => { +include: %w( +README.rdoc +lib/abstract_controller/**/*.rb +lib/action_controller/**/*.rb +lib/action_dispatch/**/*.rb +) +}, + +"actionview" => { +include: %w( +README.rdoc +lib/action_view/**/*.rb +), +exclude: "lib/action_view/vendor/*" +}, + +"actionmailer" => { +include: %w( +README.rdoc +lib/action_mailer/**/*.rb +) +}, + +"activejob" => { +include: %w( +README.md +lib/active_job/**/*.rb +) +}, + +"actioncable" => { +include: %w( +README.md +lib/action_cable/**/*.rb +) +}, + +"activestorage" => { +include: %w( +README.md +app/**/active_storage/**/*.rb +lib/active_storage/**/*.rb +) +}, + +"railties" => { +include: %w( +README.rdoc +lib/**/*.rb +), +exclude: %w( +lib/rails/generators/**/templates/**/*.rb +lib/rails/test_unit/* +lib/rails/api/generator.rb +) +} +}
 
+ + + + + + +

Class Public methods

+ +
+

+ + new(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 90
+def initialize(name)
+  super
+
+  # Every time rake runs this task is instantiated as all the rest.
+  # Be lazy computing stuff to have as light impact as possible to
+  # the rest of tasks.
+  before_running_rdoc do
+    configure_sdoc
+    configure_rdoc_files
+    setup_horo_variables
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + api_main() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 153
+def api_main
+  component_root_dir("railties") + "/RDOC_MAIN.rdoc"
+end
+
+
+ +
+ +
+

+ + configure_rdoc_files() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 119
+def configure_rdoc_files
+  rdoc_files.include(api_main)
+
+  RDOC_FILES.each do |component, cfg|
+    cdr = component_root_dir(component)
+
+    Array(cfg[:include]).each do |pattern|
+      rdoc_files.include("#{cdr}/#{pattern}")
+    end
+
+    Array(cfg[:exclude]).each do |pattern|
+      rdoc_files.exclude("#{cdr}/#{pattern}")
+    end
+  end
+
+  # Only generate documentation for files that have been
+  # changed since the API was generated.
+  if Dir.exist?("doc/rdoc") && !ENV["ALL"]
+    last_generation = DateTime.rfc2822(File.open("doc/rdoc/created.rid", &:readline))
+
+    rdoc_files.keep_if do |file|
+      File.mtime(file).to_datetime > last_generation
+    end
+
+    # Nothing to do
+    exit(0) if rdoc_files.empty?
+  end
+end
+
+
+ +
+ +
+

+ + configure_sdoc() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 108
+def configure_sdoc
+  self.title    = "Ruby on Rails API"
+  self.rdoc_dir = api_dir
+
+  options << "-m"  << api_main
+  options << "-e"  << "UTF-8"
+
+  options << "-f"  << "api"
+  options << "-T"  << "rails"
+end
+
+
+ +
+ +
+

+ + desc(description) + +

+ + +
+

Hack, ignore the desc calls performed by the original initializer.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 104
+def desc(description)
+  # no-op
+end
+
+
+ +
+ +
+

+ + setup_horo_variables() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/api/task.rb, line 148
+def setup_horo_variables
+  ENV["HORO_PROJECT_NAME"]    = "Ruby on Rails"
+  ENV["HORO_PROJECT_VERSION"] = rails_version
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/AppBuilder.html b/src/5.2/classes/Rails/AppBuilder.html new file mode 100644 index 0000000000..c988c501ad --- /dev/null +++ b/src/5.2/classes/Rails/AppBuilder.html @@ -0,0 +1,1197 @@ +--- +title: Rails::AppBuilder +layout: default +--- +
+ +
+
+ +
+ +

The application builder allows you to override elements of the application generator without being forced to reverse the operations of the default generator.

+ +

This allows you to override entire operations, like the creation of the Gemfile, README, or JavaScript files, without needing to know exactly what those operations do so you can create another template action.

+ +
class CustomAppBuilder < Rails::AppBuilder
+  def test
+    @generator.gem "rspec-rails", group: [:development, :test]
+    run "bundle install"
+    generate "rspec:install"
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 80
+def app
+  directory "app"
+
+  keep_file "app/assets/images"
+  empty_directory_with_keep_file "app/assets/javascripts/channels" unless options[:skip_action_cable]
+
+  keep_file  "app/controllers/concerns"
+  keep_file  "app/models/concerns"
+end
+
+
+ +
+ +
+

+ + bin() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 90
+def bin
+  directory "bin" do |content|
+    "#{shebang}\n" + content
+  end
+  chmod "bin", 0755 & ~File.umask, verbose: false
+end
+
+
+ +
+ +
+

+ + bin_when_updating() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 97
+def bin_when_updating
+  bin_yarn_exist = File.exist?("bin/yarn")
+
+  bin
+
+  if options[:api] && !bin_yarn_exist
+    remove_file "bin/yarn"
+  end
+end
+
+
+ +
+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 107
+def config
+  empty_directory "config"
+
+  inside "config" do
+    template "routes.rb"
+    template "application.rb"
+    template "environment.rb"
+    template "cable.yml" unless options[:skip_action_cable]
+    template "puma.rb"   unless options[:skip_puma]
+    template "spring.rb" if spring_install?
+    template "storage.yml" unless skip_active_storage?
+
+    directory "environments"
+    directory "initializers"
+    directory "locales"
+  end
+end
+
+
+ +
+ +
+

+ + config_target_version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 244
+def config_target_version
+  defined?(@config_target_version) ? @config_target_version : Rails::VERSION::STRING.to_f
+end
+
+
+ +
+ +
+

+ + config_when_updating() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 125
+def config_when_updating
+  cookie_serializer_config_exist = File.exist?("config/initializers/cookies_serializer.rb")
+  action_cable_config_exist      = File.exist?("config/cable.yml")
+  active_storage_config_exist    = File.exist?("config/storage.yml")
+  rack_cors_config_exist         = File.exist?("config/initializers/cors.rb")
+  assets_config_exist            = File.exist?("config/initializers/assets.rb")
+  csp_config_exist               = File.exist?("config/initializers/content_security_policy.rb")
+
+  @config_target_version = Rails.application.config.loaded_config_version || "5.0"
+
+  config
+
+  unless cookie_serializer_config_exist
+    gsub_file "config/initializers/cookies_serializer.rb", /json(?!,)/, "marshal"
+  end
+
+  if !options[:skip_action_cable] && !action_cable_config_exist
+    template "config/cable.yml"
+  end
+
+  if !skip_active_storage? && !active_storage_config_exist
+    template "config/storage.yml"
+  end
+
+  if options[:skip_sprockets] && !assets_config_exist
+    remove_file "config/initializers/assets.rb"
+  end
+
+  unless rack_cors_config_exist
+    remove_file "config/initializers/cors.rb"
+  end
+
+  if options[:api]
+    unless cookie_serializer_config_exist
+      remove_file "config/initializers/cookies_serializer.rb"
+    end
+
+    unless assets_config_exist
+      remove_file "config/initializers/assets.rb"
+    end
+
+    unless csp_config_exist
+      remove_file "config/initializers/content_security_policy.rb"
+    end
+  end
+end
+
+
+ +
+ +
+

+ + configru() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 62
+def configru
+  template "config.ru"
+end
+
+
+ +
+ +
+

+ + credentials() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 181
+def credentials
+  return if options[:pretend] || options[:dummy_app]
+
+  require "rails/generators/rails/credentials/credentials_generator"
+  Rails::Generators::CredentialsGenerator.new([], quiet: options[:quiet]).add_credentials_file_silently
+end
+
+
+ +
+ +
+

+ + database_yml() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 188
+def database_yml
+  template "config/databases/#{options[:database]}.yml", "config/database.yml"
+end
+
+
+ +
+ +
+

+ + db() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 192
+def db
+  directory "db"
+end
+
+
+ +
+ +
+

+ + gemfile() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 58
+def gemfile
+  template "Gemfile"
+end
+
+
+ +
+ +
+

+ + gitignore() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 66
+def gitignore
+  template "gitignore", ".gitignore"
+end
+
+
+ +
+ +
+

+ + lib() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 196
+def lib
+  empty_directory "lib"
+  empty_directory_with_keep_file "lib/tasks"
+  empty_directory_with_keep_file "lib/assets"
+end
+
+
+ +
+ +
+

+ + log() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 202
+def log
+  empty_directory_with_keep_file "log"
+end
+
+
+ +
+ +
+

+ + master_key() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 172
+def master_key
+  return if options[:pretend] || options[:dummy_app]
+
+  require "rails/generators/rails/master_key/master_key_generator"
+  master_key_generator = Rails::Generators::MasterKeyGenerator.new([], quiet: options[:quiet], force: options[:force])
+  master_key_generator.add_master_key_file_silently
+  master_key_generator.ignore_master_key_file_silently
+end
+
+
+ +
+ +
+

+ + package_json() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 76
+def package_json
+  template "package.json"
+end
+
+
+ +
+ +
+

+ + public_directory() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 206
+def public_directory
+  directory "public", "public", recursive: false
+end
+
+
+ +
+ +
+

+ + rakefile() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 46
+def rakefile
+  template "Rakefile"
+end
+
+
+ +
+ +
+

+ + readme() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 50
+def readme
+  copy_file "README.md", "README.md"
+end
+
+
+ +
+ +
+

+ + ruby_version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 54
+def ruby_version
+  template "ruby-version", ".ruby-version"
+end
+
+
+ +
+ +
+

+ + storage() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 210
+def storage
+  empty_directory_with_keep_file "storage"
+  empty_directory_with_keep_file "tmp/storage"
+end
+
+
+ +
+ +
+

+ + system_test() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 227
+def system_test
+  empty_directory_with_keep_file "test/system"
+
+  template "test/application_system_test_case.rb"
+end
+
+
+ +
+ +
+

+ + test() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 215
+def test
+  empty_directory_with_keep_file "test/fixtures"
+  empty_directory_with_keep_file "test/fixtures/files"
+  empty_directory_with_keep_file "test/controllers"
+  empty_directory_with_keep_file "test/mailers"
+  empty_directory_with_keep_file "test/models"
+  empty_directory_with_keep_file "test/helpers"
+  empty_directory_with_keep_file "test/integration"
+
+  template "test/test_helper.rb"
+end
+
+
+ +
+ +
+

+ + tmp() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 233
+def tmp
+  empty_directory_with_keep_file "tmp"
+  empty_directory_with_keep_file "tmp/pids"
+  empty_directory "tmp/cache"
+  empty_directory "tmp/cache/assets"
+end
+
+
+ +
+ +
+

+ + vendor() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 240
+def vendor
+  empty_directory_with_keep_file "vendor"
+end
+
+
+ +
+ +
+

+ + version_control() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 70
+def version_control
+  if !options[:skip_git] && !options[:pretend]
+    run "git init", capture: options[:quiet]
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application.html b/src/5.2/classes/Rails/Application.html new file mode 100644 index 0000000000..f0a0820e98 --- /dev/null +++ b/src/5.2/classes/Rails/Application.html @@ -0,0 +1,1267 @@ +--- +title: Rails::Application +layout: default +--- +
+ +
+
+ +
+ +

An Engine with the responsibility of coordinating the whole boot process.

+ +

Initialization

+ +

Rails::Application is responsible for executing all railties and engines initializers. It also executes some bootstrap initializers (check Rails::Application::Bootstrap) and finishing initializers, after all the others are executed (check Rails::Application::Finisher).

+ +

Configuration

+ +

Besides providing the same configuration as Rails::Engine and Rails::Railtie, the application object has several specific configurations, for example “cache_classes”, “consider_all_requests_local”, “filter_parameters”, “logger” and so forth.

+ +

Check Rails::Application::Configuration to see them all.

+ +

Routes

+ +

The application object is also responsible for holding the routes and reloading routes whenever the files change in development.

+ +

Middlewares

+ +

The Application is also responsible for building the middleware stack.

+ +

Booting process

+ +

The application is also responsible for setting up and executing the booting process. From the moment you require “config/application.rb” in your app, the booting process goes like this:

+ +
1)  require "config/boot.rb" to setup load paths
+2)  require railties and engines
+3)  Define Rails.application as "class MyApp::Application < Rails::Application"
+4)  Run config.before_configuration callbacks
+5)  Load config/environments/ENV.rb
+6)  Run config.before_initialize callbacks
+7)  Run Railtie#initializer defined by railties, engines and application.
+    One by one, each engine sets up its load paths, routes and runs its config/initializers/* files.
+8)  Custom Railtie#initializers added by railties, engines and applications are executed
+9)  Build the middleware stack and run to_prepare callbacks
+10) Run config.before_eager_load and eager_load! if eager_load is true
+11) Run config.after_initialize callbacks
+
+ +

Multiple Applications

+ +

If you decide to define multiple applications, then the first application that is initialized will be set to Rails.application, unless you override it with a different application.

+ +

To create a new application, you can instantiate a new instance of a class that has already been created:

+ +
class Application < Rails::Application
+end
+
+first_application  = Application.new
+second_application = Application.new(config: first_application.config)
+
+ +

In the above example, the configuration from the first application was used to initialize the second application. You can also use the initialize_copy on one of the applications to create a copy of the application which shares the configuration.

+ +

If you decide to define Rake tasks, runners, or initializers in an application other than Rails.application, then you must run them manually.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + assets
+ [R] + executor
+ [R] + reloader
+ [R] + reloaders
+ [RW] + sandbox
+ [RW] + sandbox?
+ + + + +

Class Public methods

+ +
+

+ + create(initial_variable_values = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 102
+def create(initial_variable_values = {}, &block)
+  new(initial_variable_values, &block).run_load_hooks!
+end
+
+
+ +
+ +
+

+ + find_root(from) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 106
+def find_root(from)
+  find_root_with_flag "config.ru", from, Dir.pwd
+end
+
+
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 91
+def inherited(base)
+  super
+  Rails.app_class = base
+  add_lib_to_load_path!(find_root(base.called_from))
+  ActiveSupport.run_load_hooks(:before_configuration, base)
+end
+
+
+ +
+ +
+

+ + instance() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 98
+def instance
+  super.run_load_hooks!
+end
+
+
+ +
+ +
+

+ + new(initial_variable_values = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 127
+def initialize(initial_variable_values = {}, &block)
+  super()
+  @initialized       = false
+  @reloaders         = []
+  @routes_reloader   = nil
+  @app_env_config    = nil
+  @ordered_railties  = nil
+  @railties          = nil
+  @message_verifiers = {}
+  @ran_load_hooks    = false
+
+  @executor          = Class.new(ActiveSupport::Executor)
+  @reloader          = Class.new(ActiveSupport::Reloader)
+  @reloader.executor = @executor
+
+  # are these actually used?
+  @initial_variable_values = initial_variable_values
+  @block = block
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + config_for(name, env: Rails.env) + +

+ + +
+

Convenience for loading config/foo.yml for the current Rails env.

+ +

Example:

+ +
# 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
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 226
+def config_for(name, env: Rails.env)
+  if name.is_a?(Pathname)
+    yaml = name
+  else
+    yaml = Pathname.new("#{paths["config"].existent.first}/#{name}.yml")
+  end
+
+  if yaml.exist?
+    require "erb"
+    (YAML.load(ERB.new(yaml.read).result) || {})[env] || {}
+  else
+    raise "Could not load configuration. No such file - #{yaml}"
+  end
+rescue Psych::SyntaxError => e
+  raise "YAML syntax error occurred while parsing #{yaml}. " \
+    "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
+    "Error: #{e.message}"
+end
+
+
+ +
+ +
+

+ + console(&blk) + +

+ + +
+

Sends any console called in the instance of a new application up to the console method defined in Rails::Railtie.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 298
+def console(&blk)
+  self.class.console(&blk)
+end
+
+
+ +
+ +
+

+ + credentials() + +

+ + +
+

Decrypts the credentials hash as kept in config/credentials.yml.enc. This file is encrypted with the Rails master key, which is either taken from ENV["RAILS_MASTER_KEY"] or from loading config/master.key.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 441
+def credentials
+  @credentials ||= encrypted("config/credentials.yml.enc")
+end
+
+
+ +
+ +
+

+ + encrypted(path, key_path: "config/master.key", env_key: "RAILS_MASTER_KEY") + +

+ + +
+

Shorthand to decrypt any encrypted configurations or files.

+ +

For any file added with bin/rails encrypted:edit call read to decrypt the file with the master key. The master key is either stored in config/master.key or ENV["RAILS_MASTER_KEY"].

+ +
Rails.application.encrypted("config/mystery_man.txt.enc").read
+# => "We've met before, haven't we?"
+
+ +

It's also possible to interpret encrypted YAML files with config.

+ +
Rails.application.encrypted("config/credentials.yml.enc").config
+# => { next_guys_line: "I don't think so. Where was it you think we met?" }
+
+ +

Any top-level configs are also accessible directly on the return value:

+ +
Rails.application.encrypted("config/credentials.yml.enc").next_guys_line
+# => "I don't think so. Where was it you think we met?"
+
+ +

The files or configs can also be encrypted with a custom key. To decrypt with a key in the ENV, use:

+ +
Rails.application.encrypted("config/special_tokens.yml.enc", env_key: "SPECIAL_TOKENS")
+
+ +

Or to decrypt with a file, that should be version control ignored, relative to Rails.root:

+ +
Rails.application.encrypted("config/special_tokens.yml.enc", key_path: "config/special_tokens.key")
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 472
+def encrypted(path, key_path: "config/master.key", env_key: "RAILS_MASTER_KEY")
+  ActiveSupport::EncryptedConfiguration.new(
+    config_path: Rails.root.join(path),
+    key_path: Rails.root.join(key_path),
+    env_key: env_key,
+    raise_if_missing_key: config.require_master_key
+  )
+end
+
+
+ +
+ +
+

+ + env_config() + +

+ + +
+

Stores some of the Rails initial environment parameters which will be used by middlewares and engines to configure themselves.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 247
+def env_config
+  @app_env_config ||= begin
+    super.merge(
+      "action_dispatch.parameter_filter" => config.filter_parameters,
+      "action_dispatch.redirect_filter" => config.filter_redirect,
+      "action_dispatch.secret_token" => secrets.secret_token,
+      "action_dispatch.secret_key_base" => secret_key_base,
+      "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions,
+      "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local,
+      "action_dispatch.logger" => Rails.logger,
+      "action_dispatch.backtrace_cleaner" => Rails.backtrace_cleaner,
+      "action_dispatch.key_generator" => key_generator,
+      "action_dispatch.http_auth_salt" => config.action_dispatch.http_auth_salt,
+      "action_dispatch.signed_cookie_salt" => config.action_dispatch.signed_cookie_salt,
+      "action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt,
+      "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt,
+      "action_dispatch.authenticated_encrypted_cookie_salt" => config.action_dispatch.authenticated_encrypted_cookie_salt,
+      "action_dispatch.use_authenticated_cookie_encryption" => config.action_dispatch.use_authenticated_cookie_encryption,
+      "action_dispatch.encrypted_cookie_cipher" => config.action_dispatch.encrypted_cookie_cipher,
+      "action_dispatch.signed_cookie_digest" => config.action_dispatch.signed_cookie_digest,
+      "action_dispatch.cookies_serializer" => config.action_dispatch.cookies_serializer,
+      "action_dispatch.cookies_digest" => config.action_dispatch.cookies_digest,
+      "action_dispatch.cookies_rotations" => config.action_dispatch.cookies_rotations,
+      "action_dispatch.content_security_policy" => config.content_security_policy,
+      "action_dispatch.content_security_policy_report_only" => config.content_security_policy_report_only,
+      "action_dispatch.content_security_policy_nonce_generator" => config.content_security_policy_nonce_generator
+    )
+  end
+end
+
+
+ +
+ +
+

+ + generators(&blk) + +

+ + +
+

Sends any generators called in the instance of a new application up to the generators method defined in Rails::Railtie.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 304
+def generators(&blk)
+  self.class.generators(&blk)
+end
+
+
+ +
+ +
+

+ + initialized?() + +

+ + +
+

Returns true if the application is initialized.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 148
+def initialized?
+  @initialized
+end
+
+
+ +
+ +
+

+ + initializer(name, opts = {}, &block) + +

+ + +
+

Sends the initializers to the initializer method defined in the Rails::Initializable module. Each Rails::Application class has its own set of initializers, as defined by the Initializable module.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 286
+def initializer(name, opts = {}, &block)
+  self.class.initializer(name, opts, &block)
+end
+
+
+ +
+ +
+

+ + isolate_namespace(mod) + +

+ + +
+

Sends the isolate_namespace method up to the class method.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 309
+def isolate_namespace(mod)
+  self.class.isolate_namespace(mod)
+end
+
+
+ +
+ +
+

+ + key_generator() + +

+ + +
+

Returns the application's KeyGenerator

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 172
+def key_generator
+  # number of iterations selected based on consultation with the google security
+  # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
+  @caching_key_generator ||=
+    if secret_key_base
+      ActiveSupport::CachingKeyGenerator.new(
+        ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
+      )
+    else
+      ActiveSupport::LegacyKeyGenerator.new(secrets.secret_token)
+    end
+end
+
+
+ +
+ +
+

+ + message_verifier(verifier_name) + +

+ + +
+

Returns a message verifier object.

+ +

This verifier can be used to generate and verify signed messages in the application.

+ +

It is recommended not to use the same verifier for different things, so you can get different verifiers passing the verifier_name argument.

+ +

Parameters

+
  • +

    verifier_name - the name of the message verifier.

    +
+ +

Examples

+ +
message = Rails.application.message_verifier('sensitive_data').generate('my sensible data')
+Rails.application.message_verifier('sensitive_data').verify(message)
+# => 'my sensible data'
+
+ +

See the ActiveSupport::MessageVerifier documentation for more information.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 203
+def message_verifier(verifier_name)
+  @message_verifiers[verifier_name] ||= begin
+    secret = key_generator.generate_key(verifier_name.to_s)
+    ActiveSupport::MessageVerifier.new(secret)
+  end
+end
+
+
+ +
+ +
+

+ + rake_tasks(&block) + +

+ + +
+

If you try to define a set of Rake tasks on the instance, these will get passed up to the Rake tasks defined on the application's class.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 279
+def rake_tasks(&block)
+  self.class.rake_tasks(&block)
+end
+
+
+ +
+ +
+

+ + reload_routes!() + +

+ + +
+

Reload application routes regardless if they changed or not.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 167
+def reload_routes!
+  routes_reloader.reload!
+end
+
+
+ +
+ +
+

+ + runner(&blk) + +

+ + +
+

Sends any runner called in the instance of a new application up to the runner method defined in Rails::Railtie.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 292
+def runner(&blk)
+  self.class.runner(&blk)
+end
+
+
+ +
+ +
+

+ + secret_key_base() + +

+ + +
+

The secret_key_base is used as the input secret to the application's key generator, which in turn is used to create all MessageVerifiers/MessageEncryptors, including the ones that sign and encrypt cookies.

+ +

In test and development, this is simply derived as a MD5 hash of the application's name.

+ +

In all other environments, we look for it first in ENV, then credentials.secret_key_base, and finally secrets.secret_key_base. For most applications, the correct place to store it is in the encrypted credentials file.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 428
+def secret_key_base
+  if Rails.env.development? || Rails.env.test?
+    secrets.secret_key_base ||= generate_development_secret
+  else
+    validate_secret_key_base(
+      ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || secrets.secret_key_base
+    )
+  end
+end
+
+
+ +
+ +
+

+ + secrets() + +

+ + +
+

Returns secrets added to config/secrets.yml.

+ +

Example:

+ +
development:
+  secret_key_base: 836fa3665997a860728bcb9e9a1e704d427cfc920e79d847d79c8a9a907b9e965defa4154b2b86bdec6930adbe33f21364523a6f6ce363865724549fdfc08553
+test:
+  secret_key_base: 5a37811464e7d378488b0f073e2193b093682e4e21f5d6f3ae0a4e1781e61a351fdc878a843424e81c73fb484a40d23f92c8dafac4870e74ede6e5e174423010
+production:
+  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
+  namespace: my_app_production
+
+ +

Rails.application.secrets.namespace returns my_app_production in the production environment.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 394
+def secrets
+  @secrets ||= begin
+    secrets = ActiveSupport::OrderedOptions.new
+    files = config.paths["config/secrets"].existent
+    files = files.reject { |path| path.end_with?(".enc") } unless config.read_encrypted_secrets
+    secrets.merge! Rails::Secrets.parse(files, env: Rails.env)
+
+    # Fallback to config.secret_key_base if secrets.secret_key_base isn't set
+    secrets.secret_key_base ||= config.secret_key_base
+    # Fallback to config.secret_token if secrets.secret_token isn't set
+    secrets.secret_token ||= config.secret_token
+
+    if secrets.secret_token.present?
+      ActiveSupport::Deprecation.warn(
+        "`secrets.secret_token` is deprecated in favor of `secret_key_base` and will be removed in Rails 6.0."
+      )
+    end
+
+    secrets
+  end
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + validate_secret_key_base(secret_key_base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application.rb, line 579
+def validate_secret_key_base(secret_key_base)
+  if secret_key_base.is_a?(String) && secret_key_base.present?
+    secret_key_base
+  elsif secret_key_base
+    raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String`"
+  elsif secrets.secret_token.blank?
+    raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `rails credentials:edit`"
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application/Bootstrap.html b/src/5.2/classes/Rails/Application/Bootstrap.html new file mode 100644 index 0000000000..a3fbde24aa --- /dev/null +++ b/src/5.2/classes/Rails/Application/Bootstrap.html @@ -0,0 +1,68 @@ +--- +title: Rails::Application::Bootstrap +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application/Configuration.html b/src/5.2/classes/Rails/Application/Configuration.html new file mode 100644 index 0000000000..8ab06d9d2c --- /dev/null +++ b/src/5.2/classes/Rails/Application/Configuration.html @@ -0,0 +1,1047 @@ +--- +title: Rails::Application::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + allow_concurrency
+ [R] + api_only
+ [RW] + asset_host
+ [RW] + autoflush_log
+ [RW] + beginning_of_week
+ [RW] + cache_classes
+ [RW] + cache_store
+ [RW] + consider_all_requests_local
+ [RW] + console
+ [RW] + content_security_policy_nonce_generator
+ [RW] + content_security_policy_report_only
+ [RW] + eager_load
+ [RW] + enable_dependency_loading
+ [R] + encoding
+ [RW] + exceptions_app
+ [RW] + file_watcher
+ [RW] + filter_parameters
+ [RW] + filter_redirect
+ [RW] + force_ssl
+ [RW] + helpers_paths
+ [R] + loaded_config_version
+ [RW] + log_formatter
+ [RW] + log_level
+ [RW] + log_tags
+ [RW] + logger
+ [RW] + public_file_server
+ [RW] + railties_order
+ [RW] + read_encrypted_secrets
+ [RW] + relative_url_root
+ [RW] + reload_classes_only_on_change
+ [RW] + require_master_key
+ [RW] + secret_key_base
+ [RW] + secret_token
+ [RW] + session_options
+ [RW] + ssl_options
+ [RW] + time_zone
+ [RW] + x
+ + + + +

Class Public methods

+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 24
+def initialize(*)
+  super
+  self.encoding                            = Encoding::UTF_8
+  @allow_concurrency                       = nil
+  @consider_all_requests_local             = false
+  @filter_parameters                       = []
+  @filter_redirect                         = []
+  @helpers_paths                           = []
+  @public_file_server                      = ActiveSupport::OrderedOptions.new
+  @public_file_server.enabled              = true
+  @public_file_server.index_name           = "index"
+  @force_ssl                               = false
+  @ssl_options                             = {}
+  @session_store                           = nil
+  @time_zone                               = "UTC"
+  @beginning_of_week                       = :monday
+  @log_level                               = :debug
+  @generators                              = app_generators
+  @cache_store                             = [ :file_store, "#{root}/tmp/cache/" ]
+  @railties_order                          = [:all]
+  @relative_url_root                       = ENV["RAILS_RELATIVE_URL_ROOT"]
+  @reload_classes_only_on_change           = true
+  @file_watcher                            = ActiveSupport::FileUpdateChecker
+  @exceptions_app                          = nil
+  @autoflush_log                           = true
+  @log_formatter                           = ActiveSupport::Logger::SimpleFormatter.new
+  @eager_load                              = nil
+  @secret_token                            = nil
+  @secret_key_base                         = nil
+  @api_only                                = false
+  @debug_exception_response_format         = nil
+  @x                                       = Custom.new
+  @enable_dependency_loading               = false
+  @read_encrypted_secrets                  = false
+  @content_security_policy                 = nil
+  @content_security_policy_report_only     = false
+  @content_security_policy_nonce_generator = nil
+  @require_master_key                      = false
+  @loaded_config_version                   = nil
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + annotations() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 237
+def annotations
+  SourceAnnotationExtractor::Annotation
+end
+
+
+ +
+ +
+

+ + api_only=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 132
+def api_only=(value)
+  @api_only = value
+  generators.api_only = value
+
+  @debug_exception_response_format ||= :api
+end
+
+
+ +
+ +
+

+ + colorize_logging() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 197
+def colorize_logging
+  ActiveSupport::LogSubscriber.colorize_logging
+end
+
+
+ +
+ +
+

+ + colorize_logging=(val) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 201
+def colorize_logging=(val)
+  ActiveSupport::LogSubscriber.colorize_logging = val
+  generators.colorize_logging = val
+end
+
+
+ +
+ +
+

+ + content_security_policy(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 241
+def content_security_policy(&block)
+  if block_given?
+    @content_security_policy = ActionDispatch::ContentSecurityPolicy.new(&block)
+  else
+    @content_security_policy
+  end
+end
+
+
+ +
+ +
+

+ + database_configuration() + +

+ + +
+

Loads and returns the entire raw configuration of database from values stored in config/database.yml.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 165
+def database_configuration
+  path = paths["config/database"].existent.first
+  yaml = Pathname.new(path) if path
+
+  config = if yaml && yaml.exist?
+    require "yaml"
+    require "erb"
+    loaded_yaml = YAML.load(ERB.new(yaml.read).result) || {}
+    shared = loaded_yaml.delete("shared")
+    if shared
+      loaded_yaml.each do |_k, values|
+        values.reverse_merge!(shared)
+      end
+    end
+    Hash.new(shared).merge(loaded_yaml)
+  elsif ENV["DATABASE_URL"]
+    # Value from ENV['DATABASE_URL'] is set to default database connection
+    # by Active Record.
+    {}
+  else
+    raise "Could not load database configuration. No such file - #{paths["config/database"].instance_variable_get(:@paths)}"
+  end
+
+  config
+rescue Psych::SyntaxError => e
+  raise "YAML syntax error occurred while parsing #{paths["config/database"].first}. " \
+        "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
+        "Error: #{e.message}"
+rescue => e
+  raise e, "Cannot load database configuration:\n#{e.message}", e.backtrace
+end
+
+
+ +
+ +
+

+ + debug_exception_response_format() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 139
+def debug_exception_response_format
+  @debug_exception_response_format || :default
+end
+
+
+ +
+ +
+

+ + debug_exception_response_format=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 143
+def debug_exception_response_format=(value)
+  @debug_exception_response_format = value
+end
+
+
+ +
+ +
+

+ + encoding=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 124
+def encoding=(value)
+  @encoding = value
+  silence_warnings do
+    Encoding.default_external = value
+    Encoding.default_internal = value
+  end
+end
+
+
+ +
+ +
+

+ + load_defaults(target_version) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 65
+def load_defaults(target_version)
+  case target_version.to_s
+  when "5.0"
+    if respond_to?(:action_controller)
+      action_controller.per_form_csrf_tokens = true
+      action_controller.forgery_protection_origin_check = true
+    end
+
+    ActiveSupport.to_time_preserves_timezone = true
+
+    if respond_to?(:active_record)
+      active_record.belongs_to_required_by_default = true
+    end
+
+    self.ssl_options = { hsts: { subdomains: true } }
+  when "5.1"
+    load_defaults "5.0"
+
+    if respond_to?(:assets)
+      assets.unknown_asset_fallback = false
+    end
+
+    if respond_to?(:action_view)
+      action_view.form_with_generates_remote_forms = true
+    end
+  when "5.2"
+    load_defaults "5.1"
+
+    if respond_to?(:active_record)
+      active_record.cache_versioning = true
+      # Remove the temporary load hook from SQLite3Adapter when this is removed
+      ActiveSupport.on_load(:active_record_sqlite3adapter) do
+        ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = true
+      end
+    end
+
+    if respond_to?(:action_dispatch)
+      action_dispatch.use_authenticated_cookie_encryption = true
+    end
+
+    if respond_to?(:active_support)
+      active_support.use_authenticated_message_encryption = true
+      active_support.use_sha1_digests = true
+    end
+
+    if respond_to?(:action_controller)
+      action_controller.default_protect_from_forgery = true
+    end
+
+    if respond_to?(:action_view)
+      action_view.form_with_generates_ids = true
+    end
+  else
+    raise "Unknown version #{target_version.to_s.inspect}"
+  end
+
+  @loaded_config_version = target_version
+end
+
+
+ +
+ +
+

+ + paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 147
+def paths
+  @paths ||= begin
+    paths = super
+    paths.add "config/database",    with: "config/database.yml"
+    paths.add "config/secrets",     with: "config", glob: "secrets.yml{,.enc}"
+    paths.add "config/environment", with: "config/environment.rb"
+    paths.add "lib/templates"
+    paths.add "log",                with: "log/#{Rails.env}.log"
+    paths.add "public"
+    paths.add "public/javascripts"
+    paths.add "public/stylesheets"
+    paths.add "tmp"
+    paths
+  end
+end
+
+
+ +
+ +
+

+ + session_store(new_session_store = nil, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/configuration.rb, line 206
+def session_store(new_session_store = nil, **options)
+  if new_session_store
+    if new_session_store == :active_record_store
+      begin
+        ActionDispatch::Session::ActiveRecordStore
+      rescue NameError
+        raise "`ActiveRecord::SessionStore` is extracted out of Rails into a gem. " \
+          "Please add `activerecord-session_store` to your Gemfile to use it."
+      end
+    end
+
+    @session_store = new_session_store
+    @session_options = options || {}
+  else
+    case @session_store
+    when :disabled
+      nil
+    when :active_record_store
+      ActionDispatch::Session::ActiveRecordStore
+    when Symbol
+      ActionDispatch::Session.const_get(@session_store.to_s.camelize)
+    else
+      @session_store
+    end
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application/DefaultMiddlewareStack.html b/src/5.2/classes/Rails/Application/DefaultMiddlewareStack.html new file mode 100644 index 0000000000..95b604d961 --- /dev/null +++ b/src/5.2/classes/Rails/Application/DefaultMiddlewareStack.html @@ -0,0 +1,241 @@ +--- +title: Rails::Application::DefaultMiddlewareStack +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + app
+ [R] + config
+ [R] + paths
+ + + + +

Class Public methods

+ +
+

+ + new(app, config, paths) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/default_middleware_stack.rb, line 8
+def initialize(app, config, paths)
+  @app = app
+  @config = config
+  @paths = paths
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + build_stack() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/default_middleware_stack.rb, line 14
+def build_stack
+  ActionDispatch::MiddlewareStack.new do |middleware|
+    if config.force_ssl
+      middleware.use ::ActionDispatch::SSL, config.ssl_options
+    end
+
+    middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
+
+    if config.public_file_server.enabled
+      headers = config.public_file_server.headers || {}
+
+      middleware.use ::ActionDispatch::Static, paths["public"].first, index: config.public_file_server.index_name, headers: headers
+    end
+
+    if rack_cache = load_rack_cache
+      require "action_dispatch/http/rack_cache"
+      middleware.use ::Rack::Cache, rack_cache
+    end
+
+    if config.allow_concurrency == false
+      # User has explicitly opted out of concurrent request
+      # handling: presumably their code is not threadsafe
+
+      middleware.use ::Rack::Lock
+    end
+
+    middleware.use ::ActionDispatch::Executor, app.executor
+
+    middleware.use ::Rack::Runtime
+    middleware.use ::Rack::MethodOverride unless config.api_only
+    middleware.use ::ActionDispatch::RequestId
+    middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
+
+    middleware.use ::Rails::Rack::Logger, config.log_tags
+    middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app
+    middleware.use ::ActionDispatch::DebugExceptions, app, config.debug_exception_response_format
+
+    unless config.cache_classes
+      middleware.use ::ActionDispatch::Reloader, app.reloader
+    end
+
+    middleware.use ::ActionDispatch::Callbacks
+    middleware.use ::ActionDispatch::Cookies unless config.api_only
+
+    if !config.api_only && config.session_store
+      if config.force_ssl && config.ssl_options.fetch(:secure_cookies, true) && !config.session_options.key?(:secure)
+        config.session_options[:secure] = true
+      end
+      middleware.use config.session_store, config.session_options
+      middleware.use ::ActionDispatch::Flash
+    end
+
+    unless config.api_only
+      middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware
+    end
+
+    middleware.use ::Rack::Head
+    middleware.use ::Rack::ConditionalGet
+    middleware.use ::Rack::ETag, "no-cache"
+
+    middleware.use ::Rack::TempfileReaper unless config.api_only
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application/Finisher.html b/src/5.2/classes/Rails/Application/Finisher.html new file mode 100644 index 0000000000..56ddd06855 --- /dev/null +++ b/src/5.2/classes/Rails/Application/Finisher.html @@ -0,0 +1,88 @@ +--- +title: Rails::Application::Finisher +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application/Finisher/InterlockHook.html b/src/5.2/classes/Rails/Application/Finisher/InterlockHook.html new file mode 100644 index 0000000000..548c0be2e7 --- /dev/null +++ b/src/5.2/classes/Rails/Application/Finisher/InterlockHook.html @@ -0,0 +1,140 @@ +--- +title: Rails::Application::Finisher::InterlockHook +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + complete(_state) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/finisher.rb, line 97
+def self.complete(_state)
+  ActiveSupport::Dependencies.interlock.done_running
+end
+
+
+ +
+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/finisher.rb, line 93
+def self.run
+  ActiveSupport::Dependencies.interlock.start_running
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application/Finisher/MutexHook.html b/src/5.2/classes/Rails/Application/Finisher/MutexHook.html new file mode 100644 index 0000000000..3c8e6c387c --- /dev/null +++ b/src/5.2/classes/Rails/Application/Finisher/MutexHook.html @@ -0,0 +1,188 @@ +--- +title: Rails::Application::Finisher::MutexHook +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(mutex = Mutex.new) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/finisher.rb, line 79
+def initialize(mutex = Mutex.new)
+  @mutex = mutex
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + complete(_state) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/finisher.rb, line 87
+def complete(_state)
+  @mutex.unlock
+end
+
+
+ +
+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/finisher.rb, line 83
+def run
+  @mutex.lock
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Application/RoutesReloader.html b/src/5.2/classes/Rails/Application/RoutesReloader.html new file mode 100644 index 0000000000..930db3e16e --- /dev/null +++ b/src/5.2/classes/Rails/Application/RoutesReloader.html @@ -0,0 +1,186 @@ +--- +title: Rails::Application::RoutesReloader +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [RW] + eager_load
+ [R] + paths
+ [R] + route_sets
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/routes_reloader.rb, line 12
+def initialize
+  @paths      = []
+  @route_sets = []
+  @eager_load = false
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + reload!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/application/routes_reloader.rb, line 18
+def reload!
+  clear!
+  load_paths
+  finalize!
+  route_sets.each(&:eager_load!) if eager_load
+ensure
+  revert
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/BacktraceCleaner.html b/src/5.2/classes/Rails/BacktraceCleaner.html new file mode 100644 index 0000000000..48a65ad55a --- /dev/null +++ b/src/5.2/classes/Rails/BacktraceCleaner.html @@ -0,0 +1,180 @@ +--- +title: Rails::BacktraceCleaner +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
APP_DIRS_PATTERN=/^\/?(app|config|lib|test|\(\w*\))/
 
DOT_SLASH="./".freeze
 
EMPTY_STRING="".freeze
 
RENDER_TEMPLATE_PATTERN=/:in `_render_template_\w*'/
 
SLASH="/".freeze
 
+ + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/backtrace_cleaner.rb, line 13
+def initialize
+  super
+  @root = "#{Rails.root}/".freeze
+  add_filter { |line| line.sub(@root, EMPTY_STRING) }
+  add_filter { |line| line.sub(RENDER_TEMPLATE_PATTERN, EMPTY_STRING) }
+  add_filter { |line| line.sub(DOT_SLASH, SLASH) } # for tests
+
+  add_gem_filters
+  add_silencer { |line| !APP_DIRS_PATTERN.match?(line) }
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Command.html b/src/5.2/classes/Rails/Command.html new file mode 100644 index 0000000000..0e97a9c8cd --- /dev/null +++ b/src/5.2/classes/Rails/Command.html @@ -0,0 +1,362 @@ +--- +title: Rails::Command +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
HELP_MAPPINGS=%w(-h -? --help)
 
+ + + + + + +

Class Public methods

+ +
+

+ + invoke(full_namespace, args = [], **config) + +

+ + +
+

Receives a namespace, arguments and the behavior to invoke the command.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command.rb, line 32
+def invoke(full_namespace, args = [], **config)
+  namespace = full_namespace = full_namespace.to_s
+
+  if char = namespace =~ /:(\w+)$/
+    command_name, namespace = $1, namespace.slice(0, char)
+  else
+    command_name = namespace
+  end
+
+  command_name, namespace = "help", "help" if command_name.blank? || HELP_MAPPINGS.include?(command_name)
+  command_name, namespace = "version", "version" if %w( -v --version ).include?(command_name)
+
+  command = find_by_namespace(namespace, command_name)
+  if command && command.all_commands[command_name]
+    command.perform(command_name, args, config)
+  else
+    find_by_namespace("rake").perform(full_namespace, args, config)
+  end
+end
+
+
+ +
+ +
+

+ + root() + +

+ + +
+

Returns the root of the Rails engine or app running the command.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command.rb, line 77
+def root
+  if defined?(ENGINE_ROOT)
+    Pathname.new(ENGINE_ROOT)
+  elsif defined?(APP_PATH)
+    Pathname.new(File.expand_path("../..", APP_PATH))
+  end
+end
+
+
+ +
+ + +

Class Private methods

+ +
+

+ + command_type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command.rb, line 100
+def command_type # :doc:
+  @command_type ||= "command"
+end
+
+
+ +
+ +
+

+ + file_lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command.rb, line 108
+def file_lookup_paths # :doc:
+  @file_lookup_paths ||= [ "{#{lookup_paths.join(',')}}", "**", "*_command.rb" ]
+end
+
+
+ +
+ +
+

+ + lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command.rb, line 104
+def lookup_paths # :doc:
+  @lookup_paths ||= %w( rails/commands commands )
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Command/Actions.html b/src/5.2/classes/Rails/Command/Actions.html new file mode 100644 index 0000000000..357065dd34 --- /dev/null +++ b/src/5.2/classes/Rails/Command/Actions.html @@ -0,0 +1,306 @@ +--- +title: Rails::Command::Actions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + load_generators() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/actions.rb, line 38
+def load_generators
+  engine = ::Rails::Engine.find(ENGINE_ROOT)
+  Rails::Generators.namespace = engine.railtie_namespace
+  engine.load_generators
+end
+
+
+ +
+ +
+

+ + load_tasks() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/actions.rb, line 33
+def load_tasks
+  Rake.application.init("rails")
+  Rake.application.load_rakefile
+end
+
+
+ +
+ +
+

+ + require_application!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/actions.rb, line 18
+def require_application!
+  require ENGINE_PATH if defined?(ENGINE_PATH)
+
+  if defined?(APP_PATH)
+    require APP_PATH
+  end
+end
+
+
+ +
+ +
+

+ + require_application_and_environment!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/actions.rb, line 13
+def require_application_and_environment!
+  require_application!
+  require_environment!
+end
+
+
+ +
+ +
+

+ + require_environment!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/actions.rb, line 26
+def require_environment!
+  if defined?(APP_PATH)
+    Rails.application.require_environment!
+  end
+end
+
+
+ +
+ +
+

+ + set_application_directory!() + +

+ + +
+

Change to the application's path if there is no config.ru file in current directory. This allows us to run rails server from other directories, but still get the main config.ru and properly set the tmp directory.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/actions.rb, line 9
+def set_application_directory!
+  Dir.chdir(File.expand_path("../..", APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Command/Base.html b/src/5.2/classes/Rails/Command/Base.html new file mode 100644 index 0000000000..139efa82fd --- /dev/null +++ b/src/5.2/classes/Rails/Command/Base.html @@ -0,0 +1,586 @@ +--- +title: Rails::Command::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + banner(*) + +

+ + +
+

Use Rails' default banner.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 81
+def banner(*)
+  "#{executable} #{arguments.map(&:usage).join(' ')} [options]".squish
+end
+
+
+ +
+ +
+

+ + base_name() + +

+ + +
+

Sets the base_name taking into account the current class namespace.

+ +
Rails::Command::TestCommand.base_name # => 'rails'
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 88
+def base_name
+  @base_name ||= begin
+    if base = name.to_s.split("::").first
+      base.underscore
+    end
+  end
+end
+
+
+ +
+ +
+

+ + command_name() + +

+ + +
+

Return command name without namespaces.

+ +
Rails::Command::TestCommand.command_name # => 'test'
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 99
+def command_name
+  @command_name ||= begin
+    if command = name.to_s.split("::").last
+      command.chomp!("Command")
+      command.underscore
+    end
+  end
+end
+
+
+ +
+ +
+

+ + default_command_root() + +

+ + +
+

Default file root to place extra files a command might need, placed one folder above the command file.

+ +

For a Rails::Command::TestCommand placed in rails/command/test_command.rb would return rails/test.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 121
+def default_command_root
+  path = File.expand_path(File.join("../commands", command_root_namespace), __dir__)
+  path if File.exist?(path)
+end
+
+
+ +
+ +
+

+ + desc(usage = nil, description = nil, options = {}) + +

+ + +
+

Tries to get the description from a USAGE file one folder above the command root.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 31
+def desc(usage = nil, description = nil, options = {})
+  if usage
+    super
+  else
+    @desc ||= ERB.new(File.read(usage_path)).result(binding) if usage_path
+  end
+end
+
+
+ +
+ +
+

+ + engine?() + +

+ + +
+

Returns true when the app is a Rails engine.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 25
+def engine?
+  defined?(ENGINE_ROOT)
+end
+
+
+ +
+ +
+

+ + executable() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 76
+def executable
+  "bin/rails #{command_name}"
+end
+
+
+ +
+ +
+

+ + hide_command!() + +

+ + +
+

Convenience method to hide this command from the available ones when running rails command.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 52
+def hide_command!
+  Rails::Command.hidden_commands << self
+end
+
+
+ +
+ +
+

+ + namespace(name = nil) + +

+ + +
+

Convenience method to get the namespace from the class name. It's the same as Thor default except that the Command at the end of the class is removed.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 42
+def namespace(name = nil)
+  if name
+    super
+  else
+    @namespace ||= super.chomp("_command").sub(/:command:/, ":")
+  end
+end
+
+
+ +
+ +
+

+ + printing_commands() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 72
+def printing_commands
+  namespaced_commands
+end
+
+
+ +
+ +
+

+ + usage_path() + +

+ + +
+

Path to lookup a USAGE description in a file.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 109
+def usage_path
+  if default_command_root
+    path = File.join(default_command_root, "USAGE")
+    path if File.exist?(path)
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + help() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/command/base.rb, line 152
+def help
+  if command_name = self.class.command_name
+    self.class.command_help(shell, command_name)
+  else
+    super
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Command/Helpers.html b/src/5.2/classes/Rails/Command/Helpers.html new file mode 100644 index 0000000000..e7832d394c --- /dev/null +++ b/src/5.2/classes/Rails/Command/Helpers.html @@ -0,0 +1,67 @@ +--- +title: Rails::Command::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Command/Helpers/Editor.html b/src/5.2/classes/Rails/Command/Helpers/Editor.html new file mode 100644 index 0000000000..f3d75b036e --- /dev/null +++ b/src/5.2/classes/Rails/Command/Helpers/Editor.html @@ -0,0 +1,54 @@ +--- +title: Rails::Command::Helpers::Editor +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Configuration.html b/src/5.2/classes/Rails/Configuration.html new file mode 100644 index 0000000000..0f93a7f175 --- /dev/null +++ b/src/5.2/classes/Rails/Configuration.html @@ -0,0 +1,71 @@ +--- +title: Rails::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Configuration/MiddlewareStackProxy.html b/src/5.2/classes/Rails/Configuration/MiddlewareStackProxy.html new file mode 100644 index 0000000000..bd794b1a61 --- /dev/null +++ b/src/5.2/classes/Rails/Configuration/MiddlewareStackProxy.html @@ -0,0 +1,489 @@ +--- +title: Rails::Configuration::MiddlewareStackProxy +layout: default +--- +
+ +
+
+ +
+ +

MiddlewareStackProxy is a proxy for the Rails middleware stack that allows you to configure middlewares in your application. It works basically as a command recorder, saving each command to be applied after initialization over the default middleware stack, so you can add, swap, or remove any middleware in Rails.

+ +

You can add your own middlewares by using the config.middleware.use method:

+ +
config.middleware.use Magical::Unicorns
+
+ +

This will put the Magical::Unicorns middleware on the end of the stack. You can use insert_before if you wish to add a middleware before another:

+ +
config.middleware.insert_before Rack::Head, Magical::Unicorns
+
+ +

There's also insert_after which will insert a middleware after another:

+ +
config.middleware.insert_after Rack::Head, Magical::Unicorns
+
+ +

Middlewares can also be completely swapped out and replaced with others:

+ +
config.middleware.swap ActionDispatch::Flash, Magical::Unicorns
+
+ +

And finally they can also be removed from the stack completely:

+ +
config.middleware.delete ActionDispatch::Flash
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(operations = [], delete_operations = []) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 38
+def initialize(operations = [], delete_operations = [])
+  @operations = operations
+  @delete_operations = delete_operations
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 61
+def delete(*args, &block)
+  @delete_operations << [__method__, args, block]
+end
+
+
+ +
+ +
+

+ + insert(*args, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: insert_before +
+ + + +
+ +
+

+ + insert_after(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 49
+def insert_after(*args, &block)
+  @operations << [__method__, args, block]
+end
+
+
+ +
+ +
+

+ + insert_before(*args, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: insert +
+ + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 43
+def insert_before(*args, &block)
+  @operations << [__method__, args, block]
+end
+
+
+ +
+ +
+

+ + swap(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 53
+def swap(*args, &block)
+  @operations << [__method__, args, block]
+end
+
+
+ +
+ +
+

+ + unshift(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 65
+def unshift(*args, &block)
+  @operations << [__method__, args, block]
+end
+
+
+ +
+ +
+

+ + use(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 57
+def use(*args, &block)
+  @operations << [__method__, args, block]
+end
+
+
+ +
+ + +

Instance Protected methods

+ +
+

+ + delete_operations() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 86
+def delete_operations
+  @delete_operations
+end
+
+
+ +
+ +
+

+ + operations() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/configuration.rb, line 82
+def operations
+  @operations
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Console.html b/src/5.2/classes/Rails/Console.html new file mode 100644 index 0000000000..8c89d15ada --- /dev/null +++ b/src/5.2/classes/Rails/Console.html @@ -0,0 +1,402 @@ +--- +title: Rails::Console +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + app
+ [R] + console
+ [R] + options
+ + + + +

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/console/console_command.rb, line 24
+def initialize(app, options = {})
+  @app     = app
+  @options = options
+
+  app.sandbox = sandbox?
+  app.load_console
+
+  @console = app.config.console || IRB
+
+  if @console == IRB
+    IRB::WorkSpace.prepend(BacktraceCleaner)
+  end
+end
+
+
+ +
+ +
+

+ + start(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/console/console_command.rb, line 18
+def self.start(*args)
+  new(*args).start
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + environment() + +

+ + +
+ +
+ + + +
+ Also aliased as: environment? +
+ + + + + + +
+ + +
+
# File railties/lib/rails/commands/console/console_command.rb, line 42
+def environment
+  options[:environment]
+end
+
+
+ +
+ +
+

+ + environment?() + +

+ + +
+ +
+ + + + + +
+ Alias for: environment +
+ + + +
+ +
+

+ + sandbox?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/console/console_command.rb, line 38
+def sandbox?
+  options[:sandbox]
+end
+
+
+ +
+ +
+

+ + set_environment!() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/console/console_command.rb, line 47
+def set_environment!
+  Rails.env = environment
+end
+
+
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/console/console_command.rb, line 51
+def start
+  set_environment! if environment?
+
+  if sandbox?
+    puts "Loading #{Rails.env} environment in sandbox (Rails #{Rails.version})"
+    puts "Any modifications you make will be rolled back on exit"
+  else
+    puts "Loading #{Rails.env} environment (Rails #{Rails.version})"
+  end
+
+  if defined?(console::ExtendCommandBundle)
+    console::ExtendCommandBundle.include(Rails::ConsoleMethods)
+  end
+  console.start
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Console/BacktraceCleaner.html b/src/5.2/classes/Rails/Console/BacktraceCleaner.html new file mode 100644 index 0000000000..8893d9536a --- /dev/null +++ b/src/5.2/classes/Rails/Console/BacktraceCleaner.html @@ -0,0 +1,103 @@ +--- +title: Rails::Console::BacktraceCleaner +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + filter_backtrace(bt) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/console/console_command.rb, line 11
+def filter_backtrace(bt)
+  if result = super
+    Rails.backtrace_cleaner.filter([result]).first
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/ConsoleMethods.html b/src/5.2/classes/Rails/ConsoleMethods.html new file mode 100644 index 0000000000..e350d849f4 --- /dev/null +++ b/src/5.2/classes/Rails/ConsoleMethods.html @@ -0,0 +1,276 @@ +--- +title: Rails::ConsoleMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + app(create = false) + +

+ + +
+

reference the global “app” instance, created on demand. To recreate the instance, pass a non-false value as the parameter.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/console/app.rb, line 10
+def app(create = false)
+  @app_integration_instance = nil if create
+  @app_integration_instance ||= new_session do |sess|
+    sess.host! "www.example.com"
+  end
+end
+
+
+ +
+ +
+

+ + controller() + +

+ + +
+

Gets a new instance of a controller object.

+ +

This method assumes an ApplicationController exists, and it extends ActionController::Base

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/console/helpers.rb, line 15
+def controller
+  @controller ||= ApplicationController.new
+end
+
+
+ +
+ +
+

+ + helper() + +

+ + +
+

Gets the helper methods available to the controller.

+ +

This method assumes an ApplicationController exists, and it extends ActionController::Base

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/console/helpers.rb, line 8
+def helper
+  ApplicationController.helpers
+end
+
+
+ +
+ +
+

+ + new_session() + +

+ + +
+

create a new session. If a block is given, the new session will be yielded to the block before being returned.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/console/app.rb, line 19
+def new_session
+  app = Rails.application
+  session = ActionDispatch::Integration::Session.new(app)
+  yield session if block_given?
+
+  # This makes app.url_for and app.foo_path available in the console
+  session.extend(app.routes.url_helpers)
+  session.extend(app.routes.mounted_helpers)
+
+  session
+end
+
+
+ +
+ +
+

+ + reload!(print = true) + +

+ + +
+

reloads the environment

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/console/app.rb, line 32
+def reload!(print = true)
+  puts "Reloading..." if print
+  Rails.application.reloader.reload!
+  true
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/DBConsole.html b/src/5.2/classes/Rails/DBConsole.html new file mode 100644 index 0000000000..8288ee31c4 --- /dev/null +++ b/src/5.2/classes/Rails/DBConsole.html @@ -0,0 +1,489 @@ +--- +title: Rails::DBConsole +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 11
+def initialize(options = {})
+  @options = options
+end
+
+
+ +
+ +
+

+ + start(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 7
+def self.start(*args)
+  new(*args).start
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 90
+def config
+  @config ||= begin
+    # We need to check whether the user passed the connection the
+    # first time around to show a consistent error message to people
+    # relying on 2-level database configuration.
+    if @options["connection"] && configurations[connection].blank?
+      raise ActiveRecord::AdapterNotSpecified, "'#{connection}' connection is not configured. Available configuration: #{configurations.inspect}"
+    elsif configurations[environment].blank? && configurations[connection].blank?
+      raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
+    else
+      configurations[environment].presence || configurations[connection]
+    end
+  end
+end
+
+
+ +
+ +
+

+ + connection() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 109
+def connection
+  @options.fetch(:connection, "primary")
+end
+
+
+ +
+ +
+

+ + environment() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 105
+def environment
+  Rails.respond_to?(:env) ? Rails.env : Rails::Command.environment
+end
+
+
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 15
+def start
+  ENV["RAILS_ENV"] ||= @options[:environment] || environment
+
+  case config["adapter"]
+  when /^(jdbc)?mysql/
+    args = {
+      "host"      => "--host",
+      "port"      => "--port",
+      "socket"    => "--socket",
+      "username"  => "--user",
+      "encoding"  => "--default-character-set",
+      "sslca"     => "--ssl-ca",
+      "sslcert"   => "--ssl-cert",
+      "sslcapath" => "--ssl-capath",
+      "sslcipher" => "--ssl-cipher",
+      "sslkey"    => "--ssl-key"
+    }.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact
+
+    if config["password"] && @options["include_password"]
+      args << "--password=#{config['password']}"
+    elsif config["password"] && !config["password"].to_s.empty?
+      args << "-p"
+    end
+
+    args << config["database"]
+
+    find_cmd_and_exec(["mysql", "mysql5"], *args)
+
+  when /^postgres|^postgis/
+    ENV["PGUSER"]     = config["username"] if config["username"]
+    ENV["PGHOST"]     = config["host"] if config["host"]
+    ENV["PGPORT"]     = config["port"].to_s if config["port"]
+    ENV["PGPASSWORD"] = config["password"].to_s if config["password"] && @options["include_password"]
+    find_cmd_and_exec("psql", config["database"])
+
+  when "sqlite3"
+    args = []
+
+    args << "-#{@options['mode']}" if @options["mode"]
+    args << "-header" if @options["header"]
+    args << File.expand_path(config["database"], Rails.respond_to?(:root) ? Rails.root : nil)
+
+    find_cmd_and_exec("sqlite3", *args)
+
+  when "oracle", "oracle_enhanced"
+    logon = ""
+
+    if config["username"]
+      logon = config["username"].dup
+      logon << "/#{config['password']}" if config["password"] && @options["include_password"]
+      logon << "@#{config['database']}" if config["database"]
+    end
+
+    find_cmd_and_exec("sqlplus", logon)
+
+  when "sqlserver"
+    args = []
+
+    args += ["-D", "#{config['database']}"] if config["database"]
+    args += ["-U", "#{config['username']}"] if config["username"]
+    args += ["-P", "#{config['password']}"] if config["password"]
+
+    if config["host"]
+      host_arg = "#{config['host']}".dup
+      host_arg << ":#{config['port']}" if config["port"]
+      args += ["-S", host_arg]
+    end
+
+    find_cmd_and_exec("sqsh", *args)
+
+  else
+    abort "Unknown command-line client for #{config['database']}."
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + configurations() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 114
+def configurations # :doc:
+  require APP_PATH
+  ActiveRecord::Base.configurations = Rails.application.config.database_configuration
+  ActiveRecord::Base.configurations
+end
+
+
+ +
+ +
+

+ + find_cmd_and_exec(commands, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 120
+def find_cmd_and_exec(commands, *args) # :doc:
+  commands = Array(commands)
+
+  dirs_on_path = ENV["PATH"].to_s.split(File::PATH_SEPARATOR)
+  unless (ext = RbConfig::CONFIG["EXEEXT"]).empty?
+    commands = commands.map { |cmd| "#{cmd}#{ext}" }
+  end
+
+  full_path_command = nil
+  found = commands.detect do |cmd|
+    dirs_on_path.detect do |path|
+      full_path_command = File.join(path, cmd)
+      File.file?(full_path_command) && File.executable?(full_path_command)
+    end
+  end
+
+  if found
+    exec full_path_command, *args
+  else
+    abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Engine.html b/src/5.2/classes/Rails/Engine.html new file mode 100644 index 0000000000..f4a70c65e2 --- /dev/null +++ b/src/5.2/classes/Rails/Engine.html @@ -0,0 +1,1379 @@ +--- +title: Rails::Engine +layout: default +--- +
+ +
+
+ +
+ +

Rails::Engine allows you to wrap a specific Rails application or subset of functionality and share it with other applications or within a larger packaged application. Every Rails::Application is just an engine, which allows for simple feature and application sharing.

+ +

Any Rails::Engine is also a Rails::Railtie, so the same methods (like rake_tasks and generators) and configuration options that are available in railties can also be used in engines.

+ +

Creating an Engine

+ +

If you want a gem to behave as an engine, you have to specify an Engine for it somewhere inside your plugin's lib folder (similar to how we specify a Railtie):

+ +
# lib/my_engine.rb
+module MyEngine
+  class Engine < Rails::Engine
+  end
+end
+
+ +

Then ensure that this file is loaded at the top of your config/application.rb (or in your Gemfile) and it will automatically load models, controllers and helpers inside app, load routes at config/routes.rb, load locales at config/locales/*, and load tasks at lib/tasks/*.

+ +

Configuration

+ +

Besides the Railtie configuration which is shared across the application, in a Rails::Engine you can access autoload_paths, eager_load_paths and autoload_once_paths, which, differently from a Railtie, are scoped to the current engine.

+ +
class MyEngine < Rails::Engine
+  # Add a load path for this specific Engine
+  config.autoload_paths << File.expand_path("lib/some/path", __dir__)
+
+  initializer "my_engine.add_middleware" do |app|
+    app.middleware.use MyEngine::Middleware
+  end
+end
+
+ +

Generators

+ +

You can set up generators for engines with config.generators method:

+ +
class MyEngine < Rails::Engine
+  config.generators do |g|
+    g.orm             :active_record
+    g.template_engine :erb
+    g.test_framework  :test_unit
+  end
+end
+
+ +

You can also set generators for an application by using config.app_generators:

+ +
class MyEngine < Rails::Engine
+  # note that you can also pass block to app_generators in the same way you
+  # can pass it to generators method
+  config.app_generators.orm :datamapper
+end
+
+ +

Paths

+ +

Applications and engines have flexible path configuration, meaning that you are not required to place your controllers at app/controllers, but in any place which you find convenient.

+ +

For example, let's suppose you want to place your controllers in lib/controllers. You can set that as an option:

+ +
class MyEngine < Rails::Engine
+  paths["app/controllers"] = "lib/controllers"
+end
+
+ +

You can also have your controllers loaded from both app/controllers and lib/controllers:

+ +
class MyEngine < Rails::Engine
+  paths["app/controllers"] << "lib/controllers"
+end
+
+ +

The available paths in an engine are:

+ +
class MyEngine < Rails::Engine
+  paths["app"]                 # => ["app"]
+  paths["app/controllers"]     # => ["app/controllers"]
+  paths["app/helpers"]         # => ["app/helpers"]
+  paths["app/models"]          # => ["app/models"]
+  paths["app/views"]           # => ["app/views"]
+  paths["lib"]                 # => ["lib"]
+  paths["lib/tasks"]           # => ["lib/tasks"]
+  paths["config"]              # => ["config"]
+  paths["config/initializers"] # => ["config/initializers"]
+  paths["config/locales"]      # => ["config/locales"]
+  paths["config/routes.rb"]    # => ["config/routes.rb"]
+end
+
+ +

The Application class adds a couple more paths to this set. And as in your Application, all folders under app are automatically added to the load path. If you have an app/services folder for example, it will be added by default.

+ +

Endpoint

+ +

An engine can also be a Rack application. It can be useful if you have a Rack application that you would like to wrap with Engine and provide with some of the Engine's features.

+ +

To do that, use the endpoint method:

+ +
module MyEngine
+  class Engine < Rails::Engine
+    endpoint MyRackApplication
+  end
+end
+
+ +

Now you can mount your engine in application's routes just like that:

+ +
Rails.application.routes.draw do
+  mount MyEngine::Engine => "/engine"
+end
+
+ +

Middleware stack

+ +

As an engine can now be a Rack endpoint, it can also have a middleware stack. The usage is exactly the same as in Application:

+ +
module MyEngine
+  class Engine < Rails::Engine
+    middleware.use SomeMiddleware
+  end
+end
+
+ +

Routes

+ +

If you don't specify an endpoint, routes will be used as the default endpoint. You can use them just like you use an application's routes:

+ +
# ENGINE/config/routes.rb
+MyEngine::Engine.routes.draw do
+  get "/" => "posts#index"
+end
+
+ +

Mount priority

+ +

Note that now there can be more than one router in your application, and it's better to avoid passing requests through many routers. Consider this situation:

+ +
Rails.application.routes.draw do
+  mount MyEngine::Engine => "/blog"
+  get "/blog/omg" => "main#omg"
+end
+
+ +

MyEngine is mounted at /blog, and /blog/omg points to application's controller. In such a situation, requests to /blog/omg will go through MyEngine, and if there is no such route in Engine's routes, it will be dispatched to main#omg. It's much better to swap that:

+ +
Rails.application.routes.draw do
+  get "/blog/omg" => "main#omg"
+  mount MyEngine::Engine => "/blog"
+end
+
+ +

Now, Engine will get only requests that were not handled by Application.

+ +

Engine name

+ +

There are some places where an Engine's name is used:

+
  • +

    routes: when you mount an Engine with mount(MyEngine::Engine => '/my_engine'), it's used as default :as option

    +
  • +

    rake task for installing migrations my_engine:install:migrations

    +
+ +

Engine name is set by default based on class name. For MyEngine::Engine it will be my_engine_engine. You can change it manually using the engine_name method:

+ +
module MyEngine
+  class Engine < Rails::Engine
+    engine_name "my_engine"
+  end
+end
+
+ +

Isolated Engine

+ +

Normally when you create controllers, helpers and models inside an engine, they are treated as if they were created inside the application itself. This means that all helpers and named routes from the application will be available to your engine's controllers as well.

+ +

However, sometimes you want to isolate your engine from the application, especially if your engine has its own router. To do that, you simply need to call isolate_namespace. This method requires you to pass a module where all your controllers, helpers and models should be nested to:

+ +
module MyEngine
+  class Engine < Rails::Engine
+    isolate_namespace MyEngine
+  end
+end
+
+ +

With such an engine, everything that is inside the MyEngine module will be isolated from the application.

+ +

Consider this controller:

+ +
module MyEngine
+  class FooController < ActionController::Base
+  end
+end
+
+ +

If the MyEngine engine is marked as isolated, FooController only has access to helpers from MyEngine, and url_helpers from MyEngine::Engine.routes.

+ +

The next thing that changes in isolated engines is the behavior of routes. Normally, when you namespace your controllers, you also need to namespace the related routes. With an isolated engine, the engine's namespace is automatically applied, so you don't need to specify it explicitly in your routes:

+ +
MyEngine::Engine.routes.draw do
+  resources :articles
+end
+
+ +

If MyEngine is isolated, The routes above will point to MyEngine::ArticlesController. You also don't need to use longer url helpers like my_engine_articles_path. Instead, you should simply use articles_path, like you would do with your main application.

+ +

To make this behavior consistent with other parts of the framework, isolated engines also have an effect on ActiveModel::Naming. In a normal Rails app, when you use a namespaced model such as Namespace::Article, ActiveModel::Naming will generate names with the prefix “namespace”. In an isolated engine, the prefix will be omitted in url helpers and form fields, for convenience.

+ +
polymorphic_url(MyEngine::Article.new)
+# => "articles_path" # not "my_engine_articles_path"
+
+form_for(MyEngine::Article.new) do
+  text_field :title # => <input type="text" name="article[title]" id="article_title" />
+end
+
+ +

Additionally, an isolated engine will set its own name according to its namespace, so MyEngine::Engine.engine_name will return “my_engine”. It will also set MyEngine.table_name_prefix to “my_engine_”, meaning for example that MyEngine::Article will use the my_engine_articles database table by default.

+ +

Using Engine's routes outside Engine

+ +

Since you can now mount an engine inside application's routes, you do not have direct access to Engine's url_helpers inside Application. When you mount an engine in an application's routes, a special helper is created to allow you to do that. Consider such a scenario:

+ +
# config/routes.rb
+Rails.application.routes.draw do
+  mount MyEngine::Engine => "/my_engine", as: "my_engine"
+  get "/foo" => "foo#index"
+end
+
+ +

Now, you can use the my_engine helper inside your application:

+ +
class FooController < ApplicationController
+  def index
+    my_engine.root_url # => /my_engine/
+  end
+end
+
+ +

There is also a main_app helper that gives you access to application's routes inside Engine:

+ +
module MyEngine
+  class BarController
+    def index
+      main_app.foo_path # => /foo
+    end
+  end
+end
+
+ +

Note that the :as option given to mount takes the engine_name as default, so most of the time you can simply omit it.

+ +

Finally, if you want to generate a url to an engine's route using polymorphic_url, you also need to pass the engine helper. Let's say that you want to create a form pointing to one of the engine's routes. All you need to do is pass the helper as the first element in array with attributes for url:

+ +
form_for([my_engine, @user])
+
+ +

This code will use my_engine.user_path(@user) to generate the proper route.

+ +

Isolated engine's helpers

+ +

Sometimes you may want to isolate engine, but use helpers that are defined for it. If you want to share just a few specific helpers you can add them to application's helpers in ApplicationController:

+ +
class ApplicationController < ActionController::Base
+  helper MyEngine::SharedEngineHelper
+end
+
+ +

If you want to include all of the engine's helpers, you can use the helper method on an engine's instance:

+ +
class ApplicationController < ActionController::Base
+  helper MyEngine::Engine.helpers
+end
+
+ +

It will include all of the helpers from engine's directory. Take into account that this does not include helpers defined in controllers with helper_method or other similar solutions, only helpers defined in the helpers directory will be included.

+ +

Migrations & seed data

+ +

Engines can have their own migrations. The default path for migrations is exactly the same as in application: db/migrate

+ +

To use engine's migrations in application you can use the rake task below, which copies them to application's dir:

+ +
rake ENGINE_NAME:install:migrations
+
+ +

Note that some of the migrations may be skipped if a migration with the same name already exists in application. In such a situation you must decide whether to leave that migration or rename the migration in the application and rerun copying migrations.

+ +

If your engine has migrations, you may also want to prepare data for the database in the db/seeds.rb file. You can load that data using the load_seed method, e.g.

+ +
MyEngine::Engine.load_seed
+
+ +

Loading priority

+ +

In order to change engine's priority you can use config.railties_order in the main application. It will affect the priority of loading views, helpers, assets, and all the other files related to engine or application.

+ +
# load Blog::Engine with highest priority, followed by application and other railties
+config.railties_order = [Blog::Engine, :main_app, :all]
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [RW] + called_from
+ [RW] + isolated
+ [RW] + isolated?
+ + + + +

Class Public methods

+ +
+

+ + endpoint(endpoint = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 376
+def endpoint(endpoint = nil)
+  @endpoint ||= nil
+  @endpoint = endpoint if endpoint
+  @endpoint
+end
+
+
+ +
+ +
+

+ + find(path) + +

+ + +
+

Finds engine with given path.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 414
+def find(path)
+  expanded_path = File.expand_path path
+  Rails::Engine.subclasses.each do |klass|
+    engine = klass.instance
+    return engine if File.expand_path(engine.root) == expanded_path
+  end
+  nil
+end
+
+
+ +
+ +
+

+ + find_root(from) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 372
+def find_root(from)
+  find_root_with_flag "lib", from
+end
+
+
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 358
+def inherited(base)
+  unless base.abstract_railtie?
+    Rails::Railtie::Configuration.eager_load_namespaces << base
+
+    base.called_from = begin
+      call_stack = caller_locations.map { |l| l.absolute_path || l.path }
+
+      File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] })
+    end
+  end
+
+  super
+end
+
+
+ +
+ +
+

+ + isolate_namespace(mod) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 382
+def isolate_namespace(mod)
+  engine_name(generate_railtie_name(mod.name))
+
+  routes.default_scope = { module: ActiveSupport::Inflector.underscore(mod.name) }
+  self.isolated = true
+
+  unless mod.respond_to?(:railtie_namespace)
+    name, railtie = engine_name, self
+
+    mod.singleton_class.instance_eval do
+      define_method(:railtie_namespace) { railtie }
+
+      unless mod.respond_to?(:table_name_prefix)
+        define_method(:table_name_prefix) { "#{name}_" }
+      end
+
+      unless mod.respond_to?(:use_relative_model_naming?)
+        class_eval "def use_relative_model_naming?; true; end", __FILE__, __LINE__
+      end
+
+      unless mod.respond_to?(:railtie_helpers_paths)
+        define_method(:railtie_helpers_paths) { railtie.helpers_paths }
+      end
+
+      unless mod.respond_to?(:railtie_routes_url_helpers)
+        define_method(:railtie_routes_url_helpers) { |include_path_helpers = true| railtie.routes.url_helpers(include_path_helpers) }
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 427
+def initialize
+  @_all_autoload_paths = nil
+  @_all_load_paths     = nil
+  @app                 = nil
+  @config              = nil
+  @env_config          = nil
+  @helpers             = nil
+  @routes              = nil
+  @app_build_lock      = Mutex.new
+  super
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+

Returns the underlying Rack application for this engine.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 505
+def app
+  @app || @app_build_lock.synchronize {
+    @app ||= begin
+      stack = default_middleware_stack
+      config.middleware = build_middleware.merge_into(stack)
+      config.middleware.build(endpoint)
+    end
+  }
+end
+
+
+ +
+ +
+

+ + call(env) + +

+ + +
+

Define the Rack API for this engine.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 522
+def call(env)
+  req = build_request env
+  app.call req.env
+end
+
+
+ +
+ +
+

+ + config() + +

+ + +
+

Define the configuration object for the engine.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 541
+def config
+  @config ||= Engine::Configuration.new(self.class.find_root(self.class.called_from))
+end
+
+
+ +
+ +
+

+ + eager_load!() + +

+ + +
+

Eager load the application by loading all ruby files inside eager_load paths.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 474
+def eager_load!
+  config.eager_load_paths.each do |load_path|
+    matcher = /\A#{Regexp.escape(load_path.to_s)}\/(.*)\.rb\Z/
+    Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
+      require_dependency file.sub(matcher, '\1')
+    end
+  end
+end
+
+
+ +
+ +
+

+ + endpoint() + +

+ + +
+

Returns the endpoint for this engine. If none is registered, defaults to an ActionDispatch::Routing::RouteSet.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 517
+def endpoint
+  self.class.endpoint || routes
+end
+
+
+ +
+ +
+

+ + env_config() + +

+ + +
+

Defines additional Rack env configuration that is added on each call.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 528
+def env_config
+  @env_config ||= {}
+end
+
+
+ +
+ +
+

+ + helpers() + +

+ + +
+

Returns a module with all the helpers defined for the engine.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 488
+def helpers
+  @helpers ||= begin
+    helpers = Module.new
+    all = ActionController::Base.all_helpers_from_path(helpers_paths)
+    ActionController::Base.modules_for_helpers(all).each do |mod|
+      helpers.include(mod)
+    end
+    helpers
+  end
+end
+
+
+ +
+ +
+

+ + helpers_paths() + +

+ + +
+

Returns all registered helpers paths.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 500
+def helpers_paths
+  paths["app/helpers"].existent
+end
+
+
+ +
+ +
+

+ + load_console(app = self) + +

+ + +
+

Load console and invoke the registered hooks. Check Rails::Railtie.console for more info.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 441
+def load_console(app = self)
+  require "rails/console/app"
+  require "rails/console/helpers"
+  run_console_blocks(app)
+  self
+end
+
+
+ +
+ +
+

+ + load_generators(app = self) + +

+ + +
+

Load Rails generators and invoke the registered hooks. Check Rails::Railtie.generators for more info.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 465
+def load_generators(app = self)
+  require "rails/generators"
+  run_generators_blocks(app)
+  Rails::Generators.configure!(app.config.generators)
+  self
+end
+
+
+ +
+ +
+

+ + load_runner(app = self) + +

+ + +
+

Load Rails runner and invoke the registered hooks. Check Rails::Railtie.runner for more info.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 450
+def load_runner(app = self)
+  run_runner_blocks(app)
+  self
+end
+
+
+ +
+ +
+

+ + load_seed() + +

+ + +
+

Load data from db/seeds.rb file. It can be used in to load engines' seeds, e.g.:

+ +

Blog::Engine.load_seed

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 549
+def load_seed
+  seed_file = paths["db/seeds.rb"].existent.first
+  return unless seed_file
+
+  if config.try(:active_job).try!(:queue_adapter) == :async
+    with_inline_jobs { load(seed_file) }
+  else
+    load(seed_file)
+  end
+end
+
+
+ +
+ +
+

+ + load_tasks(app = self) + +

+ + +
+

Load Rake, railties tasks and invoke the registered hooks. Check Rails::Railtie.rake_tasks for more info.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 457
+def load_tasks(app = self)
+  require "rake"
+  run_tasks_blocks(app)
+  self
+end
+
+
+ +
+ +
+

+ + railties() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 483
+def railties
+  @railties ||= Railties.new
+end
+
+
+ +
+ +
+

+ + routes(&block) + +

+ + +
+

Defines the routes for this engine. If a block is given to routes, it is appended to the engine.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 534
+def routes(&block)
+  @routes ||= ActionDispatch::Routing::RouteSet.new_with_config(config)
+  @routes.append(&block) if block_given?
+  @routes
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + load_config_initializer(initializer) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine.rb, line 661
+def load_config_initializer(initializer) # :doc:
+  ActiveSupport::Notifications.instrument("load_config_initializer.railties", initializer: initializer) do
+    load(initializer)
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Engine/Configuration.html b/src/5.2/classes/Rails/Engine/Configuration.html new file mode 100644 index 0000000000..2bd8c7bd0f --- /dev/null +++ b/src/5.2/classes/Rails/Engine/Configuration.html @@ -0,0 +1,437 @@ +--- +title: Rails::Engine::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [W] + autoload_once_paths
+ [W] + autoload_paths
+ [W] + eager_load_paths
+ [RW] + middleware
+ [R] + root
+ + + + +

Class Public methods

+ +
+

+ + new(root = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/configuration.rb, line 12
+def initialize(root = nil)
+  super()
+  @root = root
+  @generators = app_generators.dup
+  @middleware = Rails::Configuration::MiddlewareStackProxy.new
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + autoload_once_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/configuration.rb, line 79
+def autoload_once_paths
+  @autoload_once_paths ||= paths.autoload_once
+end
+
+
+ +
+ +
+

+ + autoload_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/configuration.rb, line 83
+def autoload_paths
+  @autoload_paths ||= paths.autoload_paths
+end
+
+
+ +
+ +
+

+ + eager_load_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/configuration.rb, line 75
+def eager_load_paths
+  @eager_load_paths ||= paths.eager_load
+end
+
+
+ +
+ +
+

+ + generators() + +

+ + +
+

Holds generators configuration:

+ +
config.generators do |g|
+  g.orm             :data_mapper, migration: true
+  g.template_engine :haml
+  g.test_framework  :rspec
+end
+
+ +

If you want to disable color in console, do:

+ +
config.generators.colorize_logging = false
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/configuration.rb, line 31
+def generators
+  @generators ||= Rails::Configuration::Generators.new
+  yield(@generators) if block_given?
+  @generators
+end
+
+
+ +
+ +
+

+ + paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/configuration.rb, line 37
+def paths
+  @paths ||= begin
+    paths = Rails::Paths::Root.new(@root)
+
+    paths.add "app",                 eager_load: true, glob: "{*,*/concerns}"
+    paths.add "app/assets",          glob: "*"
+    paths.add "app/controllers",     eager_load: true
+    paths.add "app/channels",        eager_load: true, glob: "**/*_channel.rb"
+    paths.add "app/helpers",         eager_load: true
+    paths.add "app/models",          eager_load: true
+    paths.add "app/mailers",         eager_load: true
+    paths.add "app/views"
+
+    paths.add "lib",                 load_path: true
+    paths.add "lib/assets",          glob: "*"
+    paths.add "lib/tasks",           glob: "**/*.rake"
+
+    paths.add "config"
+    paths.add "config/environments", glob: "#{Rails.env}.rb"
+    paths.add "config/initializers", glob: "**/*.rb"
+    paths.add "config/locales",      glob: "*.{rb,yml}"
+    paths.add "config/routes.rb"
+
+    paths.add "db"
+    paths.add "db/migrate"
+    paths.add "db/seeds.rb"
+
+    paths.add "vendor",              load_path: true
+    paths.add "vendor/assets",       glob: "*"
+
+    paths
+  end
+end
+
+
+ +
+ +
+

+ + root=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/configuration.rb, line 71
+def root=(value)
+  @root = paths.path = Pathname.new(value).expand_path
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Engine/Railties.html b/src/5.2/classes/Rails/Engine/Railties.html new file mode 100644 index 0000000000..306481c158 --- /dev/null +++ b/src/5.2/classes/Rails/Engine/Railties.html @@ -0,0 +1,217 @@ +--- +title: Rails::Engine::Railties +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + - +
  • + +
  • + each +
  • + +
  • + new +
  • + +
+ + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + _all
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/railties.rb, line 9
+def initialize
+  @_all ||= ::Rails::Railtie.subclasses.map(&:instance) +
+    ::Rails::Engine.subclasses.map(&:instance)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + -(others) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/railties.rb, line 18
+def -(others)
+  _all - others
+end
+
+
+ +
+ +
+

+ + each(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/railties.rb, line 14
+def each(*args, &block)
+  _all.each(*args, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Engine/Updater.html b/src/5.2/classes/Rails/Engine/Updater.html new file mode 100644 index 0000000000..64af44bbe9 --- /dev/null +++ b/src/5.2/classes/Rails/Engine/Updater.html @@ -0,0 +1,147 @@ +--- +title: Rails::Engine::Updater +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + generator() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/updater.rb, line 10
+def generator
+  @generator ||= Rails::Generators::PluginGenerator.new ["plugin"],
+    { engine: true }, { destination_root: ENGINE_ROOT }
+end
+
+
+ +
+ +
+

+ + run(action) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/engine/updater.rb, line 15
+def run(action)
+  generator.send(action)
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators.html b/src/5.2/classes/Rails/Generators.html new file mode 100644 index 0000000000..8866c7b44d --- /dev/null +++ b/src/5.2/classes/Rails/Generators.html @@ -0,0 +1,940 @@ +--- +title: Rails::Generators +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_ALIASES={ +rails: { +actions: "-a", +orm: "-o", +javascripts: "-j", +javascript_engine: "-je", +resource_controller: "-c", +scaffold_controller: "-c", +stylesheets: "-y", +stylesheet_engine: "-se", +scaffold_stylesheet: "-ss", +template_engine: "-e", +test_framework: "-t" +}, + +test_unit: { +fixture_replacement: "-r", +} +}
 
DEFAULT_OPTIONS={ +rails: { +api: false, +assets: true, +force_plural: false, +helper: true, +integration_tool: nil, +javascripts: true, +javascript_engine: :js, +orm: false, +resource_controller: :controller, +resource_route: true, +scaffold_controller: :scaffold_controller, +stylesheets: true, +stylesheet_engine: :css, +scaffold_stylesheet: true, +system_tests: nil, +test_framework: nil, +template_engine: :erb +} +}
 
RAILS_DEV_PATH=File.expand_path("../../../../../..", __dir__)
 

We need to store the RAILS_DEV_PATH in a constant, otherwise the path can change in Ruby 1.8.7 when we FileUtils.cd.

RESERVED_NAMES=%w[application destroy plugin runner test]
 
+ + + + + + +

Class Public methods

+ +
+

+ + api_only!() + +

+ + +
+

Configure generators for API only applications. It basically hides everything that is usually browser related, such as assets and session migration generators, and completely disable helpers and assets so generators such as scaffold won't create them.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 118
+def api_only!
+  hide_namespaces "assets", "helper", "css", "js"
+
+  options[:rails].merge!(
+    api: true,
+    assets: false,
+    helper: false,
+    template_engine: nil
+  )
+
+  if ARGV.first == "mailer"
+    options[:rails].merge!(template_engine: :erb)
+  end
+end
+
+
+ +
+ +
+

+ + fallbacks() + +

+ + +
+

Hold configured generators fallbacks. If a plugin developer wants a generator group to fallback to another group in case of missing generators, they can add a fallback.

+ +

For example, shoulda is considered a test_framework and is an extension of test_unit. However, most part of shoulda generators are similar to test_unit ones.

+ +

Shoulda then can tell generators to search for test_unit generators when some of them are not available by adding a fallback:

+ +
Rails::Generators.fallbacks[:shoulda] = :test_unit
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 110
+def fallbacks
+  @fallbacks ||= {}
+end
+
+
+ +
+ +
+

+ + help(command = "generate") + +

+ + +
+

Show help message with available generators.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 181
+def help(command = "generate")
+  puts "Usage: rails #{command} GENERATOR [args] [options]"
+  puts
+  puts "General options:"
+  puts "  -h, [--help]     # Print generator's options and usage"
+  puts "  -p, [--pretend]  # Run but do not make any changes"
+  puts "  -f, [--force]    # Overwrite files that already exist"
+  puts "  -s, [--skip]     # Skip files that already exist"
+  puts "  -q, [--quiet]    # Suppress status output"
+  puts
+  puts "Please choose a generator below."
+  puts
+
+  print_generators
+end
+
+
+ +
+ +
+

+ + hidden_namespaces() + +

+ + +
+

Returns an array of generator namespaces that are hidden. Generator namespaces may be hidden for a variety of reasons. Some are aliased such as “rails:migration” and can be invoked with the shorter “migration”, others are private to other generators such as “css:scaffold”.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 143
+def hidden_namespaces
+  @hidden_namespaces ||= begin
+    orm      = options[:rails][:orm]
+    test     = options[:rails][:test_framework]
+    template = options[:rails][:template_engine]
+    css      = options[:rails][:stylesheet_engine]
+
+    [
+      "rails",
+      "resource_route",
+      "#{orm}:migration",
+      "#{orm}:model",
+      "#{test}:controller",
+      "#{test}:helper",
+      "#{test}:integration",
+      "#{test}:system",
+      "#{test}:mailer",
+      "#{test}:model",
+      "#{test}:scaffold",
+      "#{test}:view",
+      "#{test}:job",
+      "#{template}:controller",
+      "#{template}:scaffold",
+      "#{template}:mailer",
+      "#{css}:scaffold",
+      "#{css}:assets",
+      "css:assets",
+      "css:scaffold"
+    ]
+  end
+end
+
+
+ +
+ +
+

+ + hide_namespace(*namespaces) + +

+ + +
+ +
+ + + + + +
+ Alias for: hide_namespaces +
+ + + +
+ +
+

+ + hide_namespaces(*namespaces) + +

+ + +
+ +
+ + + +
+ Also aliased as: hide_namespace +
+ + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 175
+def hide_namespaces(*namespaces)
+  hidden_namespaces.concat(namespaces)
+end
+
+
+ +
+ +
+

+ + invoke(namespace, args = ARGV, config = {}) + +

+ + +
+

Receives a namespace, arguments and the behavior to invoke the generator. It's used as the default entry point for generate, destroy and update commands.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 272
+def invoke(namespace, args = ARGV, config = {})
+  names = namespace.to_s.split(":")
+  if klass = find_by_namespace(names.pop, names.any? && names.join(":"))
+    args << "--help" if args.empty? && klass.arguments.any?(&:required?)
+    klass.start(args, config)
+  else
+    options     = sorted_groups.flat_map(&:last)
+    suggestions = options.sort_by { |suggested| levenshtein_distance(namespace.to_s, suggested) }.first(3)
+    suggestions.map! { |s| "'#{s}'" }
+    msg =  "Could not find generator '#{namespace}'. ".dup
+    msg << "Maybe you meant #{ suggestions[0...-1].join(', ')} or #{suggestions[-1]}\n"
+    msg << "Run `rails generate --help` for more options."
+    puts msg
+  end
+end
+
+
+ +
+ +
+

+ + no_color!() + +

+ + +
+

Remove the color from output.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 134
+def no_color!
+  Thor::Base.shell = Thor::Shell::Basic
+end
+
+
+ +
+ +
+

+ + print_generators() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 202
+def print_generators
+  sorted_groups.each { |b, n| print_list(b, n) }
+end
+
+
+ +
+ +
+

+ + public_namespaces() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 197
+def public_namespaces
+  lookup!
+  subclasses.map(&:namespace)
+end
+
+
+ +
+ +
+

+ + sorted_groups() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 206
+def sorted_groups
+  namespaces = public_namespaces
+  namespaces.sort!
+
+  groups = Hash.new { |h, k| h[k] = [] }
+  namespaces.each do |namespace|
+    base = namespace.split(":").first
+    groups[base] << namespace
+  end
+
+  rails = groups.delete("rails")
+  rails.map! { |n| n.sub(/^rails:/, "") }
+  rails.delete("app")
+  rails.delete("plugin")
+  rails.delete("encrypted_secrets")
+  rails.delete("encrypted_file")
+  rails.delete("encryption_key_file")
+  rails.delete("master_key")
+  rails.delete("credentials")
+
+  hidden_namespaces.each { |n| groups.delete(n.to_s) }
+
+  [[ "rails", rails ]] + groups.sort.to_a
+end
+
+
+ +
+ + +

Class Private methods

+ +
+

+ + command_type() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 311
+def command_type # :doc:
+  @command_type ||= "generator"
+end
+
+
+ +
+ +
+

+ + file_lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 319
+def file_lookup_paths # :doc:
+  @file_lookup_paths ||= [ "{#{lookup_paths.join(',')}}", "**", "*_generator.rb" ]
+end
+
+
+ +
+ +
+

+ + lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 315
+def lookup_paths # :doc:
+  @lookup_paths ||= %w( rails/generators generators )
+end
+
+
+ +
+ +
+

+ + print_list(base, namespaces) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators.rb, line 290
+def print_list(base, namespaces) # :doc:
+  namespaces = namespaces.reject { |n| hidden_namespaces.include?(n) }
+  super
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Actions.html b/src/5.2/classes/Rails/Generators/Actions.html new file mode 100644 index 0000000000..d4cbdb4f44 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Actions.html @@ -0,0 +1,1142 @@ +--- +title: Rails::Generators::Actions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + add_source(source, options = {}, &block) + +

+ + +
+

Add the given source to Gemfile

+ +

If block is given, gem entries in block are wrapped into the source group.

+ +
add_source "http://gems.github.com/"
+
+add_source "http://gems.github.com/" do
+  gem "rspec-rails"
+end
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 78
+def add_source(source, options = {}, &block)
+  log :source, source
+
+  in_root do
+    if block
+      append_file "Gemfile", "\nsource #{quote(source)} do", force: true
+      @in_group = true
+      instance_eval(&block)
+      @in_group = false
+      append_file "Gemfile", "\nend\n", force: true
+    else
+      prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
+    end
+  end
+end
+
+
+ +
+ +
+

+ + after_bundle(&block) + +

+ + +
+

Registers a callback to be executed after bundle and spring binstubs have run.

+ +
after_bundle do
+  git add: '.'
+end
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 273
+def after_bundle(&block)
+  @after_bundle_callbacks << block
+end
+
+
+ +
+ +
+

+ + application(data = nil, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: environment +
+ + + +
+ +
+

+ + capify!() + +

+ + +
+

Just run the capify command in root

+ +
capify!
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 242
+def capify!
+  ActiveSupport::Deprecation.warn("`capify!` is deprecated and will be removed in the next version of Rails.")
+  log :capify, ""
+  in_root { run("#{extify(:capify)} .", verbose: false) }
+end
+
+
+ +
+ +
+

+ + environment(data = nil, options = {}) + +

+ + +
+

Adds a line inside the Application class for config/application.rb.

+ +

If options :env is specified, the line is appended to the corresponding file in config/environments.

+ +
environment do
+  "config.action_controller.asset_host = 'cdn.provider.com'"
+end
+
+environment(nil, env: "development") do
+  "config.action_controller.asset_host = 'localhost:3000'"
+end
+
+
+ + + +
+ Also aliased as: application +
+ + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 106
+def environment(data = nil, options = {})
+  sentinel = "class Application < Rails::Application\n"
+  env_file_sentinel = "Rails.application.configure do\n"
+  data ||= yield if block_given?
+
+  in_root do
+    if options[:env].nil?
+      inject_into_file "config/application.rb", optimize_indentation(data, 4), after: sentinel, verbose: false
+    else
+      Array(options[:env]).each do |env|
+        inject_into_file "config/environments/#{env}.rb", optimize_indentation(data, 2), after: env_file_sentinel, verbose: false
+      end
+    end
+  end
+end
+
+
+ +
+ +
+

+ + gem(*args) + +

+ + +
+

Adds an entry into Gemfile for the supplied gem.

+ +
gem "rspec", group: :test
+gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/"
+gem "rails", "3.0", git: "https://github.com/rails/rails"
+gem "RedCloth", ">= 4.1.0", "< 4.2.0"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 18
+def gem(*args)
+  options = args.extract_options!
+  name, *versions = args
+
+  # Set the message to be shown in logs. Uses the git repo if one is given,
+  # otherwise use name (version).
+  parts, message = [ quote(name) ], name.dup
+
+  if versions = versions.any? ? versions : options.delete(:version)
+    _versions = Array(versions)
+    _versions.each do |version|
+      parts << quote(version)
+    end
+    message << " (#{_versions.join(", ")})"
+  end
+  message = options[:git] if options[:git]
+
+  log :gemfile, message
+
+  options.each do |option, value|
+    parts << "#{option}: #{quote(value)}"
+  end
+
+  in_root do
+    str = "gem #{parts.join(", ")}"
+    str = "  " + str if @in_group
+    str = "\n" + str
+    append_file "Gemfile", str, verbose: false
+  end
+end
+
+
+ +
+ +
+

+ + gem_group(*names, &block) + +

+ + +
+

Wraps gem entries inside a group.

+ +
gem_group :development, :test do
+  gem "rspec-rails"
+end
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 54
+def gem_group(*names, &block)
+  name = names.map(&:inspect).join(", ")
+  log :gemfile, "group #{name}"
+
+  in_root do
+    append_file "Gemfile", "\ngroup #{name} do", force: true
+
+    @in_group = true
+    instance_eval(&block)
+    @in_group = false
+
+    append_file "Gemfile", "\nend\n", force: true
+  end
+end
+
+
+ +
+ +
+

+ + generate(what, *args) + +

+ + +
+

Generate something using a generator from Rails or a plugin. The second parameter is the argument string that is passed to the generator or an Array that is joined.

+ +
generate(:authenticated, "user session")
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 212
+def generate(what, *args)
+  log :generate, what
+  argument = args.flat_map(&:to_s).join(" ")
+
+  in_root { run_ruby_script("bin/rails generate #{what} #{argument}", verbose: false) }
+end
+
+
+ +
+ +
+

+ + git(commands = {}) + +

+ + +
+

Run a command in git.

+ +
git :init
+git add: "this.file that.rb"
+git add: "onefile.rb", rm: "badfile.cxx"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 128
+def git(commands = {})
+  if commands.is_a?(Symbol)
+    run "git #{commands}"
+  else
+    commands.each do |cmd, options|
+      run "git #{cmd} #{options}"
+    end
+  end
+end
+
+
+ +
+ +
+

+ + initializer(filename, data = nil) + +

+ + +
+

Create a new initializer with the provided code (either in a block or a string).

+ +
initializer("globals.rb") do
+  data = ""
+
+  ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do |const|
+    data << "#{const} = :entp\n"
+  end
+
+  data
+end
+
+initializer("api.rb", "API_KEY = '123456'")
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 201
+def initializer(filename, data = nil)
+  log :initializer, filename
+  data ||= yield if block_given?
+  create_file("config/initializers/#{filename}", optimize_indentation(data), verbose: false)
+end
+
+
+ +
+ +
+

+ + lib(filename, data = nil) + +

+ + +
+

Create a new file in the lib/ directory. Code can be specified in a block or a data string can be given.

+ +
lib("crypto.rb") do
+  "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
+end
+
+lib("foreign.rb", "# Foreign code is fun")
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 161
+def lib(filename, data = nil)
+  log :lib, filename
+  data ||= yield if block_given?
+  create_file("lib/#{filename}", optimize_indentation(data), verbose: false)
+end
+
+
+ +
+ +
+

+ + rails_command(command, options = {}) + +

+ + +
+

Runs the supplied rake task (invoked with 'rails …')

+ +
rails_command("db:migrate")
+rails_command("db:migrate", env: "production")
+rails_command("gems:install", sudo: true)
+rails_command("gems:install", capture: true)
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 235
+def rails_command(command, options = {})
+  execute_command :rails, command, options
+end
+
+
+ +
+ +
+

+ + rake(command, options = {}) + +

+ + +
+

Runs the supplied rake task (invoked with 'rake …')

+ +
rake("db:migrate")
+rake("db:migrate", env: "production")
+rake("gems:install", sudo: true)
+rake("gems:install", capture: true)
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 225
+def rake(command, options = {})
+  execute_command :rake, command, options
+end
+
+
+ +
+ +
+

+ + rakefile(filename, data = nil) + +

+ + +
+

Create a new Rakefile with the provided code (either in a block or a string).

+ +
rakefile("bootstrap.rake") do
+  project = ask("What is the UNIX name of your project?")
+
+  <<-TASK
+    namespace :#{project} do
+      task :bootstrap do
+        puts "I like boots!"
+      end
+    end
+  TASK
+end
+
+rakefile('seed.rake', 'puts "Planting seeds"')
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 182
+def rakefile(filename, data = nil)
+  log :rakefile, filename
+  data ||= yield if block_given?
+  create_file("lib/tasks/#{filename}", optimize_indentation(data), verbose: false)
+end
+
+
+ +
+ +
+

+ + readme(path) + +

+ + +
+

Reads the given file at the source root and prints it in the console.

+ +
readme "README"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 263
+def readme(path)
+  log File.read(find_in_source_paths(path))
+end
+
+
+ +
+ +
+

+ + route(routing_code) + +

+ + +
+

Make an entry in Rails routing file config/routes.rb

+ +
route "root 'welcome#index'"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 251
+def route(routing_code)
+  log :route, routing_code
+  sentinel = /\.routes\.draw do\s*\n/m
+
+  in_root do
+    inject_into_file "config/routes.rb", optimize_indentation(routing_code, 2), after: sentinel, verbose: false, force: false
+  end
+end
+
+
+ +
+ +
+

+ + vendor(filename, data = nil) + +

+ + +
+

Create a new file in the vendor/ directory. Code can be specified in a block or a data string can be given.

+ +
vendor("sekrit.rb") do
+  sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
+  "salt = '#{sekrit_salt}'"
+end
+
+vendor("foreign.rb", "# Foreign code is fun")
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 147
+def vendor(filename, data = nil)
+  log :vendor, filename
+  data ||= yield if block_given?
+  create_file("vendor/#{filename}", optimize_indentation(data), verbose: false)
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + execute_command(executor, command, options = {}) + +

+ + +
+

Runs the supplied command using either “rake …” or “rails …” based on the executor parameter provided.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 293
+def execute_command(executor, command, options = {}) # :doc:
+  log executor, command
+  env  = options[:env] || ENV["RAILS_ENV"] || "development"
+  sudo = options[:sudo] && !Gem.win_platform? ? "sudo " : ""
+  config = { verbose: false }
+
+  config.merge!(capture: options[:capture]) if options[:capture]
+
+  in_root { run("#{sudo}#{extify(executor)} #{command} RAILS_ENV=#{env}", config) }
+end
+
+
+ +
+ +
+

+ + extify(name) + +

+ + +
+

Add an extension to the given name based on the platform.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 305
+def extify(name) # :doc:
+  if Gem.win_platform?
+    "#{name}.bat"
+  else
+    name
+  end
+end
+
+
+ +
+ +
+

+ + log(*args) + +

+ + +
+

Define log for backwards compatibility. If just one argument is sent, invoke say, otherwise invoke say_status. Differently from say and similarly to say_status, this method respects the quiet? option given.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 282
+def log(*args) # :doc:
+  if args.size == 1
+    say args.first.to_s unless options.quiet?
+  else
+    args << (behavior == :invoke ? :green : :red)
+    say_status(*args)
+  end
+end
+
+
+ +
+ +
+

+ + optimize_indentation(value, amount = 0) + +

+ + +
+

Returns optimized string with indentation

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 326
+def optimize_indentation(value, amount = 0) # :doc:
+  return "#{value}\n" unless value.is_a?(String)
+
+  if value.lines.size > 1
+    value.strip_heredoc.indent(amount)
+  else
+    "#{value.strip.indent(amount)}\n"
+  end
+end
+
+
+ +
+ +
+

+ + quote(value) + +

+ + +
+

Surround string with single quotes if there is no quotes. Otherwise fall back to double quotes

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/actions.rb, line 315
+def quote(value) # :doc:
+  return value.inspect unless value.is_a? String
+
+  if value.include?("'")
+    value.inspect
+  else
+    "'#{value}'"
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/ActiveModel.html b/src/5.2/classes/Rails/Generators/ActiveModel.html new file mode 100644 index 0000000000..7d856af0d4 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/ActiveModel.html @@ -0,0 +1,426 @@ +--- +title: Rails::Generators::ActiveModel +layout: default +--- +
+ +
+
+ +
+ +

ActiveModel is a class to be implemented by each ORM to allow Rails to generate customized controller code.

+ +

The API has the same methods as ActiveRecord, but each method returns a string that matches the ORM API.

+ +

For example:

+ +
ActiveRecord::Generators::ActiveModel.find(Foo, "params[:id]")
+# => "Foo.find(params[:id])"
+
+DataMapper::Generators::ActiveModel.find(Foo, "params[:id]")
+# => "Foo.get(params[:id])"
+
+ +

On initialization, the ActiveModel accepts the instance name that will receive the calls:

+ +
builder = ActiveRecord::Generators::ActiveModel.new "@foo"
+builder.save # => "@foo.save"
+
+ +

The only exception in ActiveModel for ActiveRecord is the use of self.build instead of self.new.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + name
+ + + + +

Class Public methods

+ +
+

+ + all(klass) + +

+ + +
+

GET index

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 36
+def self.all(klass)
+  "#{klass}.all"
+end
+
+
+ +
+ +
+

+ + build(klass, params = nil) + +

+ + +
+

GET new POST create

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 50
+def self.build(klass, params = nil)
+  if params
+    "#{klass}.new(#{params})"
+  else
+    "#{klass}.new"
+  end
+end
+
+
+ +
+ +
+

+ + find(klass, params = nil) + +

+ + +
+

GET show GET edit PATCH/PUT update DELETE destroy

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 44
+def self.find(klass, params = nil)
+  "#{klass}.find(#{params})"
+end
+
+
+ +
+ +
+

+ + new(name) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 31
+def initialize(name)
+  @name = name
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + destroy() + +

+ + +
+

DELETE destroy

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 75
+def destroy
+  "#{name}.destroy"
+end
+
+
+ +
+ +
+

+ + errors() + +

+ + +
+

POST create PATCH/PUT update

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 70
+def errors
+  "#{name}.errors"
+end
+
+
+ +
+ +
+

+ + save() + +

+ + +
+

POST create

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 59
+def save
+  "#{name}.save"
+end
+
+
+ +
+ +
+

+ + update(params = nil) + +

+ + +
+

PATCH/PUT update

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/active_model.rb, line 64
+def update(params = nil)
+  "#{name}.update(#{params})"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/AppBase.html b/src/5.2/classes/Rails/Generators/AppBase.html new file mode 100644 index 0000000000..3c5b285fa3 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/AppBase.html @@ -0,0 +1,73 @@ +--- +title: Rails::Generators::AppBase +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/AppBase/GemfileEntry.html b/src/5.2/classes/Rails/Generators/AppBase/GemfileEntry.html new file mode 100644 index 0000000000..2d9e628f08 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/AppBase/GemfileEntry.html @@ -0,0 +1,276 @@ +--- +title: Rails::Generators::AppBase::GemfileEntry +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + github(name, github, branch = nil, comment = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/app_base.rb, line 244
+def self.github(name, github, branch = nil, comment = nil)
+  if branch
+    new(name, nil, comment, github: github, branch: branch)
+  else
+    new(name, nil, comment, github: github)
+  end
+end
+
+
+ +
+ +
+

+ + new(name, version, comment, options = {}, commented_out = false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/app_base.rb, line 240
+def initialize(name, version, comment, options = {}, commented_out = false)
+  super
+end
+
+
+ +
+ +
+

+ + path(name, path, comment = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/app_base.rb, line 256
+def self.path(name, path, comment = nil)
+  new(name, nil, comment, path: path)
+end
+
+
+ +
+ +
+

+ + version(name, version, comment = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/app_base.rb, line 252
+def self.version(name, version, comment = nil)
+  new(name, version, comment)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + version() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/app_base.rb, line 260
+def version
+  version = super
+
+  if version.is_a?(Array)
+    version.join("', '")
+  else
+    version
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Base.html b/src/5.2/classes/Rails/Generators/Base.html new file mode 100644 index 0000000000..76b5e9ac10 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Base.html @@ -0,0 +1,1213 @@ +--- +title: Rails::Generators::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + base_root() + +

+ + +
+

Returns the base root for a common set of generators. This is used to dynamically guess the default source root.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 226
+def self.base_root
+  __dir__
+end
+
+
+ +
+ +
+

+ + default_source_root() + +

+ + +
+

Returns the default source root for a given generator. This is used internally by rails to set its generators source root. If you want to customize your source root, you should use source_root.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 217
+def self.default_source_root
+  return unless base_name && generator_name
+  return unless default_generator_root
+  path = File.join(default_generator_root, "templates")
+  path if File.exist?(path)
+end
+
+
+ +
+ +
+

+ + desc(description = nil) + +

+ + +
+

Tries to get the description from a USAGE file one folder above the source root otherwise uses a default description.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 39
+def self.desc(description = nil)
+  return super if description
+
+  @desc ||= if usage_path
+    ERB.new(File.read(usage_path)).result(binding)
+  else
+    "Description:\n    Create #{base_name.humanize.downcase} files for #{generator_name} generator."
+  end
+end
+
+
+ +
+ +
+

+ + hide!() + +

+ + +
+

Convenience method to hide this generator from the available ones when running rails generator command.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 59
+def self.hide!
+  Rails::Generators.hide_namespace(namespace)
+end
+
+
+ +
+ +
+

+ + hook_for(*names, &block) + +

+ + +
+

Invoke a generator based on the value supplied by the user to the given option named “name”. A class option is created when this method is invoked and you can set a hash to customize it.

+ +

Examples

+ +
module Rails::Generators
+  class ControllerGenerator < Base
+    hook_for :test_framework, aliases: "-t"
+  end
+end
+
+ +

The example above will create a test framework option and will invoke a generator based on the user supplied value.

+ +

For example, if the user invoke the controller generator as:

+ +
rails generate controller Account --test-framework=test_unit
+
+ +

The controller generator will then try to invoke the following generators:

+ +
"rails:test_unit", "test_unit:controller", "test_unit"
+
+ +

Notice that “rails:generators:test_unit” could be loaded as well, what Rails looks for is the first and last parts of the namespace. This is what allows any test framework to hook into Rails as long as it provides any of the hooks above.

+ +

Options

+ +

The first and last part used to find the generator to be invoked are guessed based on class invokes hook_for, as noticed in the example above. This can be customized with two options: :in and :as.

+ +

Let's suppose you are creating a generator that needs to invoke the controller generator from test unit. Your first attempt is:

+ +
class AwesomeGenerator < Rails::Generators::Base
+  hook_for :test_framework
+end
+
+ +

The lookup in this case for test_unit as input is:

+ +
"test_unit:awesome", "test_unit"
+
+ +

Which is not the desired lookup. You can change it by providing the :as option:

+ +
class AwesomeGenerator < Rails::Generators::Base
+  hook_for :test_framework, as: :controller
+end
+
+ +

And now it will look up at:

+ +
"test_unit:controller", "test_unit"
+
+ +

Similarly, if you want it to also look up in the rails namespace, you just need to provide the :in value:

+ +
class AwesomeGenerator < Rails::Generators::Base
+  hook_for :test_framework, in: :rails, as: :controller
+end
+
+ +

And the lookup is exactly the same as previously:

+ +
"rails:test_unit", "test_unit:controller", "test_unit"
+
+ +

Switches

+ +

All hooks come with switches for user interface. If you do not want to use any test framework, you can do:

+ +
rails generate controller Account --skip-test-framework
+
+ +

Or similarly:

+ +
rails generate controller Account --no-test-framework
+
+ +

Boolean hooks

+ +

In some cases, you may want to provide a boolean hook. For example, webrat developers might want to have webrat available on controller generator. This can be achieved as:

+ +
Rails::Generators::ControllerGenerator.hook_for :webrat, type: :boolean
+
+ +

Then, if you want webrat to be invoked, just supply:

+ +
rails generate controller Account --webrat
+
+ +

The hooks lookup is similar as above:

+ +
"rails:generators:webrat", "webrat:generators:controller", "webrat"
+
+ +

Custom invocations

+ +

You can also supply a block to hook_for to customize how the hook is going to be invoked. The block receives two arguments, an instance of the current class and the class to be invoked.

+ +

For example, in the resource generator, the controller should be invoked with a pluralized class name. But by default it is invoked with the same name as the resource generator, which is singular. To change this, we can give a block to customize how the controller can be invoked.

+ +
hook_for :resource_controller do |instance, controller|
+  instance.invoke controller, [ instance.name.pluralize ]
+end
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 172
+def self.hook_for(*names, &block)
+  options = names.extract_options!
+  in_base = options.delete(:in) || base_name
+  as_hook = options.delete(:as) || generator_name
+
+  names.each do |name|
+    unless class_options.key?(name)
+      defaults = if options[:type] == :boolean
+        {}
+      elsif [true, false].include?(default_value_for_option(name, options))
+        { banner: "" }
+      else
+        { desc: "#{name.to_s.humanize} to be invoked", banner: "NAME" }
+      end
+
+      class_option(name, defaults.merge!(options))
+    end
+
+    hooks[name] = [ in_base, as_hook ]
+    invoke_from_option(name, options, &block)
+  end
+end
+
+
+ +
+ +
+

+ + namespace(name = nil) + +

+ + +
+

Convenience method to get the namespace from the class name. It's the same as Thor default except that the Generator at the end of the class is removed.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 52
+def self.namespace(name = nil)
+  return super if name
+  @namespace ||= super.sub(/_generator$/, "").sub(/:generators:/, ":")
+end
+
+
+ +
+ +
+

+ + remove_hook_for(*names) + +

+ + +
+

Remove a previously added hook.

+ +
remove_hook_for :orm
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 198
+def self.remove_hook_for(*names)
+  remove_invocation(*names)
+
+  names.each do |name|
+    hooks.delete(name)
+  end
+end
+
+
+ +
+ +
+

+ + source_root(path = nil) + +

+ + +
+

Returns the source root for this generator using default_source_root as default.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 32
+def self.source_root(path = nil)
+  @_source_root = path if path
+  @_source_root ||= default_source_root
+end
+
+
+ +
+ + +

Class Private methods

+ +
+

+ + add_shebang_option!() + +

+ + +
+

Small macro to add ruby as an option to the generator with proper default value plus an instance helper method called shebang.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 389
+def self.add_shebang_option! # :doc:
+  class_option :ruby, type: :string, aliases: "-r", default: Thor::Util.ruby_command,
+                      desc: "Path to the Ruby binary of your choice", banner: "PATH"
+
+  no_tasks {
+    define_method :shebang do
+      @shebang ||= begin
+        command = if options[:ruby] == Thor::Util.ruby_command
+          "/usr/bin/env #{File.basename(Thor::Util.ruby_command)}"
+        else
+          options[:ruby]
+        end
+        "#!#{command}"
+      end
+    end
+  }
+end
+
+
+ +
+ +
+

+ + banner() + +

+ + +
+

Use Rails default banner.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 318
+def self.banner # :doc:
+  "rails generate #{namespace.sub(/^rails:/, '')} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
+end
+
+
+ +
+ +
+

+ + base_name() + +

+ + +
+

Sets the base_name taking into account the current class namespace.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 323
+def self.base_name # :doc:
+  @base_name ||= begin
+    if base = name.to_s.split("::").first
+      base.underscore
+    end
+  end
+end
+
+
+ +
+ +
+

+ + default_aliases_for_option(name, options) + +

+ + +
+

Returns default aliases for the option name given doing a lookup in Rails::Generators.aliases.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 350
+def self.default_aliases_for_option(name, options) # :doc:
+  default_for_option(Rails::Generators.aliases, name, options, options[:aliases])
+end
+
+
+ +
+ +
+

+ + default_for_option(config, name, options, default) + +

+ + +
+

Returns default for the option name given doing a lookup in config.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 355
+def self.default_for_option(config, name, options, default) # :doc:
+  if generator_name && (c = config[generator_name.to_sym]) && c.key?(name)
+    c[name]
+  elsif base_name && (c = config[base_name.to_sym]) && c.key?(name)
+    c[name]
+  elsif config[:rails].key?(name)
+    config[:rails][name]
+  else
+    default
+  end
+end
+
+
+ +
+ +
+

+ + default_generator_root() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 415
+def self.default_generator_root # :doc:
+  path = File.expand_path(File.join(base_name, generator_name), base_root)
+  path if File.exist?(path)
+end
+
+
+ +
+ +
+

+ + default_value_for_option(name, options) + +

+ + +
+

Returns the default value for the option name given doing a lookup in Rails::Generators.options.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 344
+def self.default_value_for_option(name, options) # :doc:
+  default_for_option(Rails::Generators.options, name, options, options[:default])
+end
+
+
+ +
+ +
+

+ + generator_name() + +

+ + +
+

Removes the namespaces and get the generator name. For example, Rails::Generators::ModelGenerator will return “model” as generator name.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 333
+def self.generator_name # :doc:
+  @generator_name ||= begin
+    if generator = name.to_s.split("::").last
+      generator.sub!(/Generator$/, "")
+      generator.underscore
+    end
+  end
+end
+
+
+ +
+ +
+

+ + usage_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 407
+def self.usage_path # :doc:
+  paths = [
+    source_root && File.expand_path("../USAGE", source_root),
+    default_generator_root && File.join(default_generator_root, "USAGE")
+  ]
+  paths.compact.detect { |path| File.exist? path }
+end
+
+
+ +
+ + + +

Instance Private methods

+ +
+

+ + extract_last_module(nesting) + +

+ + +
+

Takes in an array of nested modules and extracts the last module

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 276
+def extract_last_module(nesting) # :doc:
+  nesting.inject(Object) do |last_module, nest|
+    break unless last_module.const_defined?(nest, false)
+    last_module.const_get(nest)
+  end
+end
+
+
+ +
+ +
+

+ + indent(content, multiplier = 2) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 291
+def indent(content, multiplier = 2) # :doc:
+  spaces = " " * multiplier
+  content.each_line.map { |line| line.blank? ? line : "#{spaces}#{line}" }.join
+end
+
+
+ +
+ +
+

+ + module_namespacing(&block) + +

+ + +
+

Wrap block with namespace of current application if namespace exists and is not skipped

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 285
+def module_namespacing(&block) # :doc:
+  content = capture(&block)
+  content = wrap_with_namespace(content) if namespaced?
+  concat(content)
+end
+
+
+ +
+ +
+

+ + namespace() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 301
+def namespace # :doc:
+  Rails::Generators.namespace
+end
+
+
+ +
+ +
+

+ + namespaced?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 305
+def namespaced? # :doc:
+  !options[:skip_namespace] && namespace
+end
+
+
+ +
+ +
+

+ + namespaced_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 313
+def namespaced_path # :doc:
+  @namespaced_path ||= namespace_dirs.join("/")
+end
+
+
+ +
+ +
+

+ + wrap_with_namespace(content) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/base.rb, line 296
+def wrap_with_namespace(content) # :doc:
+  content = indent(content).chomp
+  "module #{namespace.name}\n#{content}\nend\n"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Migration.html b/src/5.2/classes/Rails/Generators/Migration.html new file mode 100644 index 0000000000..d40e7f563e --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Migration.html @@ -0,0 +1,240 @@ +--- +title: Rails::Generators::Migration +layout: default +--- +
+ +
+
+ +
+ +

Holds common methods for migrations. It assumes that migrations have the [0-9]*_name format and can be used by other frameworks (like Sequel) just by implementing the next migration version method.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + migration_class_name
+ [R] + migration_file_name
+ [R] + migration_number
+ + + + + +

Instance Public methods

+ +
+

+ + create_migration(destination, data, config = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/migration.rb, line 35
+def create_migration(destination, data, config = {}, &block)
+  action Rails::Generators::Actions::CreateMigration.new(self, destination, block || data.to_s, config)
+end
+
+
+ +
+ +
+

+ + migration_template(source, destination, config = {}) + +

+ + +
+

Creates a migration template at the given destination. The difference to the default template method is that the migration version is appended to the destination file name.

+ +

The migration version, migration file name, migration class name are available as instance variables in the template to be rendered.

+ +
migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/migration.rb, line 56
+def migration_template(source, destination, config = {})
+  source = File.expand_path(find_in_source_paths(source.to_s))
+
+  set_migration_assigns!(destination)
+  context = instance_eval("binding")
+
+  dir, base = File.split(destination)
+  numbered_destination = File.join(dir, ["%migration_number%", base].join("_"))
+
+  create_migration numbered_destination, nil, config do
+    match = ERB.version.match(/\Aerb\.rb \[(?<version>[^ ]+) /)
+    if match && match[:version] >= "2.2.0" # Ruby 2.6+
+      ERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer").result(context)
+    else
+      ERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
+    end
+  end
+end
+
+
+ +
+ +
+

+ + set_migration_assigns!(destination) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/migration.rb, line 39
+def set_migration_assigns!(destination)
+  destination = File.expand_path(destination, destination_root)
+
+  migration_dir = File.dirname(destination)
+  @migration_number     = self.class.next_migration_number(migration_dir)
+  @migration_file_name  = File.basename(destination, ".rb")
+  @migration_class_name = @migration_file_name.camelize
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/NamedBase.html b/src/5.2/classes/Rails/Generators/NamedBase.html new file mode 100644 index 0000000000..9c90ebbbf1 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/NamedBase.html @@ -0,0 +1,1458 @@ +--- +title: Rails::Generators::NamedBase +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + file_name

TODO Change this to private once we've dropped Ruby 2.2 support. Workaround for Ruby 2.2 “private attribute?” warning.

+ + + + +

Class Private methods

+ +
+

+ + check_class_collision(options = {}) + +

+ + +
+

Add a class collisions name to be checked on class initialization. You can supply a hash with a :prefix or :suffix to be tested.

+ +

Examples

+ +
check_class_collision suffix: "Decorator"
+
+ +

If the generator is invoked with class name Admin, it will check for the presence of “AdminDecorator”.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 218
+def self.check_class_collision(options = {}) # :doc:
+  define_method :check_class_collision do
+    name = if respond_to?(:controller_class_name) # for ResourceHelpers
+      controller_class_name
+    else
+      class_name
+    end
+
+    class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}"
+  end
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + js_template(source, destination) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 29
+def js_template(source, destination)
+  template(source + ".js", destination + ".js")
+end
+
+
+ +
+ +
+

+ + template(source, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 23
+def template(source, *args, &block)
+  inside_template do
+    super
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + application_name() + +

+ + +
+

Tries to retrieve the application name or simply return application.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 142
+def application_name # :doc:
+  if defined?(Rails) && Rails.application
+    Rails.application.class.name.split("::").first.underscore
+  else
+    "application"
+  end
+end
+
+
+ +
+ +
+

+ + attributes_names() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 192
+def attributes_names # :doc:
+  @attributes_names ||= attributes.each_with_object([]) do |a, names|
+    names << a.column_name
+    names << "password_confirmation" if a.password_digest?
+    names << "#{a.name}_type" if a.polymorphic?
+  end
+end
+
+
+ +
+ +
+

+ + class_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 74
+def class_name # :doc:
+  (class_path + [file_name]).map!(&:camelize).join("::")
+end
+
+
+ +
+ +
+

+ + class_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 62
+def class_path # :doc:
+  inside_template? || !namespaced? ? regular_class_path : namespaced_class_path
+end
+
+
+ +
+ +
+

+ + edit_helper() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 109
+def edit_helper # :doc:
+  "edit_#{show_helper}"
+end
+
+
+ +
+ +
+

+ + file_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 58
+def file_path # :doc:
+  @file_path ||= (class_path + [file_name]).join("/")
+end
+
+
+ +
+ +
+

+ + fixture_file_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 129
+def fixture_file_name # :doc:
+  @fixture_file_name ||= (pluralize_table_names? ? plural_file_name : file_name)
+end
+
+
+ +
+ +
+

+ + human_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 78
+def human_name # :doc:
+  @human_name ||= singular_name.humanize
+end
+
+
+ +
+ +
+

+ + i18n_scope() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 86
+def i18n_scope # :doc:
+  @i18n_scope ||= file_path.tr("/", ".")
+end
+
+
+ +
+ +
+

+ + index_helper() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 101
+def index_helper # :doc:
+  uncountable? ? "#{plural_route_name}_index" : plural_route_name
+end
+
+
+ +
+ +
+

+ + inside_template() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 47
+def inside_template # :doc:
+  @inside_template = true
+  yield
+ensure
+  @inside_template = false
+end
+
+
+ +
+ +
+

+ + inside_template?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 54
+def inside_template? # :doc:
+  @inside_template
+end
+
+
+ +
+ +
+

+ + model_resource_name(prefix: "") + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 154
+def model_resource_name(prefix: "") # :doc:
+  resource_name = "#{prefix}#{singular_table_name}"
+  if options[:model_name]
+    "[#{controller_class_path.map { |name| ":" + name }.join(", ")}, #{resource_name}]"
+  else
+    resource_name
+  end
+end
+
+
+ +
+ +
+

+ + mountable_engine?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 204
+def mountable_engine? # :doc:
+  defined?(ENGINE_ROOT) && namespaced?
+end
+
+
+ +
+ +
+

+ + namespaced_class_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 70
+def namespaced_class_path # :doc:
+  @namespaced_class_path ||= namespace_dirs + @class_path
+end
+
+
+ +
+ +
+

+ + new_helper() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 113
+def new_helper # :doc:
+  "new_#{singular_route_name}_url"
+end
+
+
+ +
+ +
+

+ + plural_file_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 125
+def plural_file_name # :doc:
+  @plural_file_name ||= file_name.pluralize
+end
+
+
+ +
+ +
+

+ + plural_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 82
+def plural_name # :doc:
+  @plural_name ||= singular_name.pluralize
+end
+
+
+ +
+ +
+

+ + plural_route_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 171
+def plural_route_name # :doc:
+  if options[:model_name]
+    "#{controller_class_path.join('_')}_#{plural_table_name}"
+  else
+    plural_table_name
+  end
+end
+
+
+ +
+ +
+

+ + plural_table_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 121
+def plural_table_name # :doc:
+  @plural_table_name ||= (pluralize_table_names? ? table_name : table_name.pluralize)
+end
+
+
+ +
+ +
+

+ + pluralize_table_names?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 200
+def pluralize_table_names? # :doc:
+  !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
+end
+
+
+ +
+ +
+

+ + redirect_resource_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 150
+def redirect_resource_name # :doc:
+  model_resource_name(prefix: "@")
+end
+
+
+ +
+ +
+

+ + regular_class_path() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 66
+def regular_class_path # :doc:
+  @class_path
+end
+
+
+ +
+ +
+

+ + route_url() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 133
+def route_url # :doc:
+  @route_url ||= class_path.collect { |dname| "/" + dname }.join + "/" + plural_file_name
+end
+
+
+ +
+ +
+

+ + show_helper() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 105
+def show_helper # :doc:
+  "#{singular_route_name}_url(@#{singular_table_name})"
+end
+
+
+ +
+ +
+

+ + singular_name() + +

+ + +
+

FIXME: We are avoiding to use alias because a bug on thor that make this method public and add it to the task list.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 43
+def singular_name # :doc:
+  file_name
+end
+
+
+ +
+ +
+

+ + singular_route_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 163
+def singular_route_name # :doc:
+  if options[:model_name]
+    "#{controller_class_path.join('_')}_#{singular_table_name}"
+  else
+    singular_table_name
+  end
+end
+
+
+ +
+ +
+

+ + singular_table_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 117
+def singular_table_name # :doc:
+  @singular_table_name ||= (pluralize_table_names? ? table_name.singularize : table_name)
+end
+
+
+ +
+ +
+

+ + table_name() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 90
+def table_name # :doc:
+  @table_name ||= begin
+    base = pluralize_table_names? ? plural_name : singular_name
+    (class_path + [base]).join("_")
+  end
+end
+
+
+ +
+ +
+

+ + uncountable?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 97
+def uncountable? # :doc:
+  singular_name == plural_name
+end
+
+
+ +
+ +
+

+ + url_helper_prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/named_base.rb, line 137
+def url_helper_prefix # :doc:
+  @url_helper_prefix ||= (class_path + [file_name]).join("_")
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/TestCase.html b/src/5.2/classes/Rails/Generators/TestCase.html new file mode 100644 index 0000000000..40147b9927 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/TestCase.html @@ -0,0 +1,117 @@ +--- +title: Rails::Generators::TestCase +layout: default +--- +
+ +
+
+ +
+ +

This class provides a TestCase for testing generators. To setup, you need just to configure the destination and set which generator is being tested:

+ +
class AppGeneratorTest < Rails::Generators::TestCase
+  tests AppGenerator
+  destination File.expand_path("../tmp", __dir__)
+end
+
+ +

If you want to ensure your destination root is clean before running each test, you can set a setup callback:

+ +
class AppGeneratorTest < Rails::Generators::TestCase
+  tests AppGenerator
+  destination File.expand_path("../tmp", __dir__)
+  setup :prepare_destination
+end
+
+ +
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Testing.html b/src/5.2/classes/Rails/Generators/Testing.html new file mode 100644 index 0000000000..58187d182f --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Testing.html @@ -0,0 +1,75 @@ +--- +title: Rails::Generators::Testing +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Testing/Assertions.html b/src/5.2/classes/Rails/Generators/Testing/Assertions.html new file mode 100644 index 0000000000..f3802763e9 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Testing/Assertions.html @@ -0,0 +1,545 @@ +--- +title: Rails::Generators::Testing::Assertions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_class_method(method, content, &block) + +

+ + +
+

Asserts the given class method exists in the given content. This method does not detect class methods inside (class << self), only class methods which starts with “self.”. When a block is given, it yields the content of the method.

+ +
assert_migration "db/migrate/create_products.rb" do |migration|
+  assert_class_method :up, migration do |up|
+    assert_match(/create_table/, up)
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 88
+def assert_class_method(method, content, &block)
+  assert_instance_method "self.#{method}", content, &block
+end
+
+
+ +
+ +
+

+ + assert_directory(relative, *contents) + +

+ + +
+ +
+ + + + + +
+ Alias for: assert_file +
+ + + +
+ +
+

+ + assert_field_default_value(attribute_type, value) + +

+ + +
+

Asserts the given attribute type gets a proper default value:

+ +
assert_field_default_value :string, "MyString"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 117
+def assert_field_default_value(attribute_type, value)
+  if value.nil?
+    assert_nil(create_generated_attribute(attribute_type).default)
+  else
+    assert_equal(value, create_generated_attribute(attribute_type).default)
+  end
+end
+
+
+ +
+ +
+

+ + assert_field_type(attribute_type, field_type) + +

+ + +
+

Asserts the given attribute type gets translated to a field type properly:

+ +
assert_field_type :date, :date_select
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 110
+def assert_field_type(attribute_type, field_type)
+  assert_equal(field_type, create_generated_attribute(attribute_type).field_type)
+end
+
+
+ +
+ +
+

+ + assert_file(relative, *contents) + +

+ + +
+

Asserts a given file exists. You need to supply an absolute path or a path relative to the configured destination:

+ +
assert_file "config/environment.rb"
+
+ +

You can also give extra arguments. If the argument is a regexp, it will check if the regular expression matches the given file content. If it's a string, it compares the file with the given string:

+ +
assert_file "config/environment.rb", /initialize/
+
+ +

Finally, when a block is given, it yields the file content:

+ +
assert_file "app/controllers/products_controller.rb" do |controller|
+  assert_instance_method :index, controller do |index|
+    assert_match(/Product\.all/, index)
+  end
+end
+
+
+ + + +
+ Also aliased as: assert_directory +
+ + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 25
+def assert_file(relative, *contents)
+  absolute = File.expand_path(relative, destination_root)
+  assert File.exist?(absolute), "Expected file #{relative.inspect} to exist, but does not"
+
+  read = File.read(absolute) if block_given? || !contents.empty?
+  yield read if block_given?
+
+  contents.each do |content|
+    case content
+    when String
+      assert_equal content, read
+    when Regexp
+      assert_match content, read
+    end
+  end
+end
+
+
+ +
+ +
+

+ + assert_instance_method(method, content) + +

+ + +
+

Asserts the given method exists in the given content. When a block is given, it yields the content of the method.

+ +
assert_file "app/controllers/products_controller.rb" do |controller|
+  assert_instance_method :index, controller do |index|
+    assert_match(/Product\.all/, index)
+  end
+end
+
+
+ + + +
+ Also aliased as: assert_method +
+ + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 100
+def assert_instance_method(method, content)
+  assert content =~ /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m, "Expected to have method #{method}"
+  yield $3.strip if block_given?
+end
+
+
+ +
+ +
+

+ + assert_method(method, content) + +

+ + +
+ +
+ + + + + +
+ Alias for: assert_instance_method +
+ + + +
+ +
+

+ + assert_migration(relative, *contents, &block) + +

+ + +
+

Asserts a given migration exists. You need to supply an absolute path or a path relative to the configured destination:

+ +
assert_migration "db/migrate/create_products.rb"
+
+ +

This method manipulates the given path and tries to find any migration which matches the migration name. For example, the call above is converted to:

+ +
assert_file "db/migrate/003_create_products.rb"
+
+ +

Consequently, assert_migration accepts the same arguments has assert_file.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 64
+def assert_migration(relative, *contents, &block)
+  file_name = migration_file_name(relative)
+  assert file_name, "Expected migration #{relative} to exist, but was not found"
+  assert_file file_name, *contents, &block
+end
+
+
+ +
+ +
+

+ + assert_no_directory(relative) + +

+ + +
+ +
+ + + + + +
+ Alias for: assert_no_file +
+ + + +
+ +
+

+ + assert_no_file(relative) + +

+ + +
+

Asserts a given file does not exist. You need to supply an absolute path or a path relative to the configured destination:

+ +
assert_no_file "config/random.rb"
+
+
+ + + +
+ Also aliased as: assert_no_directory +
+ + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 47
+def assert_no_file(relative)
+  absolute = File.expand_path(relative, destination_root)
+  assert !File.exist?(absolute), "Expected file #{relative.inspect} to not exist, but does"
+end
+
+
+ +
+ +
+

+ + assert_no_migration(relative) + +

+ + +
+

Asserts a given migration does not exist. You need to supply an absolute path or a path relative to the configured destination:

+ +
assert_no_migration "db/migrate/create_products.rb"
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/assertions.rb, line 74
+def assert_no_migration(relative)
+  file_name = migration_file_name(relative)
+  assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}"
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Testing/Behaviour.html b/src/5.2/classes/Rails/Generators/Testing/Behaviour.html new file mode 100644 index 0000000000..66c831f9e8 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Testing/Behaviour.html @@ -0,0 +1,255 @@ +--- +title: Rails::Generators::Testing::Behaviour +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + create_generated_attribute(attribute_type, name = "test", index = nil) + +

+ + +
+

Create a Rails::Generators::GeneratedAttribute by supplying the attribute type and, optionally, the attribute name:

+ +
create_generated_attribute(:string, 'name')
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/behaviour.rb, line 83
+def create_generated_attribute(attribute_type, name = "test", index = nil)
+  Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(":"))
+end
+
+
+ +
+ +
+

+ + generator(args = default_arguments, options = {}, config = {}) + +

+ + +
+

Instantiate the generator.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/behaviour.rb, line 75
+def generator(args = default_arguments, options = {}, config = {})
+  @generator ||= generator_class.new(args, options, config.reverse_merge(destination_root: destination_root))
+end
+
+
+ +
+ +
+

+ + run_generator(args = default_arguments, config = {}) + +

+ + +
+

Runs the generator configured for this class. The first argument is an array like command line arguments:

+ +
class AppGeneratorTest < Rails::Generators::TestCase
+  tests AppGenerator
+  destination File.expand_path("../tmp", __dir__)
+  setup :prepare_destination
+
+  test "database.yml is not created when skipping Active Record" do
+    run_generator %w(myapp --skip-active-record)
+    assert_no_file "config/database.yml"
+  end
+end
+
+ +

You can provide a configuration hash as second argument. This method returns the output printed by the generator.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/behaviour.rb, line 67
+def run_generator(args = default_arguments, config = {})
+  capture(:stdout) do
+    args += ["--skip-bundle"] unless args.include? "--dev"
+    generator_class.start(args, config.reverse_merge(destination_root: destination_root))
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + prepare_destination() + +

+ + +
+

Clears all files and directories in destination.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/behaviour.rb, line 98
+def prepare_destination # :doc:
+  rm_rf(destination_root)
+  mkdir_p(destination_root)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Testing/Behaviour/ClassMethods.html b/src/5.2/classes/Rails/Generators/Testing/Behaviour/ClassMethods.html new file mode 100644 index 0000000000..e00de7561e --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Testing/Behaviour/ClassMethods.html @@ -0,0 +1,188 @@ +--- +title: Rails::Generators::Testing::Behaviour::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + arguments(array) + +

+ + +
+

Sets default arguments on generator invocation. This can be overwritten when invoking it.

+ +
arguments %w(app_name --skip-active-record)
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/behaviour.rb, line 39
+def arguments(array)
+  self.default_arguments = array
+end
+
+
+ +
+ +
+

+ + destination(path) + +

+ + +
+

Sets the destination of generator files:

+ +
destination File.expand_path("../tmp", __dir__)
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/behaviour.rb, line 46
+def destination(path)
+  self.destination_root = path
+end
+
+
+ +
+ +
+

+ + tests(klass) + +

+ + +
+

Sets which generator should be tested:

+ +
tests AppGenerator
+
+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/testing/behaviour.rb, line 31
+def tests(klass)
+  self.generator_class = klass
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Generators/Testing/SetupAndTeardown.html b/src/5.2/classes/Rails/Generators/Testing/SetupAndTeardown.html new file mode 100644 index 0000000000..3a7699cd81 --- /dev/null +++ b/src/5.2/classes/Rails/Generators/Testing/SetupAndTeardown.html @@ -0,0 +1,54 @@ +--- +title: Rails::Generators::Testing::SetupAndTeardown +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Info.html b/src/5.2/classes/Rails/Info.html new file mode 100644 index 0000000000..c4186bf79f --- /dev/null +++ b/src/5.2/classes/Rails/Info.html @@ -0,0 +1,236 @@ +--- +title: Rails::Info +layout: default +--- +
+ +
+
+ +
+ +

This module helps build the runtime properties that are displayed in Rails::InfoController responses. These include the active Rails version, Ruby version, Rack version, and so on.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + property(name, value = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/info.rb, line 25
+def property(name, value = nil)
+  value ||= yield
+  properties << [name, value] if value
+rescue Exception
+end
+
+
+ +
+ +
+

+ + to_html() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/info.rb, line 43
+def to_html
+  "<table>".dup.tap do |table|
+    properties.each do |(name, value)|
+      table << %(<tr><td class="name">#{CGI.escapeHTML(name.to_s)}</td>)
+      formatted_value = if value.kind_of?(Array)
+        "<ul>" + value.map { |v| "<li>#{CGI.escapeHTML(v.to_s)}</li>" }.join + "</ul>"
+      else
+        CGI.escapeHTML(value.to_s)
+      end
+      table << %(<td class="value">#{formatted_value}</td></tr>)
+    end
+    table << "</table>"
+  end
+end
+
+
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + +
+ Also aliased as: inspect +
+ + + + + + +
+ + +
+
# File railties/lib/rails/info.rb, line 31
+def to_s
+  column_width = properties.names.map(&:length).max
+  info = properties.map do |name, value|
+    value = value.join(", ") if value.is_a?(Array)
+    "%-#{column_width}s   %s" % [name, value]
+  end
+  info.unshift "About your application's environment"
+  info * "\n"
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Initializable.html b/src/5.2/classes/Rails/Initializable.html new file mode 100644 index 0000000000..7f6879ac72 --- /dev/null +++ b/src/5.2/classes/Rails/Initializable.html @@ -0,0 +1,166 @@ +--- +title: Rails::Initializable +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + initializers() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 66
+def initializers
+  @initializers ||= self.class.initializers_for(self)
+end
+
+
+ +
+ +
+

+ + run_initializers(group = :default, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 58
+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
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Initializable/ClassMethods.html b/src/5.2/classes/Rails/Initializable/ClassMethods.html new file mode 100644 index 0000000000..2aad5f7d9b --- /dev/null +++ b/src/5.2/classes/Rails/Initializable/ClassMethods.html @@ -0,0 +1,225 @@ +--- +title: Rails::Initializable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + initializer(name, opts = {}, &blk) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 88
+def initializer(name, opts = {}, &blk)
+  raise ArgumentError, "A block must be passed when defining an initializer" unless blk
+  opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
+  initializers << Initializer.new(name, nil, opts, &blk)
+end
+
+
+ +
+ +
+

+ + initializers() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 71
+def initializers
+  @initializers ||= Collection.new
+end
+
+
+ +
+ +
+

+ + initializers_chain() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 75
+def initializers_chain
+  initializers = Collection.new
+  ancestors.reverse_each do |klass|
+    next unless klass.respond_to?(:initializers)
+    initializers = initializers + klass.initializers
+  end
+  initializers
+end
+
+
+ +
+ +
+

+ + initializers_for(binding) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 84
+def initializers_for(binding)
+  Collection.new(initializers_chain.map { |i| i.bind(binding) })
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Initializable/Collection.html b/src/5.2/classes/Rails/Initializable/Collection.html new file mode 100644 index 0000000000..dceffeb1ec --- /dev/null +++ b/src/5.2/classes/Rails/Initializable/Collection.html @@ -0,0 +1,158 @@ +--- +title: Rails::Initializable::Collection +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + TSort + +
  • + +
+ + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + +(other) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 53
+def +(other)
+  Collection.new(to_a + other.to_a)
+end
+
+
+ +
+ +
+

+ + tsort_each_child(initializer, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 49
+def tsort_each_child(initializer, &block)
+  select { |i| i.before == initializer.name || i.name == initializer.after }.each(&block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Initializable/Initializer.html b/src/5.2/classes/Rails/Initializable/Initializer.html new file mode 100644 index 0000000000..e63f38600b --- /dev/null +++ b/src/5.2/classes/Rails/Initializable/Initializer.html @@ -0,0 +1,368 @@ +--- +title: Rails::Initializable::Initializer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + block
+ [R] + name
+ + + + +

Class Public methods

+ +
+

+ + new(name, context, options, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 14
+def initialize(name, context, options, &block)
+  options[:group] ||= :default
+  @name, @context, @options, @block = name, context, options, block
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + after() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 23
+def after
+  @options[:after]
+end
+
+
+ +
+ +
+

+ + before() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 19
+def before
+  @options[:before]
+end
+
+
+ +
+ +
+

+ + belongs_to?(group) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 27
+def belongs_to?(group)
+  @options[:group] == group || @options[:group] == :all
+end
+
+
+ +
+ +
+

+ + bind(context) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 35
+def bind(context)
+  return self if @context
+  Initializer.new(@name, context, @options, &block)
+end
+
+
+ +
+ +
+

+ + context_class() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 40
+def context_class
+  @context.class
+end
+
+
+ +
+ +
+

+ + run(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/initializable.rb, line 31
+def run(*args)
+  @context.instance_exec(*args, &block)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Paths.html b/src/5.2/classes/Rails/Paths.html new file mode 100644 index 0000000000..6bc6fa848d --- /dev/null +++ b/src/5.2/classes/Rails/Paths.html @@ -0,0 +1,69 @@ +--- +title: Rails::Paths +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Paths/Path.html b/src/5.2/classes/Rails/Paths/Path.html new file mode 100644 index 0000000000..750402ae97 --- /dev/null +++ b/src/5.2/classes/Rails/Paths/Path.html @@ -0,0 +1,665 @@ +--- +title: Rails::Paths::Path +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + glob
+ + + + +

Class Public methods

+ +
+

+ + new(root, current, paths, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 115
+def initialize(root, current, paths, options = {})
+  @paths    = paths
+  @current  = current
+  @root     = root
+  @glob     = options[:glob]
+
+  options[:autoload_once] ? autoload_once! : skip_autoload_once!
+  options[:eager_load]    ? eager_load!    : skip_eager_load!
+  options[:autoload]      ? autoload!      : skip_autoload!
+  options[:load_path]     ? load_path!     : skip_load_path!
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(path) + +

+ + +
+ +
+ + + +
+ Also aliased as: push +
+ + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 166
+def <<(path)
+  @paths << path
+end
+
+
+ +
+ +
+

+ + children() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 131
+def children
+  keys = @root.keys.find_all { |k|
+    k.start_with?(@current) && k != @current
+  }
+  @root.values_at(*keys.sort)
+end
+
+
+ +
+ +
+

+ + concat(paths) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 171
+def concat(paths)
+  @paths.concat paths
+end
+
+
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 162
+def each(&block)
+  @paths.each(&block)
+end
+
+
+ +
+ +
+

+ + existent() + +

+ + +
+

Returns all expanded paths but only if they exist in the filesystem.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 209
+def existent
+  expanded.select do |f|
+    does_exist = File.exist?(f)
+
+    if !does_exist && File.symlink?(f)
+      raise "File #{f.inspect} is a symlink that does not point to a valid file"
+    end
+    does_exist
+  end
+end
+
+
+ +
+ +
+

+ + existent_directories() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 220
+def existent_directories
+  expanded.select { |d| File.directory?(d) }
+end
+
+
+ +
+ +
+

+ + expanded() + +

+ + +
+

Expands all paths against the root and return all unique values.

+
+ + + +
+ Also aliased as: to_a +
+ + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 188
+def expanded
+  raise "You need to set a path root" unless @root.path
+  result = []
+
+  each do |p|
+    path = File.expand_path(p, @root.path)
+
+    if @glob && File.directory?(path)
+      Dir.chdir(path) do
+        result.concat(Dir.glob(@glob).map { |file| File.join path, file }.sort)
+      end
+    else
+      result << path
+    end
+  end
+
+  result.uniq!
+  result
+end
+
+
+ +
+ +
+

+ + first() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 138
+def first
+  expanded.first
+end
+
+
+ +
+ +
+

+ + last() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 142
+def last
+  expanded.last
+end
+
+
+ +
+ +
+

+ + push(path) + +

+ + +
+ +
+ + + + + +
+ Alias for: << +
+ + + +
+ +
+

+ + to_a() + +

+ + +
+ +
+ + + + + +
+ Alias for: expanded +
+ + + +
+ +
+

+ + to_ary() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 179
+def to_ary
+  @paths
+end
+
+
+ +
+ +
+

+ + unshift(*paths) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 175
+def unshift(*paths)
+  @paths.unshift(*paths)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Paths/Root.html b/src/5.2/classes/Rails/Paths/Root.html new file mode 100644 index 0000000000..15175520fe --- /dev/null +++ b/src/5.2/classes/Rails/Paths/Root.html @@ -0,0 +1,601 @@ +--- +title: Rails::Paths::Root +layout: default +--- +
+ +
+
+ +
+ +

This object is an extended hash that behaves as root of the Rails::Paths system. It allows you to collect information about how you want to structure your application paths through a Hash-like API. It requires you to give a physical path on initialization.

+ +
root = Root.new "/rails"
+root.add "app/controllers", eager_load: true
+
+ +

The above command creates a new root object and adds “app/controllers” as a path. This means we can get a Rails::Paths::Path object back like below:

+ +
path = root["app/controllers"]
+path.eager_load?               # => true
+path.is_a?(Rails::Paths::Path) # => true
+
+ +

The Path object is simply an enumerable and allows you to easily add extra paths:

+ +
path.is_a?(Enumerable) # => true
+path.to_ary.inspect    # => ["app/controllers"]
+
+path << "lib/controllers"
+path.to_ary.inspect    # => ["app/controllers", "lib/controllers"]
+
+ +

Notice that when you add a path using add, the path object created already contains the path with the same path value given to add. In some situations, you may not want this behavior, so you can give :with as option.

+ +
root.add "config/routes", with: "config/routes.rb"
+root["config/routes"].inspect # => ["config/routes.rb"]
+
+ +

The add method accepts the following options as arguments: eager_load, autoload, autoload_once, and glob.

+ +

Finally, the Path object also provides a few helpers:

+ +
root = Root.new "/rails"
+root.add "app/controllers"
+
+root["app/controllers"].expanded # => ["/rails/app/controllers"]
+root["app/controllers"].existent # => ["/rails/app/controllers"]
+
+ +

Check the Rails::Paths::Path documentation for more information.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + path
+ + + + +

Class Public methods

+ +
+

+ + new(path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 49
+def initialize(path)
+  @path = path
+  @root = {}
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](path) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 64
+def [](path)
+  @root[path]
+end
+
+
+ +
+ +
+

+ + []=(path, value) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 54
+def []=(path, value)
+  glob = self[path] ? self[path].glob : nil
+  add(path, with: value, glob: glob)
+end
+
+
+ +
+ +
+

+ + add(path, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 59
+def add(path, options = {})
+  with = Array(options.fetch(:with, path))
+  @root[path] = Path.new(self, path, with, options)
+end
+
+
+ +
+ +
+

+ + all_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 80
+def all_paths
+  values.tap(&:uniq!)
+end
+
+
+ +
+ +
+

+ + autoload_once() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 84
+def autoload_once
+  filter_by(&:autoload_once?)
+end
+
+
+ +
+ +
+

+ + autoload_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 92
+def autoload_paths
+  filter_by(&:autoload?)
+end
+
+
+ +
+ +
+

+ + eager_load() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 88
+def eager_load
+  filter_by(&:eager_load?)
+end
+
+
+ +
+ +
+

+ + keys() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 72
+def keys
+  @root.keys
+end
+
+
+ +
+ +
+

+ + load_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 96
+def load_paths
+  filter_by(&:load_path?)
+end
+
+
+ +
+ +
+

+ + values() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 68
+def values
+  @root.values
+end
+
+
+ +
+ +
+

+ + values_at(*list) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/paths.rb, line 76
+def values_at(*list)
+  @root.values_at(*list)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/PluginBuilder.html b/src/5.2/classes/Rails/PluginBuilder.html new file mode 100644 index 0000000000..0e6d8ec874 --- /dev/null +++ b/src/5.2/classes/Rails/PluginBuilder.html @@ -0,0 +1,917 @@ +--- +title: Rails::PluginBuilder +layout: default +--- +
+ +
+
+ +
+ +

The plugin builder allows you to override elements of the plugin generator without being forced to reverse the operations of the default generator.

+ +

This allows you to override entire operations, like the creation of the Gemfile, README, or JavaScript files, without needing to know exactly what those operations do so you can create another template action.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
PASSTHROUGH_OPTIONS=[ +:skip_active_record, :skip_active_storage, :skip_action_mailer, :skip_javascript, :skip_action_cable, :skip_sprockets, :database, +:javascript, :skip_yarn, :api, :quiet, :pretend, :skip +]
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 19
+def app
+  if mountable?
+    if api?
+      directory "app", exclude_pattern: %r{app/(views|helpers)}
+    else
+      directory "app"
+      empty_directory_with_keep_file "app/assets/images/#{namespaced_name}"
+    end
+  elsif full?
+    empty_directory_with_keep_file "app/models"
+    empty_directory_with_keep_file "app/controllers"
+    empty_directory_with_keep_file "app/mailers"
+
+    unless api?
+      empty_directory_with_keep_file "app/assets/images/#{namespaced_name}"
+      empty_directory_with_keep_file "app/helpers"
+      empty_directory_with_keep_file "app/views"
+    end
+  end
+end
+
+
+ +
+ +
+

+ + assets_manifest() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 133
+def assets_manifest
+  template "rails/engine_manifest.js", "app/assets/config/#{underscored_name}_manifest.js"
+end
+
+
+ +
+ +
+

+ + bin(force = false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 157
+def bin(force = false)
+  bin_file = engine? ? "bin/rails.tt" : "bin/test.tt"
+  template bin_file, force: force do |content|
+    "#{shebang}\n" + content
+  end
+  chmod "bin", 0755, verbose: false
+end
+
+
+ +
+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 72
+def config
+  template "config/routes.rb" if engine?
+end
+
+
+ +
+ +
+

+ + gemfile() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 44
+def gemfile
+  template "Gemfile"
+end
+
+
+ +
+ +
+

+ + gemfile_entry() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 165
+def gemfile_entry
+  return unless inside_application?
+
+  gemfile_in_app_path = File.join(rails_app_path, "Gemfile")
+  if File.exist? gemfile_in_app_path
+    entry = "\ngem '#{name}', path: '#{relative_path}'"
+    append_file gemfile_in_app_path, entry
+  end
+end
+
+
+ +
+ +
+

+ + gemspec() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 52
+def gemspec
+  template "%name%.gemspec"
+end
+
+
+ +
+ +
+

+ + generate_test_dummy(force = false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 94
+def generate_test_dummy(force = false)
+  opts = (options.dup || {}).keep_if { |k, _| PASSTHROUGH_OPTIONS.map(&:to_s).include?(k) }
+  opts[:force] = force
+  opts[:skip_bundle] = true
+  opts[:skip_listen] = true
+  opts[:skip_git] = true
+  opts[:skip_turbolinks] = true
+  opts[:dummy_app] = true
+
+  invoke Rails::Generators::AppGenerator,
+    [ File.expand_path(dummy_path, destination_root) ], opts
+end
+
+
+ +
+ +
+

+ + gitignore() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 56
+def gitignore
+  template "gitignore", ".gitignore"
+end
+
+
+ +
+ +
+

+ + javascripts() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 146
+def javascripts
+  return if options.skip_javascript?
+
+  if mountable?
+    template "rails/javascripts.js",
+             "app/assets/javascripts/#{namespaced_name}/application.js"
+  elsif full?
+    empty_directory_with_keep_file "app/assets/javascripts/#{namespaced_name}"
+  end
+end
+
+
+ +
+ +
+

+ + lib() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 60
+def lib
+  template "lib/%namespaced_name%.rb"
+  template "lib/tasks/%namespaced_name%_tasks.rake"
+  template "lib/%namespaced_name%/version.rb"
+
+  if engine?
+    template "lib/%namespaced_name%/engine.rb"
+  else
+    template "lib/%namespaced_name%/railtie.rb"
+  end
+end
+
+
+ +
+ +
+

+ + license() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 48
+def license
+  template "MIT-LICENSE"
+end
+
+
+ +
+ +
+

+ + rakefile() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 15
+def rakefile
+  template "Rakefile"
+end
+
+
+ +
+ +
+

+ + readme() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 40
+def readme
+  template "README.md"
+end
+
+
+ +
+ +
+

+ + stylesheets() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 137
+def stylesheets
+  if mountable?
+    copy_file "rails/stylesheets.css",
+              "app/assets/stylesheets/#{namespaced_name}/application.css"
+  elsif full?
+    empty_directory_with_keep_file "app/assets/stylesheets/#{namespaced_name}"
+  end
+end
+
+
+ +
+ +
+

+ + test() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 76
+    def test
+      template "test/test_helper.rb"
+      template "test/%namespaced_name%_test.rb"
+      append_file "Rakefile", <<-EOF
+
+#{rakefile_test_tasks}
+task default: :test
+      EOF
+      if engine?
+        template "test/integration/navigation_test.rb"
+      end
+    end
+
+
+ +
+ +
+

+ + test_dummy_assets() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 115
+def test_dummy_assets
+  template "rails/javascripts.js",    "#{dummy_path}/app/assets/javascripts/application.js", force: true
+  template "rails/stylesheets.css",   "#{dummy_path}/app/assets/stylesheets/application.css", force: true
+  template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true
+end
+
+
+ +
+ +
+

+ + test_dummy_clean() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 121
+def test_dummy_clean
+  inside dummy_path do
+    remove_file "db/seeds.rb"
+    remove_file "Gemfile"
+    remove_file "lib/tasks"
+    remove_file "public/robots.txt"
+    remove_file "README.md"
+    remove_file "test"
+    remove_file "vendor"
+  end
+end
+
+
+ +
+ +
+

+ + test_dummy_config() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 107
+def test_dummy_config
+  template "rails/boot.rb", "#{dummy_path}/config/boot.rb", force: true
+  template "rails/application.rb", "#{dummy_path}/config/application.rb", force: true
+  if mountable?
+    template "rails/routes.rb", "#{dummy_path}/config/routes.rb", force: true
+  end
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Rack.html b/src/5.2/classes/Rails/Rack.html new file mode 100644 index 0000000000..a0eba2099f --- /dev/null +++ b/src/5.2/classes/Rails/Rack.html @@ -0,0 +1,69 @@ +--- +title: Rails::Rack +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Rack/Logger.html b/src/5.2/classes/Rails/Rack/Logger.html new file mode 100644 index 0000000000..b5fb2eb263 --- /dev/null +++ b/src/5.2/classes/Rails/Rack/Logger.html @@ -0,0 +1,307 @@ +--- +title: Rails::Rack::Logger +layout: default +--- +
+ +
+
+ +
+ +

Sets log tags, logs the request, calls the app, and flushes the logs.

+ +

Log tags (taggers) can be an Array containing: methods that the request object responds to, objects that respond to to_s or Proc objects that accept an instance of the request object.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app, taggers = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/rack/logger.rb, line 17
+def initialize(app, taggers = nil)
+  @app          = app
+  @taggers      = taggers || []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/rack/logger.rb, line 22
+def call(env)
+  request = ActionDispatch::Request.new(env)
+
+  if logger.respond_to?(:tagged)
+    logger.tagged(compute_tags(request)) { call_app(request, env) }
+  else
+    call_app(request, env)
+  end
+end
+
+
+ +
+ + +

Instance Private methods

+ +
+

+ + call_app(request, env) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/rack/logger.rb, line 34
+def call_app(request, env) # :doc:
+  instrumenter = ActiveSupport::Notifications.instrumenter
+  instrumenter.start "request.action_dispatch", request: request
+  logger.info { started_request_message(request) }
+  status, headers, body = @app.call(env)
+  body = ::Rack::BodyProxy.new(body) { finish(request) }
+  [status, headers, body]
+rescue Exception
+  finish(request)
+  raise
+ensure
+  ActiveSupport::LogSubscriber.flush_all!
+end
+
+
+ +
+ +
+

+ + compute_tags(request) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/rack/logger.rb, line 57
+def compute_tags(request) # :doc:
+  @taggers.collect do |tag|
+    case tag
+    when Proc
+      tag.call(request)
+    when Symbol
+      request.send(tag)
+    else
+      tag
+    end
+  end
+end
+
+
+ +
+ +
+

+ + started_request_message(request) + +

+ + +
+

Started GET “/session/new” for 127.0.0.1 at 2012-09-26 14:51:42 -0700

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/rack/logger.rb, line 49
+def started_request_message(request) # :doc:
+  'Started %s "%s" for %s at %s' % [
+    request.request_method,
+    request.filtered_path,
+    request.remote_ip,
+    Time.now.to_default_s ]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Railtie.html b/src/5.2/classes/Rails/Railtie.html new file mode 100644 index 0000000000..43166e7093 --- /dev/null +++ b/src/5.2/classes/Rails/Railtie.html @@ -0,0 +1,664 @@ +--- +title: Rails::Railtie +layout: default +--- +
+ +
+
+ +
+ +

Rails::Railtie is the core of the Rails framework and provides several hooks to extend Rails and/or modify the initialization process.

+ +

Every major component of Rails (Action Mailer, Action Controller, Active Record, etc.) implements a railtie. Each of them is responsible for their own initialization. This makes Rails itself absent of any component hooks, allowing other components to be used in place of any of the Rails defaults.

+ +

Developing a Rails extension does not require implementing a railtie, but if you need to interact with the Rails framework during or after boot, then a railtie is needed.

+ +

For example, an extension doing any of the following would need a railtie:

+
  • +

    creating initializers

    +
  • +

    configuring a Rails framework for the application, like setting a generator

    +
  • +

    adding config.* keys to the environment

    +
  • +

    setting up a subscriber with ActiveSupport::Notifications

    +
  • +

    adding Rake tasks

    +
+ +

Creating a Railtie

+ +

To extend Rails using a railtie, create a subclass of Rails::Railtie. This class must be loaded during the Rails boot process, and is conventionally called MyNamespace::Railtie.

+ +

The following example demonstrates an extension which can be used with or without Rails.

+ +
# lib/my_gem/railtie.rb
+module MyGem
+  class Railtie < Rails::Railtie
+  end
+end
+
+# lib/my_gem.rb
+require 'my_gem/railtie' if defined?(Rails)
+
+ +

Initializers

+ +

To add an initialization step to the Rails boot process from your railtie, just define the initialization code with the initializer macro:

+ +
class MyRailtie < Rails::Railtie
+  initializer "my_railtie.configure_rails_initialization" do
+    # some initialization behavior
+  end
+end
+
+ +

If specified, the block can also receive the application object, in case you need to access some application-specific configuration, like middleware:

+ +
class MyRailtie < Rails::Railtie
+  initializer "my_railtie.configure_rails_initialization" do |app|
+    app.middleware.use MyRailtie::Middleware
+  end
+end
+
+ +

Finally, you can also pass :before and :after as options to initializer, in case you want to couple it with a specific step in the initialization process.

+ +

Configuration

+ +

Railties can access a config object which contains configuration shared by all railties and the application:

+ +
class MyRailtie < Rails::Railtie
+  # Customize the ORM
+  config.app_generators.orm :my_railtie_orm
+
+  # Add a to_prepare block which is executed once in production
+  # and before each request in development.
+  config.to_prepare do
+    MyRailtie.setup!
+  end
+end
+
+ +

Loading Rake Tasks and Generators

+ +

If your railtie has Rake tasks, you can tell Rails to load them through the method rake_tasks:

+ +
class MyRailtie < Rails::Railtie
+  rake_tasks do
+    load 'path/to/my_railtie.tasks'
+  end
+end
+
+ +

By default, Rails loads generators from your load path. However, if you want to place your generators at a different location, you can specify in your railtie a block which will load them during normal generators lookup:

+ +
class MyRailtie < Rails::Railtie
+  generators do
+    require 'path/to/my_railtie_generator'
+  end
+end
+
+ +

Since filenames on the load path are shared across gems, be sure that files you load through a railtie have unique names.

+ +

Application and Engine

+ +

An engine is nothing more than a railtie with some initializers already set. And since Rails::Application is an engine, the same configuration described here can be used in both.

+ +

Be sure to look at the documentation of those specific classes for more information.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
ABSTRACT_RAILTIES=%w(Rails::Railtie Rails::Engine Rails::Application)
 
+ + + + + + +

Class Public methods

+ +
+

+ + abstract_railtie?() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 155
+def abstract_railtie?
+  ABSTRACT_RAILTIES.include?(name)
+end
+
+
+ +
+ +
+

+ + configure(&block) + +

+ + +
+

Allows you to configure the railtie. This is the same method seen in Railtie::Configurable, but this module is no longer required for all subclasses of Railtie so we provide the class method here.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 173
+def configure(&block)
+  instance.configure(&block)
+end
+
+
+ +
+ +
+

+ + console(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 143
+def console(&blk)
+  register_block_for(:load_console, &blk)
+end
+
+
+ +
+ +
+

+ + generators(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 151
+def generators(&blk)
+  register_block_for(:generators, &blk)
+end
+
+
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 133
+def inherited(base)
+  unless base.abstract_railtie?
+    subclasses << base
+  end
+end
+
+
+ +
+ +
+

+ + instance() + +

+ + +
+

Since Rails::Railtie cannot be instantiated, any methods that call instance are intended to be called only on subclasses of a Railtie.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 166
+def instance
+  @instance ||= new
+end
+
+
+ +
+ +
+

+ + railtie_name(name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 159
+def railtie_name(name = nil)
+  @railtie_name = name.to_s if name
+  @railtie_name ||= generate_railtie_name(self.name)
+end
+
+
+ +
+ +
+

+ + rake_tasks(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 139
+def rake_tasks(&blk)
+  register_block_for(:rake_tasks, &blk)
+end
+
+
+ +
+ +
+

+ + runner(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 147
+def runner(&blk)
+  register_block_for(:runner, &blk)
+end
+
+
+ +
+ +
+

+ + subclasses() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 129
+def subclasses
+  @subclasses ||= []
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+

This is used to create the config object on Railties, an instance of Railtie::Configuration, that is used by Railties and Application to store related configuration.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie.rb, line 222
+def config
+  @config ||= Railtie::Configuration.new
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Railtie/Configurable.html b/src/5.2/classes/Rails/Railtie/Configurable.html new file mode 100644 index 0000000000..4078fde640 --- /dev/null +++ b/src/5.2/classes/Rails/Railtie/Configurable.html @@ -0,0 +1,67 @@ +--- +title: Rails::Railtie::Configurable +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Railtie/Configurable/ClassMethods.html b/src/5.2/classes/Rails/Railtie/Configurable/ClassMethods.html new file mode 100644 index 0000000000..d51475fb4c --- /dev/null +++ b/src/5.2/classes/Rails/Railtie/Configurable/ClassMethods.html @@ -0,0 +1,218 @@ +--- +title: Rails::Railtie::Configurable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + configure(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configurable.rb, line 25
+def configure(&block)
+  class_eval(&block)
+end
+
+
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configurable.rb, line 13
+def inherited(base)
+  raise "You cannot inherit from a #{superclass.name} child"
+end
+
+
+ +
+ +
+

+ + instance() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configurable.rb, line 17
+def instance
+  @instance ||= new
+end
+
+
+ +
+ +
+

+ + respond_to?(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configurable.rb, line 21
+def respond_to?(*args)
+  super || instance.respond_to?(*args)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Railtie/Configuration.html b/src/5.2/classes/Rails/Railtie/Configuration.html new file mode 100644 index 0000000000..3afedc413a --- /dev/null +++ b/src/5.2/classes/Rails/Railtie/Configuration.html @@ -0,0 +1,584 @@ +--- +title: Rails::Railtie::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 8
+def initialize
+  @@options ||= {}
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + after_initialize(&block) + +

+ + +
+

Last configurable block to run. Called after frameworks initialize.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 70
+def after_initialize(&block)
+  ActiveSupport.on_load(:after_initialize, yield: true, &block)
+end
+
+
+ +
+ +
+

+ + app_generators() + +

+ + +
+

This allows you to modify application's generators from Railties.

+ +

Values set on app_generators will become defaults for application, unless application overwrites them.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 47
+def app_generators
+  @@app_generators ||= Rails::Configuration::Generators.new
+  yield(@@app_generators) if block_given?
+  @@app_generators
+end
+
+
+ +
+ +
+

+ + app_middleware() + +

+ + +
+

This allows you to modify the application's middlewares from Engines.

+ +

All operations you run on the app_middleware will be replayed on the application once it is defined and the default_middlewares are created

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 39
+def app_middleware
+  @@app_middleware ||= Rails::Configuration::MiddlewareStackProxy.new
+end
+
+
+ +
+ +
+

+ + before_configuration(&block) + +

+ + +
+

First configurable block to run. Called before any initializers are run.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 54
+def before_configuration(&block)
+  ActiveSupport.on_load(:before_configuration, yield: true, &block)
+end
+
+
+ +
+ +
+

+ + before_eager_load(&block) + +

+ + +
+

Third configurable block to run. Does not run if config.eager_load set to false.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 60
+def before_eager_load(&block)
+  ActiveSupport.on_load(:before_eager_load, yield: true, &block)
+end
+
+
+ +
+ +
+

+ + before_initialize(&block) + +

+ + +
+

Second configurable block to run. Called before frameworks initialize.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 65
+def before_initialize(&block)
+  ActiveSupport.on_load(:before_initialize, yield: true, &block)
+end
+
+
+ +
+ +
+

+ + eager_load_namespaces() + +

+ + +
+

All namespaces that are eager loaded

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 18
+def eager_load_namespaces
+  @@eager_load_namespaces ||= []
+end
+
+
+ +
+ +
+

+ + respond_to?(name, include_private = false) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 85
+def respond_to?(name, include_private = false)
+  super || @@options.key?(name.to_sym)
+end
+
+
+ +
+ +
+

+ + to_prepare(&blk) + +

+ + +
+

Defines generic callbacks to run before after_initialize. Useful for Rails::Railtie subclasses.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 81
+def to_prepare(&blk)
+  to_prepare_blocks << blk if blk
+end
+
+
+ +
+ +
+

+ + to_prepare_blocks() + +

+ + +
+

Array of callbacks defined by to_prepare.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 75
+def to_prepare_blocks
+  @@to_prepare_blocks ||= []
+end
+
+
+ +
+ +
+

+ + watchable_dirs() + +

+ + +
+

Add directories that should be watched for change. The key of the hashes should be directories and the values should be an array of extensions to match in each directory.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 30
+def watchable_dirs
+  @@watchable_dirs ||= {}
+end
+
+
+ +
+ +
+

+ + watchable_files() + +

+ + +
+

Add files that should be watched for change.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/railtie/configuration.rb, line 23
+def watchable_files
+  @@watchable_files ||= []
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Secrets.html b/src/5.2/classes/Rails/Secrets.html new file mode 100644 index 0000000000..d57ceaaf82 --- /dev/null +++ b/src/5.2/classes/Rails/Secrets.html @@ -0,0 +1,73 @@ +--- +title: Rails::Secrets +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Secrets/MissingKeyError.html b/src/5.2/classes/Rails/Secrets/MissingKeyError.html new file mode 100644 index 0000000000..9ab24961e4 --- /dev/null +++ b/src/5.2/classes/Rails/Secrets/MissingKeyError.html @@ -0,0 +1,110 @@ +--- +title: Rails::Secrets::MissingKeyError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/secrets.rb, line 11
+      def initialize
+        super(<<-end_of_message.squish)
+          Missing encryption key to decrypt secrets with.
+          Ask your team for your master key and put it in ENV["RAILS_MASTER_KEY"]
+        end_of_message
+      end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Server.html b/src/5.2/classes/Rails/Server.html new file mode 100644 index 0000000000..ed71b0eba5 --- /dev/null +++ b/src/5.2/classes/Rails/Server.html @@ -0,0 +1,378 @@ +--- +title: Rails::Server +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 19
+def initialize(options = nil)
+  @default_options = options || {}
+  super(@default_options)
+  set_environment
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 25
+    def app
+      @app ||= begin
+        app = super
+        if app.is_a?(Class)
+          ActiveSupport::Deprecation.warn(<<-MSG.squish)
+            Using `Rails::Application` subclass to start the server is deprecated and will be removed in Rails 6.0.
+            Please change `run #{app}` to `run Rails.application` in config.ru.
+          MSG
+        end
+        app.respond_to?(:to_app) ? app.to_app : app
+      end
+    end
+
+
+ +
+ +
+

+ + default_options() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 64
+def default_options
+  super.merge(@default_options)
+end
+
+
+ +
+ +
+

+ + middleware() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 60
+def middleware
+  Hash.new([])
+end
+
+
+ +
+ +
+

+ + opt_parser() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 38
+def opt_parser
+  Options.new
+end
+
+
+ +
+ +
+

+ + set_environment() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 42
+def set_environment
+  ENV["RAILS_ENV"] ||= options[:environment]
+end
+
+
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 46
+def start
+  print_boot_information
+  trap(:INT) { exit }
+  create_tmp_directories
+  setup_dev_caching
+  log_to_stdout if options[:log_stdout]
+
+  super
+ensure
+  # The '-h' option calls exit before @options is set.
+  # If we call 'options' with it unset, we get double help banners.
+  puts "Exiting" unless @options && options[:daemonize]
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/Server/Options.html b/src/5.2/classes/Rails/Server/Options.html new file mode 100644 index 0000000000..ff0d2ae7e4 --- /dev/null +++ b/src/5.2/classes/Rails/Server/Options.html @@ -0,0 +1,107 @@ +--- +title: Rails::Server::Options +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + parse!(args) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/commands/server/server_command.rb, line 14
+def parse!(args)
+  Rails::Command::ServerCommand.new([], args).server_options
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rails/VERSION.html b/src/5.2/classes/Rails/VERSION.html new file mode 100644 index 0000000000..e6e53c8ad4 --- /dev/null +++ b/src/5.2/classes/Rails/VERSION.html @@ -0,0 +1,124 @@ +--- +title: Rails::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=5
 
MINOR=2
 
PRE=nil
 
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
 
TINY=5
 
+ + + + + + + + + +
+ +
+
diff --git a/src/5.2/classes/Range.html b/src/5.2/classes/Range.html new file mode 100644 index 0000000000..9f9efa465f --- /dev/null +++ b/src/5.2/classes/Range.html @@ -0,0 +1,115 @@ +--- +title: Range +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + overlaps?(other) + +

+ + +
+

Compare two ranges and see if they overlap each other

+ +
(1..5).overlaps?(4..6) # => true
+(1..5).overlaps?(7..9) # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/range/overlaps.rb, line 7
+def overlaps?(other)
+  cover?(other.first) || other.cover?(first)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Rational.html b/src/5.2/classes/Rational.html new file mode 100644 index 0000000000..e2ed4515fe --- /dev/null +++ b/src/5.2/classes/Rational.html @@ -0,0 +1,111 @@ +--- +title: Rational +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + duplicable?() + +

+ + +
+

Rationals are not duplicable:

+ +
Rational(1).duplicable? # => false
+Rational(1).dup         # => TypeError: can't copy Rational
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 152
+def duplicable?
+  false
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/SecureRandom.html b/src/5.2/classes/SecureRandom.html new file mode 100644 index 0000000000..6d0b8924bf --- /dev/null +++ b/src/5.2/classes/SecureRandom.html @@ -0,0 +1,133 @@ +--- +title: SecureRandom +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
BASE58_ALPHABET=("0".."9").to_a + ("A".."Z").to_a + ("a".."z").to_a - ["0", "O", "I", "l"]
 
+ + + + + + +

Class Public methods

+ +
+

+ + base58(n = 16) + +

+ + +
+

SecureRandom.base58 generates a random base58 string.

+ +

The argument n specifies the length, of the random string to be generated.

+ +

If n is not specified or is nil, 16 is assumed. It may be larger in the future.

+ +

The result may contain alphanumeric characters except 0, O, I and l

+ +
p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
+p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/securerandom.rb, line 18
+def self.base58(n = 16)
+  SecureRandom.random_bytes(n).unpack("C*").map do |byte|
+    idx = byte % 64
+    idx = SecureRandom.random_number(58) if idx >= 58
+    BASE58_ALPHABET[idx]
+  end.join
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/classes/SourceAnnotationExtractor.html b/src/5.2/classes/SourceAnnotationExtractor.html new file mode 100644 index 0000000000..2a5a33f523 --- /dev/null +++ b/src/5.2/classes/SourceAnnotationExtractor.html @@ -0,0 +1,436 @@ +--- +title: SourceAnnotationExtractor +layout: default +--- +
+ +
+
+ +
+ +

Implements the logic behind the rake tasks for annotations like

+ +
rails notes
+rails notes:optimize
+
+ +

and friends. See rails -T notes and railties/lib/rails/tasks/annotations.rake.

+ +

Annotation objects are triplets :line, :tag, :text that represent the line where the annotation lives, its tag, and its text. Note the filename is not stored.

+ +

Annotations are looked for in comments and modulus whitespace they have to start with the tag optionally followed by a colon. Everything up to the end of the line (or closing ERB comment tag) is considered to be their text.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
Annotation=Struct.new(:line, :tag, :text) do +def self.directories +@@directories ||= %w(app config db lib test) + (ENV["SOURCE_ANNOTATION_DIRECTORIES"] || "").split(",") +end + +# Registers additional directories to be included +# SourceAnnotationExtractor::Annotation.register_directories("spec", "another") +def self.register_directories(*dirs) +directories.push(*dirs) +end + +def self.extensions +@@extensions ||= {} +end + +# Registers new Annotations File Extensions +# SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } +def self.register_extensions(*exts, &block) +extensions[/\.(#{exts.join("|")})$/] = block +end + +register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ } +register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ } +register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ } + +# Returns a representation of the annotation that looks like this: +# +# [126] [TODO] This algorithm is simple and clearly correct, make it faster. +# +# If +options+ has a flag <tt>:tag</tt> the tag is shown as in the example above. +# Otherwise the string contains just line and text. +def to_s(options = {}) +s = "[#{line.to_s.rjust(options[:indent])}] ".dup +s << "[#{tag}] " if options[:tag] +s << text +end +end
 
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + tag
+ + + + +

Class Public methods

+ +
+

+ + enumerate(tag, options = {}) + +

+ + +
+

Prints all annotations with tag tag under the root directories app, config, db, lib, and test (recursively).

+ +

Additional directories may be added using a comma-delimited list set using ENV['SOURCE_ANNOTATION_DIRECTORIES'].

+ +

Directories may also be explicitly set using the :dirs key in options.

+ +
SourceAnnotationExtractor.enumerate 'TODO|FIXME', dirs: %w(app lib), tag: true
+
+ +

If options has a :tag flag, it will be passed to each annotation's to_s.

+ +

See #find_in for a list of file extensions that will be taken into account.

+ +

This class method is the single entry point for the rake tasks.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/source_annotation_extractor.rb, line 71
+def self.enumerate(tag, options = {})
+  extractor = new(tag)
+  dirs = options.delete(:dirs) || Annotation.directories
+  extractor.display(extractor.find(dirs), options)
+end
+
+
+ +
+ +
+

+ + new(tag) + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/source_annotation_extractor.rb, line 79
+def initialize(tag)
+  @tag = tag
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + display(results, options = {}) + +

+ + +
+

Prints the mapping from filenames to annotations in results ordered by filename. The options hash is passed to each annotation's to_s.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/source_annotation_extractor.rb, line 131
+def display(results, options = {})
+  options[:indent] = results.flat_map { |f, a| a.map(&:line) }.max.to_s.size
+  results.keys.sort.each do |file|
+    puts "#{file}:"
+    results[file].each do |note|
+      puts "  * #{note.to_s(options)}"
+    end
+    puts
+  end
+end
+
+
+ +
+ +
+

+ + extract_annotations_from(file, pattern) + +

+ + +
+

If file is the filename of a file that contains annotations this method returns a hash with a single entry that maps file to an array of its annotations. Otherwise it returns an empty hash.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/source_annotation_extractor.rb, line 119
+def extract_annotations_from(file, pattern)
+  lineno = 0
+  result = File.readlines(file, encoding: Encoding::BINARY).inject([]) do |list, line|
+    lineno += 1
+    next list unless line =~ pattern
+    list << Annotation.new(lineno, $1, $2)
+  end
+  result.empty? ? {} : { file => result }
+end
+
+
+ +
+ +
+

+ + find(dirs) + +

+ + +
+

Returns a hash that maps filenames under dirs (recursively) to arrays with their annotations.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/source_annotation_extractor.rb, line 85
+def find(dirs)
+  dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
+end
+
+
+ +
+ +
+

+ + find_in(dir) + +

+ + +
+

Returns a hash that maps filenames under dir (recursively) to arrays with their annotations. Only files with annotations are included. Files with extension .builder, .rb, .rake, .yml, .yaml, .ruby, .css, .js and .erb are taken into account.

+
+ + + + + + + + +
+ + +
+
# File railties/lib/rails/source_annotation_extractor.rb, line 93
+def find_in(dir)
+  results = {}
+
+  Dir.glob("#{dir}/*") do |item|
+    next if File.basename(item)[0] == ?.
+
+    if File.directory?(item)
+      results.update(find_in(item))
+    else
+      extension = Annotation.extensions.detect do |regexp, _block|
+        regexp.match(item)
+      end
+
+      if extension
+        pattern = extension.last.call(tag)
+        results.update(extract_annotations_from(item, pattern)) if pattern
+      end
+    end
+  end
+
+  results
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/String.html b/src/5.2/classes/String.html new file mode 100644 index 0000000000..e3cbeba1f9 --- /dev/null +++ b/src/5.2/classes/String.html @@ -0,0 +1,2261 @@ +--- +title: String +layout: default +--- +
+ +
+
+ +
+ +

String inflections define new methods on the String class to transform names for different purposes. For instance, you can figure out the name of a table from the name of a class.

+ +
'ScaleScore'.tableize # => "scale_scores"
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
BLANK_RE=/\A[[:space:]]*\z/
 
ENCODED_BLANKS=Concurrent::Map.new do |h, enc| +h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING) +end
 
+ + + + + + + +

Instance Public methods

+ +
+

+ + acts_like_string?() + +

+ + +
+

Enables more predictable duck-typing on String-like classes. See Object#acts_like?.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/behavior.rb, line 5
+def acts_like_string?
+  true
+end
+
+
+ +
+ +
+

+ + at(position) + +

+ + +
+

If you pass a single integer, returns a substring of one character at that position. The first character of the string is at position 0, the next at position 1, and so on. If a range is supplied, a substring containing characters at offsets given by the range is returned. In both cases, if an offset is negative, it is counted from the end of the string. Returns nil if the initial offset falls outside the string. Returns an empty string if the beginning of the range is greater than the end of the string.

+ +
str = "hello"
+str.at(0)      # => "h"
+str.at(1..3)   # => "ell"
+str.at(-2)     # => "l"
+str.at(-2..-1) # => "lo"
+str.at(5)      # => nil
+str.at(5..-1)  # => ""
+
+ +

If a Regexp is given, the matching portion of the string is returned. If a String is given, that given string is returned if it occurs in the string. In both cases, nil is returned if there is no match.

+ +
str = "hello"
+str.at(/lo/) # => "lo"
+str.at(/ol/) # => nil
+str.at("lo") # => "lo"
+str.at("ol") # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/access.rb, line 29
+def at(position)
+  self[position]
+end
+
+
+ +
+ +
+

+ + blank?() + +

+ + +
+

A string is blank if it's empty or contains whitespaces only:

+ +
''.blank?       # => true
+'   '.blank?    # => true
+"\t\n\r".blank? # => true
+' blah '.blank? # => false
+
+ +

Unicode whitespace is supported:

+ +
"\u00a0".blank? # => true
+
+ +

@return [true, false]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 122
+def blank?
+  # The regexp that matches blank strings is expensive. For the case of empty
+  # strings we can speed up this method (~3.5x) with an empty? call. The
+  # penalty for the rest of strings is marginal.
+  empty? ||
+    begin
+      BLANK_RE.match?(self)
+    rescue Encoding::CompatibilityError
+      ENCODED_BLANKS[self.encoding].match?(self)
+    end
+end
+
+
+ +
+ +
+

+ + camelcase(first_letter = :upper) + +

+ + +
+ +
+ + + + + +
+ Alias for: camelize +
+ + + +
+ +
+

+ + camelize(first_letter = :upper) + +

+ + +
+

By default, camelize converts strings to UpperCamelCase. If the argument to camelize is set to :lower then camelize produces lowerCamelCase.

+ +

camelize will also convert '/' to '::' which is useful for converting paths to namespaces.

+ +
'active_record'.camelize                # => "ActiveRecord"
+'active_record'.camelize(:lower)        # => "activeRecord"
+'active_record/errors'.camelize         # => "ActiveRecord::Errors"
+'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
+
+
+ + + +
+ Also aliased as: camelcase +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 91
+def camelize(first_letter = :upper)
+  case first_letter
+  when :upper
+    ActiveSupport::Inflector.camelize(self, true)
+  when :lower
+    ActiveSupport::Inflector.camelize(self, false)
+  else
+    raise ArgumentError, "Invalid option, use either :upper or :lower."
+  end
+end
+
+
+ +
+ +
+

+ + classify() + +

+ + +
+

Creates a class name from a plural table name like Rails does for table names to models. Note that this returns a string and not a class. (To convert to an actual class follow classify with constantize.)

+ +
'ham_and_eggs'.classify # => "HamAndEgg"
+'posts'.classify        # => "Post"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 210
+def classify
+  ActiveSupport::Inflector.classify(self)
+end
+
+
+ +
+ +
+

+ + constantize() + +

+ + +
+

constantize tries to find a declared constant with the name specified in the string. It raises a NameError when the name is not in CamelCase or is not initialized. See ActiveSupport::Inflector.constantize

+ +
'Module'.constantize  # => Module
+'Class'.constantize   # => Class
+'blargle'.constantize # => NameError: wrong constant name blargle
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 67
+def constantize
+  ActiveSupport::Inflector.constantize(self)
+end
+
+
+ +
+ +
+

+ + dasherize() + +

+ + +
+

Replaces underscores with dashes in the string.

+ +
'puni_puni'.dasherize # => "puni-puni"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 134
+def dasherize
+  ActiveSupport::Inflector.dasherize(self)
+end
+
+
+ +
+ +
+

+ + deconstantize() + +

+ + +
+

Removes the rightmost segment from the constant expression in the string.

+ +
'Net::HTTP'.deconstantize   # => "Net"
+'::Net::HTTP'.deconstantize # => "::Net"
+'String'.deconstantize      # => ""
+'::String'.deconstantize    # => ""
+''.deconstantize            # => ""
+
+ +

See also demodulize.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 159
+def deconstantize
+  ActiveSupport::Inflector.deconstantize(self)
+end
+
+
+ +
+ +
+

+ + demodulize() + +

+ + +
+

Removes the module part from the constant expression in the string.

+ +
'ActiveSupport::Inflector::Inflections'.demodulize # => "Inflections"
+'Inflections'.demodulize                           # => "Inflections"
+'::Inflections'.demodulize                         # => "Inflections"
+''.demodulize                                      # => ''
+
+ +

See also deconstantize.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 146
+def demodulize
+  ActiveSupport::Inflector.demodulize(self)
+end
+
+
+ +
+ +
+

+ + exclude?(string) + +

+ + +
+

The inverse of String#include?. Returns true if the string does not include the other string.

+ +
"hello".exclude? "lo" # => false
+"hello".exclude? "ol" # => true
+"hello".exclude? ?h   # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/exclude.rb, line 10
+def exclude?(string)
+  !include?(string)
+end
+
+
+ +
+ +
+

+ + first(limit = 1) + +

+ + +
+

Returns the first character. If a limit is supplied, returns a substring from the beginning of the string until it reaches the limit value. If the given limit is greater than or equal to the string length, returns a copy of self.

+ +
str = "hello"
+str.first    # => "h"
+str.first(1) # => "h"
+str.first(2) # => "he"
+str.first(0) # => ""
+str.first(6) # => "hello"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/access.rb, line 77
+def first(limit = 1)
+  if limit == 0
+    ""
+  elsif limit >= size
+    dup
+  else
+    to(limit - 1)
+  end
+end
+
+
+ +
+ +
+

+ + foreign_key(separate_class_name_and_id_with_underscore = true) + +

+ + +
+

Creates a foreign key name from a class name. separate_class_name_and_id_with_underscore sets whether the method should put '_' between the name and 'id'.

+ +
'Message'.foreign_key        # => "message_id"
+'Message'.foreign_key(false) # => "messageid"
+'Admin::Post'.foreign_key    # => "post_id"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 251
+def foreign_key(separate_class_name_and_id_with_underscore = true)
+  ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
+end
+
+
+ +
+ +
+

+ + from(position) + +

+ + +
+

Returns a substring from the given position to the end of the string. If the position is negative, it is counted from the end of the string.

+ +
str = "hello"
+str.from(0)  # => "hello"
+str.from(3)  # => "lo"
+str.from(-2) # => "lo"
+
+ +

You can mix it with to method and do fun things like:

+ +
str = "hello"
+str.from(0).to(-1) # => "hello"
+str.from(1).to(-2) # => "ell"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/access.rb, line 46
+def from(position)
+  self[position..-1]
+end
+
+
+ +
+ +
+

+ + html_safe() + +

+ + +
+

Marks a string as trusted safe. It will be inserted into HTML with no additional escaping performed. It is your responsibility to ensure that the string contains no malicious content. This method is equivalent to the raw helper in views. It is recommended that you use sanitize instead of this method. It should never be called on user input.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 255
+def html_safe
+  ActiveSupport::SafeBuffer.new(self)
+end
+
+
+ +
+ +
+

+ + humanize(capitalize: true, keep_id_suffix: false) + +

+ + +
+

Capitalizes the first word, turns underscores into spaces, and (by default)strips a trailing '_id' if present. Like titleize, this is meant for creating pretty output.

+ +

The capitalization of the first word can be turned off by setting the optional parameter capitalize to false. By default, this parameter is true.

+ +

The trailing '_id' can be kept and capitalized by setting the optional parameter keep_id_suffix to true. By default, this parameter is false.

+ +
'employee_salary'.humanize                    # => "Employee salary"
+'author_id'.humanize                          # => "Author"
+'author_id'.humanize(capitalize: false)       # => "author"
+'_id'.humanize                                # => "Id"
+'author_id'.humanize(keep_id_suffix: true)    # => "Author Id"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 231
+def humanize(capitalize: true, keep_id_suffix: false)
+  ActiveSupport::Inflector.humanize(self, capitalize: capitalize, keep_id_suffix: keep_id_suffix)
+end
+
+
+ +
+ +
+

+ + in_time_zone(zone = ::Time.zone) + +

+ + +
+

Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default is set, otherwise converts String to a Time via String#to_time

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/zones.rb, line 9
+def in_time_zone(zone = ::Time.zone)
+  if zone
+    ::Time.find_zone!(zone).parse(self)
+  else
+    to_time
+  end
+end
+
+
+ +
+ +
+

+ + indent(amount, indent_string = nil, indent_empty_lines = false) + +

+ + +
+

Indents the lines in the receiver:

+ +
<<EOS.indent(2)
+def some_method
+  some_code
+end
+EOS
+# =>
+  def some_method
+    some_code
+  end
+
+ +

The second argument, indent_string, specifies which indent string to use. The default is nil, which tells the method to make a guess by peeking at the first indented line, and fallback to a space if there is none.

+ +
"  foo".indent(2)        # => "    foo"
+"foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
+"foo".indent(2, "\t")    # => "\t\tfoo"
+
+ +

While indent_string is typically one space or tab, it may be any string.

+ +

The third argument, indent_empty_lines, is a flag that says whether empty lines should be indented. Default is false.

+ +
"foo\n\nbar".indent(2)            # => "  foo\n\n  bar"
+"foo\n\nbar".indent(2, nil, true) # => "  foo\n  \n  bar"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/indent.rb, line 42
+def indent(amount, indent_string = nil, indent_empty_lines = false)
+  dup.tap { |_| _.indent!(amount, indent_string, indent_empty_lines) }
+end
+
+
+ +
+ +
+

+ + indent!(amount, indent_string = nil, indent_empty_lines = false) + +

+ + +
+

Same as indent, except it indents the receiver in-place.

+ +

Returns the indented string, or nil if there was nothing to indent.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/indent.rb, line 7
+def indent!(amount, indent_string = nil, indent_empty_lines = false)
+  indent_string = indent_string || self[/^[ \t]/] || " "
+  re = indent_empty_lines ? /^/ : /^(?!$)/
+  gsub!(re, indent_string * amount)
+end
+
+
+ +
+ +
+

+ + inquiry() + +

+ + +
+

Wraps the current string in the ActiveSupport::StringInquirer class, which gives you a prettier way to test for equality.

+ +
env = 'production'.inquiry
+env.production?  # => true
+env.development? # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inquiry.rb, line 12
+def inquiry
+  ActiveSupport::StringInquirer.new(self)
+end
+
+
+ +
+ +
+

+ + is_utf8?() + +

+ + +
+

Returns true if string has utf_8 encoding.

+ +
utf_8_str = "some string".encode "UTF-8"
+iso_str = "some string".encode "ISO-8859-1"
+
+utf_8_str.is_utf8? # => true
+iso_str.is_utf8?   # => false
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/multibyte.rb, line 47
+def is_utf8?
+  case encoding
+  when Encoding::UTF_8
+    valid_encoding?
+  when Encoding::ASCII_8BIT, Encoding::US_ASCII
+    dup.force_encoding(Encoding::UTF_8).valid_encoding?
+  else
+    false
+  end
+end
+
+
+ +
+ +
+

+ + last(limit = 1) + +

+ + +
+

Returns the last character of the string. If a limit is supplied, returns a substring from the end of the string until it reaches the limit value (counting backwards). If the given limit is greater than or equal to the string length, returns a copy of self.

+ +
str = "hello"
+str.last    # => "o"
+str.last(1) # => "o"
+str.last(2) # => "lo"
+str.last(0) # => ""
+str.last(6) # => "hello"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/access.rb, line 97
+def last(limit = 1)
+  if limit == 0
+    ""
+  elsif limit >= size
+    dup
+  else
+    from(-limit)
+  end
+end
+
+
+ +
+ +
+

+ + mb_chars() + +

+ + +
+

Multibyte proxy

+ +

mb_chars is a multibyte safe proxy for string methods.

+ +

It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.

+ +
>> "lj".upcase
+=> "lj"
+>> "lj".mb_chars.upcase.to_s
+=> "LJ"
+
+ +

NOTE: An above example is useful for pre Ruby 2.4. Ruby 2.4 supports Unicode case mappings.

+ +

Method chaining

+ +

All the methods on the Chars proxy which normally return a string will return a Chars object. This allows method chaining on the result of any of these methods.

+ +
name.mb_chars.reverse.length # => 12
+
+ +

Interoperability and configuration

+ +

The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between String and Char work like expected. The bang! methods change the internal string representation in the Chars object. Interoperability problems can be resolved easily with a to_s call.

+ +

For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/multibyte.rb, line 36
+def mb_chars
+  ActiveSupport::Multibyte.proxy_class.new(self)
+end
+
+
+ +
+ +
+

+ + parameterize(separator: "-", preserve_case: false) + +

+ + +
+

Replaces special characters in a string so that it may be used as part of a 'pretty' URL.

+ +
class Person
+  def to_param
+    "#{id}-#{name.parameterize}"
+  end
+end
+
+@person = Person.find(1)
+# => #<Person id: 1, name: "Donald E. Knuth">
+
+<%= link_to(@person.name, person_path) %>
+# => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
+
+ +

To preserve the case of the characters in a string, use the preserve_case argument.

+ +
class Person
+  def to_param
+    "#{id}-#{name.parameterize(preserve_case: true)}"
+  end
+end
+
+@person = Person.find(1)
+# => #<Person id: 1, name: "Donald E. Knuth">
+
+<%= link_to(@person.name, person_path) %>
+# => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 190
+def parameterize(separator: "-", preserve_case: false)
+  ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case)
+end
+
+
+ +
+ +
+

+ + pluralize(count = nil, locale = :en) + +

+ + +
+

Returns the plural form of the word in the string.

+ +

If the optional parameter count is specified, the singular form will be returned if count == 1. For any other value of count the plural will be returned.

+ +

If the optional parameter locale is specified, the word will be pluralized as a word of that language. By default, this parameter is set to :en. You must define your own inflection rules for languages other than English.

+ +
'post'.pluralize             # => "posts"
+'octopus'.pluralize          # => "octopi"
+'sheep'.pluralize            # => "sheep"
+'words'.pluralize            # => "words"
+'the blue mailman'.pluralize # => "the blue mailmen"
+'CamelOctopus'.pluralize     # => "CamelOctopi"
+'apple'.pluralize(1)         # => "apple"
+'apple'.pluralize(2)         # => "apples"
+'ley'.pluralize(:es)         # => "leyes"
+'ley'.pluralize(1, :es)      # => "ley"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 33
+def pluralize(count = nil, locale = :en)
+  locale = count if count.is_a?(Symbol)
+  if count == 1
+    dup
+  else
+    ActiveSupport::Inflector.pluralize(self, locale)
+  end
+end
+
+
+ +
+ +
+

+ + remove(*patterns) + +

+ + +
+

Returns a new string with all occurrences of the patterns removed.

+ +
str = "foo bar test"
+str.remove(" test")                 # => "foo bar"
+str.remove(" test", /bar/)          # => "foo "
+str                                 # => "foo bar test"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 32
+def remove(*patterns)
+  dup.remove!(*patterns)
+end
+
+
+ +
+ +
+

+ + remove!(*patterns) + +

+ + +
+

Alters the string by removing all occurrences of the patterns.

+ +
str = "foo bar test"
+str.remove!(" test", /bar/)         # => "foo "
+str                                 # => "foo "
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 40
+def remove!(*patterns)
+  patterns.each do |pattern|
+    gsub! pattern, ""
+  end
+
+  self
+end
+
+
+ +
+ +
+

+ + safe_constantize() + +

+ + +
+

safe_constantize tries to find a declared constant with the name specified in the string. It returns nil when the name is not in CamelCase or is not initialized. See ActiveSupport::Inflector.safe_constantize

+ +
'Module'.safe_constantize  # => Module
+'Class'.safe_constantize   # => Class
+'blargle'.safe_constantize # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 78
+def safe_constantize
+  ActiveSupport::Inflector.safe_constantize(self)
+end
+
+
+ +
+ +
+

+ + singularize(locale = :en) + +

+ + +
+

The reverse of pluralize, returns the singular form of a word in a string.

+ +

If the optional parameter locale is specified, the word will be singularized as a word of that language. By default, this parameter is set to :en. You must define your own inflection rules for languages other than English.

+ +
'posts'.singularize            # => "post"
+'octopi'.singularize           # => "octopus"
+'sheep'.singularize            # => "sheep"
+'word'.singularize             # => "word"
+'the blue mailmen'.singularize # => "the blue mailman"
+'CamelOctopi'.singularize      # => "CamelOctopus"
+'leyes'.singularize(:es)       # => "ley"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 56
+def singularize(locale = :en)
+  ActiveSupport::Inflector.singularize(self, locale)
+end
+
+
+ +
+ +
+

+ + squish() + +

+ + +
+

Returns the string, first removing all whitespace on both ends of the string, and then changing remaining consecutive whitespace groups into one space each.

+ +

Note that it handles both ASCII and Unicode whitespace.

+ +
%{ Multi-line
+   string }.squish                   # => "Multi-line string"
+" foo   bar    \n   \t   boo".squish # => "foo bar boo"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 13
+def squish
+  dup.squish!
+end
+
+
+ +
+ +
+

+ + squish!() + +

+ + +
+

Performs a destructive squish. See String#squish.

+ +
str = " foo   bar    \n   \t   boo"
+str.squish!                         # => "foo bar boo"
+str                                 # => "foo bar boo"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 21
+def squish!
+  gsub!(/[[:space:]]+/, " ")
+  strip!
+  self
+end
+
+
+ +
+ +
+

+ + strip_heredoc() + +

+ + +
+

Strips indentation in heredocs.

+ +

For example in

+ +
if options[:usage]
+  puts <<-USAGE.strip_heredoc
+    This command does such and such.
+
+    Supported options are:
+      -h         This message
+      ...
+  USAGE
+end
+
+ +

the user would see the usage message aligned against the left margin.

+ +

Technically, it looks for the least indented non-empty line in the whole string, and removes that amount of leading whitespace.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/strip.rb, line 22
+def strip_heredoc
+  gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
+end
+
+
+ +
+ +
+

+ + tableize() + +

+ + +
+

Creates the name of a table like Rails does for models to table names. This method uses the pluralize method on the last word in the string.

+ +
'RawScaledScorer'.tableize # => "raw_scaled_scorers"
+'ham_and_egg'.tableize     # => "ham_and_eggs"
+'fancyCategory'.tableize   # => "fancy_categories"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 200
+def tableize
+  ActiveSupport::Inflector.tableize(self)
+end
+
+
+ +
+ +
+

+ + titlecase(keep_id_suffix: false) + +

+ + +
+ +
+ + + + + +
+ Alias for: titleize +
+ + + +
+ +
+

+ + titleize(keep_id_suffix: false) + +

+ + +
+

Capitalizes all the words and replaces some characters in the string to create a nicer looking title. titleize is meant for creating pretty output. It is not used in the Rails internals.

+ +

The trailing '_id','Id'.. can be kept and capitalized by setting the optional parameter keep_id_suffix to true. By default, this parameter is false.

+ +

titleize is also aliased as titlecase.

+ +
'man from the boondocks'.titleize                       # => "Man From The Boondocks"
+'x-men: the last stand'.titleize                        # => "X Men: The Last Stand"
+'string_ending_with_id'.titleize(keep_id_suffix: true)  # => "String Ending With Id"
+
+
+ + + +
+ Also aliased as: titlecase +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 116
+def titleize(keep_id_suffix: false)
+  ActiveSupport::Inflector.titleize(self, keep_id_suffix: keep_id_suffix)
+end
+
+
+ +
+ +
+

+ + to(position) + +

+ + +
+

Returns a substring from the beginning of the string to the given position. If the position is negative, it is counted from the end of the string.

+ +
str = "hello"
+str.to(0)  # => "h"
+str.to(3)  # => "hell"
+str.to(-2) # => "hell"
+
+ +

You can mix it with from method and do fun things like:

+ +
str = "hello"
+str.from(0).to(-1) # => "hello"
+str.from(1).to(-2) # => "ell"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/access.rb, line 63
+def to(position)
+  self[0..position]
+end
+
+
+ +
+ +
+

+ + to_date() + +

+ + +
+

Converts a string to a Date value.

+ +
"1-1-2012".to_date   # => Sun, 01 Jan 2012
+"01/01/2012".to_date # => Sun, 01 Jan 2012
+"2012-12-13".to_date # => Thu, 13 Dec 2012
+"12/13/2012".to_date # => ArgumentError: invalid date
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/conversions.rb, line 46
+def to_date
+  ::Date.parse(self, false) unless blank?
+end
+
+
+ +
+ +
+

+ + to_datetime() + +

+ + +
+

Converts a string to a DateTime value.

+ +
"1-1-2012".to_datetime            # => Sun, 01 Jan 2012 00:00:00 +0000
+"01/01/2012 23:59:59".to_datetime # => Sun, 01 Jan 2012 23:59:59 +0000
+"2012-12-13 12:50".to_datetime    # => Thu, 13 Dec 2012 12:50:00 +0000
+"12/13/2012".to_datetime          # => ArgumentError: invalid date
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/conversions.rb, line 56
+def to_datetime
+  ::DateTime.parse(self, false) unless blank?
+end
+
+
+ +
+ +
+

+ + to_time(form = :local) + +

+ + +
+

Converts a string to a Time value. The form can be either :utc or :local (default :local).

+ +

The time is parsed using Time.parse method. If form is :local, then the time is in the system timezone. If the date part is missing then the current date is used and if the time part is missing then it is assumed to be 00:00:00.

+ +
"13-12-2012".to_time               # => 2012-12-13 00:00:00 +0100
+"06:12".to_time                    # => 2012-12-13 06:12:00 +0100
+"2012-12-13 06:12".to_time         # => 2012-12-13 06:12:00 +0100
+"2012-12-13T06:12".to_time         # => 2012-12-13 06:12:00 +0100
+"2012-12-13T06:12".to_time(:utc)   # => 2012-12-13 06:12:00 UTC
+"12/13/2012".to_time               # => ArgumentError: argument out of range
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/conversions.rb, line 21
+def to_time(form = :local)
+  parts = Date._parse(self, false)
+  used_keys = %i(year mon mday hour min sec sec_fraction offset)
+  return if (parts.keys & used_keys).empty?
+
+  now = Time.now
+  time = Time.new(
+    parts.fetch(:year, now.year),
+    parts.fetch(:mon, now.month),
+    parts.fetch(:mday, now.day),
+    parts.fetch(:hour, 0),
+    parts.fetch(:min, 0),
+    parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
+    parts.fetch(:offset, form == :utc ? 0 : nil)
+  )
+
+  form == :utc ? time.utc : time.to_time
+end
+
+
+ +
+ +
+

+ + truncate(truncate_at, options = {}) + +

+ + +
+

Truncates a given text after a given length if text is longer than length:

+ +
'Once upon a time in a world far far away'.truncate(27)
+# => "Once upon a time in a wo..."
+
+ +

Pass a string or regexp :separator to truncate text at a natural break:

+ +
'Once upon a time in a world far far away'.truncate(27, separator: ' ')
+# => "Once upon a time in a..."
+
+'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
+# => "Once upon a time in a..."
+
+ +

The last characters will be replaced with the :omission string (defaults to “…”) for a total length not exceeding length:

+ +
'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
+# => "And they f... (continued)"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 66
+def truncate(truncate_at, options = {})
+  return dup unless length > truncate_at
+
+  omission = options[:omission] || "..."
+  length_with_room_for_omission = truncate_at - omission.length
+  stop = \
+    if options[:separator]
+      rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
+    else
+      length_with_room_for_omission
+    end
+
+  "#{self[0, stop]}#{omission}"
+end
+
+
+ +
+ +
+

+ + truncate_words(words_count, options = {}) + +

+ + +
+

Truncates a given text after a given number of words (words_count):

+ +
'Once upon a time in a world far far away'.truncate_words(4)
+# => "Once upon a time..."
+
+ +

Pass a string or regexp :separator to specify a different separator of words:

+ +
'Once<br>upon<br>a<br>time<br>in<br>a<br>world'.truncate_words(5, separator: '<br>')
+# => "Once<br>upon<br>a<br>time<br>in..."
+
+ +

The last characters will be replaced with the :omission string (defaults to “…”):

+ +
'And they found that many people were sleeping better.'.truncate_words(5, omission: '... (continued)')
+# => "And they found that many... (continued)"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 95
+def truncate_words(words_count, options = {})
+  sep = options[:separator] || /\s+/
+  sep = Regexp.escape(sep.to_s) unless Regexp === sep
+  if self =~ /\A((?>.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m
+    $1 + (options[:omission] || "...")
+  else
+    dup
+  end
+end
+
+
+ +
+ +
+

+ + underscore() + +

+ + +
+

The reverse of camelize. Makes an underscored, lowercase form from the expression in the string.

+ +

underscore will also change '::' to '/' to convert namespaces to paths.

+ +
'ActiveModel'.underscore         # => "active_model"
+'ActiveModel::Errors'.underscore # => "active_model/errors"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 127
+def underscore
+  ActiveSupport::Inflector.underscore(self)
+end
+
+
+ +
+ +
+

+ + upcase_first() + +

+ + +
+

Converts just the first character to uppercase.

+ +
'what a Lovely Day'.upcase_first # => "What a Lovely Day"
+'w'.upcase_first                 # => "W"
+''.upcase_first                  # => ""
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 240
+def upcase_first
+  ActiveSupport::Inflector.upcase_first(self)
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Symbol.html b/src/5.2/classes/Symbol.html new file mode 100644 index 0000000000..6abfdd8d61 --- /dev/null +++ b/src/5.2/classes/Symbol.html @@ -0,0 +1,113 @@ +--- +title: Symbol +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + duplicable?() + +

+ + +
+

Symbols are not duplicable:

+ +
:my_symbol.duplicable? # => false
+:my_symbol.dup         # => TypeError: can't dup Symbol
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 86
+def duplicable?
+  false
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/Time.html b/src/5.2/classes/Time.html new file mode 100644 index 0000000000..8c56be9690 --- /dev/null +++ b/src/5.2/classes/Time.html @@ -0,0 +1,2434 @@ +--- +title: Time +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
COMMON_YEAR_DAYS_IN_MONTH=[nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
 
DATE_FORMATS={ +db: "%Y-%m-%d %H:%M:%S", +number: "%Y%m%d%H%M%S", +nsec: "%Y%m%d%H%M%S%9N", +usec: "%Y%m%d%H%M%S%6N", +time: "%H:%M", +short: "%d %b %H:%M", +long: "%B %d, %Y %H:%M", +long_ordinal: lambda { |time| +day_format = ActiveSupport::Inflector.ordinalize(time.day) +time.strftime("%B #{day_format}, %Y %H:%M") +}, +rfc822: lambda { |time| +offset_format = time.formatted_offset(false) +time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}") +}, +iso8601: lambda { |time| time.iso8601 } +}
 
+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + zone_default
+ + + + +

Class Public methods

+ +
+

+ + ===(other) + +

+ + +
+

Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 17
+def ===(other)
+  super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
+end
+
+
+ +
+ +
+

+ + at(*args) + +

+ + +
+ +
+ + + +
+ Also aliased as: at_without_coercion +
+ + + +
+ Alias for: at_with_coercion +
+ + + +
+ +
+

+ + at_with_coercion(*args) + +

+ + +
+

Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime instances can be used when called with a single argument

+
+ + + +
+ Also aliased as: at +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 44
+def at_with_coercion(*args)
+  return at_without_coercion(*args) if args.size != 1
+
+  # Time.at can be called with a time or numerical value
+  time_or_number = args.first
+
+  if time_or_number.is_a?(ActiveSupport::TimeWithZone) || time_or_number.is_a?(DateTime)
+    at_without_coercion(time_or_number.to_f).getlocal
+  else
+    at_without_coercion(time_or_number)
+  end
+end
+
+
+ +
+ +
+

+ + at_without_coercion(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: at +
+ + + +
+ +
+

+ + current() + +

+ + +
+

Returns Time.zone.now when Time.zone or config.time_zone are set, otherwise just returns Time.now.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 38
+def current
+  ::Time.zone ? ::Time.zone.now : ::Time.now
+end
+
+
+ +
+ +
+

+ + days_in_month(month, year = current.year) + +

+ + +
+

Returns the number of days in the given month. If no year is specified, it will use the current year.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 23
+def days_in_month(month, year = current.year)
+  if month == 2 && ::Date.gregorian_leap?(year)
+    29
+  else
+    COMMON_YEAR_DAYS_IN_MONTH[month]
+  end
+end
+
+
+ +
+ +
+

+ + days_in_year(year = current.year) + +

+ + +
+

Returns the number of days in the given year. If no year is specified, it will use the current year.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 33
+def days_in_year(year = current.year)
+  days_in_month(2, year) + 337
+end
+
+
+ +
+ +
+

+ + find_zone(time_zone) + +

+ + +
+

Returns a TimeZone instance matching the time zone provided. Accepts the time zone in any format supported by Time.zone=. Returns nil for invalid time zones.

+ +
Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
+Time.find_zone "NOT-A-TIMEZONE"   # => nil
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 109
+def find_zone(time_zone)
+  find_zone!(time_zone) rescue nil
+end
+
+
+ +
+ +
+

+ + find_zone!(time_zone) + +

+ + +
+

Returns a TimeZone instance matching the time zone provided. Accepts the time zone in any format supported by Time.zone=. Raises an ArgumentError for invalid time zones.

+ +
Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
+Time.find_zone! "EST"              # => #<ActiveSupport::TimeZone @name="EST" ...>
+Time.find_zone! -5.hours           # => #<ActiveSupport::TimeZone @name="Bogota" ...>
+Time.find_zone! nil                # => nil
+Time.find_zone! false              # => false
+Time.find_zone! "NOT-A-TIMEZONE"   # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 82
+def find_zone!(time_zone)
+  if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
+    time_zone
+  else
+    # Look up the timezone based on the identifier (unless we've been
+    # passed a TZInfo::Timezone)
+    unless time_zone.respond_to?(:period_for_local)
+      time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
+    end
+
+    # Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone
+    if time_zone.is_a?(ActiveSupport::TimeZone)
+      time_zone
+    else
+      ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
+    end
+  end
+rescue TZInfo::InvalidTimezoneIdentifier
+  raise ArgumentError, "Invalid Timezone: #{time_zone}"
+end
+
+
+ +
+ +
+

+ + rfc3339(str) + +

+ + +
+

Creates a Time instance from an RFC 3339 string.

+ +
Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
+
+ +

If the time or offset components are missing then an ArgumentError will be raised.

+ +
Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 66
+def rfc3339(str)
+  parts = Date._rfc3339(str)
+
+  raise ArgumentError, "invalid date" if parts.empty?
+
+  Time.new(
+    parts.fetch(:year),
+    parts.fetch(:mon),
+    parts.fetch(:mday),
+    parts.fetch(:hour),
+    parts.fetch(:min),
+    parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
+    parts.fetch(:offset)
+  )
+end
+
+
+ +
+ +
+

+ + use_zone(time_zone) + +

+ + +
+

Allows override of Time.zone locally inside supplied block; resets Time.zone to existing value when done.

+ +
class ApplicationController < ActionController::Base
+  around_action :set_time_zone
+
+  private
+
+  def set_time_zone
+    Time.use_zone(current_user.timezone) { yield }
+  end
+end
+
+ +

NOTE: This won't affect any ActiveSupport::TimeWithZone objects that have already been created, e.g. any model timestamp attributes that have been read before the block will remain in the application's default timezone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 62
+def use_zone(time_zone)
+  new_zone = find_zone!(time_zone)
+  begin
+    old_zone, ::Time.zone = ::Time.zone, new_zone
+    yield
+  ensure
+    ::Time.zone = old_zone
+  end
+end
+
+
+ +
+ +
+

+ + zone() + +

+ + +
+

Returns the TimeZone for the current request, if this has been set (via Time.zone=). If Time.zone has not been set for the current request, returns the TimeZone specified in config.time_zone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 14
+def zone
+  Thread.current[:time_zone] || zone_default
+end
+
+
+ +
+ +
+

+ + zone=(time_zone) + +

+ + +
+

Sets Time.zone to a TimeZone object for the current request/thread.

+ +

This method accepts any of the following:

+
  • +

    A Rails TimeZone object.

    +
  • +

    An identifier for a Rails TimeZone object (e.g., “Eastern Time (US & Canada)”, -5.hours).

    +
  • +

    A TZInfo::Timezone object.

    +
  • +

    An identifier for a TZInfo::Timezone object (e.g., “America/New_York”).

    +
+ +

Here's an example of how you might set Time.zone on a per request basis and reset it when the request is done. current_user.time_zone just needs to return a string identifying the user's preferred time zone:

+ +
class ApplicationController < ActionController::Base
+  around_action :set_time_zone
+
+  def set_time_zone
+    if logged_in?
+      Time.use_zone(current_user.time_zone) { yield }
+    else
+      yield
+    end
+  end
+end
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 41
+def zone=(time_zone)
+  Thread.current[:time_zone] = find_zone!(time_zone)
+end
+
+
+ +
+ + + +

Instance Public methods

+ +
+

+ + -(other) + +

+ + +
+ +
+ + + + + + + +
+ Alias for: minus_with_coercion +
+ + + +
+ +
+

+ + <=>(other) + +

+ + +
+ +
+ + + +
+ Also aliased as: compare_without_coercion +
+ + + +
+ Alias for: compare_with_coercion +
+ + + +
+ +
+

+ + acts_like_time?() + +

+ + +
+

Duck-types as a Time-like class. See Object#acts_like?.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/acts_like.rb, line 7
+def acts_like_time?
+  true
+end
+
+
+ +
+ +
+

+ + advance(options) + +

+ + +
+

Uses Date to provide precise Time calculations for years, months, and days according to the proleptic Gregorian calendar. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.

+ +
Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
+Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
+Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1)   # => 2015-08-01 15:35:00 -0700
+Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1)    # => 2015-08-02 14:35:00 -0700
+Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1)   # => 2015-08-08 14:35:00 -0700
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 162
+def advance(options)
+  unless options[:weeks].nil?
+    options[:weeks], partial_weeks = options[:weeks].divmod(1)
+    options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
+  end
+
+  unless options[:days].nil?
+    options[:days], partial_days = options[:days].divmod(1)
+    options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
+  end
+
+  d = to_date.advance(options)
+  d = d.gregorian if d.julian?
+  time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
+  seconds_to_advance = \
+    options.fetch(:seconds, 0) +
+    options.fetch(:minutes, 0) * 60 +
+    options.fetch(:hours, 0) * 3600
+
+  if seconds_to_advance.zero?
+    time_advanced_by_date
+  else
+    time_advanced_by_date.since(seconds_to_advance)
+  end
+end
+
+
+ +
+ +
+

+ + ago(seconds) + +

+ + +
+

Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 189
+def ago(seconds)
+  since(-seconds)
+end
+
+
+ +
+ +
+

+ + at_beginning_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + at_beginning_of_hour() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_hour +
+ + + +
+ +
+

+ + at_beginning_of_minute() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_minute +
+ + + +
+ +
+

+ + at_end_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_day +
+ + + +
+ +
+

+ + at_end_of_hour() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_hour +
+ + + +
+ +
+

+ + at_end_of_minute() + +

+ + +
+ +
+ + + + + +
+ Alias for: end_of_minute +
+ + + +
+ +
+

+ + at_midday() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + at_middle_of_day() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + at_midnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + at_noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + beginning_of_day() + +

+ + +
+

Returns a new Time representing the start of the day (0:00)

+
+ + + +
+ Also aliased as: midnight, at_midnight, at_beginning_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 202
+def beginning_of_day
+  change(hour: 0)
+end
+
+
+ +
+ +
+

+ + beginning_of_hour() + +

+ + +
+

Returns a new Time representing the start of the hour (x:00)

+
+ + + +
+ Also aliased as: at_beginning_of_hour +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 231
+def beginning_of_hour
+  change(min: 0)
+end
+
+
+ +
+ +
+

+ + beginning_of_minute() + +

+ + +
+

Returns a new Time representing the start of the minute (x:xx:00)

+
+ + + +
+ Also aliased as: at_beginning_of_minute +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 247
+def beginning_of_minute
+  change(sec: 0)
+end
+
+
+ +
+ +
+

+ + change(options) + +

+ + +
+

Returns a new Time where one or more of the elements have been changed according to the options parameter. The time options (:hour, :min, :sec, :usec, :nsec) reset cascadingly, so if only the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour and minute is passed, then sec, usec and nsec is set to 0. The options parameter takes a hash with any of these keys: :year, :month, :day, :hour, :min, :sec, :usec, :nsec, :offset. Pass either :usec or :nsec, not both.

+ +
Time.new(2012, 8, 29, 22, 35, 0).change(day: 1)              # => Time.new(2012, 8, 1, 22, 35, 0)
+Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1)  # => Time.new(1981, 8, 1, 22, 35, 0)
+Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 120
+def change(options)
+  new_year   = options.fetch(:year, year)
+  new_month  = options.fetch(:month, month)
+  new_day    = options.fetch(:day, day)
+  new_hour   = options.fetch(:hour, hour)
+  new_min    = options.fetch(:min, options[:hour] ? 0 : min)
+  new_sec    = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
+  new_offset = options.fetch(:offset, nil)
+
+  if new_nsec = options[:nsec]
+    raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
+    new_usec = Rational(new_nsec, 1000)
+  else
+    new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
+  end
+
+  raise ArgumentError, "argument out of range" if new_usec >= 1000000
+
+  new_sec += Rational(new_usec, 1000000)
+
+  if new_offset
+    ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
+  elsif utc?
+    ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
+  elsif zone
+    ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
+  else
+    ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
+  end
+end
+
+
+ +
+ +
+

+ + compare_with_coercion(other) + +

+ + +
+

Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances can be chronologically compared with a Time

+
+ + + +
+ Also aliased as: <=> +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 293
+def compare_with_coercion(other)
+  # we're avoiding Time#to_datetime and Time#to_time because they're expensive
+  if other.class == Time
+    compare_without_coercion(other)
+  elsif other.is_a?(Time)
+    compare_without_coercion(other.to_time)
+  else
+    to_datetime <=> other
+  end
+end
+
+
+ +
+ +
+

+ + compare_without_coercion(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: <=> +
+ + + +
+ +
+

+ + end_of_day() + +

+ + +
+

Returns a new Time representing the end of the day, 23:59:59.999999

+
+ + + +
+ Also aliased as: at_end_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 220
+def end_of_day
+  change(
+    hour: 23,
+    min: 59,
+    sec: 59,
+    usec: Rational(999999999, 1000)
+  )
+end
+
+
+ +
+ +
+

+ + end_of_hour() + +

+ + +
+

Returns a new Time representing the end of the hour, x:59:59.999999

+
+ + + +
+ Also aliased as: at_end_of_hour +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 237
+def end_of_hour
+  change(
+    min: 59,
+    sec: 59,
+    usec: Rational(999999999, 1000)
+  )
+end
+
+
+ +
+ +
+

+ + end_of_minute() + +

+ + +
+

Returns a new Time representing the end of the minute, x:xx:59.999999

+
+ + + +
+ Also aliased as: at_end_of_minute +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 253
+def end_of_minute
+  change(
+    sec: 59,
+    usec: Rational(999999999, 1000)
+  )
+end
+
+
+ +
+ +
+

+ + eql?(other) + +

+ + +
+ +
+ + + +
+ Also aliased as: eql_without_coercion +
+ + + +
+ Alias for: eql_with_coercion +
+ + + +
+ +
+

+ + eql_with_coercion(other) + +

+ + +
+

Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances can be eql? to an equivalent Time

+
+ + + +
+ Also aliased as: eql? +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 308
+def eql_with_coercion(other)
+  # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
+  other = other.comparable_time if other.respond_to?(:comparable_time)
+  eql_without_coercion(other)
+end
+
+
+ +
+ +
+

+ + eql_without_coercion(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: eql? +
+ + + +
+ +
+

+ + formatted_offset(colon = true, alternate_utc_string = nil) + +

+ + +
+

Returns a formatted string of the offset from UTC, or an alternative string if the time zone is already UTC.

+ +
Time.local(2000).formatted_offset        # => "-06:00"
+Time.local(2000).formatted_offset(false) # => "-0600"
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/conversions.rb, line 66
+def formatted_offset(colon = true, alternate_utc_string = nil)
+  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
+end
+
+
+ +
+ +
+

+ + in(seconds) + +

+ + +
+ +
+ + + + + +
+ Alias for: since +
+ + + +
+ +
+

+ + midday() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + middle_of_day() + +

+ + +
+

Returns a new Time representing the middle of the day (12:00)

+
+ + + +
+ Also aliased as: midday, noon, at_midday, at_noon, at_middle_of_day +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 210
+def middle_of_day
+  change(hour: 12)
+end
+
+
+ +
+ +
+

+ + midnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + +
+ +
+

+ + minus_with_coercion(other) + +

+ + +
+

Time#- can also be used to determine the number of seconds between two Time instances. We're layering on additional behavior so that ActiveSupport::TimeWithZone instances are coerced into values that Time#- will recognize

+
+ + + +
+ Also aliased as: - +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 284
+def minus_with_coercion(other)
+  other = other.comparable_time if other.respond_to?(:comparable_time)
+  other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
+end
+
+
+ +
+ +
+

+ + minus_without_coercion(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: - +
+ + + +
+ +
+

+ + minus_without_duration(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: - +
+ + + +
+ +
+

+ + noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + +
+ +
+

+ + sec_fraction() + +

+ + +
+

Returns the fraction of a second as a Rational

+ +
Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 104
+def sec_fraction
+  subsec
+end
+
+
+ +
+ +
+

+ + seconds_since_midnight() + +

+ + +
+

Returns the number of seconds since 00:00:00.

+ +
Time.new(2012, 8, 29,  0,  0,  0).seconds_since_midnight # => 0.0
+Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
+Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 88
+def seconds_since_midnight
+  to_i - change(hour: 0).to_i + (usec / 1.0e+6)
+end
+
+
+ +
+ +
+

+ + seconds_until_end_of_day() + +

+ + +
+

Returns the number of seconds until 23:59:59.

+ +
Time.new(2012, 8, 29,  0,  0,  0).seconds_until_end_of_day # => 86399
+Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
+Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 97
+def seconds_until_end_of_day
+  end_of_day.to_i - to_i
+end
+
+
+ +
+ +
+

+ + since(seconds) + +

+ + +
+

Returns a new Time representing the time a number of seconds since the instance time

+
+ + + +
+ Also aliased as: in +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 194
+def since(seconds)
+  self + seconds
+rescue
+  to_datetime.since(seconds)
+end
+
+
+ +
+ +
+

+ + to_default_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+

Converts to a formatted string. See DATE_FORMATS for built-in formats.

+ +

This method is aliased to to_s.

+ +
time = Time.now                    # => 2007-01-18 06:10:17 -06:00
+
+time.to_formatted_s(:time)         # => "06:10"
+time.to_s(:time)                   # => "06:10"
+
+time.to_formatted_s(:db)           # => "2007-01-18 06:10:17"
+time.to_formatted_s(:number)       # => "20070118061017"
+time.to_formatted_s(:short)        # => "18 Jan 06:10"
+time.to_formatted_s(:long)         # => "January 18, 2007 06:10"
+time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
+time.to_formatted_s(:rfc822)       # => "Thu, 18 Jan 2007 06:10:17 -0600"
+time.to_formatted_s(:iso8601)      # => "2007-01-18T06:10:17-06:00"
+
+ +

Adding your own time formats to to_formatted_s

+ +

You can add your own formats to the Time::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a time argument as the value.

+ +
# config/initializers/time_formats.rb
+Time::DATE_FORMATS[:month_and_year] = '%B %Y'
+Time::DATE_FORMATS[:short_ordinal]  = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
+
+
+ + + +
+ Also aliased as: to_s +
+ + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/conversions.rb, line 51
+def to_formatted_s(format = :default)
+  if formatter = DATE_FORMATS[format]
+    formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+  else
+    to_default_s
+  end
+end
+
+
+ +
+ +
+

+ + to_s(format = :default) + +

+ + +
+ +
+ + + +
+ Also aliased as: to_default_s +
+ + + +
+ Alias for: to_formatted_s +
+ + + +
+ +
+

+ + to_time() + +

+ + +
+

Either return self or the time in the local system timezone depending on the setting of ActiveSupport.to_time_preserves_timezone.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/time/compatibility.rb, line 13
+def to_time
+  preserve_timezone ? self : getlocal
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/TrueClass.html b/src/5.2/classes/TrueClass.html new file mode 100644 index 0000000000..ec3a06298f --- /dev/null +++ b/src/5.2/classes/TrueClass.html @@ -0,0 +1,200 @@ +--- +title: TrueClass +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+

true is not blank:

+ +
true.blank? # => false
+
+ +

@return [false]

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 79
+def blank?
+  false
+end
+
+
+ +
+ +
+

+ + duplicable?() + +

+ + +
+

true is not duplicable:

+ +
true.duplicable? # => false
+true.dup         # => TypeError: can't dup TrueClass
+
+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 70
+def duplicable?
+  false
+end
+
+
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns self.

+
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 27
+def to_param
+  self
+end
+
+
+ +
+ + + + +
+ +
+
diff --git a/src/5.2/classes/URI.html b/src/5.2/classes/URI.html new file mode 100644 index 0000000000..a0056be2ca --- /dev/null +++ b/src/5.2/classes/URI.html @@ -0,0 +1,103 @@ +--- +title: URI +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + parser() + +

+ + +
+ +
+ + + + + + + + +
+ + +
+
# File activesupport/lib/active_support/core_ext/uri.rb, line 20
+def parser
+  @parser ||= URI::Parser.new
+end
+
+
+ +
+ + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/README_md.html b/src/5.2/files/actioncable/README_md.html new file mode 100644 index 0000000000..172176d4bd --- /dev/null +++ b/src/5.2/files/actioncable/README_md.html @@ -0,0 +1,523 @@ +--- +title: README.md +layout: default +--- +
+ + +
+
+ +
+ +

Action Cable – Integrated WebSockets for Rails

+ +

Action Cable seamlessly integrates WebSockets with the rest of your Rails application. It allows for real-time features to be written in Ruby in the same style and form as the rest of your Rails application, while still being performant and scalable. It's a full-stack offering that provides both a client-side JavaScript framework and a server-side Ruby framework. You have access to your full domain model written with Active Record or your ORM of choice.

+ +

Terminology

+ +

A single Action Cable server can handle multiple connection instances. It has one connection instance per WebSocket connection. A single user may have multiple WebSockets open to your application if they use multiple browser tabs or devices. The client of a WebSocket connection is called the consumer.

+ +

Each consumer can in turn subscribe to multiple cable channels. Each channel encapsulates a logical unit of work, similar to what a controller does in a regular MVC setup. For example, you could have a ChatChannel and an AppearancesChannel, and a consumer could be subscribed to either or to both of these channels. At the very least, a consumer should be subscribed to one channel.

+ +

When the consumer is subscribed to a channel, they act as a subscriber. The connection between the subscriber and the channel is, surprise-surprise, called a subscription. A consumer can act as a subscriber to a given channel any number of times. For example, a consumer could subscribe to multiple chat rooms at the same time. (And remember that a physical user may have multiple consumers, one per tab/device open to your connection).

+ +

Each channel can then again be streaming zero or more broadcastings. A broadcasting is a pubsub link where anything transmitted by the broadcaster is sent directly to the channel subscribers who are streaming that named broadcasting.

+ +

As you can see, this is a fairly deep architectural stack. There's a lot of new terminology to identify the new pieces, and on top of that, you're dealing with both client and server side reflections of each unit.

+ +

Examples

+ +

A full-stack example

+ +

The first thing you must do is define your ApplicationCable::Connection class in Ruby. This is the place where you authorize the incoming connection, and proceed to establish it, if all is well. Here's the simplest example starting with the server-side connection class:

+ +
# 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
+
+    private
+      def find_verified_user
+        if verified_user = User.find_by(id: cookies.encrypted[:user_id])
+          verified_user
+        else
+          reject_unauthorized_connection
+        end
+      end
+  end
+end
+
+ +

Here identified_by is a connection identifier that can be used to find the specific connection again or later. Note that anything marked as an identifier will automatically create a delegate by the same name on any channel instances created off the connection.

+ +

This relies on the fact that you will already have handled authentication of the user, and that a successful authentication sets a signed cookie with the user_id. This cookie is then automatically sent to the connection instance when a new connection is attempted, and you use that to set the current_user. By identifying the connection by this same current_user, you're also ensuring that you can later retrieve all open connections by a given user (and potentially disconnect them all if the user is deleted or deauthorized).

+ +

Next, you should define your ApplicationCable::Channel class in Ruby. This is the place where you put shared logic between your channels.

+ +
# app/channels/application_cable/channel.rb
+module ApplicationCable
+  class Channel < ActionCable::Channel::Base
+  end
+end
+
+ +

The client-side needs to setup a consumer instance of this connection. That's done like so:

+ +
// app/assets/javascripts/cable.js
+//= require action_cable
+//= require_self
+//= require_tree ./channels
+
+(function() {
+  this.App || (this.App = {});
+
+  App.cable = ActionCable.createConsumer("ws://cable.example.com");
+}).call(this);
+
+ +

The ws://cable.example.com address must point to your Action Cable server(s), and it must share a cookie namespace with the rest of the application (which may live under example.com). This ensures that the signed cookie will be correctly sent.

+ +

That's all you need to establish the connection! But of course, this isn't very useful in itself. This just gives you the plumbing. To make stuff happen, you need content. That content is defined by declaring channels on the server and allowing the consumer to subscribe to them.

+ +

Channel example 1: User appearances

+ +

Here's a simple example of a channel that tracks whether a user is online or not, and also what page they are currently on. (This is useful for creating presence features like showing a green dot next to a user's name if they're online).

+ +

First you declare the server-side 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
+
+ +

The #subscribed callback is invoked when, as we'll show below, a client-side subscription is initiated. In this case, we take that opportunity to say “the current user has indeed appeared”. That appear/disappear API could be backed by Redis or a database or whatever else. Here's what the client-side of that looks like:

+ +
# app/assets/javascripts/cable/subscriptions/appearance.coffee
+App.cable.subscriptions.create "AppearanceChannel",
+  # Called when the subscription is ready for use on the server
+  connected: ->
+    @install()
+    @appear()
+
+  # Called when the WebSocket connection is closed
+  disconnected: ->
+    @uninstall()
+
+  # Called when the subscription is rejected by the server
+  rejected: ->
+    @uninstall()
+
+  appear: ->
+    # Calls `AppearanceChannel#appear(data)` on the server
+    @perform("appear", appearing_on: $("main").data("appearing-on"))
+
+  away: ->
+    # Calls `AppearanceChannel#away` on the server
+    @perform("away")
+
+
+  buttonSelector = "[data-behavior~=appear_away]"
+
+  install: ->
+    $(document).on "turbolinks:load.appearance", =>
+      @appear()
+
+    $(document).on "click.appearance", buttonSelector, =>
+      @away()
+      false
+
+    $(buttonSelector).show()
+
+  uninstall: ->
+    $(document).off(".appearance")
+    $(buttonSelector).hide()
+
+ +

Simply calling App.cable.subscriptions.create will setup the subscription, which will call AppearanceChannel#subscribed, which in turn is linked to the original App.cable -> ApplicationCable::Connection instances.

+ +

Next, we link the client-side appear method to AppearanceChannel#appear(data). This is possible because the server-side channel instance will automatically expose the public methods declared on the class (minus the callbacks), so that these can be reached as remote procedure calls via a subscription's perform method.

+ +

Channel example 2: Receiving new web notifications

+ +

The appearance example was all about exposing server functionality to client-side invocation over the WebSocket connection. But the great thing about WebSockets is that it's a two-way street. So now let's show an example where the server invokes an action on the client.

+ +

This is a web notification channel that allows you to trigger client-side web notifications when you broadcast to the right streams:

+ +
# app/channels/web_notifications_channel.rb
+class WebNotificationsChannel < ApplicationCable::Channel
+  def subscribed
+    stream_from "web_notifications_#{current_user.id}"
+  end
+end
+
+ +
# Client-side, which assumes you've already requested the right to send web notifications
+App.cable.subscriptions.create "WebNotificationsChannel",
+  received: (data) ->
+    new Notification data["title"], body: data["body"]
+
+ +
# Somewhere in your app this is called, perhaps from a NewCommentJob
+ActionCable.server.broadcast \
+  "web_notifications_#{current_user.id}", { title: 'New things!', body: 'All the news that is fit to print' }
+
+ +

The ActionCable.server.broadcast call places a message in the Action Cable pubsub queue under a separate broadcasting name for each user. For a user with an ID of 1, the broadcasting name would be web_notifications_1. The channel has been instructed to stream everything that arrives at web_notifications_1 directly to the client by invoking the #received(data) callback. The data is the hash sent as the second parameter to the server-side broadcast call, JSON encoded for the trip across the wire, and unpacked for the data argument arriving to #received.

+ +

Passing Parameters to Channel

+ +

You can pass parameters from the client side to the server side when creating a subscription. For example:

+ +
# app/channels/chat_channel.rb
+class ChatChannel < ApplicationCable::Channel
+  def subscribed
+    stream_from "chat_#{params[:room]}"
+  end
+end
+
+ +

If you pass an object as the first argument to subscriptions.create, that object will become the params hash in your cable channel. The keyword channel is required.

+ +
# Client-side, which assumes you've already requested the right to send web notifications
+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>
+    """
+
+ +
# Somewhere in your app this is called, perhaps from a NewCommentJob
+ActionCable.server.broadcast \
+  "chat_#{room}", { sent_by: 'Paul', body: 'This is a cool chat app.' }
+
+ +

Rebroadcasting message

+ +

A common use case is to rebroadcast a message sent by one client to any other connected clients.

+ +
# 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
+
+ +
# Client-side, which assumes you've already requested the right to send web notifications
+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." })
+
+ +

The rebroadcast will be received by all connected clients, including the client that sent the message. Note that params are the same as they were when you subscribed to the channel.

+ +

More complete examples

+ +

See the rails/actioncable-examples repository for a full example of how to setup Action Cable in a Rails app, and how to add channels.

+ +

Configuration

+ +

Action Cable has three required configurations: a subscription adapter, allowed request origins, and the cable server URL (which can optionally be set on the client side).

+ +

Redis

+ +

By default, ActionCable::Server::Base will look for a configuration file in Rails.root.join('config/cable.yml'). This file must specify an adapter and a URL for each Rails environment. It may use the following format:

+ +
production: &production
+  adapter: redis
+  url: redis://10.10.3.153:6381
+development: &development
+  adapter: redis
+  url: redis://localhost:6379
+test: *development
+
+ +

You can also change the location of the Action Cable config file in a Rails initializer with something like:

+ +
Rails.application.paths.add "config/cable", with: "somewhere/else/cable.yml"
+
+ +

Allowed Request Origins

+ +

Action Cable will only accept requests from specific origins.

+ +

By default, only an origin matching the cable server itself will be permitted. Additional origins can be specified using strings or regular expressions, provided in an array.

+ +
Rails.application.config.action_cable.allowed_request_origins = ['http://rubyonrails.com', /http:\/\/ruby.*/]
+
+ +

When running in the development environment, this defaults to “localhost:3000”.

+ +

To disable protection and allow requests from any origin:

+ +
Rails.application.config.action_cable.disable_request_forgery_protection = true
+
+ +

To disable automatic access for same-origin requests, and strictly allow only the configured origins:

+ +
Rails.application.config.action_cable.allow_same_origin_as_host = false
+
+ +

Consumer Configuration

+ +

Once you have decided how to run your cable server (see below), you must provide the server URL (or path) to your client-side setup. There are two ways you can do this.

+ +

The first is to simply pass it in when creating your consumer. For a standalone server, this would be something like: App.cable = ActionCable.createConsumer("ws://example.com:28080"), and for an in-app server, something like: App.cable = ActionCable.createConsumer("/cable").

+ +

The second option is to pass the server URL through the action_cable_meta_tag in your layout. This uses a URL or path typically set via config.action_cable.url in the environment configuration files, or defaults to “/cable”.

+ +

This method is especially useful if your WebSocket URL might change between environments. If you host your production server via https, you will need to use the wss scheme for your Action Cable server, but development might remain http and use the ws scheme. You might use localhost in development and your domain in production.

+ +

In any case, to vary the WebSocket URL between environments, add the following configuration to each environment:

+ +
config.action_cable.url = "ws://example.com:28080"
+
+ +

Then add the following line to your layout before your JavaScript tag:

+ +
<%= action_cable_meta_tag %>
+
+ +

And finally, create your consumer like so:

+ +
App.cable = ActionCable.createConsumer()
+
+ +

Other Configurations

+ +

The other common option to configure is the log tags applied to the per-connection logger. Here's an example that uses the user account id if available, else “no-account” while tagging:

+ +
config.action_cable.log_tags = [
+  -> request { request.env['user_account_id'] || "no-account" },
+  :action_cable,
+  -> request { request.uuid }
+]
+
+ +

For a full list of all configuration options, see the ActionCable::Server::Configuration class.

+ +

Also note that your server must provide at least the same number of database connections as you have workers. The default worker pool is set to 4, so that means you have to make at least that available. You can change that in config/database.yml through the pool attribute.

+ +

Running the cable server

+ +

Standalone

+ +

The cable server(s) is separated from your normal application server. It's still a Rack application, but it is its own Rack application. The recommended basic setup is as follows:

+ +
# cable/config.ru
+require_relative '../config/environment'
+Rails.application.eager_load!
+
+run ActionCable.server
+
+ +

Then you start the server using a binstub in bin/cable ala:

+ +
#!/bin/bash
+bundle exec puma -p 28080 cable/config.ru
+
+ +

The above will start a cable server on port 28080.

+ +

In app

+ +

If you are using a server that supports the Rack socket hijacking API, Action Cable can run alongside your Rails application. For example, to listen for WebSocket requests on /websocket, specify that path to config.action_cable.mount_path:

+ +
# config/application.rb
+class Application < Rails::Application
+  config.action_cable.mount_path = '/websocket'
+end
+
+ +

For every instance of your server you create and for every worker your server spawns, you will also have a new instance of Action Cable, but the use of Redis keeps messages synced across connections.

+ +

Notes

+ +

Beware that currently, the cable server will not auto-reload any changes in the framework. As we've discussed, long-running cable connections mean long-running objects. We don't yet have a way of reloading the classes of those objects in a safe manner. So when you change your channels, or the model your channels use, you must restart the cable server.

+ +

We'll get all this abstracted properly when the framework is integrated into Rails.

+ +

The WebSocket server doesn't have access to the session, but it has access to the cookies. This can be used when you need to handle authentication. You can see one way of doing that with Devise in this article.

+ +

Dependencies

+ +

Action Cable provides a subscription adapter interface to process its pubsub internals. By default, asynchronous, inline, PostgreSQL, and Redis adapters are included. The default adapter in new Rails applications is the asynchronous (async) adapter. To create your own adapter, you can look at ActionCable::SubscriptionAdapter::Base for all methods that must be implemented, and any of the adapters included within Action Cable as example implementations.

+ +

The Ruby side of things is built on top of websocket-driver, nio4r, and concurrent-ruby.

+ +

Deployment

+ +

Action Cable is powered by a combination of WebSockets and threads. All of the connection management is handled internally by utilizing Ruby's native thread support, which means you can use all your regular Rails models with no problems as long as you haven't committed any thread-safety sins.

+ +

The Action Cable server does not need to be a multi-threaded application server. This is because Action Cable uses the Rack socket hijacking API to take over control of connections from the application server. Action Cable then manages connections internally, in a multithreaded manner, regardless of whether the application server is multi-threaded or not. So Action Cable works with all the popular application servers – Unicorn, Puma and Passenger.

+ +

Action Cable does not work with WEBrick, because WEBrick does not support the Rack socket hijacking API.

+ +

Frontend assets

+ +

Action Cable's frontend assets are distributed through two channels: the official gem and npm package, both titled actioncable.

+ +

Gem usage

+ +

Through the actioncable gem, Action Cable's frontend assets are available through the Rails Asset Pipeline. Create a cable.js or cable.coffee file (this is automatically done for you with Rails generators), and then simply require the assets:

+ +

In JavaScript…

+ +
//= require action_cable
+
+ +

… and in CoffeeScript:

+ +
#= require action_cable
+
+ +

npm usage

+ +

In addition to being available through the actioncable gem, Action Cable's frontend JS assets are also bundled in an officially supported npm module, intended for usage in standalone frontend applications that communicate with a Rails application. A common use case for this could be if you have a decoupled frontend application written in React, Ember.js, etc. and want to add real-time WebSocket functionality.

+ +

Installation

+ +
npm install actioncable --save
+
+ +

Usage

+ +

The ActionCable constant is available as a require-able module, so you only have to require the package to gain access to the API that is provided.

+ +

In JavaScript…

+ +
ActionCable = require('actioncable')
+
+var cable = ActionCable.createConsumer('wss://RAILS-API-PATH.com/cable')
+
+cable.subscriptions.create('AppearanceChannel', {
+  // normal channel code goes here...
+});
+
+ +

and in CoffeeScript…

+ +
ActionCable = require('actioncable')
+
+cable = ActionCable.createConsumer('wss://RAILS-API-PATH.com/cable')
+
+cable.subscriptions.create 'AppearanceChannel',
+    # normal channel code goes here...
+
+ +

Download and Installation

+ +

The latest version of Action Cable can be installed with RubyGems, or with npm.

+ +

Source code can be downloaded as part of the Rails project on GitHub

+ + +

License

+ +

Action Cable is released under the MIT license:

+ + +

Support

+ +

API documentation is at:

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/channel/base_rb.html b/src/5.2/files/actioncable/lib/action_cable/channel/base_rb.html new file mode 100644 index 0000000000..faac142193 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/channel/base_rb.html @@ -0,0 +1,87 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/channel/broadcasting_rb.html b/src/5.2/files/actioncable/lib/action_cable/channel/broadcasting_rb.html new file mode 100644 index 0000000000..7f4d7c495e --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/channel/broadcasting_rb.html @@ -0,0 +1,82 @@ +--- +title: broadcasting.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/to_param
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/channel/callbacks_rb.html b/src/5.2/files/actioncable/lib/action_cable/channel/callbacks_rb.html new file mode 100644 index 0000000000..36c2c5a6bc --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/channel/callbacks_rb.html @@ -0,0 +1,82 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/channel/naming_rb.html b/src/5.2/files/actioncable/lib/action_cable/channel/naming_rb.html new file mode 100644 index 0000000000..4567896f52 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/channel/naming_rb.html @@ -0,0 +1,74 @@ +--- +title: naming.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/channel/periodic_timers_rb.html b/src/5.2/files/actioncable/lib/action_cable/channel/periodic_timers_rb.html new file mode 100644 index 0000000000..d076057967 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/channel/periodic_timers_rb.html @@ -0,0 +1,74 @@ +--- +title: periodic_timers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/channel/streams_rb.html b/src/5.2/files/actioncable/lib/action_cable/channel/streams_rb.html new file mode 100644 index 0000000000..86d5ef457d --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/channel/streams_rb.html @@ -0,0 +1,74 @@ +--- +title: streams.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/channel_rb.html b/src/5.2/files/actioncable/lib/action_cable/channel_rb.html new file mode 100644 index 0000000000..7b224a78f4 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/channel_rb.html @@ -0,0 +1,70 @@ +--- +title: channel.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/authorization_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/authorization_rb.html new file mode 100644 index 0000000000..cea6b6fecf --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/authorization_rb.html @@ -0,0 +1,79 @@ +--- +title: authorization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/base_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/base_rb.html new file mode 100644 index 0000000000..d8e680cbc9 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/base_rb.html @@ -0,0 +1,87 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/client_socket_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/client_socket_rb.html new file mode 100644 index 0000000000..bab0185412 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/client_socket_rb.html @@ -0,0 +1,78 @@ +--- +title: client_socket.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • websocket/driver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/identification_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/identification_rb.html new file mode 100644 index 0000000000..1e8816abdf --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/identification_rb.html @@ -0,0 +1,82 @@ +--- +title: identification.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/internal_channel_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/internal_channel_rb.html new file mode 100644 index 0000000000..69e1048798 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/internal_channel_rb.html @@ -0,0 +1,72 @@ +--- +title: internal_channel.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/message_buffer_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/message_buffer_rb.html new file mode 100644 index 0000000000..3a676140da --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/message_buffer_rb.html @@ -0,0 +1,70 @@ +--- +title: message_buffer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/stream_event_loop_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/stream_event_loop_rb.html new file mode 100644 index 0000000000..87c06b5aea --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/stream_event_loop_rb.html @@ -0,0 +1,87 @@ +--- +title: stream_event_loop.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • nio
  • + +
  • thread
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/stream_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/stream_rb.html new file mode 100644 index 0000000000..68ee878612 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/stream_rb.html @@ -0,0 +1,78 @@ +--- +title: stream.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/subscriptions_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/subscriptions_rb.html new file mode 100644 index 0000000000..49815f6911 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/subscriptions_rb.html @@ -0,0 +1,82 @@ +--- +title: subscriptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/tagged_logger_proxy_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/tagged_logger_proxy_rb.html new file mode 100644 index 0000000000..c9169a0c5f --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/tagged_logger_proxy_rb.html @@ -0,0 +1,77 @@ +--- +title: tagged_logger_proxy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection/web_socket_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection/web_socket_rb.html new file mode 100644 index 0000000000..79d9cc2c97 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection/web_socket_rb.html @@ -0,0 +1,78 @@ +--- +title: web_socket.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • websocket/driver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/connection_rb.html b/src/5.2/files/actioncable/lib/action_cable/connection_rb.html new file mode 100644 index 0000000000..4d681f5f9d --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/connection_rb.html @@ -0,0 +1,70 @@ +--- +title: connection.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/engine_rb.html b/src/5.2/files/actioncable/lib/action_cable/engine_rb.html new file mode 100644 index 0000000000..bac47bb41e --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/engine_rb.html @@ -0,0 +1,86 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
  • action_cable
  • + +
  • action_cable/helpers/action_cable_helper
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/gem_version_rb.html b/src/5.2/files/actioncable/lib/action_cable/gem_version_rb.html new file mode 100644 index 0000000000..fc853f4bc1 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/helpers/action_cable_helper_rb.html b/src/5.2/files/actioncable/lib/action_cable/helpers/action_cable_helper_rb.html new file mode 100644 index 0000000000..2d0efa4258 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/helpers/action_cable_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: action_cable_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/remote_connections_rb.html b/src/5.2/files/actioncable/lib/action_cable/remote_connections_rb.html new file mode 100644 index 0000000000..5fd4ed9a75 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/remote_connections_rb.html @@ -0,0 +1,87 @@ +--- +title: remote_connections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/server/base_rb.html b/src/5.2/files/actioncable/lib/action_cable/server/base_rb.html new file mode 100644 index 0000000000..6a38b3d377 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/server/base_rb.html @@ -0,0 +1,87 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/server/broadcasting_rb.html b/src/5.2/files/actioncable/lib/action_cable/server/broadcasting_rb.html new file mode 100644 index 0000000000..6ad6126968 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/server/broadcasting_rb.html @@ -0,0 +1,81 @@ +--- +title: broadcasting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/server/configuration_rb.html b/src/5.2/files/actioncable/lib/action_cable/server/configuration_rb.html new file mode 100644 index 0000000000..1de00410b0 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/server/configuration_rb.html @@ -0,0 +1,79 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/server/connections_rb.html b/src/5.2/files/actioncable/lib/action_cable/server/connections_rb.html new file mode 100644 index 0000000000..c92d73fa3a --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/server/connections_rb.html @@ -0,0 +1,70 @@ +--- +title: connections.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/server/worker/active_record_connection_management_rb.html b/src/5.2/files/actioncable/lib/action_cable/server/worker/active_record_connection_management_rb.html new file mode 100644 index 0000000000..39985f1aff --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/server/worker/active_record_connection_management_rb.html @@ -0,0 +1,81 @@ +--- +title: active_record_connection_management.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/server/worker_rb.html b/src/5.2/files/actioncable/lib/action_cable/server/worker_rb.html new file mode 100644 index 0000000000..88db9f0a83 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/server/worker_rb.html @@ -0,0 +1,89 @@ +--- +title: worker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
  • active_support/core_ext/module/attribute_accessors_per_thread
  • + +
  • concurrent
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/server_rb.html b/src/5.2/files/actioncable/lib/action_cable/server_rb.html new file mode 100644 index 0000000000..e2ed4c5e1a --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/server_rb.html @@ -0,0 +1,70 @@ +--- +title: server.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/async_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/async_rb.html new file mode 100644 index 0000000000..1c11906a05 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/async_rb.html @@ -0,0 +1,87 @@ +--- +title: async.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_cable/subscription_adapter/inline
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/base_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/base_rb.html new file mode 100644 index 0000000000..dece74dbbf --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/base_rb.html @@ -0,0 +1,77 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/channel_prefix_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/channel_prefix_rb.html new file mode 100644 index 0000000000..3f2b6ce64d --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/channel_prefix_rb.html @@ -0,0 +1,70 @@ +--- +title: channel_prefix.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/inline_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/inline_rb.html new file mode 100644 index 0000000000..5758a73586 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/inline_rb.html @@ -0,0 +1,70 @@ +--- +title: inline.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/postgresql_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/postgresql_rb.html new file mode 100644 index 0000000000..5133f970b6 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/postgresql_rb.html @@ -0,0 +1,97 @@ +--- +title: postgresql.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pg
  • + +
  • thread
  • + +
  • digest/sha1
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/redis_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/redis_rb.html new file mode 100644 index 0000000000..7f2d114c4f --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/redis_rb.html @@ -0,0 +1,89 @@ +--- +title: redis.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • redis
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/subscriber_map_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/subscriber_map_rb.html new file mode 100644 index 0000000000..ac657c98a3 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter/subscriber_map_rb.html @@ -0,0 +1,77 @@ +--- +title: subscriber_map.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/subscription_adapter_rb.html b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter_rb.html new file mode 100644 index 0000000000..b3b8b3bf75 --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/subscription_adapter_rb.html @@ -0,0 +1,70 @@ +--- +title: subscription_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actioncable/lib/action_cable/version_rb.html b/src/5.2/files/actioncable/lib/action_cable/version_rb.html new file mode 100644 index 0000000000..d9df29f6cf --- /dev/null +++ b/src/5.2/files/actioncable/lib/action_cable/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/README_rdoc.html b/src/5.2/files/actionmailer/README_rdoc.html new file mode 100644 index 0000000000..bc1b5e28b8 --- /dev/null +++ b/src/5.2/files/actionmailer/README_rdoc.html @@ -0,0 +1,221 @@ +--- +title: README.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Action Mailer – Easy email delivery and testing

+ +

Action Mailer is a framework for designing email service layers. These layers are used to consolidate code for sending out forgotten passwords, welcome wishes on signup, invoices for billing, and any other use case that requires a written notification to either a person or another system.

+ +

Action Mailer is in essence a wrapper around Action Controller and the Mail gem. It provides a way to make emails using templates in the same way that Action Controller renders views using templates.

+ +

Additionally, an Action Mailer class can be used to process incoming email, such as allowing a blog to accept new posts from an email (which could even have been sent from a phone).

+ +

Sending emails

+ +

The framework works by initializing any instance variables you want to be available in the email template, followed by a call to mail to deliver the email.

+ +

This can be as simple as:

+ +
class Notifier < ActionMailer::Base
+  default from: 'system@loudthinking.com'
+
+  def welcome(recipient)
+    @recipient = recipient
+    mail(to: recipient,
+         subject: "[Signed up] Welcome #{recipient}")
+  end
+end
+
+ +

The body of the email is created by using an Action View template (regular ERB) that has the instance variables that are declared in the mailer action.

+ +

So the corresponding body template for the method above could look like this:

+ +
Hello there,
+
+Mr. <%= @recipient %>
+
+Thank you for signing up!
+
+ +

If the recipient was given as “david@loudthinking.com”, the email generated would look like this:

+ +
Date: Mon, 25 Jan 2010 22:48:09 +1100
+From: system@loudthinking.com
+To: david@loudthinking.com
+Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail>
+Subject: [Signed up] Welcome david@loudthinking.com
+Mime-Version: 1.0
+Content-Type: text/plain;
+      charset="US-ASCII";
+Content-Transfer-Encoding: 7bit
+
+Hello there,
+
+Mr. david@loudthinking.com
+
+Thank you for signing up!
+
+ +

In order to send mails, you simply call the method and then call deliver_now on the return value.

+ +

Calling the method returns a Mail Message object:

+ +
message = Notifier.welcome("david@loudthinking.com")   # => Returns a Mail::Message object
+message.deliver_now                                    # => delivers the email
+
+ +

Or you can just chain the methods together like:

+ +
Notifier.welcome("david@loudthinking.com").deliver_now # Creates the email and sends it immediately
+
+ +

Setting defaults

+ +

It is possible to set default values that will be used in every method in your Action Mailer class. To implement this functionality, you just call the public class method default which you get for free from ActionMailer::Base. This method accepts a Hash as the parameter. You can use any of the headers, email messages have, like :from as the key. You can also pass in a string as the key, like “Content-Type”, but Action Mailer does this out of the box for you, so you won't need to worry about that. Finally, it is also possible to pass in a Proc that will get evaluated when it is needed.

+ +

Note that every value you set with this method will get overwritten if you use the same key in your mailer method.

+ +

Example:

+ +
class AuthenticationMailer < ActionMailer::Base
+  default from: "awesome@application.com", subject: Proc.new { "E-mail was generated at #{Time.now}" }
+  .....
+end
+
+ +

Receiving emails

+ +

To receive emails, you need to implement a public instance method called receive that takes an email object as its single parameter. The Action Mailer framework has a corresponding class method, which is also called receive, that accepts a raw, unprocessed email as a string, which it then turns into the email object and calls the receive instance method.

+ +

Example:

+ +
class Mailman < ActionMailer::Base
+  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
+
+ +

This Mailman can be the target for Postfix or other MTAs. In Rails, you would use the runner in the trivial case like this:

+ +
rails runner 'Mailman.receive(STDIN.read)'
+
+ +

However, invoking Rails in the runner for each mail to be received is very resource intensive. A single instance of Rails should be run within a daemon, if it is going to process more than just a limited amount of email.

+ +

Configuration

+ +

The Base class has the full list of configuration options. Here's an example:

+ +
ActionMailer::Base.smtp_settings = {
+  address:        'smtp.yourserver.com', # default: localhost
+  port:           '25',                  # default: 25
+  user_name:      'user',
+  password:       'pass',
+  authentication: :plain                 # :plain, :login or :cram_md5
+}
+
+ +

Download and installation

+ +

The latest version of Action Mailer can be installed with RubyGems:

+ +
$ gem install actionmailer
+
+ +

Source code can be downloaded as part of the Rails project on GitHub:

+ + +

License

+ +

Action Mailer is released under the MIT license:

+ + +

Support

+ +

API documentation is at

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/base_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/base_rb.html new file mode 100644 index 0000000000..1df5e8730b --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/base_rb.html @@ -0,0 +1,101 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mail
  • + +
  • action_mailer/collector
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/module/anonymous
  • + +
  • action_mailer/log_subscriber
  • + +
  • action_mailer/rescuable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/collector_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/collector_rb.html new file mode 100644 index 0000000000..f1e443013a --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/collector_rb.html @@ -0,0 +1,87 @@ +--- +title: collector.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller/collector
  • + +
  • active_support/core_ext/hash/reverse_merge
  • + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/delivery_job_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/delivery_job_rb.html new file mode 100644 index 0000000000..a411a63a48 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/delivery_job_rb.html @@ -0,0 +1,76 @@ +--- +title: delivery_job.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_job
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/delivery_methods_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/delivery_methods_rb.html new file mode 100644 index 0000000000..a61ce85112 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/delivery_methods_rb.html @@ -0,0 +1,80 @@ +--- +title: delivery_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • tmpdir
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/gem_version_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/gem_version_rb.html new file mode 100644 index 0000000000..378efdd7b1 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/inline_preview_interceptor_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/inline_preview_interceptor_rb.html new file mode 100644 index 0000000000..61c1f9d9a1 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/inline_preview_interceptor_rb.html @@ -0,0 +1,83 @@ +--- +title: inline_preview_interceptor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • base64
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/log_subscriber_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/log_subscriber_rb.html new file mode 100644 index 0000000000..319bc83754 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/log_subscriber_rb.html @@ -0,0 +1,83 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/mail_helper_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/mail_helper_rb.html new file mode 100644 index 0000000000..2ae23c25f4 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/mail_helper_rb.html @@ -0,0 +1,70 @@ +--- +title: mail_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/message_delivery_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/message_delivery_rb.html new file mode 100644 index 0000000000..67af15f68b --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/message_delivery_rb.html @@ -0,0 +1,83 @@ +--- +title: message_delivery.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delegate
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/parameterized_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/parameterized_rb.html new file mode 100644 index 0000000000..7f7223a368 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/parameterized_rb.html @@ -0,0 +1,72 @@ +--- +title: parameterized.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/preview_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/preview_rb.html new file mode 100644 index 0000000000..76d2757e91 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/preview_rb.html @@ -0,0 +1,87 @@ +--- +title: preview.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/descendants_tracker
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/railtie_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/railtie_rb.html new file mode 100644 index 0000000000..1917304791 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/railtie_rb.html @@ -0,0 +1,84 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_job/railtie
  • + +
  • action_mailer
  • + +
  • rails
  • + +
  • abstract_controller/railties/routes_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/rescuable_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/rescuable_rb.html new file mode 100644 index 0000000000..df308d6db8 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/rescuable_rb.html @@ -0,0 +1,70 @@ +--- +title: rescuable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/test_case_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/test_case_rb.html new file mode 100644 index 0000000000..84ec4689b6 --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/test_case_rb.html @@ -0,0 +1,93 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/test_case
  • + +
  • rails-dom-testing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/test_helper_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/test_helper_rb.html new file mode 100644 index 0000000000..c0030cef1d --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/test_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_job
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionmailer/lib/action_mailer/version_rb.html b/src/5.2/files/actionmailer/lib/action_mailer/version_rb.html new file mode 100644 index 0000000000..1fd2feae6d --- /dev/null +++ b/src/5.2/files/actionmailer/lib/action_mailer/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/README_rdoc.html b/src/5.2/files/actionpack/README_rdoc.html new file mode 100644 index 0000000000..ac2c337db1 --- /dev/null +++ b/src/5.2/files/actionpack/README_rdoc.html @@ -0,0 +1,108 @@ +--- +title: README.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Action Pack – From request to response

+ +

Action Pack is a framework for handling and responding to web requests. It provides mechanisms for routing (mapping request URLs to actions), defining controllers that implement actions, and generating responses by rendering views, which are templates of various formats. In short, Action Pack provides the view and controller layers in the MVC paradigm.

+ +

It consists of several modules:

+
  • +

    Action Dispatch, which parses information about the web request, handles routing as defined by the user, and does advanced processing related to HTTP such as MIME-type negotiation, decoding parameters in POST, PATCH, or PUT bodies, handling HTTP caching logic, cookies and sessions.

    +
  • +

    Action Controller, which provides a base controller class that can be subclassed to implement filters and actions to handle requests. The result of an action is typically content generated from views.

    +
+ +

With the Ruby on Rails framework, users only directly interface with the Action Controller module. Necessary Action Dispatch functionality is activated by default and Action View rendering is implicitly triggered by Action Controller. However, these modules are designed to function on their own and can be used outside of Rails.

+ +

Download and installation

+ +

The latest version of Action Pack can be installed with RubyGems:

+ +
$ gem install actionpack
+
+ +

Source code can be downloaded as part of the Rails project on GitHub:

+ + +

License

+ +

Action Pack is released under the MIT license:

+ + +

Support

+ +

API documentation is at:

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/asset_paths_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/asset_paths_rb.html new file mode 100644 index 0000000000..dcaffa06b1 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/asset_paths_rb.html @@ -0,0 +1,68 @@ +--- +title: asset_paths.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/base_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/base_rb.html new file mode 100644 index 0000000000..ffca053987 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/base_rb.html @@ -0,0 +1,93 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller/error
  • + +
  • active_support/configurable
  • + +
  • active_support/descendants_tracker
  • + +
  • active_support/core_ext/module/anonymous
  • + +
  • active_support/core_ext/module/attr_internal
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/caching/fragments_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/caching/fragments_rb.html new file mode 100644 index 0000000000..2388623838 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/caching/fragments_rb.html @@ -0,0 +1,76 @@ +--- +title: fragments.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/caching_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/caching_rb.html new file mode 100644 index 0000000000..909edbf09b --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/caching_rb.html @@ -0,0 +1,76 @@ +--- +title: caching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/callbacks_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/callbacks_rb.html new file mode 100644 index 0000000000..72e94f1c65 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/callbacks_rb.html @@ -0,0 +1,72 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/collector_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/collector_rb.html new file mode 100644 index 0000000000..3759724556 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/collector_rb.html @@ -0,0 +1,80 @@ +--- +title: collector.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/mime_type
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/error_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/error_rb.html new file mode 100644 index 0000000000..d7f1364523 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/error_rb.html @@ -0,0 +1,68 @@ +--- +title: error.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/helpers_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/helpers_rb.html new file mode 100644 index 0000000000..da9ff454fb --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/helpers_rb.html @@ -0,0 +1,87 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/dependencies
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/logger_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/logger_rb.html new file mode 100644 index 0000000000..a3c77b0e41 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/logger_rb.html @@ -0,0 +1,76 @@ +--- +title: logger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/benchmarkable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/railties/routes_helpers_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/railties/routes_helpers_rb.html new file mode 100644 index 0000000000..3aacb20b04 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/railties/routes_helpers_rb.html @@ -0,0 +1,72 @@ +--- +title: routes_helpers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/rendering_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/rendering_rb.html new file mode 100644 index 0000000000..77f17ac556 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/rendering_rb.html @@ -0,0 +1,91 @@ +--- +title: rendering.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller/error
  • + +
  • action_view
  • + +
  • action_view/view_paths
  • + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/translation_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/translation_rb.html new file mode 100644 index 0000000000..1c75f96454 --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/translation_rb.html @@ -0,0 +1,70 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/abstract_controller/url_for_rb.html b/src/5.2/files/actionpack/lib/abstract_controller/url_for_rb.html new file mode 100644 index 0000000000..780245d78c --- /dev/null +++ b/src/5.2/files/actionpack/lib/abstract_controller/url_for_rb.html @@ -0,0 +1,72 @@ +--- +title: url_for.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/api/api_rendering_rb.html b/src/5.2/files/actionpack/lib/action_controller/api/api_rendering_rb.html new file mode 100644 index 0000000000..b38f697c97 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/api/api_rendering_rb.html @@ -0,0 +1,70 @@ +--- +title: api_rendering.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/api_rb.html b/src/5.2/files/actionpack/lib/action_controller/api_rb.html new file mode 100644 index 0000000000..c788292033 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/api_rb.html @@ -0,0 +1,87 @@ +--- +title: api.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view
  • + +
  • action_controller
  • + +
  • action_controller/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/base_rb.html b/src/5.2/files/actionpack/lib/action_controller/base_rb.html new file mode 100644 index 0000000000..4c897151bf --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/base_rb.html @@ -0,0 +1,89 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view
  • + +
  • action_controller/log_subscriber
  • + +
  • action_controller/metal/params_wrapper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/caching_rb.html b/src/5.2/files/actionpack/lib/action_controller/caching_rb.html new file mode 100644 index 0000000000..184cc60619 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/caching_rb.html @@ -0,0 +1,70 @@ +--- +title: caching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/form_builder_rb.html b/src/5.2/files/actionpack/lib/action_controller/form_builder_rb.html new file mode 100644 index 0000000000..c84f35cfef --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/form_builder_rb.html @@ -0,0 +1,72 @@ +--- +title: form_builder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/log_subscriber_rb.html b/src/5.2/files/actionpack/lib/action_controller/log_subscriber_rb.html new file mode 100644 index 0000000000..f660767802 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/log_subscriber_rb.html @@ -0,0 +1,77 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/basic_implicit_render_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/basic_implicit_render_rb.html new file mode 100644 index 0000000000..54b64169e8 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/basic_implicit_render_rb.html @@ -0,0 +1,68 @@ +--- +title: basic_implicit_render.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/conditional_get_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/conditional_get_rb.html new file mode 100644 index 0000000000..5bafa0814c --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/conditional_get_rb.html @@ -0,0 +1,80 @@ +--- +title: conditional_get.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/content_security_policy_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/content_security_policy_rb.html new file mode 100644 index 0000000000..31c5f45e41 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/content_security_policy_rb.html @@ -0,0 +1,74 @@ +--- +title: content_security_policy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/cookies_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/cookies_rb.html new file mode 100644 index 0000000000..094d14ccd5 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/cookies_rb.html @@ -0,0 +1,70 @@ +--- +title: cookies.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/data_streaming_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/data_streaming_rb.html new file mode 100644 index 0000000000..167e580a7d --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/data_streaming_rb.html @@ -0,0 +1,80 @@ +--- +title: data_streaming.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_controller/metal/exceptions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/etag_with_flash_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/etag_with_flash_rb.html new file mode 100644 index 0000000000..4085daf65e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/etag_with_flash_rb.html @@ -0,0 +1,70 @@ +--- +title: etag_with_flash.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/etag_with_template_digest_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/etag_with_template_digest_rb.html new file mode 100644 index 0000000000..ad35ecbdc5 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/etag_with_template_digest_rb.html @@ -0,0 +1,72 @@ +--- +title: etag_with_template_digest.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/exceptions_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/exceptions_rb.html new file mode 100644 index 0000000000..61c14a89b6 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/exceptions_rb.html @@ -0,0 +1,68 @@ +--- +title: exceptions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/flash_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/flash_rb.html new file mode 100644 index 0000000000..8f9669be91 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/flash_rb.html @@ -0,0 +1,72 @@ +--- +title: flash.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/force_ssl_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/force_ssl_rb.html new file mode 100644 index 0000000000..9b9d181828 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/force_ssl_rb.html @@ -0,0 +1,84 @@ +--- +title: force_ssl.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/hash/slice
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/head_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/head_rb.html new file mode 100644 index 0000000000..2a1f570b62 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/head_rb.html @@ -0,0 +1,70 @@ +--- +title: head.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/helpers_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/helpers_rb.html new file mode 100644 index 0000000000..a4667e808c --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/helpers_rb.html @@ -0,0 +1,74 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/http_authentication_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/http_authentication_rb.html new file mode 100644 index 0000000000..0f506947b4 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/http_authentication_rb.html @@ -0,0 +1,96 @@ +--- +title: http_authentication.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/implicit_render_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/implicit_render_rb.html new file mode 100644 index 0000000000..f46820e3b6 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/implicit_render_rb.html @@ -0,0 +1,70 @@ +--- +title: implicit_render.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/instrumentation_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/instrumentation_rb.html new file mode 100644 index 0000000000..9513ae447d --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/instrumentation_rb.html @@ -0,0 +1,84 @@ +--- +title: instrumentation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • benchmark
  • + +
  • abstract_controller/logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/live_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/live_rb.html new file mode 100644 index 0000000000..74e59e0efa --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/live_rb.html @@ -0,0 +1,97 @@ +--- +title: live.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/response
  • + +
  • delegate
  • + +
  • active_support/json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/mime_responds_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/mime_responds_rb.html new file mode 100644 index 0000000000..e59b5003c4 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/mime_responds_rb.html @@ -0,0 +1,87 @@ +--- +title: mime_responds.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller/collector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/parameter_encoding_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/parameter_encoding_rb.html new file mode 100644 index 0000000000..665f85423f --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/parameter_encoding_rb.html @@ -0,0 +1,72 @@ +--- +title: parameter_encoding.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/params_wrapper_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/params_wrapper_rb.html new file mode 100644 index 0000000000..62b50e6f4f --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/params_wrapper_rb.html @@ -0,0 +1,95 @@ +--- +title: params_wrapper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/module/anonymous
  • + +
  • action_dispatch/http/mime_type
  • + +
  • mutex_m
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/redirecting_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/redirecting_rb.html new file mode 100644 index 0000000000..3cd384d53c --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/redirecting_rb.html @@ -0,0 +1,72 @@ +--- +title: redirecting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/renderers_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/renderers_rb.html new file mode 100644 index 0000000000..9bc48f0018 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/renderers_rb.html @@ -0,0 +1,89 @@ +--- +title: renderers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/rendering_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/rendering_rb.html new file mode 100644 index 0000000000..001526cfa9 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/rendering_rb.html @@ -0,0 +1,74 @@ +--- +title: rendering.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/request_forgery_protection_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/request_forgery_protection_rb.html new file mode 100644 index 0000000000..8f5f2daf49 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/request_forgery_protection_rb.html @@ -0,0 +1,103 @@ +--- +title: request_forgery_protection.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/session/abstract/id
  • + +
  • action_controller/metal/exceptions
  • + +
  • active_support/security_utils
  • + +
  • active_support/core_ext/string/strip
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/rescue_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/rescue_rb.html new file mode 100644 index 0000000000..62c51d1825 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/rescue_rb.html @@ -0,0 +1,70 @@ +--- +title: rescue.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/streaming_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/streaming_rb.html new file mode 100644 index 0000000000..503255aa1e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/streaming_rb.html @@ -0,0 +1,78 @@ +--- +title: streaming.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/chunked
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/strong_parameters_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/strong_parameters_rb.html new file mode 100644 index 0000000000..4d7ae3536b --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/strong_parameters_rb.html @@ -0,0 +1,113 @@ +--- +title: strong_parameters.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • active_support/core_ext/hash/transform_values
  • + +
  • active_support/core_ext/array/wrap
  • + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/rescuable
  • + +
  • action_dispatch/http/upload
  • + +
  • rack/test
  • + +
  • stringio
  • + +
  • set
  • + +
  • yaml
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/testing_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/testing_rb.html new file mode 100644 index 0000000000..c2b2cfa1a3 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/testing_rb.html @@ -0,0 +1,70 @@ +--- +title: testing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal/url_for_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal/url_for_rb.html new file mode 100644 index 0000000000..11f5949e8b --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal/url_for_rb.html @@ -0,0 +1,70 @@ +--- +title: url_for.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/metal_rb.html b/src/5.2/files/actionpack/lib/action_controller/metal_rb.html new file mode 100644 index 0000000000..438b526d82 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/metal_rb.html @@ -0,0 +1,91 @@ +--- +title: metal.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • action_dispatch/middleware/stack
  • + +
  • action_dispatch/http/request
  • + +
  • action_dispatch/http/response
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/railtie_rb.html b/src/5.2/files/actionpack/lib/action_controller/railtie_rb.html new file mode 100644 index 0000000000..5db05a6fb2 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/railtie_rb.html @@ -0,0 +1,88 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
  • action_controller
  • + +
  • action_dispatch/railtie
  • + +
  • abstract_controller/railties/routes_helpers
  • + +
  • action_controller/railties/helpers
  • + +
  • action_view/railtie
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/railties/helpers_rb.html b/src/5.2/files/actionpack/lib/action_controller/railties/helpers_rb.html new file mode 100644 index 0000000000..4cf5a917ab --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/railties/helpers_rb.html @@ -0,0 +1,72 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/renderer_rb.html b/src/5.2/files/actionpack/lib/action_controller/renderer_rb.html new file mode 100644 index 0000000000..79e2ace13e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/renderer_rb.html @@ -0,0 +1,85 @@ +--- +title: renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/template_assertions_rb.html b/src/5.2/files/actionpack/lib/action_controller/template_assertions_rb.html new file mode 100644 index 0000000000..32c0672d3c --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/template_assertions_rb.html @@ -0,0 +1,70 @@ +--- +title: template_assertions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_controller/test_case_rb.html b/src/5.2/files/actionpack/lib/action_controller/test_case_rb.html new file mode 100644 index 0000000000..01e904fdce --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_controller/test_case_rb.html @@ -0,0 +1,113 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/session/abstract/id
  • + +
  • active_support/core_ext/hash/conversions
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/core_ext/module/anonymous
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/testing/constant_lookup
  • + +
  • action_controller/template_assertions
  • + +
  • rails-dom-testing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/cache_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/cache_rb.html new file mode 100644 index 0000000000..ee807ccc3a --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/cache_rb.html @@ -0,0 +1,76 @@ +--- +title: cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/content_security_policy_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/content_security_policy_rb.html new file mode 100644 index 0000000000..6add963515 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/content_security_policy_rb.html @@ -0,0 +1,87 @@ +--- +title: content_security_policy.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/deep_dup
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/filter_parameters_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/filter_parameters_rb.html new file mode 100644 index 0000000000..43227d3f25 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/filter_parameters_rb.html @@ -0,0 +1,80 @@ +--- +title: filter_parameters.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/parameter_filter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/filter_redirect_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/filter_redirect_rb.html new file mode 100644 index 0000000000..f92721e0ea --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/filter_redirect_rb.html @@ -0,0 +1,72 @@ +--- +title: filter_redirect.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/headers_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/headers_rb.html new file mode 100644 index 0000000000..2a164f5b2f --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/headers_rb.html @@ -0,0 +1,77 @@ +--- +title: headers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/mime_negotiation_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/mime_negotiation_rb.html new file mode 100644 index 0000000000..144ad11128 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/mime_negotiation_rb.html @@ -0,0 +1,84 @@ +--- +title: mime_negotiation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/mime_type_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/mime_type_rb.html new file mode 100644 index 0000000000..f020e2b9e1 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/mime_type_rb.html @@ -0,0 +1,93 @@ +--- +title: mime_type.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • singleton
  • + +
  • active_support/core_ext/string/starts_ends_with
  • + +
  • action_dispatch/http/mime_types
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/mime_types_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/mime_types_rb.html new file mode 100644 index 0000000000..f9c05bb33e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/mime_types_rb.html @@ -0,0 +1,74 @@ +--- +title: mime_types.rb +layout: default +--- +
+ + +
+
+ +
+ +

Build list of Mime types for HTTP responses www.iana.org/assignments/media-types/

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/parameter_filter_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/parameter_filter_rb.html new file mode 100644 index 0000000000..51e8a4277a --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/parameter_filter_rb.html @@ -0,0 +1,85 @@ +--- +title: parameter_filter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/duplicable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/parameters_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/parameters_rb.html new file mode 100644 index 0000000000..d6f75a3c0b --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/parameters_rb.html @@ -0,0 +1,85 @@ +--- +title: parameters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/rack_cache_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/rack_cache_rb.html new file mode 100644 index 0000000000..3f73b61d07 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/rack_cache_rb.html @@ -0,0 +1,101 @@ +--- +title: rack_cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/cache
  • + +
  • rack/cache/context
  • + +
  • active_support/cache
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/request_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/request_rb.html new file mode 100644 index 0000000000..0fdee14f17 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/request_rb.html @@ -0,0 +1,111 @@ +--- +title: request.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • stringio
  • + +
  • active_support/inflector
  • + +
  • action_dispatch/http/headers
  • + +
  • action_controller/metal/exceptions
  • + +
  • rack/request
  • + +
  • action_dispatch/http/cache
  • + +
  • action_dispatch/http/mime_negotiation
  • + +
  • action_dispatch/http/parameters
  • + +
  • action_dispatch/http/filter_parameters
  • + +
  • action_dispatch/http/upload
  • + +
  • action_dispatch/http/url
  • + +
  • active_support/core_ext/array/conversions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/response_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/response_rb.html new file mode 100644 index 0000000000..7d4ec4d6ff --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/response_rb.html @@ -0,0 +1,91 @@ +--- +title: response.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • action_dispatch/http/filter_redirect
  • + +
  • action_dispatch/http/cache
  • + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/upload_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/upload_rb.html new file mode 100644 index 0000000000..0c038cc4d4 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/upload_rb.html @@ -0,0 +1,77 @@ +--- +title: upload.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/http/url_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/http/url_rb.html new file mode 100644 index 0000000000..1d938a1301 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/http/url_rb.html @@ -0,0 +1,80 @@ +--- +title: url.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/formatter_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/formatter_rb.html new file mode 100644 index 0000000000..dd49e69842 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/formatter_rb.html @@ -0,0 +1,89 @@ +--- +title: formatter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_controller/metal/exceptions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/builder_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/builder_rb.html new file mode 100644 index 0000000000..f7f72fc08a --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/builder_rb.html @@ -0,0 +1,78 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/gtg/transition_table
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/simulator_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/simulator_rb.html new file mode 100644 index 0000000000..7398743ec1 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/simulator_rb.html @@ -0,0 +1,78 @@ +--- +title: simulator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/transition_table_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/transition_table_rb.html new file mode 100644 index 0000000000..8243b99379 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/gtg/transition_table_rb.html @@ -0,0 +1,80 @@ +--- +title: transition_table.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/nfa/dot
  • + +
  • erb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/builder_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/builder_rb.html new file mode 100644 index 0000000000..08a2bfbde6 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/builder_rb.html @@ -0,0 +1,80 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/nfa/transition_table
  • + +
  • action_dispatch/journey/gtg/transition_table
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/dot_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/dot_rb.html new file mode 100644 index 0000000000..fda4e9274f --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/dot_rb.html @@ -0,0 +1,70 @@ +--- +title: dot.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/simulator_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/simulator_rb.html new file mode 100644 index 0000000000..b70a90fe80 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/simulator_rb.html @@ -0,0 +1,78 @@ +--- +title: simulator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/transition_table_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/transition_table_rb.html new file mode 100644 index 0000000000..aa0d583dae --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/nfa/transition_table_rb.html @@ -0,0 +1,78 @@ +--- +title: transition_table.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/nfa/dot
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/nodes/node_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/nodes/node_rb.html new file mode 100644 index 0000000000..eebb467bd7 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/nodes/node_rb.html @@ -0,0 +1,78 @@ +--- +title: node.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/visitors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html new file mode 100644 index 0000000000..c8580dfc53 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html @@ -0,0 +1,87 @@ +--- +title: parser_extras.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/scanner
  • + +
  • action_dispatch/journey/nodes/node
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/parser_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/parser_rb.html new file mode 100644 index 0000000000..6f64472859 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/parser_rb.html @@ -0,0 +1,91 @@ +--- +title: parser.rb +layout: default +--- +
+ + +
+
+ +
+ +

DO NOT MODIFY!!!! This file is automatically generated by Racc 1.4.14 from Racc grammar file “”.

+ +
+ + + + +

Required Files

+
    + +
  • racc/parser.rb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/path/pattern_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/path/pattern_rb.html new file mode 100644 index 0000000000..937bb7f328 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/path/pattern_rb.html @@ -0,0 +1,70 @@ +--- +title: pattern.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/route_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/route_rb.html new file mode 100644 index 0000000000..bfa89231b8 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/route_rb.html @@ -0,0 +1,83 @@ +--- +title: route.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/router/utils_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/router/utils_rb.html new file mode 100644 index 0000000000..ec04d2a928 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/router/utils_rb.html @@ -0,0 +1,70 @@ +--- +title: utils.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/router_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/router_rb.html new file mode 100644 index 0000000000..bbf7b0f220 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/router_rb.html @@ -0,0 +1,88 @@ +--- +title: router.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/router/utils
  • + +
  • action_dispatch/journey/routes
  • + +
  • action_dispatch/journey/formatter
  • + +
  • action_dispatch/journey/parser
  • + +
  • action_dispatch/journey/route
  • + +
  • action_dispatch/journey/path/pattern
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/routes_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/routes_rb.html new file mode 100644 index 0000000000..44fa6b841f --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/routes_rb.html @@ -0,0 +1,70 @@ +--- +title: routes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/scanner_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/scanner_rb.html new file mode 100644 index 0000000000..f4a5d63c0d --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/scanner_rb.html @@ -0,0 +1,78 @@ +--- +title: scanner.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey/visitors_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey/visitors_rb.html new file mode 100644 index 0000000000..528eef0101 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey/visitors_rb.html @@ -0,0 +1,77 @@ +--- +title: visitors.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/journey_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/journey_rb.html new file mode 100644 index 0000000000..436112a4c7 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/journey_rb.html @@ -0,0 +1,71 @@ +--- +title: journey.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/router
  • + +
  • action_dispatch/journey/gtg/builder
  • + +
  • action_dispatch/journey/gtg/simulator
  • + +
  • action_dispatch/journey/nfa/builder
  • + +
  • action_dispatch/journey/nfa/simulator
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/callbacks_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/callbacks_rb.html new file mode 100644 index 0000000000..2353eeafe9 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/callbacks_rb.html @@ -0,0 +1,75 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/cookies_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/cookies_rb.html new file mode 100644 index 0000000000..16b7bb6d4c --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/cookies_rb.html @@ -0,0 +1,97 @@ +--- +title: cookies.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/key_generator
  • + +
  • active_support/message_verifier
  • + +
  • active_support/json
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_exceptions_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_exceptions_rb.html new file mode 100644 index 0000000000..c00f775997 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_exceptions_rb.html @@ -0,0 +1,101 @@ +--- +title: debug_exceptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/request
  • + +
  • action_dispatch/middleware/exception_wrapper
  • + +
  • action_dispatch/routing/inspector
  • + +
  • action_view
  • + +
  • action_view/base
  • + +
  • pp
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_locks_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_locks_rb.html new file mode 100644 index 0000000000..770114090e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/debug_locks_rb.html @@ -0,0 +1,77 @@ +--- +title: debug_locks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/exception_wrapper_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/exception_wrapper_rb.html new file mode 100644 index 0000000000..368c928829 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/exception_wrapper_rb.html @@ -0,0 +1,85 @@ +--- +title: exception_wrapper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/executor_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/executor_rb.html new file mode 100644 index 0000000000..ef276a6a4d --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/executor_rb.html @@ -0,0 +1,83 @@ +--- +title: executor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/body_proxy
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/flash_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/flash_rb.html new file mode 100644 index 0000000000..73283efffa --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/flash_rb.html @@ -0,0 +1,89 @@ +--- +title: flash.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/public_exceptions_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/public_exceptions_rb.html new file mode 100644 index 0000000000..e922324885 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/public_exceptions_rb.html @@ -0,0 +1,75 @@ +--- +title: public_exceptions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/reloader_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/reloader_rb.html new file mode 100644 index 0000000000..b1aba30c3e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/reloader_rb.html @@ -0,0 +1,75 @@ +--- +title: reloader.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html new file mode 100644 index 0000000000..f1bc8e91ee --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html @@ -0,0 +1,87 @@ +--- +title: remote_ip.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • ipaddr
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/request_id_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/request_id_rb.html new file mode 100644 index 0000000000..6ddb6ebfd2 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/request_id_rb.html @@ -0,0 +1,85 @@ +--- +title: request_id.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
  • active_support/core_ext/string/access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/abstract_store_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/abstract_store_rb.html new file mode 100644 index 0000000000..d5168fdbe6 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/abstract_store_rb.html @@ -0,0 +1,101 @@ +--- +title: abstract_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/utils
  • + +
  • rack/request
  • + +
  • rack/session/abstract/id
  • + +
  • action_dispatch/middleware/cookies
  • + +
  • action_dispatch/request/session
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cache_store_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cache_store_rb.html new file mode 100644 index 0000000000..d3dff6248e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cache_store_rb.html @@ -0,0 +1,85 @@ +--- +title: cache_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/middleware/session/abstract_store
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cookie_store_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cookie_store_rb.html new file mode 100644 index 0000000000..dd39735159 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/cookie_store_rb.html @@ -0,0 +1,91 @@ +--- +title: cookie_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
  • action_dispatch/middleware/session/abstract_store
  • + +
  • rack/session/cookie
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/mem_cache_store_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/mem_cache_store_rb.html new file mode 100644 index 0000000000..38caa2ed34 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/session/mem_cache_store_rb.html @@ -0,0 +1,87 @@ +--- +title: mem_cache_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/middleware/session/abstract_store
  • + +
  • rack/session/dalli
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/show_exceptions_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/show_exceptions_rb.html new file mode 100644 index 0000000000..997e5ce2e4 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/show_exceptions_rb.html @@ -0,0 +1,85 @@ +--- +title: show_exceptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/request
  • + +
  • action_dispatch/middleware/exception_wrapper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/ssl_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/ssl_rb.html new file mode 100644 index 0000000000..8897893562 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/ssl_rb.html @@ -0,0 +1,75 @@ +--- +title: ssl.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/stack_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/stack_rb.html new file mode 100644 index 0000000000..b0bf492775 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/stack_rb.html @@ -0,0 +1,87 @@ +--- +title: stack.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
  • active_support/dependencies
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/middleware/static_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/middleware/static_rb.html new file mode 100644 index 0000000000..b213d7e18a --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/middleware/static_rb.html @@ -0,0 +1,89 @@ +--- +title: static.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/utils
  • + +
  • active_support/core_ext/uri
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/railtie_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/railtie_rb.html new file mode 100644 index 0000000000..8cd4b8d68b --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/railtie_rb.html @@ -0,0 +1,91 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch
  • + +
  • active_support/messages/rotation_configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/request/session_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/request/session_rb.html new file mode 100644 index 0000000000..9fa9b52dc9 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/request/session_rb.html @@ -0,0 +1,83 @@ +--- +title: session.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/session/abstract/id
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/request/utils_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/request/utils_rb.html new file mode 100644 index 0000000000..0737213a60 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/request/utils_rb.html @@ -0,0 +1,85 @@ +--- +title: utils.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/endpoint_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/endpoint_rb.html new file mode 100644 index 0000000000..4ac69a677e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/endpoint_rb.html @@ -0,0 +1,72 @@ +--- +title: endpoint.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/inspector_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/inspector_rb.html new file mode 100644 index 0000000000..f9af695e65 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/inspector_rb.html @@ -0,0 +1,91 @@ +--- +title: inspector.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delegate
  • + +
  • active_support/core_ext/string/strip
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/mapper_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/mapper_rb.html new file mode 100644 index 0000000000..ab05cbecf9 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/mapper_rb.html @@ -0,0 +1,113 @@ +--- +title: mapper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/regexp
  • + +
  • action_dispatch/routing/redirection
  • + +
  • action_dispatch/routing/endpoint
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/polymorphic_routes_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/polymorphic_routes_rb.html new file mode 100644 index 0000000000..a8c9cbf21b --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/polymorphic_routes_rb.html @@ -0,0 +1,72 @@ +--- +title: polymorphic_routes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/redirection_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/redirection_rb.html new file mode 100644 index 0000000000..5fb7df1899 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/redirection_rb.html @@ -0,0 +1,99 @@ +--- +title: redirection.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/request
  • + +
  • active_support/core_ext/uri
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • rack/utils
  • + +
  • action_controller/metal/exceptions
  • + +
  • action_dispatch/routing/endpoint
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/route_set_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/route_set_rb.html new file mode 100644 index 0000000000..9fe2adcb7e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/route_set_rb.html @@ -0,0 +1,123 @@ +--- +title: route_set.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/core_ext/module/remove_method
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • action_controller/metal/exceptions
  • + +
  • action_dispatch/http/request
  • + +
  • action_dispatch/routing/endpoint
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/routes_proxy_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/routes_proxy_rb.html new file mode 100644 index 0000000000..d9d6a15c6f --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/routes_proxy_rb.html @@ -0,0 +1,78 @@ +--- +title: routes_proxy.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing/url_for_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing/url_for_rb.html new file mode 100644 index 0000000000..c4b302c565 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing/url_for_rb.html @@ -0,0 +1,74 @@ +--- +title: url_for.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/routing_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/routing_rb.html new file mode 100644 index 0000000000..75b5ba62b6 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/routing_rb.html @@ -0,0 +1,78 @@ +--- +title: routing.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/system_test_case_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/system_test_case_rb.html new file mode 100644 index 0000000000..a6bb475089 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/system_test_case_rb.html @@ -0,0 +1,99 @@ +--- +title: system_test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • capybara/dsl
  • + +
  • capybara/minitest
  • + +
  • action_controller
  • + +
  • action_dispatch/system_testing/driver
  • + +
  • action_dispatch/system_testing/browser
  • + +
  • action_dispatch/system_testing/server
  • + +
  • action_dispatch/system_testing/test_helpers/screenshot_helper
  • + +
  • action_dispatch/system_testing/test_helpers/setup_and_teardown
  • + +
  • action_dispatch/system_testing/test_helpers/undef_methods
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/system_testing/browser_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/browser_rb.html new file mode 100644 index 0000000000..d1b58ef1a5 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/browser_rb.html @@ -0,0 +1,70 @@ +--- +title: browser.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/system_testing/driver_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/driver_rb.html new file mode 100644 index 0000000000..8d48ff296e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/driver_rb.html @@ -0,0 +1,70 @@ +--- +title: driver.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/system_testing/server_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/server_rb.html new file mode 100644 index 0000000000..65b31c8c70 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/server_rb.html @@ -0,0 +1,70 @@ +--- +title: server.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper_rb.html new file mode 100644 index 0000000000..078844b6dc --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper_rb.html @@ -0,0 +1,74 @@ +--- +title: screenshot_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown_rb.html new file mode 100644 index 0000000000..c676dbde30 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown_rb.html @@ -0,0 +1,72 @@ +--- +title: setup_and_teardown.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/undef_methods_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/undef_methods_rb.html new file mode 100644 index 0000000000..0f8eec4327 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/undef_methods_rb.html @@ -0,0 +1,72 @@ +--- +title: undef_methods.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/assertion_response_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertion_response_rb.html new file mode 100644 index 0000000000..f83a77c3cc --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertion_response_rb.html @@ -0,0 +1,75 @@ +--- +title: assertion_response.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/response_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/response_rb.html new file mode 100644 index 0000000000..a2a2aaa37c --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/response_rb.html @@ -0,0 +1,74 @@ +--- +title: response.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/routing_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/routing_rb.html new file mode 100644 index 0000000000..d25aa78096 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions/routing_rb.html @@ -0,0 +1,94 @@ +--- +title: routing.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • uri
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • active_support/core_ext/string/access
  • + +
  • action_controller/metal/exceptions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions_rb.html new file mode 100644 index 0000000000..1235bcd60c --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/assertions_rb.html @@ -0,0 +1,78 @@ +--- +title: assertions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails-dom-testing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/integration_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/integration_rb.html new file mode 100644 index 0000000000..76db6b1ee3 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/integration_rb.html @@ -0,0 +1,113 @@ +--- +title: integration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • stringio
  • + +
  • uri
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • active_support/core_ext/object/try
  • + +
  • rack/test
  • + +
  • minitest
  • + +
  • action_dispatch/testing/request_encoder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/request_encoder_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/request_encoder_rb.html new file mode 100644 index 0000000000..baa02e37f3 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/request_encoder_rb.html @@ -0,0 +1,79 @@ +--- +title: request_encoder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/test_process_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/test_process_rb.html new file mode 100644 index 0000000000..da4270521e --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/test_process_rb.html @@ -0,0 +1,89 @@ +--- +title: test_process.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/middleware/cookies
  • + +
  • action_dispatch/middleware/flash
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/test_request_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/test_request_rb.html new file mode 100644 index 0000000000..0717cf1e3a --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/test_request_rb.html @@ -0,0 +1,85 @@ +--- +title: test_request.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionpack/lib/action_dispatch/testing/test_response_rb.html b/src/5.2/files/actionpack/lib/action_dispatch/testing/test_response_rb.html new file mode 100644 index 0000000000..e91213fb01 --- /dev/null +++ b/src/5.2/files/actionpack/lib/action_dispatch/testing/test_response_rb.html @@ -0,0 +1,85 @@ +--- +title: test_response.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/testing/request_encoder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/README_rdoc.html b/src/5.2/files/actionview/README_rdoc.html new file mode 100644 index 0000000000..ce3caeb95a --- /dev/null +++ b/src/5.2/files/actionview/README_rdoc.html @@ -0,0 +1,99 @@ +--- +title: README.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Action View

+ +

Action View is a framework for handling view template lookup and rendering, and provides view helpers that assist when building HTML forms, Atom feeds and more. Template formats that Action View handles are ERB (embedded Ruby, typically used to inline short Ruby snippets inside HTML), and XML Builder.

+ +

Download and installation

+ +

The latest version of Action View can be installed with RubyGems:

+ +
$ gem install actionview
+
+ +

Source code can be downloaded as part of the Rails project on GitHub:

+ + +

License

+ +

Action View is released under the MIT license:

+ + +

Support

+ +

API documentation is at

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/base_rb.html b/src/5.2/files/actionview/lib/action_view/base_rb.html new file mode 100644 index 0000000000..976724224f --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/base_rb.html @@ -0,0 +1,99 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attr_internal
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/ordered_options
  • + +
  • action_view/log_subscriber
  • + +
  • action_view/helpers
  • + +
  • action_view/context
  • + +
  • action_view/template
  • + +
  • action_view/lookup_context
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/buffers_rb.html b/src/5.2/files/actionview/lib/action_view/buffers_rb.html new file mode 100644 index 0000000000..399b88b087 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/buffers_rb.html @@ -0,0 +1,76 @@ +--- +title: buffers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/context_rb.html b/src/5.2/files/actionview/lib/action_view/context_rb.html new file mode 100644 index 0000000000..cb5cd8be2d --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/context_rb.html @@ -0,0 +1,70 @@ +--- +title: context.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/dependency_tracker_rb.html b/src/5.2/files/actionview/lib/action_view/dependency_tracker_rb.html new file mode 100644 index 0000000000..88fa9e71b5 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/dependency_tracker_rb.html @@ -0,0 +1,78 @@ +--- +title: dependency_tracker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • action_view/path_set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/digestor_rb.html b/src/5.2/files/actionview/lib/action_view/digestor_rb.html new file mode 100644 index 0000000000..1293aa0676 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/digestor_rb.html @@ -0,0 +1,101 @@ +--- +title: digestor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • action_view/dependency_tracker
  • + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/flows_rb.html b/src/5.2/files/actionview/lib/action_view/flows_rb.html new file mode 100644 index 0000000000..c7480e1b2e --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/flows_rb.html @@ -0,0 +1,78 @@ +--- +title: flows.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/gem_version_rb.html b/src/5.2/files/actionview/lib/action_view/gem_version_rb.html new file mode 100644 index 0000000000..fd1476650b --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/active_model_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/active_model_helper_rb.html new file mode 100644 index 0000000000..a1cd29ce7a --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/active_model_helper_rb.html @@ -0,0 +1,84 @@ +--- +title: active_model_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/asset_tag_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/asset_tag_helper_rb.html new file mode 100644 index 0000000000..589191de04 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/asset_tag_helper_rb.html @@ -0,0 +1,92 @@ +--- +title: asset_tag_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/object/inclusion
  • + +
  • active_support/core_ext/object/try
  • + +
  • action_view/helpers/asset_url_helper
  • + +
  • action_view/helpers/tag_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/asset_url_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/asset_url_helper_rb.html new file mode 100644 index 0000000000..29c218d426 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/asset_url_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: asset_url_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/atom_feed_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/atom_feed_helper_rb.html new file mode 100644 index 0000000000..a0a59c97ad --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/atom_feed_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: atom_feed_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/cache_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/cache_helper_rb.html new file mode 100644 index 0000000000..384877c00e --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/cache_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: cache_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/capture_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/capture_helper_rb.html new file mode 100644 index 0000000000..c404a2d957 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/capture_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: capture_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/controller_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/controller_helper_rb.html new file mode 100644 index 0000000000..32a92111ee --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/controller_helper_rb.html @@ -0,0 +1,78 @@ +--- +title: controller_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attr_internal
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/csp_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/csp_helper_rb.html new file mode 100644 index 0000000000..5e44ca6c60 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/csp_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: csp_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/csrf_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/csrf_helper_rb.html new file mode 100644 index 0000000000..300dd8eab0 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/csrf_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: csrf_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/date_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/date_helper_rb.html new file mode 100644 index 0000000000..2a86c0536d --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/date_helper_rb.html @@ -0,0 +1,99 @@ +--- +title: date_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • action_view/helpers/tag_helper
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/date/conversions
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/object/acts_like
  • + +
  • active_support/core_ext/object/with_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/debug_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/debug_helper_rb.html new file mode 100644 index 0000000000..3ed1ba9b83 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/debug_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: debug_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/form_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/form_helper_rb.html new file mode 100644 index 0000000000..661c57916d --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/form_helper_rb.html @@ -0,0 +1,109 @@ +--- +title: form_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
  • action_view/helpers/date_helper
  • + +
  • action_view/helpers/tag_helper
  • + +
  • action_view/helpers/form_tag_helper
  • + +
  • action_view/helpers/active_model_helper
  • + +
  • action_view/model_naming
  • + +
  • action_view/record_identifier
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/form_options_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/form_options_helper_rb.html new file mode 100644 index 0000000000..d91029e248 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/form_options_helper_rb.html @@ -0,0 +1,97 @@ +--- +title: form_options_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
  • erb
  • + +
  • action_view/helpers/form_helper
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/array/wrap
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/form_tag_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/form_tag_helper_rb.html new file mode 100644 index 0000000000..2b60b35e51 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/form_tag_helper_rb.html @@ -0,0 +1,86 @@ +--- +title: form_tag_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
  • action_view/helpers/tag_helper
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/javascript_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/javascript_helper_rb.html new file mode 100644 index 0000000000..627d021163 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/javascript_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: javascript_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tag_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/number_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/number_helper_rb.html new file mode 100644 index 0000000000..4f7780924b --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/number_helper_rb.html @@ -0,0 +1,93 @@ +--- +title: number_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/number_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/output_safety_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/output_safety_helper_rb.html new file mode 100644 index 0000000000..e098fd6395 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/output_safety_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: output_safety_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/record_tag_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/record_tag_helper_rb.html new file mode 100644 index 0000000000..b11c5048a1 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/record_tag_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: record_tag_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/rendering_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/rendering_helper_rb.html new file mode 100644 index 0000000000..ddc453f85c --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/rendering_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: rendering_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/sanitize_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/sanitize_helper_rb.html new file mode 100644 index 0000000000..e6d4923d39 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/sanitize_helper_rb.html @@ -0,0 +1,84 @@ +--- +title: sanitize_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
  • rails-html-sanitizer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tag_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tag_helper_rb.html new file mode 100644 index 0000000000..cbe6596a28 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tag_helper_rb.html @@ -0,0 +1,82 @@ +--- +title: tag_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/base_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/base_rb.html new file mode 100644 index 0000000000..d430f98957 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/base_rb.html @@ -0,0 +1,70 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/check_box_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/check_box_rb.html new file mode 100644 index 0000000000..af2882930f --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/check_box_rb.html @@ -0,0 +1,78 @@ +--- +title: check_box.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tags/checkable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/checkable_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/checkable_rb.html new file mode 100644 index 0000000000..180a576959 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/checkable_rb.html @@ -0,0 +1,70 @@ +--- +title: checkable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_check_boxes_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_check_boxes_rb.html new file mode 100644 index 0000000000..71d3b58ceb --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_check_boxes_rb.html @@ -0,0 +1,78 @@ +--- +title: collection_check_boxes.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tags/collection_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_helpers_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_helpers_rb.html new file mode 100644 index 0000000000..720cb8462c --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_helpers_rb.html @@ -0,0 +1,70 @@ +--- +title: collection_helpers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_radio_buttons_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_radio_buttons_rb.html new file mode 100644 index 0000000000..53745ed3ea --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_radio_buttons_rb.html @@ -0,0 +1,78 @@ +--- +title: collection_radio_buttons.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tags/collection_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_select_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_select_rb.html new file mode 100644 index 0000000000..584427d3d5 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/collection_select_rb.html @@ -0,0 +1,70 @@ +--- +title: collection_select.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/color_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/color_field_rb.html new file mode 100644 index 0000000000..10fe2813c6 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/color_field_rb.html @@ -0,0 +1,70 @@ +--- +title: color_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/date_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/date_field_rb.html new file mode 100644 index 0000000000..efce13d359 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/date_field_rb.html @@ -0,0 +1,70 @@ +--- +title: date_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/date_select_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/date_select_rb.html new file mode 100644 index 0000000000..ce7178d170 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/date_select_rb.html @@ -0,0 +1,78 @@ +--- +title: date_select.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_field_rb.html new file mode 100644 index 0000000000..5774bcd9f3 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_field_rb.html @@ -0,0 +1,70 @@ +--- +title: datetime_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_local_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_local_field_rb.html new file mode 100644 index 0000000000..8ebbb73993 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_local_field_rb.html @@ -0,0 +1,70 @@ +--- +title: datetime_local_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_select_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_select_rb.html new file mode 100644 index 0000000000..94a7377e9f --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/datetime_select_rb.html @@ -0,0 +1,70 @@ +--- +title: datetime_select.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/email_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/email_field_rb.html new file mode 100644 index 0000000000..295b93e4b2 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/email_field_rb.html @@ -0,0 +1,70 @@ +--- +title: email_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/file_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/file_field_rb.html new file mode 100644 index 0000000000..882a13227a --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/file_field_rb.html @@ -0,0 +1,70 @@ +--- +title: file_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/grouped_collection_select_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/grouped_collection_select_rb.html new file mode 100644 index 0000000000..298a28cfcb --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/grouped_collection_select_rb.html @@ -0,0 +1,70 @@ +--- +title: grouped_collection_select.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/hidden_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/hidden_field_rb.html new file mode 100644 index 0000000000..344332fbb3 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/hidden_field_rb.html @@ -0,0 +1,70 @@ +--- +title: hidden_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/label_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/label_rb.html new file mode 100644 index 0000000000..8af7204949 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/label_rb.html @@ -0,0 +1,70 @@ +--- +title: label.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/month_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/month_field_rb.html new file mode 100644 index 0000000000..13297a2728 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/month_field_rb.html @@ -0,0 +1,70 @@ +--- +title: month_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/number_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/number_field_rb.html new file mode 100644 index 0000000000..88b127f579 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/number_field_rb.html @@ -0,0 +1,70 @@ +--- +title: number_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/password_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/password_field_rb.html new file mode 100644 index 0000000000..79904d088f --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/password_field_rb.html @@ -0,0 +1,70 @@ +--- +title: password_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/placeholderable_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/placeholderable_rb.html new file mode 100644 index 0000000000..660e314b14 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/placeholderable_rb.html @@ -0,0 +1,70 @@ +--- +title: placeholderable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/radio_button_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/radio_button_rb.html new file mode 100644 index 0000000000..84caee094c --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/radio_button_rb.html @@ -0,0 +1,78 @@ +--- +title: radio_button.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tags/checkable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/range_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/range_field_rb.html new file mode 100644 index 0000000000..6ee80e26a7 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/range_field_rb.html @@ -0,0 +1,70 @@ +--- +title: range_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/search_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/search_field_rb.html new file mode 100644 index 0000000000..eb0b0d6f4b --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/search_field_rb.html @@ -0,0 +1,70 @@ +--- +title: search_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/select_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/select_rb.html new file mode 100644 index 0000000000..9f041abb4f --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/select_rb.html @@ -0,0 +1,70 @@ +--- +title: select.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/tel_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/tel_field_rb.html new file mode 100644 index 0000000000..9bec1e0c81 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/tel_field_rb.html @@ -0,0 +1,70 @@ +--- +title: tel_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/text_area_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/text_area_rb.html new file mode 100644 index 0000000000..59462901e3 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/text_area_rb.html @@ -0,0 +1,78 @@ +--- +title: text_area.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tags/placeholderable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/text_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/text_field_rb.html new file mode 100644 index 0000000000..227be35018 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/text_field_rb.html @@ -0,0 +1,78 @@ +--- +title: text_field.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tags/placeholderable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/time_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/time_field_rb.html new file mode 100644 index 0000000000..853cc82007 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/time_field_rb.html @@ -0,0 +1,70 @@ +--- +title: time_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/time_select_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/time_select_rb.html new file mode 100644 index 0000000000..21c7a4fead --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/time_select_rb.html @@ -0,0 +1,70 @@ +--- +title: time_select.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/time_zone_select_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/time_zone_select_rb.html new file mode 100644 index 0000000000..14ee7b62a6 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/time_zone_select_rb.html @@ -0,0 +1,72 @@ +--- +title: time_zone_select.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/translator_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/translator_rb.html new file mode 100644 index 0000000000..aa1c053262 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/translator_rb.html @@ -0,0 +1,70 @@ +--- +title: translator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/url_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/url_field_rb.html new file mode 100644 index 0000000000..9687ceed87 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/url_field_rb.html @@ -0,0 +1,70 @@ +--- +title: url_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags/week_field_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags/week_field_rb.html new file mode 100644 index 0000000000..f64a7106fe --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags/week_field_rb.html @@ -0,0 +1,70 @@ +--- +title: week_field.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/tags_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/tags_rb.html new file mode 100644 index 0000000000..6d076f04cb --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/tags_rb.html @@ -0,0 +1,70 @@ +--- +title: tags.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/text_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/text_helper_rb.html new file mode 100644 index 0000000000..1b735d31b1 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/text_helper_rb.html @@ -0,0 +1,82 @@ +--- +title: text_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/translation_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/translation_helper_rb.html new file mode 100644 index 0000000000..7c1ae5fad0 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/translation_helper_rb.html @@ -0,0 +1,84 @@ +--- +title: translation_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tag_helper
  • + +
  • active_support/core_ext/string/access
  • + +
  • i18n/exceptions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers/url_helper_rb.html b/src/5.2/files/actionview/lib/action_view/helpers/url_helper_rb.html new file mode 100644 index 0000000000..9f689eb9ee --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers/url_helper_rb.html @@ -0,0 +1,88 @@ +--- +title: url_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/javascript_helper
  • + +
  • active_support/core_ext/array/access
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/helpers_rb.html b/src/5.2/files/actionview/lib/action_view/helpers_rb.html new file mode 100644 index 0000000000..d610322af6 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/helpers_rb.html @@ -0,0 +1,78 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/benchmarkable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/layouts_rb.html b/src/5.2/files/actionview/lib/action_view/layouts_rb.html new file mode 100644 index 0000000000..b01510e53c --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/layouts_rb.html @@ -0,0 +1,82 @@ +--- +title: layouts.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/rendering
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/log_subscriber_rb.html b/src/5.2/files/actionview/lib/action_view/log_subscriber_rb.html new file mode 100644 index 0000000000..4a6518c8d4 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/log_subscriber_rb.html @@ -0,0 +1,83 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/lookup_context_rb.html b/src/5.2/files/actionview/lib/action_view/lookup_context_rb.html new file mode 100644 index 0000000000..ebc67b417f --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/lookup_context_rb.html @@ -0,0 +1,93 @@ +--- +title: lookup_context.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • active_support/core_ext/module/remove_method
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • action_view/template/resolver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/model_naming_rb.html b/src/5.2/files/actionview/lib/action_view/model_naming_rb.html new file mode 100644 index 0000000000..1b7b2ae953 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/model_naming_rb.html @@ -0,0 +1,68 @@ +--- +title: model_naming.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/path_set_rb.html b/src/5.2/files/actionview/lib/action_view/path_set_rb.html new file mode 100644 index 0000000000..1cbd40e9b7 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/path_set_rb.html @@ -0,0 +1,68 @@ +--- +title: path_set.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/railtie_rb.html b/src/5.2/files/actionview/lib/action_view/railtie_rb.html new file mode 100644 index 0000000000..51884dd131 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/railtie_rb.html @@ -0,0 +1,89 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view
  • + +
  • rails
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/record_identifier_rb.html b/src/5.2/files/actionview/lib/action_view/record_identifier_rb.html new file mode 100644 index 0000000000..d88d0929f2 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/record_identifier_rb.html @@ -0,0 +1,80 @@ +--- +title: record_identifier.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module
  • + +
  • action_view/model_naming
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/renderer/abstract_renderer_rb.html b/src/5.2/files/actionview/lib/action_view/renderer/abstract_renderer_rb.html new file mode 100644 index 0000000000..4a99a323c2 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/renderer/abstract_renderer_rb.html @@ -0,0 +1,70 @@ +--- +title: abstract_renderer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/renderer/partial_renderer/collection_caching_rb.html b/src/5.2/files/actionview/lib/action_view/renderer/partial_renderer/collection_caching_rb.html new file mode 100644 index 0000000000..63b3ff9ff9 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/renderer/partial_renderer/collection_caching_rb.html @@ -0,0 +1,70 @@ +--- +title: collection_caching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/renderer/partial_renderer_rb.html b/src/5.2/files/actionview/lib/action_view/renderer/partial_renderer_rb.html new file mode 100644 index 0000000000..06b16f195e --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/renderer/partial_renderer_rb.html @@ -0,0 +1,87 @@ +--- +title: partial_renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • action_view/renderer/partial_renderer/collection_caching
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/renderer/renderer_rb.html b/src/5.2/files/actionview/lib/action_view/renderer/renderer_rb.html new file mode 100644 index 0000000000..247096ef08 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/renderer/renderer_rb.html @@ -0,0 +1,75 @@ +--- +title: renderer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/renderer/streaming_template_renderer_rb.html b/src/5.2/files/actionview/lib/action_view/renderer/streaming_template_renderer_rb.html new file mode 100644 index 0000000000..eea8f9db1b --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/renderer/streaming_template_renderer_rb.html @@ -0,0 +1,76 @@ +--- +title: streaming_template_renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fiber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/renderer/template_renderer_rb.html b/src/5.2/files/actionview/lib/action_view/renderer/template_renderer_rb.html new file mode 100644 index 0000000000..abd2748a20 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/renderer/template_renderer_rb.html @@ -0,0 +1,76 @@ +--- +title: template_renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/rendering_rb.html b/src/5.2/files/actionview/lib/action_view/rendering_rb.html new file mode 100644 index 0000000000..98fedcfa95 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/rendering_rb.html @@ -0,0 +1,80 @@ +--- +title: rendering.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/view_paths
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/routing_url_for_rb.html b/src/5.2/files/actionview/lib/action_view/routing_url_for_rb.html new file mode 100644 index 0000000000..563f963d56 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/routing_url_for_rb.html @@ -0,0 +1,86 @@ +--- +title: routing_url_for.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/routing/polymorphic_routes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/error_rb.html b/src/5.2/files/actionview/lib/action_view/template/error_rb.html new file mode 100644 index 0000000000..fc9867e23a --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/error_rb.html @@ -0,0 +1,83 @@ +--- +title: error.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/handlers/builder_rb.html b/src/5.2/files/actionview/lib/action_view/template/handlers/builder_rb.html new file mode 100644 index 0000000000..504be3f2a8 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/handlers/builder_rb.html @@ -0,0 +1,87 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • builder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/handlers/erb/erubi_rb.html b/src/5.2/files/actionview/lib/action_view/template/handlers/erb/erubi_rb.html new file mode 100644 index 0000000000..2c403bfe6a --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/handlers/erb/erubi_rb.html @@ -0,0 +1,87 @@ +--- +title: erubi.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • erubi
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/handlers/erb_rb.html b/src/5.2/files/actionview/lib/action_view/template/handlers/erb_rb.html new file mode 100644 index 0000000000..1751153038 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/handlers/erb_rb.html @@ -0,0 +1,79 @@ +--- +title: erb.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/handlers/html_rb.html b/src/5.2/files/actionview/lib/action_view/template/handlers/html_rb.html new file mode 100644 index 0000000000..d146575e27 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/handlers/html_rb.html @@ -0,0 +1,79 @@ +--- +title: html.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/handlers/raw_rb.html b/src/5.2/files/actionview/lib/action_view/template/handlers/raw_rb.html new file mode 100644 index 0000000000..670f9c404c --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/handlers/raw_rb.html @@ -0,0 +1,79 @@ +--- +title: raw.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/handlers_rb.html b/src/5.2/files/actionview/lib/action_view/template/handlers_rb.html new file mode 100644 index 0000000000..0d17fc0b97 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/handlers_rb.html @@ -0,0 +1,77 @@ +--- +title: handlers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/html_rb.html b/src/5.2/files/actionview/lib/action_view/template/html_rb.html new file mode 100644 index 0000000000..9adcce86a1 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/html_rb.html @@ -0,0 +1,75 @@ +--- +title: html.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/resolver_rb.html b/src/5.2/files/actionview/lib/action_view/template/resolver_rb.html new file mode 100644 index 0000000000..ec9d89a93d --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/resolver_rb.html @@ -0,0 +1,103 @@ +--- +title: resolver.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • active_support/core_ext/class
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • action_view/template
  • + +
  • thread
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/text_rb.html b/src/5.2/files/actionview/lib/action_view/template/text_rb.html new file mode 100644 index 0000000000..b959f83be6 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/text_rb.html @@ -0,0 +1,75 @@ +--- +title: text.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template/types_rb.html b/src/5.2/files/actionview/lib/action_view/template/types_rb.html new file mode 100644 index 0000000000..66c86277cb --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template/types_rb.html @@ -0,0 +1,87 @@ +--- +title: types.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/template_rb.html b/src/5.2/files/actionview/lib/action_view/template_rb.html new file mode 100644 index 0000000000..9b82e3234e --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/template_rb.html @@ -0,0 +1,89 @@ +--- +title: template.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • thread
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/test_case_rb.html b/src/5.2/files/actionview/lib/action_view/test_case_rb.html new file mode 100644 index 0000000000..7a84ceca51 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/test_case_rb.html @@ -0,0 +1,107 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
  • action_controller
  • + +
  • action_controller/test_case
  • + +
  • action_view
  • + +
  • rails-dom-testing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/testing/resolvers_rb.html b/src/5.2/files/actionview/lib/action_view/testing/resolvers_rb.html new file mode 100644 index 0000000000..47250c5ea5 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/testing/resolvers_rb.html @@ -0,0 +1,85 @@ +--- +title: resolvers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/template/resolver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/version_rb.html b/src/5.2/files/actionview/lib/action_view/version_rb.html new file mode 100644 index 0000000000..62b448a864 --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/actionview/lib/action_view/view_paths_rb.html b/src/5.2/files/actionview/lib/action_view/view_paths_rb.html new file mode 100644 index 0000000000..ac2c75a78f --- /dev/null +++ b/src/5.2/files/actionview/lib/action_view/view_paths_rb.html @@ -0,0 +1,72 @@ +--- +title: view_paths.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/README_md.html b/src/5.2/files/activejob/README_md.html new file mode 100644 index 0000000000..ceb34bf1da --- /dev/null +++ b/src/5.2/files/activejob/README_md.html @@ -0,0 +1,163 @@ +--- +title: README.md +layout: default +--- +
+ + +
+
+ +
+ +

Active Job – Make work happen later

+ +

Active Job is a framework for declaring jobs and making them run on a variety of queueing backends. These jobs can be everything from regularly scheduled clean-ups, to billing charges, to mailings. Anything that can be chopped up into small units of work and run in parallel, really.

+ +

It also serves as the backend for Action Mailer's deliver_later functionality that makes it easy to turn any mailing into a job for running later. That's one of the most common jobs in a modern web application: sending emails outside of the request-response cycle, so the user doesn't have to wait on it.

+ +

The main point is to ensure that all Rails apps will have a job infrastructure in place, even if it's in the form of an “immediate runner”. We can then have framework features and other gems build on top of that, without having to worry about API differences between Delayed Job and Resque. Picking your queuing backend becomes more of an operational concern, then. And you'll be able to switch between them without having to rewrite your jobs.

+ +

Usage

+ +

To learn how to use your preferred queueing backend see its adapter documentation at ActiveJob::QueueAdapters.

+ +

Declare a job like so:

+ +
class MyJob < ActiveJob::Base
+  queue_as :my_jobs
+
+  def perform(record)
+    record.do_work
+  end
+end
+
+ +

Enqueue a job like so:

+ +
MyJob.perform_later record  # Enqueue a job to be performed as soon as the queueing system is free.
+
+ +
MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record)  # Enqueue a job to be performed tomorrow at noon.
+
+ +
MyJob.set(wait: 1.week).perform_later(record) # Enqueue a job to be performed 1 week from now.
+
+ +

That's it!

+ +

GlobalID support

+ +

Active Job supports GlobalID serialization for parameters. This makes it possible to pass live Active Record objects to your job instead of class/id pairs, which you then have to manually deserialize. Before, jobs would look like this:

+ +
class TrashableCleanupJob
+  def perform(trashable_class, trashable_id, depth)
+    trashable = trashable_class.constantize.find(trashable_id)
+    trashable.cleanup(depth)
+  end
+end
+
+ +

Now you can simply do:

+ +
class TrashableCleanupJob
+  def perform(trashable, depth)
+    trashable.cleanup(depth)
+  end
+end
+
+ +

This works with any class that mixes in GlobalID::Identification, which by default has been mixed into Active Record classes.

+ +

Supported queueing systems

+ +

Active Job has built-in adapters for multiple queueing backends (Sidekiq, Resque, Delayed Job and others). To get an up-to-date list of the adapters see the API Documentation for ActiveJob::QueueAdapters.

+ +

Auxiliary gems

+ + +

Download and installation

+ +

The latest version of Active Job can be installed with RubyGems:

+ +
$ gem install activejob
+
+ +

Source code can be downloaded as part of the Rails project on GitHub:

+ + +

License

+ +

Active Job is released under the MIT license:

+ + +

Support

+ +

API documentation is at:

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/arguments_rb.html b/src/5.2/files/activejob/lib/active_job/arguments_rb.html new file mode 100644 index 0000000000..d32c6f48bf --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/arguments_rb.html @@ -0,0 +1,87 @@ +--- +title: arguments.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/base_rb.html b/src/5.2/files/activejob/lib/active_job/base_rb.html new file mode 100644 index 0000000000..417d2676b5 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/base_rb.html @@ -0,0 +1,101 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_job/core
  • + +
  • active_job/queue_adapter
  • + +
  • active_job/queue_name
  • + +
  • active_job/queue_priority
  • + +
  • active_job/enqueuing
  • + +
  • active_job/execution
  • + +
  • active_job/callbacks
  • + +
  • active_job/exceptions
  • + +
  • active_job/logging
  • + +
  • active_job/translation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/callbacks_rb.html b/src/5.2/files/activejob/lib/active_job/callbacks_rb.html new file mode 100644 index 0000000000..44536ec574 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/callbacks_rb.html @@ -0,0 +1,80 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/configured_job_rb.html b/src/5.2/files/activejob/lib/active_job/configured_job_rb.html new file mode 100644 index 0000000000..6f12c0c199 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/configured_job_rb.html @@ -0,0 +1,68 @@ +--- +title: configured_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/core_rb.html b/src/5.2/files/activejob/lib/active_job/core_rb.html new file mode 100644 index 0000000000..d76c3830fc --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/core_rb.html @@ -0,0 +1,72 @@ +--- +title: core.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/enqueuing_rb.html b/src/5.2/files/activejob/lib/active_job/enqueuing_rb.html new file mode 100644 index 0000000000..500898d00a --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/enqueuing_rb.html @@ -0,0 +1,80 @@ +--- +title: enqueuing.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_job/arguments
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/exceptions_rb.html b/src/5.2/files/activejob/lib/active_job/exceptions_rb.html new file mode 100644 index 0000000000..65d93d2255 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/exceptions_rb.html @@ -0,0 +1,82 @@ +--- +title: exceptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/numeric/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/execution_rb.html b/src/5.2/files/activejob/lib/active_job/execution_rb.html new file mode 100644 index 0000000000..315a19934e --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/execution_rb.html @@ -0,0 +1,82 @@ +--- +title: execution.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/rescuable
  • + +
  • active_job/arguments
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/gem_version_rb.html b/src/5.2/files/activejob/lib/active_job/gem_version_rb.html new file mode 100644 index 0000000000..50d0179478 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/logging_rb.html b/src/5.2/files/activejob/lib/active_job/logging_rb.html new file mode 100644 index 0000000000..f7764fbe9f --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/logging_rb.html @@ -0,0 +1,84 @@ +--- +title: logging.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/transform_values
  • + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/tagged_logging
  • + +
  • active_support/logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapter_rb.html new file mode 100644 index 0000000000..194655b27e --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapter_rb.html @@ -0,0 +1,80 @@ +--- +title: queue_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/async_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/async_adapter_rb.html new file mode 100644 index 0000000000..20d142130c --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/async_adapter_rb.html @@ -0,0 +1,91 @@ +--- +title: async_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
  • concurrent/scheduled_task
  • + +
  • concurrent/executor/thread_pool_executor
  • + +
  • concurrent/utility/processor_counter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/backburner_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/backburner_adapter_rb.html new file mode 100644 index 0000000000..620f69a257 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/backburner_adapter_rb.html @@ -0,0 +1,85 @@ +--- +title: backburner_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • backburner
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/delayed_job_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/delayed_job_adapter_rb.html new file mode 100644 index 0000000000..c754a887d0 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/delayed_job_adapter_rb.html @@ -0,0 +1,85 @@ +--- +title: delayed_job_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delayed_job
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/inline_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/inline_adapter_rb.html new file mode 100644 index 0000000000..ae88748d07 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/inline_adapter_rb.html @@ -0,0 +1,77 @@ +--- +title: inline_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/qu_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/qu_adapter_rb.html new file mode 100644 index 0000000000..9e0c1c560d --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/qu_adapter_rb.html @@ -0,0 +1,85 @@ +--- +title: qu_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • qu
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/que_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/que_adapter_rb.html new file mode 100644 index 0000000000..7480040ea6 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/que_adapter_rb.html @@ -0,0 +1,85 @@ +--- +title: que_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • que
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/queue_classic_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/queue_classic_adapter_rb.html new file mode 100644 index 0000000000..f6ffb7656a --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/queue_classic_adapter_rb.html @@ -0,0 +1,85 @@ +--- +title: queue_classic_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • queue_classic
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/resque_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/resque_adapter_rb.html new file mode 100644 index 0000000000..fda3e904ca --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/resque_adapter_rb.html @@ -0,0 +1,93 @@ +--- +title: resque_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • resque
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/array/access
  • + +
  • resque-scheduler
  • + +
  • resque_scheduler
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/sidekiq_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/sidekiq_adapter_rb.html new file mode 100644 index 0000000000..927bc3e885 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/sidekiq_adapter_rb.html @@ -0,0 +1,85 @@ +--- +title: sidekiq_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • sidekiq
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/sneakers_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/sneakers_adapter_rb.html new file mode 100644 index 0000000000..aad0d8118f --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/sneakers_adapter_rb.html @@ -0,0 +1,89 @@ +--- +title: sneakers_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • sneakers
  • + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/sucker_punch_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/sucker_punch_adapter_rb.html new file mode 100644 index 0000000000..84fea10f30 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/sucker_punch_adapter_rb.html @@ -0,0 +1,85 @@ +--- +title: sucker_punch_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • sucker_punch
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters/test_adapter_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters/test_adapter_rb.html new file mode 100644 index 0000000000..875eaace93 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters/test_adapter_rb.html @@ -0,0 +1,77 @@ +--- +title: test_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_adapters_rb.html b/src/5.2/files/activejob/lib/active_job/queue_adapters_rb.html new file mode 100644 index 0000000000..9c1658e2df --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_adapters_rb.html @@ -0,0 +1,70 @@ +--- +title: queue_adapters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_name_rb.html b/src/5.2/files/activejob/lib/active_job/queue_name_rb.html new file mode 100644 index 0000000000..afc350258f --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_name_rb.html @@ -0,0 +1,72 @@ +--- +title: queue_name.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/queue_priority_rb.html b/src/5.2/files/activejob/lib/active_job/queue_priority_rb.html new file mode 100644 index 0000000000..17ae53a872 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/queue_priority_rb.html @@ -0,0 +1,72 @@ +--- +title: queue_priority.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/railtie_rb.html b/src/5.2/files/activejob/lib/active_job/railtie_rb.html new file mode 100644 index 0000000000..6c49204afb --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/railtie_rb.html @@ -0,0 +1,80 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • global_id/railtie
  • + +
  • active_job
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/test_case_rb.html b/src/5.2/files/activejob/lib/active_job/test_case_rb.html new file mode 100644 index 0000000000..520c0a99af --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/test_case_rb.html @@ -0,0 +1,83 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/test_case
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/test_helper_rb.html b/src/5.2/files/activejob/lib/active_job/test_helper_rb.html new file mode 100644 index 0000000000..eaa24cb892 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/test_helper_rb.html @@ -0,0 +1,86 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/subclasses
  • + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/translation_rb.html b/src/5.2/files/activejob/lib/active_job/translation_rb.html new file mode 100644 index 0000000000..1b20477a48 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/translation_rb.html @@ -0,0 +1,68 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activejob/lib/active_job/version_rb.html b/src/5.2/files/activejob/lib/active_job/version_rb.html new file mode 100644 index 0000000000..31ced3aab7 --- /dev/null +++ b/src/5.2/files/activejob/lib/active_job/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/README_rdoc.html b/src/5.2/files/activemodel/README_rdoc.html new file mode 100644 index 0000000000..47d23fb234 --- /dev/null +++ b/src/5.2/files/activemodel/README_rdoc.html @@ -0,0 +1,322 @@ +--- +title: README.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Active Model – model interfaces for Rails

+ +

Active Model provides a known set of interfaces for usage in model classes. They allow for Action Pack helpers to interact with non-Active Record models, for example. Active Model also helps with building custom ORMs for use outside of the Rails framework.

+ +

Prior to Rails 3.0, if a plugin or gem developer wanted to have an object interact with Action Pack helpers, it was required to either copy chunks of code from Rails, or monkey patch entire helpers to make them handle objects that did not exactly conform to the Active Record interface. This would result in code duplication and fragile applications that broke on upgrades. Active Model solves this by defining an explicit API. You can read more about the API in ActiveModel::Lint::Tests.

+ +

Active Model provides a default module that implements the basic API required to integrate with Action Pack out of the box: ActiveModel::Model.

+ +
class Person
+  include ActiveModel::Model
+
+  attr_accessor :name, :age
+  validates_presence_of :name
+end
+
+person = Person.new(name: 'bob', age: '18')
+person.name   # => 'bob'
+person.age    # => '18'
+person.valid? # => true
+
+ +

It includes model name introspections, conversions, translations and validations, resulting in a class suitable to be used with Action Pack. See ActiveModel::Model for more examples.

+ +

Active Model also provides the following functionality to have ORM-like behavior out of the box:

+
  • +

    Add attribute magic to objects

    + +
    class Person
    +  include ActiveModel::AttributeMethods
    +
    +  attribute_method_prefix 'clear_'
    +  define_attribute_methods :name, :age
    +
    +  attr_accessor :name, :age
    +
    +  def clear_attribute(attr)
    +    send("#{attr}=", nil)
    +  end
    +end
    +
    +person = Person.new
    +person.clear_name
    +person.clear_age
    +
    + +

    Learn more

    +
  • +

    Callbacks for certain operations

    + +
    class Person
    +  extend ActiveModel::Callbacks
    +  define_model_callbacks :create
    +
    +  def create
    +    run_callbacks :create do
    +      # Your create action methods here
    +    end
    +  end
    +end
    +
    + +

    This generates before_create, around_create and after_create class methods that wrap your create method.

    + +

    Learn more

    +
  • +

    Tracking value changes

    + +
    class Person
    +  include ActiveModel::Dirty
    +
    +  define_attribute_methods :name
    +
    +  def name
    +    @name
    +  end
    +
    +  def name=(val)
    +    name_will_change! unless val == @name
    +    @name = val
    +  end
    +
    +  def save
    +    # do persistence work
    +    changes_applied
    +  end
    +end
    +
    +person = Person.new
    +person.name             # => nil
    +person.changed?         # => false
    +person.name = 'bob'
    +person.changed?         # => true
    +person.changed          # => ['name']
    +person.changes          # => { 'name' => [nil, 'bob'] }
    +person.save
    +person.name = 'robert'
    +person.save
    +person.previous_changes # => {'name' => ['bob, 'robert']}
    +
    + +

    Learn more

    +
  • +

    Adding errors interface to objects

    + +

    Exposing error messages allows objects to interact with Action Pack helpers seamlessly.

    + +
    class Person
    +
    +  def initialize
    +    @errors = ActiveModel::Errors.new(self)
    +  end
    +
    +  attr_accessor :name
    +  attr_reader   :errors
    +
    +  def validate!
    +    errors.add(:name, "cannot be nil") if name.nil?
    +  end
    +
    +  def self.human_attribute_name(attr, options = {})
    +    "Name"
    +  end
    +end
    +
    +person = Person.new
    +person.name = nil
    +person.validate!
    +person.errors.full_messages
    +# => ["Name cannot be nil"]
    +
    + +

    Learn more

    +
  • +

    Model name introspection

    + +
    class NamedPerson
    +  extend ActiveModel::Naming
    +end
    +
    +NamedPerson.model_name.name   # => "NamedPerson"
    +NamedPerson.model_name.human  # => "Named person"
    +
    + +

    Learn more

    +
  • +

    Making objects serializable

    + +

    ActiveModel::Serialization provides a standard interface for your object to provide to_json serialization.

    + +
    class SerialPerson
    +  include ActiveModel::Serialization
    +
    +  attr_accessor :name
    +
    +  def attributes
    +    {'name' => name}
    +  end
    +end
    +
    +s = SerialPerson.new
    +s.serializable_hash   # => {"name"=>nil}
    +
    +class SerialPerson
    +  include ActiveModel::Serializers::JSON
    +end
    +
    +s = SerialPerson.new
    +s.to_json             # => "{\"name\":null}"
    +
    + +

    Learn more

    +
  • +

    Internationalization (i18n) support

    + +
    class Person
    +  extend ActiveModel::Translation
    +end
    +
    +Person.human_attribute_name('my_attribute')
    +# => "My attribute"
    +
    + +

    Learn more

    +
  • +

    Validation support

    + +
    class Person
    +  include ActiveModel::Validations
    +
    +  attr_accessor :first_name, :last_name
    +
    +  validates_each :first_name, :last_name do |record, attr, value|
    +    record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
    +  end
    +end
    +
    +person = Person.new
    +person.first_name = 'zoolander'
    +person.valid?  # => false
    +
    + +

    Learn more

    +
  • +

    Custom validators

    + +
    class HasNameValidator < ActiveModel::Validator
    +  def validate(record)
    +    record.errors.add(:name, "must exist") if record.name.blank?
    +  end
    +end
    +
    +class ValidatorPerson
    +  include ActiveModel::Validations
    +  validates_with HasNameValidator
    +  attr_accessor :name
    +end
    +
    +p = ValidatorPerson.new
    +p.valid?                  # =>  false
    +p.errors.full_messages    # => ["Name must exist"]
    +p.name = "Bob"
    +p.valid?                  # =>  true
    +
    + +

    Learn more

    +
+ +

Download and installation

+ +

The latest version of Active Model can be installed with RubyGems:

+ +
$ gem install activemodel
+
+ +

Source code can be downloaded as part of the Rails project on GitHub

+ + +

License

+ +

Active Model is released under the MIT license:

+ + +

Support

+ +

API documentation is at:

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute/user_provided_default_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute/user_provided_default_rb.html new file mode 100644 index 0000000000..649f80e3cf --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute/user_provided_default_rb.html @@ -0,0 +1,76 @@ +--- +title: user_provided_default.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute_assignment_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute_assignment_rb.html new file mode 100644 index 0000000000..a916481711 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute_assignment_rb.html @@ -0,0 +1,78 @@ +--- +title: attribute_assignment.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute_methods_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute_methods_rb.html new file mode 100644 index 0000000000..6a934f2ece --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute_methods_rb.html @@ -0,0 +1,87 @@ +--- +title: attribute_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute_mutation_tracker_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute_mutation_tracker_rb.html new file mode 100644 index 0000000000..4d2d3b447f --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute_mutation_tracker_rb.html @@ -0,0 +1,76 @@ +--- +title: attribute_mutation_tracker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute_rb.html new file mode 100644 index 0000000000..3c684c90b2 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute_rb.html @@ -0,0 +1,76 @@ +--- +title: attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/duplicable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute_set/builder_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute_set/builder_rb.html new file mode 100644 index 0000000000..a4d2b350a1 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute_set/builder_rb.html @@ -0,0 +1,76 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute_set/yaml_encoder_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute_set/yaml_encoder_rb.html new file mode 100644 index 0000000000..03e11ed180 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute_set/yaml_encoder_rb.html @@ -0,0 +1,68 @@ +--- +title: yaml_encoder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attribute_set_rb.html b/src/5.2/files/activemodel/lib/active_model/attribute_set_rb.html new file mode 100644 index 0000000000..1af2db67ad --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attribute_set_rb.html @@ -0,0 +1,80 @@ +--- +title: attribute_set.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/deep_dup
  • + +
  • active_model/attribute_set/builder
  • + +
  • active_model/attribute_set/yaml_encoder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/attributes_rb.html b/src/5.2/files/activemodel/lib/active_model/attributes_rb.html new file mode 100644 index 0000000000..8fb9bfa824 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/attributes_rb.html @@ -0,0 +1,84 @@ +--- +title: attributes.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute_set
  • + +
  • active_model/attribute/user_provided_default
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/callbacks_rb.html b/src/5.2/files/activemodel/lib/active_model/callbacks_rb.html new file mode 100644 index 0000000000..409e379e29 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/callbacks_rb.html @@ -0,0 +1,80 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/conversion_rb.html b/src/5.2/files/activemodel/lib/active_model/conversion_rb.html new file mode 100644 index 0000000000..07f17c90bb --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/conversion_rb.html @@ -0,0 +1,72 @@ +--- +title: conversion.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/dirty_rb.html b/src/5.2/files/activemodel/lib/active_model/dirty_rb.html new file mode 100644 index 0000000000..3c7c012421 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/dirty_rb.html @@ -0,0 +1,84 @@ +--- +title: dirty.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/hash_with_indifferent_access
  • + +
  • active_support/core_ext/object/duplicable
  • + +
  • active_model/attribute_mutation_tracker
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/errors_rb.html b/src/5.2/files/activemodel/lib/active_model/errors_rb.html new file mode 100644 index 0000000000..b66dae778b --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/errors_rb.html @@ -0,0 +1,95 @@ +--- +title: errors.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/conversions
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/core_ext/object/deep_dup
  • + +
  • active_support/core_ext/string/filters
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/forbidden_attributes_protection_rb.html b/src/5.2/files/activemodel/lib/active_model/forbidden_attributes_protection_rb.html new file mode 100644 index 0000000000..3ab8aa2ee6 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/forbidden_attributes_protection_rb.html @@ -0,0 +1,75 @@ +--- +title: forbidden_attributes_protection.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/gem_version_rb.html b/src/5.2/files/activemodel/lib/active_model/gem_version_rb.html new file mode 100644 index 0000000000..21e38a38d4 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/lint_rb.html b/src/5.2/files/activemodel/lib/active_model/lint_rb.html new file mode 100644 index 0000000000..89822c3d35 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/lint_rb.html @@ -0,0 +1,72 @@ +--- +title: lint.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/model_rb.html b/src/5.2/files/activemodel/lib/active_model/model_rb.html new file mode 100644 index 0000000000..8db5158a80 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/model_rb.html @@ -0,0 +1,70 @@ +--- +title: model.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/naming_rb.html b/src/5.2/files/activemodel/lib/active_model/naming_rb.html new file mode 100644 index 0000000000..a19fb1376a --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/naming_rb.html @@ -0,0 +1,91 @@ +--- +title: naming.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/module/introspection
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/railtie_rb.html b/src/5.2/files/activemodel/lib/active_model/railtie_rb.html new file mode 100644 index 0000000000..34e5d59f0a --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/railtie_rb.html @@ -0,0 +1,78 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model
  • + +
  • rails
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/secure_password_rb.html b/src/5.2/files/activemodel/lib/active_model/secure_password_rb.html new file mode 100644 index 0000000000..59a6f59d74 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/secure_password_rb.html @@ -0,0 +1,82 @@ +--- +title: secure_password.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bcrypt
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/serialization_rb.html b/src/5.2/files/activemodel/lib/active_model/serialization_rb.html new file mode 100644 index 0000000000..8378e2f25c --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/serialization_rb.html @@ -0,0 +1,80 @@ +--- +title: serialization.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/hash/slice
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/serializers/json_rb.html b/src/5.2/files/activemodel/lib/active_model/serializers/json_rb.html new file mode 100644 index 0000000000..d3d4f58cf0 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/serializers/json_rb.html @@ -0,0 +1,82 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/translation_rb.html b/src/5.2/files/activemodel/lib/active_model/translation_rb.html new file mode 100644 index 0000000000..a0e9848ce6 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/translation_rb.html @@ -0,0 +1,70 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/big_integer_rb.html b/src/5.2/files/activemodel/lib/active_model/type/big_integer_rb.html new file mode 100644 index 0000000000..a16aed6019 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/big_integer_rb.html @@ -0,0 +1,78 @@ +--- +title: big_integer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/integer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/binary_rb.html b/src/5.2/files/activemodel/lib/active_model/type/binary_rb.html new file mode 100644 index 0000000000..bcfe7dd7f5 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/binary_rb.html @@ -0,0 +1,70 @@ +--- +title: binary.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/boolean_rb.html b/src/5.2/files/activemodel/lib/active_model/type/boolean_rb.html new file mode 100644 index 0000000000..275ee9fa82 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/boolean_rb.html @@ -0,0 +1,77 @@ +--- +title: boolean.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/date_rb.html b/src/5.2/files/activemodel/lib/active_model/type/date_rb.html new file mode 100644 index 0000000000..3638725506 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/date_rb.html @@ -0,0 +1,70 @@ +--- +title: date.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/date_time_rb.html b/src/5.2/files/activemodel/lib/active_model/type/date_time_rb.html new file mode 100644 index 0000000000..86a5877f2f --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/date_time_rb.html @@ -0,0 +1,70 @@ +--- +title: date_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/decimal_rb.html b/src/5.2/files/activemodel/lib/active_model/type/decimal_rb.html new file mode 100644 index 0000000000..390b0fea5f --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/decimal_rb.html @@ -0,0 +1,78 @@ +--- +title: decimal.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal/util
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/float_rb.html b/src/5.2/files/activemodel/lib/active_model/type/float_rb.html new file mode 100644 index 0000000000..8857104fc7 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/float_rb.html @@ -0,0 +1,70 @@ +--- +title: float.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time_rb.html b/src/5.2/files/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time_rb.html new file mode 100644 index 0000000000..16bdef15ee --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time_rb.html @@ -0,0 +1,79 @@ +--- +title: accepts_multiparameter_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/helpers/mutable_rb.html b/src/5.2/files/activemodel/lib/active_model/type/helpers/mutable_rb.html new file mode 100644 index 0000000000..6de32bfa1f --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/helpers/mutable_rb.html @@ -0,0 +1,74 @@ +--- +title: mutable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/helpers/numeric_rb.html b/src/5.2/files/activemodel/lib/active_model/type/helpers/numeric_rb.html new file mode 100644 index 0000000000..6bdfa6de02 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/helpers/numeric_rb.html @@ -0,0 +1,74 @@ +--- +title: numeric.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/helpers/time_value_rb.html b/src/5.2/files/activemodel/lib/active_model/type/helpers/time_value_rb.html new file mode 100644 index 0000000000..4370eec666 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/helpers/time_value_rb.html @@ -0,0 +1,84 @@ +--- +title: time_value.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/zones
  • + +
  • active_support/core_ext/time/zones
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/helpers/timezone_rb.html b/src/5.2/files/activemodel/lib/active_model/type/helpers/timezone_rb.html new file mode 100644 index 0000000000..48880e0a42 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/helpers/timezone_rb.html @@ -0,0 +1,82 @@ +--- +title: timezone.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/zones
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/helpers_rb.html b/src/5.2/files/activemodel/lib/active_model/type/helpers_rb.html new file mode 100644 index 0000000000..be488110d7 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/helpers_rb.html @@ -0,0 +1,71 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/helpers/accepts_multiparameter_time
  • + +
  • active_model/type/helpers/numeric
  • + +
  • active_model/type/helpers/mutable
  • + +
  • active_model/type/helpers/time_value
  • + +
  • active_model/type/helpers/timezone
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/immutable_string_rb.html b/src/5.2/files/activemodel/lib/active_model/type/immutable_string_rb.html new file mode 100644 index 0000000000..278748d121 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/immutable_string_rb.html @@ -0,0 +1,72 @@ +--- +title: immutable_string.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/integer_rb.html b/src/5.2/files/activemodel/lib/active_model/type/integer_rb.html new file mode 100644 index 0000000000..e50f5a6d62 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/integer_rb.html @@ -0,0 +1,70 @@ +--- +title: integer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/registry_rb.html b/src/5.2/files/activemodel/lib/active_model/type/registry_rb.html new file mode 100644 index 0000000000..b0aa785c1a --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/registry_rb.html @@ -0,0 +1,79 @@ +--- +title: registry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/string_rb.html b/src/5.2/files/activemodel/lib/active_model/type/string_rb.html new file mode 100644 index 0000000000..95be532d64 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/string_rb.html @@ -0,0 +1,78 @@ +--- +title: string.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/immutable_string
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/time_rb.html b/src/5.2/files/activemodel/lib/active_model/type/time_rb.html new file mode 100644 index 0000000000..d4f0e552b5 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/time_rb.html @@ -0,0 +1,70 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type/value_rb.html b/src/5.2/files/activemodel/lib/active_model/type/value_rb.html new file mode 100644 index 0000000000..fa5d8b08b1 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type/value_rb.html @@ -0,0 +1,77 @@ +--- +title: value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/type_rb.html b/src/5.2/files/activemodel/lib/active_model/type_rb.html new file mode 100644 index 0000000000..3ba2aee983 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/type_rb.html @@ -0,0 +1,104 @@ +--- +title: type.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/helpers
  • + +
  • active_model/type/value
  • + +
  • active_model/type/big_integer
  • + +
  • active_model/type/binary
  • + +
  • active_model/type/boolean
  • + +
  • active_model/type/date
  • + +
  • active_model/type/date_time
  • + +
  • active_model/type/decimal
  • + +
  • active_model/type/float
  • + +
  • active_model/type/immutable_string
  • + +
  • active_model/type/integer
  • + +
  • active_model/type/string
  • + +
  • active_model/type/time
  • + +
  • active_model/type/registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/absence_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/absence_rb.html new file mode 100644 index 0000000000..289cb50cb3 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/absence_rb.html @@ -0,0 +1,72 @@ +--- +title: absence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/acceptance_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/acceptance_rb.html new file mode 100644 index 0000000000..066ca59a5f --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/acceptance_rb.html @@ -0,0 +1,83 @@ +--- +title: acceptance.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/callbacks_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/callbacks_rb.html new file mode 100644 index 0000000000..f46ff4346a --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/callbacks_rb.html @@ -0,0 +1,74 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/clusivity_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/clusivity_rb.html new file mode 100644 index 0000000000..0dad918d03 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/clusivity_rb.html @@ -0,0 +1,78 @@ +--- +title: clusivity.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/range
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/confirmation_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/confirmation_rb.html new file mode 100644 index 0000000000..80695a3d1f --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/confirmation_rb.html @@ -0,0 +1,72 @@ +--- +title: confirmation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/exclusion_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/exclusion_rb.html new file mode 100644 index 0000000000..0e3f36e3ec --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/exclusion_rb.html @@ -0,0 +1,80 @@ +--- +title: exclusion.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/clusivity
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/format_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/format_rb.html new file mode 100644 index 0000000000..dbe80a0e9d --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/format_rb.html @@ -0,0 +1,72 @@ +--- +title: format.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/helper_methods_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/helper_methods_rb.html new file mode 100644 index 0000000000..9d3099f46e --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/helper_methods_rb.html @@ -0,0 +1,72 @@ +--- +title: helper_methods.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/inclusion_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/inclusion_rb.html new file mode 100644 index 0000000000..33f2d6f575 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/inclusion_rb.html @@ -0,0 +1,80 @@ +--- +title: inclusion.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/clusivity
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/length_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/length_rb.html new file mode 100644 index 0000000000..1f8dedce1c --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/length_rb.html @@ -0,0 +1,72 @@ +--- +title: length.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/numericality_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/numericality_rb.html new file mode 100644 index 0000000000..e9cf591773 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/numericality_rb.html @@ -0,0 +1,80 @@ +--- +title: numericality.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal/util
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/presence_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/presence_rb.html new file mode 100644 index 0000000000..480840c6ba --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/presence_rb.html @@ -0,0 +1,72 @@ +--- +title: presence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/validates_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/validates_rb.html new file mode 100644 index 0000000000..366b0d263c --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/validates_rb.html @@ -0,0 +1,80 @@ +--- +title: validates.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/slice
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations/with_rb.html b/src/5.2/files/activemodel/lib/active_model/validations/with_rb.html new file mode 100644 index 0000000000..289fb2b3a9 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations/with_rb.html @@ -0,0 +1,80 @@ +--- +title: with.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validations_rb.html b/src/5.2/files/activemodel/lib/active_model/validations_rb.html new file mode 100644 index 0000000000..fcfefd5515 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validations_rb.html @@ -0,0 +1,91 @@ +--- +title: validations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/hash/except
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/validator_rb.html b/src/5.2/files/activemodel/lib/active_model/validator_rb.html new file mode 100644 index 0000000000..1ace4b1b04 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/validator_rb.html @@ -0,0 +1,83 @@ +--- +title: validator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/anonymous
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activemodel/lib/active_model/version_rb.html b/src/5.2/files/activemodel/lib/active_model/version_rb.html new file mode 100644 index 0000000000..dc0161dc47 --- /dev/null +++ b/src/5.2/files/activemodel/lib/active_model/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/README_rdoc.html b/src/5.2/files/activerecord/README_rdoc.html new file mode 100644 index 0000000000..9b99cd2e60 --- /dev/null +++ b/src/5.2/files/activerecord/README_rdoc.html @@ -0,0 +1,271 @@ +--- +title: README.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Active Record – Object-relational mapping in Rails

+ +

Active Record connects classes to relational database tables to establish an almost zero-configuration persistence layer for applications. The library provides a base class that, when subclassed, sets up a mapping between the new class and an existing table in the database. In the context of an application, these classes are commonly referred to as models. Models can also be connected to other models; this is done by defining associations.

+ +

Active Record relies heavily on naming in that it uses class and association names to establish mappings between respective database tables and foreign key columns. Although these mappings can be defined explicitly, it's recommended to follow naming conventions, especially when getting started with the library.

+ +

A short rundown of some of the major features:

+
  • +

    Automated mapping between classes and tables, attributes and columns.

    + +
    class Product < ActiveRecord::Base
    +end
    +
    + +

    Learn more

    +
+ +

The Product class is automatically mapped to the table named “products”, which might look like this:

+ +
CREATE TABLE products (
+  id bigint NOT NULL auto_increment,
+  name varchar(255),
+  PRIMARY KEY  (id)
+);
+
+ +

This would also define the following accessors: Product#name and Product#name=(new_name).

+
  • +

    Associations between objects defined by simple class methods.

    + +
    class Firm < ActiveRecord::Base
    +  has_many   :clients
    +  has_one    :account
    +  belongs_to :conglomerate
    +end
    +
    + +

    Learn more

    +
  • +

    Aggregations of value objects.

    + +
    class Account < ActiveRecord::Base
    +  composed_of :balance, class_name: 'Money',
    +              mapping: %w(balance amount)
    +  composed_of :address,
    +              mapping: [%w(address_street street), %w(address_city city)]
    +end
    +
    + +

    Learn more

    +
  • +

    Validation rules that can differ for new or existing objects.

    + +
    class Account < ActiveRecord::Base
    +  validates :subdomain, :name, :email_address, :password, presence: true
    +  validates :subdomain, uniqueness: true
    +  validates :terms_of_service, acceptance: true, on: :create
    +  validates :password, :email_address, confirmation: true, on: :create
    +end
    +
    + +

    Learn more

    +
  • +

    Callbacks available for the entire life cycle (instantiation, saving, destroying, validating, etc.).

    + +
    class Person < ActiveRecord::Base
    +  before_destroy :invalidate_payment_plan
    +  # the `invalidate_payment_plan` method gets called just before Person#destroy
    +end
    +
    + +

    Learn more

    +
  • +

    Inheritance hierarchies.

    + +
    class Company < ActiveRecord::Base; end
    +class Firm < Company; end
    +class Client < Company; end
    +class PriorityClient < Client; end
    +
    + +

    Learn more

    +
  • +

    Transactions.

    + +
    # Database transaction
    +Account.transaction do
    +  david.withdrawal(100)
    +  mary.deposit(100)
    +end
    +
    + +

    Learn more

    +
  • +

    Reflections on columns, associations, and aggregations.

    + +
    reflection = Firm.reflect_on_association(:clients)
    +reflection.klass # => Client (class)
    +Firm.columns # Returns an array of column descriptors for the firms table
    +
    + +

    Learn more

    +
  • +

    Database abstraction through simple adapters.

    + +
    # connect to SQLite3
    +ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'dbfile.sqlite3')
    +
    +# connect to MySQL with authentication
    +ActiveRecord::Base.establish_connection(
    +  adapter:  'mysql2',
    +  host:     'localhost',
    +  username: 'me',
    +  password: 'secret',
    +  database: 'activerecord'
    +)
    +
    + +

    Learn more and read about the built-in support for MySQL, PostgreSQL, and SQLite3.

    +
  • +

    Logging support for Log4r and Logger.

    + +
    ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
    +ActiveRecord::Base.logger = Log4r::Logger.new('Application Log')
    +
    +
  • +

    Database agnostic schema management with Migrations.

    + +
    class AddSystemSettings < ActiveRecord::Migration[5.0]
    +  def up
    +    create_table :system_settings do |t|
    +      t.string  :name
    +      t.string  :label
    +      t.text    :value
    +      t.string  :type
    +      t.integer :position
    +    end
    +
    +    SystemSetting.create name: 'notice', label: 'Use notice?', value: 1
    +  end
    +
    +  def down
    +    drop_table :system_settings
    +  end
    +end
    +
    + +

    Learn more

    +
+ +

Philosophy

+ +

Active Record is an implementation of the object-relational mapping (ORM) pattern by the same name described by Martin Fowler:

+ +
"An object that wraps a row in a database table or view,
+encapsulates the database access, and adds domain logic on that data."
+
+ +

Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is object-relational mapping. The prime directive for this mapping has been to minimize the amount of code needed to build a real-world domain model. This is made possible by relying on a number of conventions that make it easy for Active Record to infer complex relations and structures from a minimal amount of explicit direction.

+ +

Convention over Configuration:

+
  • +

    No XML files!

    +
  • +

    Lots of reflection and run-time extension

    +
  • +

    Magic is not inherently a bad word

    +
+ +

Admit the Database:

+
  • +

    Lets you drop down to SQL for odd cases and performance

    +
  • +

    Doesn't attempt to duplicate or replace data definitions

    +
+ +

Download and installation

+ +

The latest version of Active Record can be installed with RubyGems:

+ +
$ gem install activerecord
+
+ +

Source code can be downloaded as part of the Rails project on GitHub:

+ + +

License

+ +

Active Record is released under the MIT license:

+ + +

Support

+ +

API documentation is at:

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/aggregations_rb.html b/src/5.2/files/activerecord/lib/active_record/aggregations_rb.html new file mode 100644 index 0000000000..cb53f6cbd2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/aggregations_rb.html @@ -0,0 +1,72 @@ +--- +title: aggregations.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/association_relation_rb.html b/src/5.2/files/activerecord/lib/active_record/association_relation_rb.html new file mode 100644 index 0000000000..c22d6128cf --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/association_relation_rb.html @@ -0,0 +1,75 @@ +--- +title: association_relation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/alias_tracker_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/alias_tracker_rb.html new file mode 100644 index 0000000000..b032869085 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/alias_tracker_rb.html @@ -0,0 +1,78 @@ +--- +title: alias_tracker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/conversions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/association_rb.html new file mode 100644 index 0000000000..09bdad2fc2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/association_rb.html @@ -0,0 +1,78 @@ +--- +title: association.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/wrap
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/association_scope_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/association_scope_rb.html new file mode 100644 index 0000000000..7bfc1762f2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/association_scope_rb.html @@ -0,0 +1,70 @@ +--- +title: association_scope.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/belongs_to_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/belongs_to_association_rb.html new file mode 100644 index 0000000000..7c61cad846 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/belongs_to_association_rb.html @@ -0,0 +1,70 @@ +--- +title: belongs_to_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/belongs_to_polymorphic_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/belongs_to_polymorphic_association_rb.html new file mode 100644 index 0000000000..87f89be197 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/belongs_to_polymorphic_association_rb.html @@ -0,0 +1,70 @@ +--- +title: belongs_to_polymorphic_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/builder/association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/builder/association_rb.html new file mode 100644 index 0000000000..b2fbd7d852 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/builder/association_rb.html @@ -0,0 +1,86 @@ +--- +title: association.rb +layout: default +--- +
+ + +
+
+ +
+ +

This is the parent Association class which defines the variables used by all associations.

+ +

The hierarchy is defined as follows:

+ +
Association
+  - SingularAssociation
+    - BelongsToAssociation
+    - HasOneAssociation
+  - CollectionAssociation
+    - HasManyAssociation
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/builder/belongs_to_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/builder/belongs_to_rb.html new file mode 100644 index 0000000000..2271cc760e --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/builder/belongs_to_rb.html @@ -0,0 +1,70 @@ +--- +title: belongs_to.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/builder/collection_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/builder/collection_association_rb.html new file mode 100644 index 0000000000..c10664d931 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/builder/collection_association_rb.html @@ -0,0 +1,78 @@ +--- +title: collection_association.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/associations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many_rb.html new file mode 100644 index 0000000000..513abe7e24 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many_rb.html @@ -0,0 +1,70 @@ +--- +title: has_and_belongs_to_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/builder/has_many_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/builder/has_many_rb.html new file mode 100644 index 0000000000..8a2a44ef0b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/builder/has_many_rb.html @@ -0,0 +1,70 @@ +--- +title: has_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/builder/has_one_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/builder/has_one_rb.html new file mode 100644 index 0000000000..2b1dc73bdf --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/builder/has_one_rb.html @@ -0,0 +1,70 @@ +--- +title: has_one.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/builder/singular_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/builder/singular_association_rb.html new file mode 100644 index 0000000000..76c34921ca --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/builder/singular_association_rb.html @@ -0,0 +1,76 @@ +--- +title: singular_association.rb +layout: default +--- +
+ + +
+
+ +
+ +

This class is inherited by the has_one and belongs_to association classes

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/collection_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/collection_association_rb.html new file mode 100644 index 0000000000..187e169d3b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/collection_association_rb.html @@ -0,0 +1,70 @@ +--- +title: collection_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/collection_proxy_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/collection_proxy_rb.html new file mode 100644 index 0000000000..cb99b35dc8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/collection_proxy_rb.html @@ -0,0 +1,77 @@ +--- +title: collection_proxy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/foreign_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/foreign_association_rb.html new file mode 100644 index 0000000000..010caf1c72 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/foreign_association_rb.html @@ -0,0 +1,70 @@ +--- +title: foreign_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/has_many_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/has_many_association_rb.html new file mode 100644 index 0000000000..d6b16d901c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/has_many_association_rb.html @@ -0,0 +1,70 @@ +--- +title: has_many_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/has_many_through_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/has_many_through_association_rb.html new file mode 100644 index 0000000000..ea2a4ecfaa --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/has_many_through_association_rb.html @@ -0,0 +1,70 @@ +--- +title: has_many_through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/has_one_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/has_one_association_rb.html new file mode 100644 index 0000000000..3db1844283 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/has_one_association_rb.html @@ -0,0 +1,70 @@ +--- +title: has_one_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/has_one_through_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/has_one_through_association_rb.html new file mode 100644 index 0000000000..c1aa498ab3 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/has_one_through_association_rb.html @@ -0,0 +1,70 @@ +--- +title: has_one_through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_association_rb.html new file mode 100644 index 0000000000..33519b9650 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_association_rb.html @@ -0,0 +1,78 @@ +--- +title: join_association.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/associations/join_dependency/join_part
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_base_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_base_rb.html new file mode 100644 index 0000000000..9924edda02 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_base_rb.html @@ -0,0 +1,78 @@ +--- +title: join_base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/associations/join_dependency/join_part
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_part_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_part_rb.html new file mode 100644 index 0000000000..d5353f374b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency/join_part_rb.html @@ -0,0 +1,70 @@ +--- +title: join_part.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/join_dependency_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency_rb.html new file mode 100644 index 0000000000..b3c0835afa --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/join_dependency_rb.html @@ -0,0 +1,72 @@ +--- +title: join_dependency.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/preloader/association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/preloader/association_rb.html new file mode 100644 index 0000000000..7ddf335189 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/preloader/association_rb.html @@ -0,0 +1,70 @@ +--- +title: association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/preloader/through_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/preloader/through_association_rb.html new file mode 100644 index 0000000000..e2404d0dd4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/preloader/through_association_rb.html @@ -0,0 +1,70 @@ +--- +title: through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/preloader_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/preloader_rb.html new file mode 100644 index 0000000000..8c3d909183 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/preloader_rb.html @@ -0,0 +1,70 @@ +--- +title: preloader.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/singular_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/singular_association_rb.html new file mode 100644 index 0000000000..549ba74255 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/singular_association_rb.html @@ -0,0 +1,70 @@ +--- +title: singular_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations/through_association_rb.html b/src/5.2/files/activerecord/lib/active_record/associations/through_association_rb.html new file mode 100644 index 0000000000..3471e4c0be --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations/through_association_rb.html @@ -0,0 +1,70 @@ +--- +title: through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/associations_rb.html b/src/5.2/files/activerecord/lib/active_record/associations_rb.html new file mode 100644 index 0000000000..29dc4ef1ce --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/associations_rb.html @@ -0,0 +1,93 @@ +--- +title: associations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/string/conversions
  • + +
  • active_support/core_ext/module/remove_method
  • + +
  • active_record/errors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_assignment_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_assignment_rb.html new file mode 100644 index 0000000000..20b8d276b8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_assignment_rb.html @@ -0,0 +1,78 @@ +--- +title: attribute_assignment.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/forbidden_attributes_protection
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_decorators_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_decorators_rb.html new file mode 100644 index 0000000000..4df3845465 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_decorators_rb.html @@ -0,0 +1,68 @@ +--- +title: attribute_decorators.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/before_type_cast_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/before_type_cast_rb.html new file mode 100644 index 0000000000..e2aa358046 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/before_type_cast_rb.html @@ -0,0 +1,72 @@ +--- +title: before_type_cast.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/dirty_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/dirty_rb.html new file mode 100644 index 0000000000..2b1ef41e7c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/dirty_rb.html @@ -0,0 +1,82 @@ +--- +title: dirty.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/primary_key_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/primary_key_rb.html new file mode 100644 index 0000000000..c80330ed6a --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/primary_key_rb.html @@ -0,0 +1,82 @@ +--- +title: primary_key.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/query_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/query_rb.html new file mode 100644 index 0000000000..b7ef2d087d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/query_rb.html @@ -0,0 +1,83 @@ +--- +title: query.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/read_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/read_rb.html new file mode 100644 index 0000000000..812dbf1bdc --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/read_rb.html @@ -0,0 +1,72 @@ +--- +title: read.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/serialization_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/serialization_rb.html new file mode 100644 index 0000000000..5a497ec994 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/serialization_rb.html @@ -0,0 +1,81 @@ +--- +title: serialization.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/time_zone_conversion_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/time_zone_conversion_rb.html new file mode 100644 index 0000000000..c942c5c2a8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/time_zone_conversion_rb.html @@ -0,0 +1,72 @@ +--- +title: time_zone_conversion.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods/write_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods/write_rb.html new file mode 100644 index 0000000000..55e52e1f99 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods/write_rb.html @@ -0,0 +1,72 @@ +--- +title: write.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attribute_methods_rb.html b/src/5.2/files/activerecord/lib/active_record/attribute_methods_rb.html new file mode 100644 index 0000000000..e10725bb1d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attribute_methods_rb.html @@ -0,0 +1,82 @@ +--- +title: attribute_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mutex_m
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/attributes_rb.html b/src/5.2/files/activerecord/lib/active_record/attributes_rb.html new file mode 100644 index 0000000000..243d8e5e03 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/attributes_rb.html @@ -0,0 +1,82 @@ +--- +title: attributes.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute/user_provided_default
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/autosave_association_rb.html b/src/5.2/files/activerecord/lib/active_record/autosave_association_rb.html new file mode 100644 index 0000000000..587fafa6f7 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/autosave_association_rb.html @@ -0,0 +1,72 @@ +--- +title: autosave_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/base_rb.html b/src/5.2/files/activerecord/lib/active_record/base_rb.html new file mode 100644 index 0000000000..41165036d5 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/base_rb.html @@ -0,0 +1,127 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
  • active_support/benchmarkable
  • + +
  • active_support/dependencies
  • + +
  • active_support/descendants_tracker
  • + +
  • active_support/time
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/hash/deep_merge
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/hash/transform_values
  • + +
  • active_support/core_ext/string/behavior
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • active_support/core_ext/module/introspection
  • + +
  • active_support/core_ext/object/duplicable
  • + +
  • active_support/core_ext/class/subclasses
  • + +
  • active_record/attribute_decorators
  • + +
  • active_record/define_callbacks
  • + +
  • active_record/errors
  • + +
  • active_record/log_subscriber
  • + +
  • active_record/explain_subscriber
  • + +
  • active_record/relation/delegation
  • + +
  • active_record/attributes
  • + +
  • active_record/type_caster
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/callbacks_rb.html b/src/5.2/files/activerecord/lib/active_record/callbacks_rb.html new file mode 100644 index 0000000000..d04ea5638b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/callbacks_rb.html @@ -0,0 +1,70 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/coders/json_rb.html b/src/5.2/files/activerecord/lib/active_record/coders/json_rb.html new file mode 100644 index 0000000000..6a1ff81c04 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/coders/json_rb.html @@ -0,0 +1,70 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/coders/yaml_column_rb.html b/src/5.2/files/activerecord/lib/active_record/coders/yaml_column_rb.html new file mode 100644 index 0000000000..b9f3e4b552 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/coders/yaml_column_rb.html @@ -0,0 +1,76 @@ +--- +title: yaml_column.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/collection_cache_key_rb.html b/src/5.2/files/activerecord/lib/active_record/collection_cache_key_rb.html new file mode 100644 index 0000000000..ea76735926 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/collection_cache_key_rb.html @@ -0,0 +1,72 @@ +--- +title: collection_cache_key.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool_rb.html new file mode 100644 index 0000000000..778086b9e4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool_rb.html @@ -0,0 +1,101 @@ +--- +title: connection_pool.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_limits_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_limits_rb.html new file mode 100644 index 0000000000..d8784c727c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_limits_rb.html @@ -0,0 +1,72 @@ +--- +title: database_limits.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_statements_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_statements_rb.html new file mode 100644 index 0000000000..361c02e9bc --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_statements_rb.html @@ -0,0 +1,81 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/query_cache_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/query_cache_rb.html new file mode 100644 index 0000000000..ba8472d28e --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/query_cache_rb.html @@ -0,0 +1,84 @@ +--- +title: query_cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/quoting_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/quoting_rb.html new file mode 100644 index 0000000000..59bfbddd3e --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/quoting_rb.html @@ -0,0 +1,84 @@ +--- +title: quoting.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/big_decimal/conversions
  • + +
  • active_support/multibyte/chars
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/savepoints_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/savepoints_rb.html new file mode 100644 index 0000000000..d0c59fa22f --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/savepoints_rb.html @@ -0,0 +1,72 @@ +--- +title: savepoints.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_creation_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_creation_rb.html new file mode 100644 index 0000000000..a6becc2e52 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_creation_rb.html @@ -0,0 +1,85 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/strip
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions_rb.html new file mode 100644 index 0000000000..f1f4f1cd43 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions_rb.html @@ -0,0 +1,81 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper_rb.html new file mode 100644 index 0000000000..01cf6838e1 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper_rb.html @@ -0,0 +1,78 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/compact
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_statements_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_statements_rb.html new file mode 100644 index 0000000000..b11a8d4729 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_statements_rb.html @@ -0,0 +1,86 @@ +--- +title: schema_statements.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/migration/join_table
  • + +
  • active_support/core_ext/string/access
  • + +
  • digest/sha2
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/transaction_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/transaction_rb.html new file mode 100644 index 0000000000..7355e0ee3b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract/transaction_rb.html @@ -0,0 +1,83 @@ +--- +title: transaction.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_adapter_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_adapter_rb.html new file mode 100644 index 0000000000..6bb158b8f4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_adapter_rb.html @@ -0,0 +1,107 @@ +--- +title: abstract_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/connection_adapters/determine_if_preparable_visitor
  • + +
  • active_record/connection_adapters/schema_cache
  • + +
  • active_record/connection_adapters/sql_type_metadata
  • + +
  • active_record/connection_adapters/abstract/schema_dumper
  • + +
  • active_record/connection_adapters/abstract/schema_creation
  • + +
  • active_support/concurrency/load_interlock_aware_monitor
  • + +
  • arel/collectors/bind
  • + +
  • arel/collectors/composite
  • + +
  • arel/collectors/sql_string
  • + +
  • arel/collectors/substitute_binds
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter_rb.html new file mode 100644 index 0000000000..e3f4762f23 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter_rb.html @@ -0,0 +1,107 @@ +--- +title: abstract_mysql_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/connection_adapters/abstract_adapter
  • + +
  • active_record/connection_adapters/statement_pool
  • + +
  • active_record/connection_adapters/mysql/column
  • + +
  • active_record/connection_adapters/mysql/explain_pretty_printer
  • + +
  • active_record/connection_adapters/mysql/quoting
  • + +
  • active_record/connection_adapters/mysql/schema_creation
  • + +
  • active_record/connection_adapters/mysql/schema_definitions
  • + +
  • active_record/connection_adapters/mysql/schema_dumper
  • + +
  • active_record/connection_adapters/mysql/schema_statements
  • + +
  • active_record/connection_adapters/mysql/type_metadata
  • + +
  • active_support/core_ext/string/strip
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/column_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/column_rb.html new file mode 100644 index 0000000000..24f475b7fd --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/column_rb.html @@ -0,0 +1,79 @@ +--- +title: column.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/connection_specification_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/connection_specification_rb.html new file mode 100644 index 0000000000..3c68846a42 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/connection_specification_rb.html @@ -0,0 +1,80 @@ +--- +title: connection_specification.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • uri
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor_rb.html new file mode 100644 index 0000000000..8d3cecfbfe --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor_rb.html @@ -0,0 +1,72 @@ +--- +title: determine_if_preparable_visitor.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/column_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/column_rb.html new file mode 100644 index 0000000000..751e9e8eb3 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/column_rb.html @@ -0,0 +1,72 @@ +--- +title: column.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/database_statements_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/database_statements_rb.html new file mode 100644 index 0000000000..45c64fb010 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/database_statements_rb.html @@ -0,0 +1,76 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer_rb.html new file mode 100644 index 0000000000..b108749b80 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer_rb.html @@ -0,0 +1,72 @@ +--- +title: explain_pretty_printer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/quoting_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/quoting_rb.html new file mode 100644 index 0000000000..f22edebab4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/quoting_rb.html @@ -0,0 +1,72 @@ +--- +title: quoting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_creation_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_creation_rb.html new file mode 100644 index 0000000000..ec0216f842 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_creation_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions_rb.html new file mode 100644 index 0000000000..d3ae7d43d6 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions_rb.html @@ -0,0 +1,83 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper_rb.html new file mode 100644 index 0000000000..b8915e0ce1 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_statements_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_statements_rb.html new file mode 100644 index 0000000000..1a1a565978 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_statements_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/type_metadata_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/type_metadata_rb.html new file mode 100644 index 0000000000..66d7a2de2a --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql/type_metadata_rb.html @@ -0,0 +1,72 @@ +--- +title: type_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql2_adapter_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql2_adapter_rb.html new file mode 100644 index 0000000000..6054703dc0 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/mysql2_adapter_rb.html @@ -0,0 +1,91 @@ +--- +title: mysql2_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/connection_adapters/abstract_mysql_adapter
  • + +
  • active_record/connection_adapters/mysql/database_statements
  • + +
  • mysql2
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/column_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/column_rb.html new file mode 100644 index 0000000000..e5534ed530 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/column_rb.html @@ -0,0 +1,70 @@ +--- +title: column.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/database_statements_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/database_statements_rb.html new file mode 100644 index 0000000000..f89be58ea5 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/database_statements_rb.html @@ -0,0 +1,76 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer_rb.html new file mode 100644 index 0000000000..c1db727c2b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer_rb.html @@ -0,0 +1,72 @@ +--- +title: explain_pretty_printer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/array_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/array_rb.html new file mode 100644 index 0000000000..a938b72e2d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/array_rb.html @@ -0,0 +1,76 @@ +--- +title: array.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_rb.html new file mode 100644 index 0000000000..8d26d6354f --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_rb.html @@ -0,0 +1,83 @@ +--- +title: bit.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_varying_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_varying_rb.html new file mode 100644 index 0000000000..a43ef6492d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_varying_rb.html @@ -0,0 +1,74 @@ +--- +title: bit_varying.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea_rb.html new file mode 100644 index 0000000000..ba4778cba9 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea_rb.html @@ -0,0 +1,76 @@ +--- +title: bytea.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr_rb.html new file mode 100644 index 0000000000..82d267c193 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr_rb.html @@ -0,0 +1,82 @@ +--- +title: cidr.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • ipaddr
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_rb.html new file mode 100644 index 0000000000..075f9987b3 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_rb.html @@ -0,0 +1,74 @@ +--- +title: date.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time_rb.html new file mode 100644 index 0000000000..7774c6ec1c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time_rb.html @@ -0,0 +1,74 @@ +--- +title: date_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal_rb.html new file mode 100644 index 0000000000..f77f1fac13 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal_rb.html @@ -0,0 +1,74 @@ +--- +title: decimal.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum_rb.html new file mode 100644 index 0000000000..9d68cf9cd2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum_rb.html @@ -0,0 +1,74 @@ +--- +title: enum.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore_rb.html new file mode 100644 index 0000000000..16e2565848 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore_rb.html @@ -0,0 +1,74 @@ +--- +title: hstore.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/inet_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/inet_rb.html new file mode 100644 index 0000000000..03e79f3757 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/inet_rb.html @@ -0,0 +1,74 @@ +--- +title: inet.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb_rb.html new file mode 100644 index 0000000000..2267ad09a5 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb_rb.html @@ -0,0 +1,74 @@ +--- +title: jsonb.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/legacy_point_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/legacy_point_rb.html new file mode 100644 index 0000000000..48b0eac484 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/legacy_point_rb.html @@ -0,0 +1,74 @@ +--- +title: legacy_point.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/money_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/money_rb.html new file mode 100644 index 0000000000..e962bbad53 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/money_rb.html @@ -0,0 +1,74 @@ +--- +title: money.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/oid_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/oid_rb.html new file mode 100644 index 0000000000..31baaf4a22 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/oid_rb.html @@ -0,0 +1,74 @@ +--- +title: oid.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/point_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/point_rb.html new file mode 100644 index 0000000000..adee918e3b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/point_rb.html @@ -0,0 +1,74 @@ +--- +title: point.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/range_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/range_rb.html new file mode 100644 index 0000000000..ef276a29ac --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/range_rb.html @@ -0,0 +1,74 @@ +--- +title: range.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string_rb.html new file mode 100644 index 0000000000..99e99e3b85 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string_rb.html @@ -0,0 +1,74 @@ +--- +title: specialized_string.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer_rb.html new file mode 100644 index 0000000000..0a0a90e6fe --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer_rb.html @@ -0,0 +1,74 @@ +--- +title: type_map_initializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid_rb.html new file mode 100644 index 0000000000..06aea296c9 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid_rb.html @@ -0,0 +1,74 @@ +--- +title: uuid.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector_rb.html new file mode 100644 index 0000000000..3578a39962 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector_rb.html @@ -0,0 +1,74 @@ +--- +title: vector.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml_rb.html new file mode 100644 index 0000000000..92d5c785fa --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml_rb.html @@ -0,0 +1,74 @@ +--- +title: xml.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid_rb.html new file mode 100644 index 0000000000..addd5e9bc7 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid_rb.html @@ -0,0 +1,124 @@ +--- +title: oid.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/connection_adapters/postgresql/oid/array
  • + +
  • active_record/connection_adapters/postgresql/oid/bit
  • + +
  • active_record/connection_adapters/postgresql/oid/bit_varying
  • + +
  • active_record/connection_adapters/postgresql/oid/bytea
  • + +
  • active_record/connection_adapters/postgresql/oid/cidr
  • + +
  • active_record/connection_adapters/postgresql/oid/date
  • + +
  • active_record/connection_adapters/postgresql/oid/date_time
  • + +
  • active_record/connection_adapters/postgresql/oid/decimal
  • + +
  • active_record/connection_adapters/postgresql/oid/enum
  • + +
  • active_record/connection_adapters/postgresql/oid/hstore
  • + +
  • active_record/connection_adapters/postgresql/oid/inet
  • + +
  • active_record/connection_adapters/postgresql/oid/jsonb
  • + +
  • active_record/connection_adapters/postgresql/oid/money
  • + +
  • active_record/connection_adapters/postgresql/oid/oid
  • + +
  • active_record/connection_adapters/postgresql/oid/point
  • + +
  • active_record/connection_adapters/postgresql/oid/legacy_point
  • + +
  • active_record/connection_adapters/postgresql/oid/range
  • + +
  • active_record/connection_adapters/postgresql/oid/specialized_string
  • + +
  • active_record/connection_adapters/postgresql/oid/uuid
  • + +
  • active_record/connection_adapters/postgresql/oid/vector
  • + +
  • active_record/connection_adapters/postgresql/oid/xml
  • + +
  • active_record/connection_adapters/postgresql/oid/type_map_initializer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/quoting_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/quoting_rb.html new file mode 100644 index 0000000000..3cf9ee8eb8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/quoting_rb.html @@ -0,0 +1,85 @@ +--- +title: quoting.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity_rb.html new file mode 100644 index 0000000000..8bda575c94 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity_rb.html @@ -0,0 +1,72 @@ +--- +title: referential_integrity.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation_rb.html new file mode 100644 index 0000000000..8fe2acf6df --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions_rb.html new file mode 100644 index 0000000000..6a3ea59f84 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions_rb.html @@ -0,0 +1,85 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper_rb.html new file mode 100644 index 0000000000..8e14f1885e --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements_rb.html new file mode 100644 index 0000000000..16ee04244f --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata_rb.html new file mode 100644 index 0000000000..d240510c56 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata_rb.html @@ -0,0 +1,77 @@ +--- +title: type_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/utils_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/utils_rb.html new file mode 100644 index 0000000000..c9e76384e2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql/utils_rb.html @@ -0,0 +1,74 @@ +--- +title: utils.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql_adapter_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql_adapter_rb.html new file mode 100644 index 0000000000..2c8cccccb8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/postgresql_adapter_rb.html @@ -0,0 +1,127 @@ +--- +title: postgresql_adapter.rb +layout: default +--- +
+ + +
+
+ +
+ +

Make sure we're using pg high enough for type casts and Ruby 2.2+ compatibility

+ +
+ + + + +

Required Files

+
    + +
  • pg
  • + +
  • active_record/connection_adapters/abstract_adapter
  • + +
  • active_record/connection_adapters/statement_pool
  • + +
  • active_record/connection_adapters/postgresql/column
  • + +
  • active_record/connection_adapters/postgresql/database_statements
  • + +
  • active_record/connection_adapters/postgresql/explain_pretty_printer
  • + +
  • active_record/connection_adapters/postgresql/oid
  • + +
  • active_record/connection_adapters/postgresql/quoting
  • + +
  • active_record/connection_adapters/postgresql/referential_integrity
  • + +
  • active_record/connection_adapters/postgresql/schema_creation
  • + +
  • active_record/connection_adapters/postgresql/schema_definitions
  • + +
  • active_record/connection_adapters/postgresql/schema_dumper
  • + +
  • active_record/connection_adapters/postgresql/schema_statements
  • + +
  • active_record/connection_adapters/postgresql/type_metadata
  • + +
  • active_record/connection_adapters/postgresql/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/schema_cache_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/schema_cache_rb.html new file mode 100644 index 0000000000..44a8324637 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/schema_cache_rb.html @@ -0,0 +1,77 @@ +--- +title: schema_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sql_type_metadata_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sql_type_metadata_rb.html new file mode 100644 index 0000000000..ddb46dee0b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sql_type_metadata_rb.html @@ -0,0 +1,77 @@ +--- +title: sql_type_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer_rb.html new file mode 100644 index 0000000000..862d6c13c8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer_rb.html @@ -0,0 +1,72 @@ +--- +title: explain_pretty_printer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/quoting_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/quoting_rb.html new file mode 100644 index 0000000000..2e7cb98393 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/quoting_rb.html @@ -0,0 +1,72 @@ +--- +title: quoting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_creation_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_creation_rb.html new file mode 100644 index 0000000000..2c4d2c3134 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_creation_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions_rb.html new file mode 100644 index 0000000000..5c93561d0e --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions_rb.html @@ -0,0 +1,79 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper_rb.html new file mode 100644 index 0000000000..071c408fc3 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements_rb.html new file mode 100644 index 0000000000..6e0072b82c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3_adapter_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3_adapter_rb.html new file mode 100644 index 0000000000..6e36644622 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/sqlite3_adapter_rb.html @@ -0,0 +1,107 @@ +--- +title: sqlite3_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/connection_adapters/abstract_adapter
  • + +
  • active_record/connection_adapters/statement_pool
  • + +
  • active_record/connection_adapters/sqlite3/explain_pretty_printer
  • + +
  • active_record/connection_adapters/sqlite3/quoting
  • + +
  • active_record/connection_adapters/sqlite3/schema_creation
  • + +
  • active_record/connection_adapters/sqlite3/schema_definitions
  • + +
  • active_record/connection_adapters/sqlite3/schema_dumper
  • + +
  • active_record/connection_adapters/sqlite3/schema_statements
  • + +
  • sqlite3
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_adapters/statement_pool_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_adapters/statement_pool_rb.html new file mode 100644 index 0000000000..5aedf7a795 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_adapters/statement_pool_rb.html @@ -0,0 +1,70 @@ +--- +title: statement_pool.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/connection_handling_rb.html b/src/5.2/files/activerecord/lib/active_record/connection_handling_rb.html new file mode 100644 index 0000000000..99e336a305 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/connection_handling_rb.html @@ -0,0 +1,72 @@ +--- +title: connection_handling.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/core_rb.html b/src/5.2/files/activerecord/lib/active_record/core_rb.html new file mode 100644 index 0000000000..e0bbf298a4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/core_rb.html @@ -0,0 +1,86 @@ +--- +title: core.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • active_support/core_ext/string/filters
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/counter_cache_rb.html b/src/5.2/files/activerecord/lib/active_record/counter_cache_rb.html new file mode 100644 index 0000000000..437020987b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/counter_cache_rb.html @@ -0,0 +1,72 @@ +--- +title: counter_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/define_callbacks_rb.html b/src/5.2/files/activerecord/lib/active_record/define_callbacks_rb.html new file mode 100644 index 0000000000..52ddf7bf4a --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/define_callbacks_rb.html @@ -0,0 +1,70 @@ +--- +title: define_callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/dynamic_matchers_rb.html b/src/5.2/files/activerecord/lib/active_record/dynamic_matchers_rb.html new file mode 100644 index 0000000000..586e5acf6d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/dynamic_matchers_rb.html @@ -0,0 +1,81 @@ +--- +title: dynamic_matchers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/enum_rb.html b/src/5.2/files/activerecord/lib/active_record/enum_rb.html new file mode 100644 index 0000000000..ef2243a0b6 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/enum_rb.html @@ -0,0 +1,80 @@ +--- +title: enum.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/deep_dup
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/errors_rb.html b/src/5.2/files/activerecord/lib/active_record/errors_rb.html new file mode 100644 index 0000000000..dd252a3d4f --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/errors_rb.html @@ -0,0 +1,151 @@ +--- +title: errors.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/explain_rb.html b/src/5.2/files/activerecord/lib/active_record/explain_rb.html new file mode 100644 index 0000000000..78e61ba71f --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/explain_rb.html @@ -0,0 +1,78 @@ +--- +title: explain.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/explain_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/explain_registry_rb.html b/src/5.2/files/activerecord/lib/active_record/explain_registry_rb.html new file mode 100644 index 0000000000..e903d60042 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/explain_registry_rb.html @@ -0,0 +1,76 @@ +--- +title: explain_registry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/per_thread_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/explain_subscriber_rb.html b/src/5.2/files/activerecord/lib/active_record/explain_subscriber_rb.html new file mode 100644 index 0000000000..e8aa985eae --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/explain_subscriber_rb.html @@ -0,0 +1,80 @@ +--- +title: explain_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/notifications
  • + +
  • active_record/explain_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/fixture_set/file_rb.html b/src/5.2/files/activerecord/lib/active_record/fixture_set/file_rb.html new file mode 100644 index 0000000000..c0a3b7c31c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/fixture_set/file_rb.html @@ -0,0 +1,85 @@ +--- +title: file.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • erb
  • + +
  • yaml
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/fixtures_rb.html b/src/5.2/files/activerecord/lib/active_record/fixtures_rb.html new file mode 100644 index 0000000000..5c9b3e8d88 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/fixtures_rb.html @@ -0,0 +1,107 @@ +--- +title: fixtures.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • erb
  • + +
  • yaml
  • + +
  • zlib
  • + +
  • set
  • + +
  • active_support/dependencies
  • + +
  • active_support/core_ext/digest/uuid
  • + +
  • active_record/fixture_set/file
  • + +
  • active_record/errors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/gem_version_rb.html b/src/5.2/files/activerecord/lib/active_record/gem_version_rb.html new file mode 100644 index 0000000000..5706eeb551 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/inheritance_rb.html b/src/5.2/files/activerecord/lib/active_record/inheritance_rb.html new file mode 100644 index 0000000000..d36027c73d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/inheritance_rb.html @@ -0,0 +1,82 @@ +--- +title: inheritance.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/integration_rb.html b/src/5.2/files/activerecord/lib/active_record/integration_rb.html new file mode 100644 index 0000000000..56152abead --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/integration_rb.html @@ -0,0 +1,82 @@ +--- +title: integration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/internal_metadata_rb.html b/src/5.2/files/activerecord/lib/active_record/internal_metadata_rb.html new file mode 100644 index 0000000000..36777fc8aa --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/internal_metadata_rb.html @@ -0,0 +1,78 @@ +--- +title: internal_metadata.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/scoping/default
  • + +
  • active_record/scoping/named
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/legacy_yaml_adapter_rb.html b/src/5.2/files/activerecord/lib/active_record/legacy_yaml_adapter_rb.html new file mode 100644 index 0000000000..6b12e19af7 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/legacy_yaml_adapter_rb.html @@ -0,0 +1,76 @@ +--- +title: legacy_yaml_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/locking/optimistic_rb.html b/src/5.2/files/activerecord/lib/active_record/locking/optimistic_rb.html new file mode 100644 index 0000000000..d741ff0d17 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/locking/optimistic_rb.html @@ -0,0 +1,74 @@ +--- +title: optimistic.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/locking/pessimistic_rb.html b/src/5.2/files/activerecord/lib/active_record/locking/pessimistic_rb.html new file mode 100644 index 0000000000..e4284cb101 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/locking/pessimistic_rb.html @@ -0,0 +1,72 @@ +--- +title: pessimistic.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/log_subscriber_rb.html b/src/5.2/files/activerecord/lib/active_record/log_subscriber_rb.html new file mode 100644 index 0000000000..216cbea4b9 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/log_subscriber_rb.html @@ -0,0 +1,75 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/migration/command_recorder_rb.html b/src/5.2/files/activerecord/lib/active_record/migration/command_recorder_rb.html new file mode 100644 index 0000000000..b02a22f448 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/migration/command_recorder_rb.html @@ -0,0 +1,77 @@ +--- +title: command_recorder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/migration/compatibility_rb.html b/src/5.2/files/activerecord/lib/active_record/migration/compatibility_rb.html new file mode 100644 index 0000000000..4681ada1f1 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/migration/compatibility_rb.html @@ -0,0 +1,87 @@ +--- +title: compatibility.rb +layout: default +--- +
+ + + +
diff --git a/src/5.2/files/activerecord/lib/active_record/migration/join_table_rb.html b/src/5.2/files/activerecord/lib/active_record/migration/join_table_rb.html new file mode 100644 index 0000000000..600d2bd1b7 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/migration/join_table_rb.html @@ -0,0 +1,75 @@ +--- +title: join_table.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/migration_rb.html b/src/5.2/files/activerecord/lib/active_record/migration_rb.html new file mode 100644 index 0000000000..ce55ad6459 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/migration_rb.html @@ -0,0 +1,99 @@ +--- +title: migration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • zlib
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/model_schema_rb.html b/src/5.2/files/activerecord/lib/active_record/model_schema_rb.html new file mode 100644 index 0000000000..b18b6caf88 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/model_schema_rb.html @@ -0,0 +1,82 @@ +--- +title: model_schema.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/nested_attributes_rb.html b/src/5.2/files/activerecord/lib/active_record/nested_attributes_rb.html new file mode 100644 index 0000000000..62d9b317de --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/nested_attributes_rb.html @@ -0,0 +1,93 @@ +--- +title: nested_attributes.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/core_ext/object/try
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/no_touching_rb.html b/src/5.2/files/activerecord/lib/active_record/no_touching_rb.html new file mode 100644 index 0000000000..de8fa1ddbb --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/no_touching_rb.html @@ -0,0 +1,72 @@ +--- +title: no_touching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/null_relation_rb.html b/src/5.2/files/activerecord/lib/active_record/null_relation_rb.html new file mode 100644 index 0000000000..e2ec89aa7d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/null_relation_rb.html @@ -0,0 +1,68 @@ +--- +title: null_relation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/persistence_rb.html b/src/5.2/files/activerecord/lib/active_record/persistence_rb.html new file mode 100644 index 0000000000..8cfdd89cbf --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/persistence_rb.html @@ -0,0 +1,72 @@ +--- +title: persistence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/query_cache_rb.html b/src/5.2/files/activerecord/lib/active_record/query_cache_rb.html new file mode 100644 index 0000000000..551470b87c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/query_cache_rb.html @@ -0,0 +1,77 @@ +--- +title: query_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/querying_rb.html b/src/5.2/files/activerecord/lib/active_record/querying_rb.html new file mode 100644 index 0000000000..127d8225a3 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/querying_rb.html @@ -0,0 +1,72 @@ +--- +title: querying.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/railtie_rb.html b/src/5.2/files/activerecord/lib/active_record/railtie_rb.html new file mode 100644 index 0000000000..cfb4e4d5f8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/railtie_rb.html @@ -0,0 +1,107 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record
  • + +
  • rails
  • + +
  • active_model/railtie
  • + +
  • action_controller/railtie
  • + +
  • active_record/railties/console_sandbox
  • + +
  • active_record/base
  • + +
  • active_record/base
  • + +
  • active_record/relation/record_fetch_warning
  • + +
  • active_record/railties/controller_runtime
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/railties/console_sandbox_rb.html b/src/5.2/files/activerecord/lib/active_record/railties/console_sandbox_rb.html new file mode 100644 index 0000000000..7836e979b0 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/railties/console_sandbox_rb.html @@ -0,0 +1,68 @@ +--- +title: console_sandbox.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/railties/controller_runtime_rb.html b/src/5.2/files/activerecord/lib/active_record/railties/controller_runtime_rb.html new file mode 100644 index 0000000000..ed07110b9b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/railties/controller_runtime_rb.html @@ -0,0 +1,78 @@ +--- +title: controller_runtime.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attr_internal
  • + +
  • active_record/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/readonly_attributes_rb.html b/src/5.2/files/activerecord/lib/active_record/readonly_attributes_rb.html new file mode 100644 index 0000000000..79fa5a5528 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/readonly_attributes_rb.html @@ -0,0 +1,72 @@ +--- +title: readonly_attributes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/reflection_rb.html b/src/5.2/files/activerecord/lib/active_record/reflection_rb.html new file mode 100644 index 0000000000..cf2ffb13da --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/reflection_rb.html @@ -0,0 +1,93 @@ +--- +title: reflection.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/batches/batch_enumerator_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/batches/batch_enumerator_rb.html new file mode 100644 index 0000000000..b05212b88d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/batches/batch_enumerator_rb.html @@ -0,0 +1,77 @@ +--- +title: batch_enumerator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/batches_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/batches_rb.html new file mode 100644 index 0000000000..6e5a902476 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/batches_rb.html @@ -0,0 +1,85 @@ +--- +title: batches.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/relation/batches/batch_enumerator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/calculations_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/calculations_rb.html new file mode 100644 index 0000000000..8f65d21d87 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/calculations_rb.html @@ -0,0 +1,72 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/delegation_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/delegation_rb.html new file mode 100644 index 0000000000..b37a52e3d4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/delegation_rb.html @@ -0,0 +1,72 @@ +--- +title: delegation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/finder_methods_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/finder_methods_rb.html new file mode 100644 index 0000000000..4e8a76ce20 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/finder_methods_rb.html @@ -0,0 +1,80 @@ +--- +title: finder_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/from_clause_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/from_clause_rb.html new file mode 100644 index 0000000000..fe3484113a --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/from_clause_rb.html @@ -0,0 +1,75 @@ +--- +title: from_clause.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/merger_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/merger_rb.html new file mode 100644 index 0000000000..9f26b7bc67 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/merger_rb.html @@ -0,0 +1,85 @@ +--- +title: merger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/array_handler_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/array_handler_rb.html new file mode 100644 index 0000000000..2e57e8bcad --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/array_handler_rb.html @@ -0,0 +1,75 @@ +--- +title: array_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/association_query_value_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/association_query_value_rb.html new file mode 100644 index 0000000000..4b9897d6b4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/association_query_value_rb.html @@ -0,0 +1,75 @@ +--- +title: association_query_value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/base_handler_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/base_handler_rb.html new file mode 100644 index 0000000000..e2f8fc4907 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/base_handler_rb.html @@ -0,0 +1,75 @@ +--- +title: base_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler_rb.html new file mode 100644 index 0000000000..aaffbd8b96 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler_rb.html @@ -0,0 +1,75 @@ +--- +title: basic_object_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value_rb.html new file mode 100644 index 0000000000..5011698eb9 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value_rb.html @@ -0,0 +1,75 @@ +--- +title: polymorphic_array_value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/range_handler_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/range_handler_rb.html new file mode 100644 index 0000000000..1e2adc9083 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/range_handler_rb.html @@ -0,0 +1,79 @@ +--- +title: range_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/relation_handler_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/relation_handler_rb.html new file mode 100644 index 0000000000..f01142d7cc --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder/relation_handler_rb.html @@ -0,0 +1,75 @@ +--- +title: relation_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder_rb.html new file mode 100644 index 0000000000..25208e4aff --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/predicate_builder_rb.html @@ -0,0 +1,97 @@ +--- +title: predicate_builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/relation/predicate_builder/array_handler
  • + +
  • active_record/relation/predicate_builder/base_handler
  • + +
  • active_record/relation/predicate_builder/basic_object_handler
  • + +
  • active_record/relation/predicate_builder/range_handler
  • + +
  • active_record/relation/predicate_builder/relation_handler
  • + +
  • active_record/relation/predicate_builder/association_query_value
  • + +
  • active_record/relation/predicate_builder/polymorphic_array_value
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/query_attribute_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/query_attribute_rb.html new file mode 100644 index 0000000000..5a59645076 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/query_attribute_rb.html @@ -0,0 +1,83 @@ +--- +title: query_attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/query_methods_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/query_methods_rb.html new file mode 100644 index 0000000000..5ed1273f23 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/query_methods_rb.html @@ -0,0 +1,103 @@ +--- +title: query_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/relation/from_clause
  • + +
  • active_record/relation/query_attribute
  • + +
  • active_record/relation/where_clause
  • + +
  • active_record/relation/where_clause_factory
  • + +
  • active_model/forbidden_attributes_protection
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html new file mode 100644 index 0000000000..f3e4dae639 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html @@ -0,0 +1,79 @@ +--- +title: record_fetch_warning.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/spawn_methods_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/spawn_methods_rb.html new file mode 100644 index 0000000000..09c4e3e729 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/spawn_methods_rb.html @@ -0,0 +1,89 @@ +--- +title: spawn_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_record/relation/merger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/where_clause_factory_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/where_clause_factory_rb.html new file mode 100644 index 0000000000..e545cd113d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/where_clause_factory_rb.html @@ -0,0 +1,75 @@ +--- +title: where_clause_factory.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation/where_clause_rb.html b/src/5.2/files/activerecord/lib/active_record/relation/where_clause_rb.html new file mode 100644 index 0000000000..d433268af8 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation/where_clause_rb.html @@ -0,0 +1,75 @@ +--- +title: where_clause.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/relation_rb.html b/src/5.2/files/activerecord/lib/active_record/relation_rb.html new file mode 100644 index 0000000000..539dff8919 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/relation_rb.html @@ -0,0 +1,77 @@ +--- +title: relation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/result_rb.html b/src/5.2/files/activerecord/lib/active_record/result_rb.html new file mode 100644 index 0000000000..e688027bde --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/result_rb.html @@ -0,0 +1,75 @@ +--- +title: result.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/runtime_registry_rb.html b/src/5.2/files/activerecord/lib/active_record/runtime_registry_rb.html new file mode 100644 index 0000000000..73bd45e5a2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/runtime_registry_rb.html @@ -0,0 +1,76 @@ +--- +title: runtime_registry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/per_thread_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/sanitization_rb.html b/src/5.2/files/activerecord/lib/active_record/sanitization_rb.html new file mode 100644 index 0000000000..e9244a1733 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/sanitization_rb.html @@ -0,0 +1,76 @@ +--- +title: sanitization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/schema_dumper_rb.html b/src/5.2/files/activerecord/lib/active_record/schema_dumper_rb.html new file mode 100644 index 0000000000..4780c5fb9c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/schema_dumper_rb.html @@ -0,0 +1,76 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/schema_migration_rb.html b/src/5.2/files/activerecord/lib/active_record/schema_migration_rb.html new file mode 100644 index 0000000000..4d0cb68d18 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/schema_migration_rb.html @@ -0,0 +1,78 @@ +--- +title: schema_migration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/scoping/default
  • + +
  • active_record/scoping/named
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/schema_rb.html b/src/5.2/files/activerecord/lib/active_record/schema_rb.html new file mode 100644 index 0000000000..b582aa21b3 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/schema_rb.html @@ -0,0 +1,75 @@ +--- +title: schema.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/scoping/default_rb.html b/src/5.2/files/activerecord/lib/active_record/scoping/default_rb.html new file mode 100644 index 0000000000..daae730fb5 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/scoping/default_rb.html @@ -0,0 +1,74 @@ +--- +title: default.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/scoping/named_rb.html b/src/5.2/files/activerecord/lib/active_record/scoping/named_rb.html new file mode 100644 index 0000000000..64b3b5d153 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/scoping/named_rb.html @@ -0,0 +1,86 @@ +--- +title: named.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array
  • + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/scoping_rb.html b/src/5.2/files/activerecord/lib/active_record/scoping_rb.html new file mode 100644 index 0000000000..bc3315fce4 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/scoping_rb.html @@ -0,0 +1,78 @@ +--- +title: scoping.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/per_thread_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/secure_token_rb.html b/src/5.2/files/activerecord/lib/active_record/secure_token_rb.html new file mode 100644 index 0000000000..bbc177c8d2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/secure_token_rb.html @@ -0,0 +1,80 @@ +--- +title: secure_token.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/serialization_rb.html b/src/5.2/files/activerecord/lib/active_record/serialization_rb.html new file mode 100644 index 0000000000..3aa5c60703 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/serialization_rb.html @@ -0,0 +1,70 @@ +--- +title: serialization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/statement_cache_rb.html b/src/5.2/files/activerecord/lib/active_record/statement_cache_rb.html new file mode 100644 index 0000000000..cf2afea876 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/statement_cache_rb.html @@ -0,0 +1,68 @@ +--- +title: statement_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/store_rb.html b/src/5.2/files/activerecord/lib/active_record/store_rb.html new file mode 100644 index 0000000000..c876dcef32 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/store_rb.html @@ -0,0 +1,82 @@ +--- +title: store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/suppressor_rb.html b/src/5.2/files/activerecord/lib/active_record/suppressor_rb.html new file mode 100644 index 0000000000..69c68746fa --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/suppressor_rb.html @@ -0,0 +1,72 @@ +--- +title: suppressor.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/table_metadata_rb.html b/src/5.2/files/activerecord/lib/active_record/table_metadata_rb.html new file mode 100644 index 0000000000..57c5a46865 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/table_metadata_rb.html @@ -0,0 +1,68 @@ +--- +title: table_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/tasks/database_tasks_rb.html b/src/5.2/files/activerecord/lib/active_record/tasks/database_tasks_rb.html new file mode 100644 index 0000000000..0aa7a2e5e2 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/tasks/database_tasks_rb.html @@ -0,0 +1,79 @@ +--- +title: database_tasks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/tasks/mysql_database_tasks_rb.html b/src/5.2/files/activerecord/lib/active_record/tasks/mysql_database_tasks_rb.html new file mode 100644 index 0000000000..64baedde7a --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/tasks/mysql_database_tasks_rb.html @@ -0,0 +1,70 @@ +--- +title: mysql_database_tasks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/tasks/postgresql_database_tasks_rb.html b/src/5.2/files/activerecord/lib/active_record/tasks/postgresql_database_tasks_rb.html new file mode 100644 index 0000000000..5771fe271b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/tasks/postgresql_database_tasks_rb.html @@ -0,0 +1,80 @@ +--- +title: postgresql_database_tasks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • tempfile
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/tasks/sqlite_database_tasks_rb.html b/src/5.2/files/activerecord/lib/active_record/tasks/sqlite_database_tasks_rb.html new file mode 100644 index 0000000000..700d89de17 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/tasks/sqlite_database_tasks_rb.html @@ -0,0 +1,78 @@ +--- +title: sqlite_database_tasks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/timestamp_rb.html b/src/5.2/files/activerecord/lib/active_record/timestamp_rb.html new file mode 100644 index 0000000000..1becfaf9d1 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/timestamp_rb.html @@ -0,0 +1,70 @@ +--- +title: timestamp.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/touch_later_rb.html b/src/5.2/files/activerecord/lib/active_record/touch_later_rb.html new file mode 100644 index 0000000000..3a3d337fdb --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/touch_later_rb.html @@ -0,0 +1,72 @@ +--- +title: touch_later.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/transactions_rb.html b/src/5.2/files/activerecord/lib/active_record/transactions_rb.html new file mode 100644 index 0000000000..344315e0c1 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/transactions_rb.html @@ -0,0 +1,72 @@ +--- +title: transactions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/translation_rb.html b/src/5.2/files/activerecord/lib/active_record/translation_rb.html new file mode 100644 index 0000000000..ccc4c1ecce --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/translation_rb.html @@ -0,0 +1,70 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/adapter_specific_registry_rb.html b/src/5.2/files/activerecord/lib/active_record/type/adapter_specific_registry_rb.html new file mode 100644 index 0000000000..3bcc315da1 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/adapter_specific_registry_rb.html @@ -0,0 +1,91 @@ +--- +title: adapter_specific_registry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/date_rb.html b/src/5.2/files/activerecord/lib/active_record/type/date_rb.html new file mode 100644 index 0000000000..9b9a2a4be0 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/date_rb.html @@ -0,0 +1,77 @@ +--- +title: date.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/date_time_rb.html b/src/5.2/files/activerecord/lib/active_record/type/date_time_rb.html new file mode 100644 index 0000000000..e8d9cf78ff --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/date_time_rb.html @@ -0,0 +1,77 @@ +--- +title: date_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/decimal_without_scale_rb.html b/src/5.2/files/activerecord/lib/active_record/type/decimal_without_scale_rb.html new file mode 100644 index 0000000000..1a02a68c56 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/decimal_without_scale_rb.html @@ -0,0 +1,70 @@ +--- +title: decimal_without_scale.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/hash_lookup_type_map_rb.html b/src/5.2/files/activerecord/lib/active_record/type/hash_lookup_type_map_rb.html new file mode 100644 index 0000000000..133a2cd15a --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/hash_lookup_type_map_rb.html @@ -0,0 +1,70 @@ +--- +title: hash_lookup_type_map.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/internal/timezone_rb.html b/src/5.2/files/activerecord/lib/active_record/type/internal/timezone_rb.html new file mode 100644 index 0000000000..ac4fe5860a --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/internal/timezone_rb.html @@ -0,0 +1,74 @@ +--- +title: timezone.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/json_rb.html b/src/5.2/files/activerecord/lib/active_record/type/json_rb.html new file mode 100644 index 0000000000..92fd55c64d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/json_rb.html @@ -0,0 +1,81 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/serialized_rb.html b/src/5.2/files/activerecord/lib/active_record/type/serialized_rb.html new file mode 100644 index 0000000000..6cc33d30de --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/serialized_rb.html @@ -0,0 +1,72 @@ +--- +title: serialized.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/text_rb.html b/src/5.2/files/activerecord/lib/active_record/type/text_rb.html new file mode 100644 index 0000000000..dba5022a9b --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/text_rb.html @@ -0,0 +1,70 @@ +--- +title: text.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/time_rb.html b/src/5.2/files/activerecord/lib/active_record/type/time_rb.html new file mode 100644 index 0000000000..a0023a23b3 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/time_rb.html @@ -0,0 +1,77 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/type_map_rb.html b/src/5.2/files/activerecord/lib/active_record/type/type_map_rb.html new file mode 100644 index 0000000000..f7b9aecffe --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/type_map_rb.html @@ -0,0 +1,78 @@ +--- +title: type_map.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type/unsigned_integer_rb.html b/src/5.2/files/activerecord/lib/active_record/type/unsigned_integer_rb.html new file mode 100644 index 0000000000..19585bbf1d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type/unsigned_integer_rb.html @@ -0,0 +1,70 @@ +--- +title: unsigned_integer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type_caster/connection_rb.html b/src/5.2/files/activerecord/lib/active_record/type_caster/connection_rb.html new file mode 100644 index 0000000000..2f106d284e --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type_caster/connection_rb.html @@ -0,0 +1,68 @@ +--- +title: connection.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type_caster/map_rb.html b/src/5.2/files/activerecord/lib/active_record/type_caster/map_rb.html new file mode 100644 index 0000000000..91396d7547 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type_caster/map_rb.html @@ -0,0 +1,68 @@ +--- +title: map.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type_caster_rb.html b/src/5.2/files/activerecord/lib/active_record/type_caster_rb.html new file mode 100644 index 0000000000..0171a08e59 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type_caster_rb.html @@ -0,0 +1,78 @@ +--- +title: type_caster.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/type_caster/map
  • + +
  • active_record/type_caster/connection
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/type_rb.html b/src/5.2/files/activerecord/lib/active_record/type_rb.html new file mode 100644 index 0000000000..e1f167f69e --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/type_rb.html @@ -0,0 +1,102 @@ +--- +title: type.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type
  • + +
  • active_record/type/internal/timezone
  • + +
  • active_record/type/date
  • + +
  • active_record/type/date_time
  • + +
  • active_record/type/decimal_without_scale
  • + +
  • active_record/type/json
  • + +
  • active_record/type/time
  • + +
  • active_record/type/text
  • + +
  • active_record/type/unsigned_integer
  • + +
  • active_record/type/serialized
  • + +
  • active_record/type/adapter_specific_registry
  • + +
  • active_record/type/type_map
  • + +
  • active_record/type/hash_lookup_type_map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/validations/absence_rb.html b/src/5.2/files/activerecord/lib/active_record/validations/absence_rb.html new file mode 100644 index 0000000000..242d84853d --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/validations/absence_rb.html @@ -0,0 +1,72 @@ +--- +title: absence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/validations/associated_rb.html b/src/5.2/files/activerecord/lib/active_record/validations/associated_rb.html new file mode 100644 index 0000000000..2a6045b274 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/validations/associated_rb.html @@ -0,0 +1,72 @@ +--- +title: associated.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/validations/length_rb.html b/src/5.2/files/activerecord/lib/active_record/validations/length_rb.html new file mode 100644 index 0000000000..c4117b559f --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/validations/length_rb.html @@ -0,0 +1,72 @@ +--- +title: length.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/validations/presence_rb.html b/src/5.2/files/activerecord/lib/active_record/validations/presence_rb.html new file mode 100644 index 0000000000..527606af1c --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/validations/presence_rb.html @@ -0,0 +1,72 @@ +--- +title: presence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/validations/uniqueness_rb.html b/src/5.2/files/activerecord/lib/active_record/validations/uniqueness_rb.html new file mode 100644 index 0000000000..77183d9081 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/validations/uniqueness_rb.html @@ -0,0 +1,72 @@ +--- +title: uniqueness.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/validations_rb.html b/src/5.2/files/activerecord/lib/active_record/validations_rb.html new file mode 100644 index 0000000000..86447def9f --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/validations_rb.html @@ -0,0 +1,93 @@ +--- +title: validations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/validations/associated
  • + +
  • active_record/validations/uniqueness
  • + +
  • active_record/validations/presence
  • + +
  • active_record/validations/absence
  • + +
  • active_record/validations/length
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activerecord/lib/active_record/version_rb.html b/src/5.2/files/activerecord/lib/active_record/version_rb.html new file mode 100644 index 0000000000..55f2655a21 --- /dev/null +++ b/src/5.2/files/activerecord/lib/active_record/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/README_md.html b/src/5.2/files/activestorage/README_md.html new file mode 100644 index 0000000000..9047142c37 --- /dev/null +++ b/src/5.2/files/activestorage/README_md.html @@ -0,0 +1,210 @@ +--- +title: README.md +layout: default +--- +
+ + +
+
+ +
+ +

Active Storage

+ +

Active Storage makes it simple to upload and reference files in cloud services like Amazon S3, Google Cloud Storage, or Microsoft Azure Storage, and attach those files to Active Records. Supports having one main service and mirrors in other services for redundancy. It also provides a disk service for testing or local deployments, but the focus is on cloud storage.

+ +

Files can be uploaded from the server to the cloud or directly from the client to the cloud.

+ +

Image files can furthermore be transformed using on-demand variants for quality, aspect ratio, size, or any other MiniMagick supported transformation.

+ +

Compared to other storage solutions

+ +

A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in Blob and Attachment models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the Attachment join model, which then connects to the actual Blob.

+ +

Blob models store attachment metadata (filename, content-type, etc.), and their identifier key in the storage service. Blob models do not store the actual binary data. They are intended to be immutable in spirit. One file, one blob. You can associate the same blob with multiple application models as well. And if you want to do transformations of a given Blob, the idea is that you'll simply create a new one, rather than attempt to mutate the existing one (though of course you can delete the previous version later if you don't need it).

+ +

Installation

+ +

Run rails active_storage:install to copy over active_storage migrations.

+ +

Examples

+ +

One attachment:

+ +
class User < ApplicationRecord
+  # Associates an attachment and a blob. When the user is destroyed they are
+  # purged by default (models destroyed, and resource files deleted).
+  has_one_attached :avatar
+end
+
+# Attach an avatar to the user.
+user.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpg")
+
+# Does the user have an avatar?
+user.avatar.attached? # => true
+
+# Synchronously destroy the avatar and actual resource files.
+user.avatar.purge
+
+# Destroy the associated models and actual resource files async, via Active Job.
+user.avatar.purge_later
+
+# Does the user have an avatar?
+user.avatar.attached? # => false
+
+# Generate a permanent URL for the blob that points to the application.
+# Upon access, a redirect to the actual service endpoint is returned.
+# This indirection decouples the public URL from the actual one, and
+# allows for example mirroring attachments in different services for
+# high-availability. The redirection has an HTTP expiration of 5 min.
+url_for(user.avatar)
+
+class AvatarsController < ApplicationController
+  def update
+    # params[:avatar] contains a ActionDispatch::Http::UploadedFile object
+    Current.user.avatar.attach(params.require(:avatar))
+    redirect_to Current.user
+  end
+end
+
+ +

Many attachments:

+ +
class Message < ApplicationRecord
+  has_many_attached :images
+end
+
+ +
<%= form_with model: @message, local: true do |form| %>
+  <%= form.text_field :title, placeholder: "Title" %><br>
+  <%= form.text_area :content %><br><br>
+
+  <%= form.file_field :images, multiple: true %><br>
+  <%= form.submit %>
+<% end %>
+
+ +
class MessagesController < ApplicationController
+  def index
+    # Use the built-in with_attached_images scope to avoid N+1
+    @messages = Message.all.with_attached_images
+  end
+
+  def create
+    message = Message.create! params.require(:message).permit(:title, :content)
+    message.images.attach(params[:message][:images])
+    redirect_to message
+  end
+
+  def show
+    @message = Message.find(params[:id])
+  end
+end
+
+ +

Variation of image attachment:

+ +
<%# Hitting the variant URL will lazy transform the original blob and then redirect to its new service location %>
+<%= image_tag user.avatar.variant(resize: "100x100") %>
+
+ +

Direct uploads

+ +

Active Storage, with its included JavaScript library, supports uploading directly from the client to the cloud.

+ +

Direct upload installation

+
  1. +

    Include activestorage.js in your application's JavaScript bundle.

    + +

    Using the asset pipeline:

    + +
    //= require activestorage
    +
    + +

    Using the npm package:

    + +
    import * as ActiveStorage from "activestorage"
    +ActiveStorage.start()
    +
    +
  2. +

    Annotate file inputs with the direct upload URL.

    + +
    <%= form.file_field :attachments, multiple: true, direct_upload: true %>
    +
    +
  3. +

    That's it! Uploads begin upon form submission.

    +
+ +

Direct upload JavaScript events

+ +

| Event name | Event target | Event data (event.detail) | Description | | — | — | — | — | | direct-uploads:start | <form> | None | A form containing files for direct upload fields was submitted. | | direct-upload:initialize | <input> | {id, file} | Dispatched for every file after form submission. | | direct-upload:start | <input> | {id, file} | A direct upload is starting. | | direct-upload:before-blob-request | <input> | {id, file, xhr} | Before making a request to your application for direct upload metadata. | | direct-upload:before-storage-request | <input> | {id, file, xhr} | Before making a request to store a file. | | direct-upload:progress | <input> | {id, file, progress} | As requests to store files progress. | | direct-upload:error | <input> | {id, file, error} | An error occurred. An alert will display unless this event is canceled. | | direct-upload:end | <input> | {id, file} | A direct upload has ended. | | direct-uploads:end | <form> | None | All direct uploads have ended. |

+ +

License

+ +

Active Storage is released under the MIT License.

+ +

Support

+ +

API documentation is at:

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/controllers/active_storage/base_controller_rb.html b/src/5.2/files/activestorage/app/controllers/active_storage/base_controller_rb.html new file mode 100644 index 0000000000..fc0935b383 --- /dev/null +++ b/src/5.2/files/activestorage/app/controllers/active_storage/base_controller_rb.html @@ -0,0 +1,81 @@ +--- +title: base_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

The base controller for all ActiveStorage controllers.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/controllers/active_storage/blobs_controller_rb.html b/src/5.2/files/activestorage/app/controllers/active_storage/blobs_controller_rb.html new file mode 100644 index 0000000000..cf5f1d3f1a --- /dev/null +++ b/src/5.2/files/activestorage/app/controllers/active_storage/blobs_controller_rb.html @@ -0,0 +1,81 @@ +--- +title: blobs_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Take a signed permanent reference for a blob and turn it into an expiring service URL for download. Note: These URLs are publicly accessible. If you need to enforce access protection beyond the security-through-obscurity factor of the signed blob references, you'll need to implement your own authenticated redirection controller.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/controllers/active_storage/direct_uploads_controller_rb.html b/src/5.2/files/activestorage/app/controllers/active_storage/direct_uploads_controller_rb.html new file mode 100644 index 0000000000..6881ea1b18 --- /dev/null +++ b/src/5.2/files/activestorage/app/controllers/active_storage/direct_uploads_controller_rb.html @@ -0,0 +1,81 @@ +--- +title: direct_uploads_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Creates a new blob on the server side in anticipation of a direct-to-service upload from the client side. When the client-side upload is completed, the signed_blob_id can be submitted as part of the form to reference the blob that was created up front.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/controllers/active_storage/disk_controller_rb.html b/src/5.2/files/activestorage/app/controllers/active_storage/disk_controller_rb.html new file mode 100644 index 0000000000..c84d44886a --- /dev/null +++ b/src/5.2/files/activestorage/app/controllers/active_storage/disk_controller_rb.html @@ -0,0 +1,81 @@ +--- +title: disk_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Serves files stored with the disk service in the same way that the cloud services do. This means using expiring, signed URLs that are meant for immediate access, not permanent linking. Always go through the BlobsController, or your own authenticated controller, rather than directly to the service url.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/controllers/active_storage/representations_controller_rb.html b/src/5.2/files/activestorage/app/controllers/active_storage/representations_controller_rb.html new file mode 100644 index 0000000000..5760bf207c --- /dev/null +++ b/src/5.2/files/activestorage/app/controllers/active_storage/representations_controller_rb.html @@ -0,0 +1,81 @@ +--- +title: representations_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Take a signed permanent reference for a blob representation and turn it into an expiring service URL for download. Note: These URLs are publicly accessible. If you need to enforce access protection beyond the security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own authenticated redirection controller.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/controllers/concerns/active_storage/set_blob_rb.html b/src/5.2/files/activestorage/app/controllers/concerns/active_storage/set_blob_rb.html new file mode 100644 index 0000000000..a88dcd561a --- /dev/null +++ b/src/5.2/files/activestorage/app/controllers/concerns/active_storage/set_blob_rb.html @@ -0,0 +1,68 @@ +--- +title: set_blob.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/jobs/active_storage/analyze_job_rb.html b/src/5.2/files/activestorage/app/jobs/active_storage/analyze_job_rb.html new file mode 100644 index 0000000000..8d877687e2 --- /dev/null +++ b/src/5.2/files/activestorage/app/jobs/active_storage/analyze_job_rb.html @@ -0,0 +1,81 @@ +--- +title: analyze_job.rb +layout: default +--- +
+ + +
+
+ +
+ +

Provides asynchronous analysis of ActiveStorage::Blob records via ActiveStorage::Blob#analyze_later.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/jobs/active_storage/base_job_rb.html b/src/5.2/files/activestorage/app/jobs/active_storage/base_job_rb.html new file mode 100644 index 0000000000..cd9de69ffe --- /dev/null +++ b/src/5.2/files/activestorage/app/jobs/active_storage/base_job_rb.html @@ -0,0 +1,75 @@ +--- +title: base_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/jobs/active_storage/purge_job_rb.html b/src/5.2/files/activestorage/app/jobs/active_storage/purge_job_rb.html new file mode 100644 index 0000000000..5fc1cf2627 --- /dev/null +++ b/src/5.2/files/activestorage/app/jobs/active_storage/purge_job_rb.html @@ -0,0 +1,83 @@ +--- +title: purge_job.rb +layout: default +--- +
+ + +
+
+ +
+ +

Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/attachment_rb.html b/src/5.2/files/activestorage/app/models/active_storage/attachment_rb.html new file mode 100644 index 0000000000..2dd2ecf9b8 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/attachment_rb.html @@ -0,0 +1,83 @@ +--- +title: attachment.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/blob/analyzable_rb.html b/src/5.2/files/activestorage/app/models/active_storage/blob/analyzable_rb.html new file mode 100644 index 0000000000..939bebe822 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/blob/analyzable_rb.html @@ -0,0 +1,85 @@ +--- +title: analyzable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_storage/analyzer/null_analyzer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/blob/identifiable_rb.html b/src/5.2/files/activestorage/app/models/active_storage/blob/identifiable_rb.html new file mode 100644 index 0000000000..10c3081317 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/blob/identifiable_rb.html @@ -0,0 +1,77 @@ +--- +title: identifiable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/blob/representable_rb.html b/src/5.2/files/activestorage/app/models/active_storage/blob/representable_rb.html new file mode 100644 index 0000000000..bd8fa2d533 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/blob/representable_rb.html @@ -0,0 +1,77 @@ +--- +title: representable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/blob_rb.html b/src/5.2/files/activestorage/app/models/active_storage/blob_rb.html new file mode 100644 index 0000000000..c916883a04 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/blob_rb.html @@ -0,0 +1,94 @@ +--- +title: blob.rb +layout: default +--- +
+ + +
+
+ +
+ +

A blob is a record that contains the metadata about a file and a key for where that file resides on the service. Blobs can be created in two ways:

+
  1. +

    Subsequent to the file being uploaded server-side to the service via create_after_upload!.

    +
  2. +

    Ahead of the file being directly uploaded client-side to the service via create_before_direct_upload!.

    +
+ +

The first option doesn't require any client-side JavaScript integration, and can be used by any other back-end service that deals with files. The second option is faster, since you're not using your own server as a staging point for uploads, and can work with deployments like Heroku that do not provide large amounts of disk space.

+ +

Blobs are intended to be immutable in as-so-far as their reference to a specific file goes. You're allowed to update a blob's metadata on a subsequent pass, but you should not update the key or change the uploaded file. If you need to create a derivative or otherwise change the blob, simply create a new blob and purge the old one.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/current_rb.html b/src/5.2/files/activestorage/app/models/active_storage/current_rb.html new file mode 100644 index 0000000000..235155e27c --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/current_rb.html @@ -0,0 +1,68 @@ +--- +title: current.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/filename/parameters_rb.html b/src/5.2/files/activestorage/app/models/active_storage/filename/parameters_rb.html new file mode 100644 index 0000000000..ad936a9863 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/filename/parameters_rb.html @@ -0,0 +1,75 @@ +--- +title: parameters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/filename_rb.html b/src/5.2/files/activestorage/app/models/active_storage/filename_rb.html new file mode 100644 index 0000000000..e7c3fbc408 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/filename_rb.html @@ -0,0 +1,81 @@ +--- +title: filename.rb +layout: default +--- +
+ + +
+
+ +
+ +

Encapsulates a string representing a filename to provide convenient access to parts of it and sanitization. A Filename instance is returned by ActiveStorage::Blob#filename, and is comparable so it can be used for sorting.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/preview_rb.html b/src/5.2/files/activestorage/app/models/active_storage/preview_rb.html new file mode 100644 index 0000000000..47991914c2 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/preview_rb.html @@ -0,0 +1,101 @@ +--- +title: preview.rb +layout: default +--- +
+ + +
+
+ +
+ +

Some non-image blobs can be previewed: that is, they can be presented as images. A video blob can be previewed by extracting its first frame, and a PDF blob can be previewed by extracting its first page.

+ +

A previewer extracts a preview image from a blob. Active Storage provides previewers for videos and PDFs: ActiveStorage::Previewer::VideoPreviewer and ActiveStorage::Previewer::PDFPreviewer. Build custom previewers by subclassing ActiveStorage::Previewer and implementing the requisite methods. Consult the ActiveStorage::Previewer documentation for more details on what's required of previewers.

+ +

To choose the previewer for a blob, Active Storage calls accept? on each registered previewer in order. It uses the first previewer for which accept? returns true when given the blob. In a Rails application, add or remove previewers by manipulating Rails.application.config.active_storage.previewers in an initializer:

+ +
Rails.application.config.active_storage.previewers
+# => [ ActiveStorage::Previewer::PDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
+
+# Add a custom previewer for Microsoft Office documents:
+Rails.application.config.active_storage.previewers << DOCXPreviewer
+# => [ ActiveStorage::Previewer::PDFPreviewer, ActiveStorage::Previewer::VideoPreviewer, DOCXPreviewer ]
+
+ +

Outside of a Rails application, modify ActiveStorage.previewers instead.

+ +

The built-in previewers rely on third-party system libraries. Specifically, the built-in video previewer requires ffmpeg. Two PDF previewers are provided: one requires Poppler, and the other requires mupdf (version 1.8 or newer). To preview PDFs, install either Poppler or mupdf.

+ +

These libraries are not provided by Rails. You must install them yourself to use the built-in previewers. Before you install and use third-party software, make sure you understand the licensing implications of doing so.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/variant_rb.html b/src/5.2/files/activestorage/app/models/active_storage/variant_rb.html new file mode 100644 index 0000000000..9d95974405 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/variant_rb.html @@ -0,0 +1,85 @@ +--- +title: variant.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_storage/downloading
  • + +
  • mini_magick
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/app/models/active_storage/variation_rb.html b/src/5.2/files/activestorage/app/models/active_storage/variation_rb.html new file mode 100644 index 0000000000..238b42edf6 --- /dev/null +++ b/src/5.2/files/activestorage/app/models/active_storage/variation_rb.html @@ -0,0 +1,99 @@ +--- +title: variation.rb +layout: default +--- +
+ + +
+
+ +
+ +

A set of transformations that can be applied to a blob to create a variant. This class is exposed via the ActiveStorage::Blob#variant method and should rarely be used directly.

+ +

In case you do need to use this directly, it's instantiated using a hash of transformations where the key is the command and the value is the arguments. Example:

+ +
ActiveStorage::Variation.new(resize: "100x100", monochrome: true, trim: true, rotate: "-90")
+
+ +

You can also combine multiple transformations in one step, e.g. for center-weighted cropping:

+ +
ActiveStorage::Variation.new(combine_options: {
+  resize: "100x100^",
+  gravity: "center",
+  crop: "100x100+0+0",
+})
+
+ +

A list of all possible transformations is available at www.imagemagick.org/script/mogrify.php.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/analyzer/image_analyzer_rb.html b/src/5.2/files/activestorage/lib/active_storage/analyzer/image_analyzer_rb.html new file mode 100644 index 0000000000..10338a4d05 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/analyzer/image_analyzer_rb.html @@ -0,0 +1,85 @@ +--- +title: image_analyzer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mini_magick
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/analyzer/null_analyzer_rb.html b/src/5.2/files/activestorage/lib/active_storage/analyzer/null_analyzer_rb.html new file mode 100644 index 0000000000..f20441fb90 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/analyzer/null_analyzer_rb.html @@ -0,0 +1,75 @@ +--- +title: null_analyzer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/analyzer/video_analyzer_rb.html b/src/5.2/files/activestorage/lib/active_storage/analyzer/video_analyzer_rb.html new file mode 100644 index 0000000000..b24985fa3d --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/analyzer/video_analyzer_rb.html @@ -0,0 +1,85 @@ +--- +title: video_analyzer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/compact
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/analyzer_rb.html b/src/5.2/files/activestorage/lib/active_storage/analyzer_rb.html new file mode 100644 index 0000000000..e51869d60a --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/analyzer_rb.html @@ -0,0 +1,83 @@ +--- +title: analyzer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_storage/downloading
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/attached/macros_rb.html b/src/5.2/files/activestorage/lib/active_storage/attached/macros_rb.html new file mode 100644 index 0000000000..1f3ce5d792 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/attached/macros_rb.html @@ -0,0 +1,77 @@ +--- +title: macros.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/attached/many_rb.html b/src/5.2/files/activestorage/lib/active_storage/attached/many_rb.html new file mode 100644 index 0000000000..ecb490cebb --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/attached/many_rb.html @@ -0,0 +1,77 @@ +--- +title: many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/attached/one_rb.html b/src/5.2/files/activestorage/lib/active_storage/attached/one_rb.html new file mode 100644 index 0000000000..b8d92153ef --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/attached/one_rb.html @@ -0,0 +1,77 @@ +--- +title: one.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/attached_rb.html b/src/5.2/files/activestorage/lib/active_storage/attached_rb.html new file mode 100644 index 0000000000..eeb538dd76 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/attached_rb.html @@ -0,0 +1,97 @@ +--- +title: attached.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch
  • + +
  • action_dispatch/http/upload
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_storage/attached/one
  • + +
  • active_storage/attached/many
  • + +
  • active_storage/attached/macros
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/downloading_rb.html b/src/5.2/files/activestorage/lib/active_storage/downloading_rb.html new file mode 100644 index 0000000000..0bb5bea09b --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/downloading_rb.html @@ -0,0 +1,78 @@ +--- +title: downloading.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • tmpdir
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/engine_rb.html b/src/5.2/files/activestorage/lib/active_storage/engine_rb.html new file mode 100644 index 0000000000..f25b0f27d6 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/engine_rb.html @@ -0,0 +1,103 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
  • active_storage
  • + +
  • active_storage/previewer/poppler_pdf_previewer
  • + +
  • active_storage/previewer/mupdf_previewer
  • + +
  • active_storage/previewer/video_previewer
  • + +
  • active_storage/analyzer/image_analyzer
  • + +
  • active_storage/analyzer/video_analyzer
  • + +
  • active_storage/attached
  • + +
  • yaml
  • + +
  • erb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/errors_rb.html b/src/5.2/files/activestorage/lib/active_storage/errors_rb.html new file mode 100644 index 0000000000..f36c376fd1 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/errors_rb.html @@ -0,0 +1,79 @@ +--- +title: errors.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/gem_version_rb.html b/src/5.2/files/activestorage/lib/active_storage/gem_version_rb.html new file mode 100644 index 0000000000..e209e0b51a --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/log_subscriber_rb.html b/src/5.2/files/activestorage/lib/active_storage/log_subscriber_rb.html new file mode 100644 index 0000000000..b534571e86 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/log_subscriber_rb.html @@ -0,0 +1,83 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/previewer/mupdf_previewer_rb.html b/src/5.2/files/activestorage/lib/active_storage/previewer/mupdf_previewer_rb.html new file mode 100644 index 0000000000..b3d46c9c49 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/previewer/mupdf_previewer_rb.html @@ -0,0 +1,77 @@ +--- +title: mupdf_previewer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/previewer/poppler_pdf_previewer_rb.html b/src/5.2/files/activestorage/lib/active_storage/previewer/poppler_pdf_previewer_rb.html new file mode 100644 index 0000000000..ebfa1bc3df --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/previewer/poppler_pdf_previewer_rb.html @@ -0,0 +1,77 @@ +--- +title: poppler_pdf_previewer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/previewer/video_previewer_rb.html b/src/5.2/files/activestorage/lib/active_storage/previewer/video_previewer_rb.html new file mode 100644 index 0000000000..27f1738320 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/previewer/video_previewer_rb.html @@ -0,0 +1,77 @@ +--- +title: video_previewer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/previewer_rb.html b/src/5.2/files/activestorage/lib/active_storage/previewer_rb.html new file mode 100644 index 0000000000..57f9b64f23 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/previewer_rb.html @@ -0,0 +1,85 @@ +--- +title: previewer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_storage/downloading
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/service/azure_storage_service_rb.html b/src/5.2/files/activestorage/lib/active_storage/service/azure_storage_service_rb.html new file mode 100644 index 0000000000..7fdc9b82ea --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/service/azure_storage_service_rb.html @@ -0,0 +1,89 @@ +--- +title: azure_storage_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/numeric/bytes
  • + +
  • azure/storage
  • + +
  • azure/storage/core/auth/shared_access_signature
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/service/configurator_rb.html b/src/5.2/files/activestorage/lib/active_storage/service/configurator_rb.html new file mode 100644 index 0000000000..463512dfcd --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/service/configurator_rb.html @@ -0,0 +1,75 @@ +--- +title: configurator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/service/disk_service_rb.html b/src/5.2/files/activestorage/lib/active_storage/service/disk_service_rb.html new file mode 100644 index 0000000000..8a436db2b5 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/service/disk_service_rb.html @@ -0,0 +1,93 @@ +--- +title: disk_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • pathname
  • + +
  • digest/md5
  • + +
  • active_support/core_ext/numeric/bytes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/service/gcs_service_rb.html b/src/5.2/files/activestorage/lib/active_storage/service/gcs_service_rb.html new file mode 100644 index 0000000000..9e87edc40a --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/service/gcs_service_rb.html @@ -0,0 +1,89 @@ +--- +title: gcs_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • google/cloud/storage
  • + +
  • net/http
  • + +
  • active_support/core_ext/object/to_query
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/service/mirror_service_rb.html b/src/5.2/files/activestorage/lib/active_storage/service/mirror_service_rb.html new file mode 100644 index 0000000000..e3226bc20a --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/service/mirror_service_rb.html @@ -0,0 +1,85 @@ +--- +title: mirror_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/service/s3_service_rb.html b/src/5.2/files/activestorage/lib/active_storage/service/s3_service_rb.html new file mode 100644 index 0000000000..f67ad7422a --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/service/s3_service_rb.html @@ -0,0 +1,87 @@ +--- +title: s3_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • aws-sdk-s3
  • + +
  • active_support/core_ext/numeric/bytes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/service_rb.html b/src/5.2/files/activestorage/lib/active_storage/service_rb.html new file mode 100644 index 0000000000..26dc5972d3 --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/service_rb.html @@ -0,0 +1,87 @@ +--- +title: service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_storage/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activestorage/lib/active_storage/version_rb.html b/src/5.2/files/activestorage/lib/active_storage/version_rb.html new file mode 100644 index 0000000000..e4cf87d91e --- /dev/null +++ b/src/5.2/files/activestorage/lib/active_storage/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/README_rdoc.html b/src/5.2/files/activesupport/README_rdoc.html new file mode 100644 index 0000000000..9eca745d8d --- /dev/null +++ b/src/5.2/files/activesupport/README_rdoc.html @@ -0,0 +1,99 @@ +--- +title: README.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Active Support – Utility classes and Ruby extensions from Rails

+ +

Active Support is a collection of utility classes and standard library extensions that were found useful for the Rails framework. These additions reside in this package so they can be loaded as needed in Ruby projects outside of Rails.

+ +

Download and installation

+ +

The latest version of Active Support can be installed with RubyGems:

+ +
$ gem install activesupport
+
+ +

Source code can be downloaded as part of the Rails project on GitHub:

+ + +

License

+ +

Active Support is released under the MIT license:

+ + +

Support

+ +

API documentation is at:

+ + +

Bug reports for the Ruby on Rails project can be filed here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/all_rb.html b/src/5.2/files/activesupport/lib/active_support/all_rb.html new file mode 100644 index 0000000000..c989aeb2ca --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/all_rb.html @@ -0,0 +1,67 @@ +--- +title: all.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/time
  • + +
  • active_support/core_ext
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/array_inquirer_rb.html b/src/5.2/files/activesupport/lib/active_support/array_inquirer_rb.html new file mode 100644 index 0000000000..79756953d0 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/array_inquirer_rb.html @@ -0,0 +1,75 @@ +--- +title: array_inquirer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/backtrace_cleaner_rb.html b/src/5.2/files/activesupport/lib/active_support/backtrace_cleaner_rb.html new file mode 100644 index 0000000000..e52ceaf440 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/backtrace_cleaner_rb.html @@ -0,0 +1,75 @@ +--- +title: backtrace_cleaner.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/benchmarkable_rb.html b/src/5.2/files/activesupport/lib/active_support/benchmarkable_rb.html new file mode 100644 index 0000000000..7b9a94de66 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/benchmarkable_rb.html @@ -0,0 +1,80 @@ +--- +title: benchmarkable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/benchmark
  • + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/builder_rb.html b/src/5.2/files/activesupport/lib/active_support/builder_rb.html new file mode 100644 index 0000000000..9cfa83e2fd --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/builder_rb.html @@ -0,0 +1,63 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • builder
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache/file_store_rb.html b/src/5.2/files/activesupport/lib/active_support/cache/file_store_rb.html new file mode 100644 index 0000000000..cc65ed989f --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache/file_store_rb.html @@ -0,0 +1,93 @@ +--- +title: file_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/marshal
  • + +
  • active_support/core_ext/file/atomic
  • + +
  • active_support/core_ext/string/conversions
  • + +
  • uri/common
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache/mem_cache_store_rb.html b/src/5.2/files/activesupport/lib/active_support/cache/mem_cache_store_rb.html new file mode 100644 index 0000000000..570b1ab675 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache/mem_cache_store_rb.html @@ -0,0 +1,91 @@ +--- +title: mem_cache_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • dalli
  • + +
  • active_support/core_ext/marshal
  • + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache/memory_store_rb.html b/src/5.2/files/activesupport/lib/active_support/cache/memory_store_rb.html new file mode 100644 index 0000000000..9d6c76362b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache/memory_store_rb.html @@ -0,0 +1,85 @@ +--- +title: memory_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache/null_store_rb.html b/src/5.2/files/activesupport/lib/active_support/cache/null_store_rb.html new file mode 100644 index 0000000000..dfd652705e --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache/null_store_rb.html @@ -0,0 +1,79 @@ +--- +title: null_store.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache/redis_cache_store_rb.html b/src/5.2/files/activesupport/lib/active_support/cache/redis_cache_store_rb.html new file mode 100644 index 0000000000..d92099facc --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache/redis_cache_store_rb.html @@ -0,0 +1,99 @@ +--- +title: redis_cache_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • redis
  • + +
  • redis/distributed
  • + +
  • redis/connection/hiredis
  • + +
  • digest/sha2
  • + +
  • active_support/core_ext/marshal
  • + +
  • active_support/core_ext/hash/transform_values
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_middleware_rb.html b/src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_middleware_rb.html new file mode 100644 index 0000000000..8bbe7dbc7c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_middleware_rb.html @@ -0,0 +1,84 @@ +--- +title: local_cache_middleware.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/body_proxy
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_rb.html b/src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_rb.html new file mode 100644 index 0000000000..c0c3434ee9 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache/strategy/local_cache_rb.html @@ -0,0 +1,93 @@ +--- +title: local_cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/duplicable
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/per_thread_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/cache_rb.html b/src/5.2/files/activesupport/lib/active_support/cache_rb.html new file mode 100644 index 0000000000..4b307fcc05 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/cache_rb.html @@ -0,0 +1,103 @@ +--- +title: cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/array/wrap
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/numeric/bytes
  • + +
  • active_support/core_ext/numeric/time
  • + +
  • active_support/core_ext/object/to_param
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • connection_pool
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/callbacks_rb.html b/src/5.2/files/activesupport/lib/active_support/callbacks_rb.html new file mode 100644 index 0000000000..b277d57d58 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/callbacks_rb.html @@ -0,0 +1,111 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/descendants_tracker
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/deprecation
  • + +
  • thread
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/concern_rb.html b/src/5.2/files/activesupport/lib/active_support/concern_rb.html new file mode 100644 index 0000000000..fdb41ea47a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/concern_rb.html @@ -0,0 +1,70 @@ +--- +title: concern.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor_rb.html b/src/5.2/files/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor_rb.html new file mode 100644 index 0000000000..1fdba2fb80 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor_rb.html @@ -0,0 +1,85 @@ +--- +title: load_interlock_aware_monitor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/concurrency/share_lock_rb.html b/src/5.2/files/activesupport/lib/active_support/concurrency/share_lock_rb.html new file mode 100644 index 0000000000..48be69f082 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/concurrency/share_lock_rb.html @@ -0,0 +1,87 @@ +--- +title: share_lock.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/configurable_rb.html b/src/5.2/files/activesupport/lib/active_support/configurable_rb.html new file mode 100644 index 0000000000..ac10ece354 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/configurable_rb.html @@ -0,0 +1,93 @@ +--- +title: configurable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/ordered_options
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array/access_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array/access_rb.html new file mode 100644 index 0000000000..b78dad79d8 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array/access_rb.html @@ -0,0 +1,68 @@ +--- +title: access.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array/conversions_rb.html new file mode 100644 index 0000000000..55f21caa63 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array/conversions_rb.html @@ -0,0 +1,93 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/xml_mini
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/core_ext/object/to_param
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/builder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array/extract_options_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array/extract_options_rb.html new file mode 100644 index 0000000000..c17db177f5 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array/extract_options_rb.html @@ -0,0 +1,70 @@ +--- +title: extract_options.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array/grouping_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array/grouping_rb.html new file mode 100644 index 0000000000..4a3d6191f4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array/grouping_rb.html @@ -0,0 +1,68 @@ +--- +title: grouping.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array/inquiry_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array/inquiry_rb.html new file mode 100644 index 0000000000..956d3bd300 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array/inquiry_rb.html @@ -0,0 +1,83 @@ +--- +title: inquiry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/array_inquirer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array/prepend_and_append_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array/prepend_and_append_rb.html new file mode 100644 index 0000000000..895526136b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array/prepend_and_append_rb.html @@ -0,0 +1,68 @@ +--- +title: prepend_and_append.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array/wrap_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array/wrap_rb.html new file mode 100644 index 0000000000..9c137eb840 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array/wrap_rb.html @@ -0,0 +1,68 @@ +--- +title: wrap.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/array_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/array_rb.html new file mode 100644 index 0000000000..9fe09a1b9d --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/array_rb.html @@ -0,0 +1,75 @@ +--- +title: array.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/wrap
  • + +
  • active_support/core_ext/array/access
  • + +
  • active_support/core_ext/array/conversions
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/array/grouping
  • + +
  • active_support/core_ext/array/prepend_and_append
  • + +
  • active_support/core_ext/array/inquiry
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/benchmark_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/benchmark_rb.html new file mode 100644 index 0000000000..65b6681d90 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/benchmark_rb.html @@ -0,0 +1,76 @@ +--- +title: benchmark.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • benchmark
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal/conversions_rb.html new file mode 100644 index 0000000000..80887fef1f --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal/conversions_rb.html @@ -0,0 +1,78 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal
  • + +
  • bigdecimal/util
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal_rb.html new file mode 100644 index 0000000000..d85e1b4eea --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/big_decimal_rb.html @@ -0,0 +1,63 @@ +--- +title: big_decimal.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/big_decimal/conversions
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_accessors_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_accessors_rb.html new file mode 100644 index 0000000000..46b9ba693b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_accessors_rb.html @@ -0,0 +1,69 @@ +--- +title: attribute_accessors.rb +layout: default +--- +
+ + +
+
+ +
+ +

cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d, but we keep this around for libraries that directly require it knowing they want cattr_*. No need to deprecate.

+ +
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_rb.html new file mode 100644 index 0000000000..90d9572b31 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/class/attribute_rb.html @@ -0,0 +1,80 @@ +--- +title: attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/class/subclasses_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/class/subclasses_rb.html new file mode 100644 index 0000000000..788dc09874 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/class/subclasses_rb.html @@ -0,0 +1,68 @@ +--- +title: subclasses.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/class_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/class_rb.html new file mode 100644 index 0000000000..d9439493d4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/class_rb.html @@ -0,0 +1,65 @@ +--- +title: class.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/class/subclasses
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date/acts_like_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date/acts_like_rb.html new file mode 100644 index 0000000000..cd7d85a262 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date/acts_like_rb.html @@ -0,0 +1,76 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/acts_like
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date/blank_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date/blank_rb.html new file mode 100644 index 0000000000..8f8fdb081e --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date/blank_rb.html @@ -0,0 +1,76 @@ +--- +title: blank.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date/calculations_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date/calculations_rb.html new file mode 100644 index 0000000000..0ad84ae2b2 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date/calculations_rb.html @@ -0,0 +1,93 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/duration
  • + +
  • active_support/core_ext/object/acts_like
  • + +
  • active_support/core_ext/date/zones
  • + +
  • active_support/core_ext/time/zones
  • + +
  • active_support/core_ext/date_and_time/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date/conversions_rb.html new file mode 100644 index 0000000000..26438c71a2 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date/conversions_rb.html @@ -0,0 +1,82 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/inflector/methods
  • + +
  • active_support/core_ext/date/zones
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date/zones_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date/zones_rb.html new file mode 100644 index 0000000000..102f6a7828 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date/zones_rb.html @@ -0,0 +1,78 @@ +--- +title: zones.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/core_ext/date_and_time/zones
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/calculations_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/calculations_rb.html new file mode 100644 index 0000000000..fe47a1dbac --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/calculations_rb.html @@ -0,0 +1,78 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/compatibility_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/compatibility_rb.html new file mode 100644 index 0000000000..28c48d3ac0 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/compatibility_rb.html @@ -0,0 +1,78 @@ +--- +title: compatibility.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/zones_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/zones_rb.html new file mode 100644 index 0000000000..e381216757 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_and_time/zones_rb.html @@ -0,0 +1,72 @@ +--- +title: zones.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_rb.html new file mode 100644 index 0000000000..183d1272af --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_rb.html @@ -0,0 +1,71 @@ +--- +title: date.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/date/acts_like
  • + +
  • active_support/core_ext/date/blank
  • + +
  • active_support/core_ext/date/calculations
  • + +
  • active_support/core_ext/date/conversions
  • + +
  • active_support/core_ext/date/zones
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/acts_like_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/acts_like_rb.html new file mode 100644 index 0000000000..e08c1d6001 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/acts_like_rb.html @@ -0,0 +1,78 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/core_ext/object/acts_like
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/blank_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/blank_rb.html new file mode 100644 index 0000000000..a348cfc8fa --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/blank_rb.html @@ -0,0 +1,76 @@ +--- +title: blank.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/calculations_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/calculations_rb.html new file mode 100644 index 0000000000..74bb3820af --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/calculations_rb.html @@ -0,0 +1,76 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/compatibility_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/compatibility_rb.html new file mode 100644 index 0000000000..59a8736d45 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/compatibility_rb.html @@ -0,0 +1,78 @@ +--- +title: compatibility.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/date_and_time/compatibility
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/conversions_rb.html new file mode 100644 index 0000000000..3dbfb4e7fa --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time/conversions_rb.html @@ -0,0 +1,91 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/inflector/methods
  • + +
  • active_support/core_ext/time/conversions
  • + +
  • active_support/core_ext/date_time/calculations
  • + +
  • active_support/values/time_zone
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/date_time_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time_rb.html new file mode 100644 index 0000000000..58d10bf085 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/date_time_rb.html @@ -0,0 +1,71 @@ +--- +title: date_time.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/date_time/acts_like
  • + +
  • active_support/core_ext/date_time/blank
  • + +
  • active_support/core_ext/date_time/calculations
  • + +
  • active_support/core_ext/date_time/compatibility
  • + +
  • active_support/core_ext/date_time/conversions
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/digest/uuid_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/digest/uuid_rb.html new file mode 100644 index 0000000000..26136a7d20 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/digest/uuid_rb.html @@ -0,0 +1,78 @@ +--- +title: uuid.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/digest_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/digest_rb.html new file mode 100644 index 0000000000..ce64a02d97 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/digest_rb.html @@ -0,0 +1,63 @@ +--- +title: digest.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/digest/uuid
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/enumerable_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/enumerable_rb.html new file mode 100644 index 0000000000..9e2b0e7339 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/enumerable_rb.html @@ -0,0 +1,77 @@ +--- +title: enumerable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/file/atomic_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/file/atomic_rb.html new file mode 100644 index 0000000000..f503dd55a3 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/file/atomic_rb.html @@ -0,0 +1,78 @@ +--- +title: atomic.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • tempfile
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/file_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/file_rb.html new file mode 100644 index 0000000000..624c272d32 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/file_rb.html @@ -0,0 +1,63 @@ +--- +title: file.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/file/atomic
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/compact_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/compact_rb.html new file mode 100644 index 0000000000..32b62fa307 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/compact_rb.html @@ -0,0 +1,68 @@ +--- +title: compact.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/conversions_rb.html new file mode 100644 index 0000000000..fd3d4bc76b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/conversions_rb.html @@ -0,0 +1,103 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/xml_mini
  • + +
  • active_support/time
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/core_ext/object/to_param
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/core_ext/array/wrap
  • + +
  • active_support/core_ext/hash/reverse_merge
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/builder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html new file mode 100644 index 0000000000..e3114e7573 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html @@ -0,0 +1,68 @@ +--- +title: deep_merge.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/except_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/except_rb.html new file mode 100644 index 0000000000..038c0ad5f3 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/except_rb.html @@ -0,0 +1,68 @@ +--- +title: except.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/indifferent_access_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/indifferent_access_rb.html new file mode 100644 index 0000000000..91b2c53c30 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/indifferent_access_rb.html @@ -0,0 +1,83 @@ +--- +title: indifferent_access.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/hash_with_indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/keys_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/keys_rb.html new file mode 100644 index 0000000000..87d33e4579 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/keys_rb.html @@ -0,0 +1,68 @@ +--- +title: keys.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/reverse_merge_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/reverse_merge_rb.html new file mode 100644 index 0000000000..74915660ef --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/reverse_merge_rb.html @@ -0,0 +1,68 @@ +--- +title: reverse_merge.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/slice_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/slice_rb.html new file mode 100644 index 0000000000..1780a9732a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/slice_rb.html @@ -0,0 +1,68 @@ +--- +title: slice.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash/transform_values_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/transform_values_rb.html new file mode 100644 index 0000000000..7e27809206 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash/transform_values_rb.html @@ -0,0 +1,68 @@ +--- +title: transform_values.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/hash_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/hash_rb.html new file mode 100644 index 0000000000..548a2ecac4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/hash_rb.html @@ -0,0 +1,79 @@ +--- +title: hash.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/compact
  • + +
  • active_support/core_ext/hash/conversions
  • + +
  • active_support/core_ext/hash/deep_merge
  • + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/hash/reverse_merge
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/hash/transform_values
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/integer/inflections_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/integer/inflections_rb.html new file mode 100644 index 0000000000..44b9ff1b31 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/integer/inflections_rb.html @@ -0,0 +1,83 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/integer/multiple_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/integer/multiple_rb.html new file mode 100644 index 0000000000..46bb529868 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/integer/multiple_rb.html @@ -0,0 +1,68 @@ +--- +title: multiple.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/integer/time_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/integer/time_rb.html new file mode 100644 index 0000000000..8b7138424e --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/integer/time_rb.html @@ -0,0 +1,85 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/duration
  • + +
  • active_support/core_ext/numeric/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/integer_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/integer_rb.html new file mode 100644 index 0000000000..7969c0c4f7 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/integer_rb.html @@ -0,0 +1,67 @@ +--- +title: integer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/integer/multiple
  • + +
  • active_support/core_ext/integer/inflections
  • + +
  • active_support/core_ext/integer/time
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/agnostics_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/agnostics_rb.html new file mode 100644 index 0000000000..13b29e3bf3 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/agnostics_rb.html @@ -0,0 +1,68 @@ +--- +title: agnostics.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/concern_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/concern_rb.html new file mode 100644 index 0000000000..1217a9aabd --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/concern_rb.html @@ -0,0 +1,76 @@ +--- +title: concern.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/concerning
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/reporting_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/reporting_rb.html new file mode 100644 index 0000000000..4cfd23a8ce --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/reporting_rb.html @@ -0,0 +1,68 @@ +--- +title: reporting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/singleton_class_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/singleton_class_rb.html new file mode 100644 index 0000000000..79dfc605ad --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel/singleton_class_rb.html @@ -0,0 +1,68 @@ +--- +title: singleton_class.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/kernel_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel_rb.html new file mode 100644 index 0000000000..6382cf04ec --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/kernel_rb.html @@ -0,0 +1,69 @@ +--- +title: kernel.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/kernel/agnostics
  • + +
  • active_support/core_ext/kernel/concern
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/load_error_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/load_error_rb.html new file mode 100644 index 0000000000..28abe4ace0 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/load_error_rb.html @@ -0,0 +1,68 @@ +--- +title: load_error.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/marshal_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/marshal_rb.html new file mode 100644 index 0000000000..13aa4b8968 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/marshal_rb.html @@ -0,0 +1,68 @@ +--- +title: marshal.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/aliasing_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/aliasing_rb.html new file mode 100644 index 0000000000..a122446885 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/aliasing_rb.html @@ -0,0 +1,68 @@ +--- +title: aliasing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/anonymous_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/anonymous_rb.html new file mode 100644 index 0000000000..3a453fce19 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/anonymous_rb.html @@ -0,0 +1,68 @@ +--- +title: anonymous.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/attr_internal_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/attr_internal_rb.html new file mode 100644 index 0000000000..cebaad05ea --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/attr_internal_rb.html @@ -0,0 +1,68 @@ +--- +title: attr_internal.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread_rb.html new file mode 100644 index 0000000000..820d9af70c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread_rb.html @@ -0,0 +1,78 @@ +--- +title: attribute_accessors_per_thread.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_rb.html new file mode 100644 index 0000000000..6b899b96cf --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_rb.html @@ -0,0 +1,78 @@ +--- +title: attribute_accessors.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/concerning_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/concerning_rb.html new file mode 100644 index 0000000000..66af046102 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/concerning_rb.html @@ -0,0 +1,83 @@ +--- +title: concerning.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/delegation_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/delegation_rb.html new file mode 100644 index 0000000000..b16d931666 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/delegation_rb.html @@ -0,0 +1,80 @@ +--- +title: delegation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/deprecation_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/deprecation_rb.html new file mode 100644 index 0000000000..a60a38f3ca --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/deprecation_rb.html @@ -0,0 +1,75 @@ +--- +title: deprecation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/introspection_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/introspection_rb.html new file mode 100644 index 0000000000..9d53e9b1af --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/introspection_rb.html @@ -0,0 +1,83 @@ +--- +title: introspection.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/reachable_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/reachable_rb.html new file mode 100644 index 0000000000..697963e34d --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/reachable_rb.html @@ -0,0 +1,78 @@ +--- +title: reachable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/anonymous
  • + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/redefine_method_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/redefine_method_rb.html new file mode 100644 index 0000000000..47678234d1 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/redefine_method_rb.html @@ -0,0 +1,68 @@ +--- +title: redefine_method.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module/remove_method_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module/remove_method_rb.html new file mode 100644 index 0000000000..c5f991299a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module/remove_method_rb.html @@ -0,0 +1,76 @@ +--- +title: remove_method.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/module_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/module_rb.html new file mode 100644 index 0000000000..860fa7c5a4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/module_rb.html @@ -0,0 +1,85 @@ +--- +title: module.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/aliasing
  • + +
  • active_support/core_ext/module/introspection
  • + +
  • active_support/core_ext/module/anonymous
  • + +
  • active_support/core_ext/module/reachable
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/module/attribute_accessors_per_thread
  • + +
  • active_support/core_ext/module/attr_internal
  • + +
  • active_support/core_ext/module/concerning
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/module/deprecation
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/core_ext/module/remove_method
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/name_error_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/name_error_rb.html new file mode 100644 index 0000000000..d7c3462a08 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/name_error_rb.html @@ -0,0 +1,68 @@ +--- +title: name_error.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/bytes_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/bytes_rb.html new file mode 100644 index 0000000000..7627ec6915 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/bytes_rb.html @@ -0,0 +1,68 @@ +--- +title: bytes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/conversions_rb.html new file mode 100644 index 0000000000..2e6dac3b04 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/conversions_rb.html @@ -0,0 +1,82 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/big_decimal/conversions
  • + +
  • active_support/number_helper
  • + +
  • active_support/core_ext/module/deprecation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/inquiry_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/inquiry_rb.html new file mode 100644 index 0000000000..130f1f0a60 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/inquiry_rb.html @@ -0,0 +1,70 @@ +--- +title: inquiry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/time_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/time_rb.html new file mode 100644 index 0000000000..4588f0c3d3 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric/time_rb.html @@ -0,0 +1,91 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/duration
  • + +
  • active_support/core_ext/time/calculations
  • + +
  • active_support/core_ext/time/acts_like
  • + +
  • active_support/core_ext/date/calculations
  • + +
  • active_support/core_ext/date/acts_like
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/numeric_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric_rb.html new file mode 100644 index 0000000000..2896bf637a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/numeric_rb.html @@ -0,0 +1,69 @@ +--- +title: numeric.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/numeric/bytes
  • + +
  • active_support/core_ext/numeric/time
  • + +
  • active_support/core_ext/numeric/inquiry
  • + +
  • active_support/core_ext/numeric/conversions
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/acts_like_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/acts_like_rb.html new file mode 100644 index 0000000000..cd6b852881 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/acts_like_rb.html @@ -0,0 +1,68 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/blank_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/blank_rb.html new file mode 100644 index 0000000000..46501c7765 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/blank_rb.html @@ -0,0 +1,94 @@ +--- +title: blank.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/regexp
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/conversions_rb.html new file mode 100644 index 0000000000..3075abf85c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/conversions_rb.html @@ -0,0 +1,69 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/to_param
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/core_ext/array/conversions
  • + +
  • active_support/core_ext/hash/conversions
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/deep_dup_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/deep_dup_rb.html new file mode 100644 index 0000000000..aeaa174dea --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/deep_dup_rb.html @@ -0,0 +1,80 @@ +--- +title: deep_dup.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/duplicable
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/duplicable_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/duplicable_rb.html new file mode 100644 index 0000000000..55a5ea76c4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/duplicable_rb.html @@ -0,0 +1,94 @@ +--- +title: duplicable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/inclusion_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/inclusion_rb.html new file mode 100644 index 0000000000..3de015a64f --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/inclusion_rb.html @@ -0,0 +1,68 @@ +--- +title: inclusion.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/instance_variables_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/instance_variables_rb.html new file mode 100644 index 0000000000..d55404ced4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/instance_variables_rb.html @@ -0,0 +1,68 @@ +--- +title: instance_variables.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/json_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/json_rb.html new file mode 100644 index 0000000000..5e3ec0de6b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/json_rb.html @@ -0,0 +1,149 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ +
+ +

Hack to load json gem first so we can overwrite its to_json.

+ +
+ + + + +

Required Files

+
    + +
  • json
  • + +
  • bigdecimal
  • + +
  • uri/generic
  • + +
  • pathname
  • + +
  • active_support/core_ext/big_decimal/conversions
  • + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/object/instance_variables
  • + +
  • time
  • + +
  • active_support/core_ext/time/conversions
  • + +
  • active_support/core_ext/date_time/conversions
  • + +
  • active_support/core_ext/date/conversions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/to_param_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/to_param_rb.html new file mode 100644 index 0000000000..31b52cbb1b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/to_param_rb.html @@ -0,0 +1,63 @@ +--- +title: to_param.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/to_query
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/to_query_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/to_query_rb.html new file mode 100644 index 0000000000..ec5c50f068 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/to_query_rb.html @@ -0,0 +1,86 @@ +--- +title: to_query.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/try_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/try_rb.html new file mode 100644 index 0000000000..cd558691d7 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/try_rb.html @@ -0,0 +1,87 @@ +--- +title: try.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delegate
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object/with_options_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object/with_options_rb.html new file mode 100644 index 0000000000..3b6c71bd6e --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object/with_options_rb.html @@ -0,0 +1,83 @@ +--- +title: with_options.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/option_merger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/object_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/object_rb.html new file mode 100644 index 0000000000..265dd5e4cd --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/object_rb.html @@ -0,0 +1,85 @@ +--- +title: object.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/acts_like
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/core_ext/object/duplicable
  • + +
  • active_support/core_ext/object/deep_dup
  • + +
  • active_support/core_ext/object/try
  • + +
  • active_support/core_ext/object/inclusion
  • + +
  • active_support/core_ext/object/conversions
  • + +
  • active_support/core_ext/object/instance_variables
  • + +
  • active_support/core_ext/object/json
  • + +
  • active_support/core_ext/object/to_param
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/core_ext/object/with_options
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/range/compare_range_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/range/compare_range_rb.html new file mode 100644 index 0000000000..38161f90f6 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/range/compare_range_rb.html @@ -0,0 +1,68 @@ +--- +title: compare_range.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/range/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/range/conversions_rb.html new file mode 100644 index 0000000000..350c9d158a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/range/conversions_rb.html @@ -0,0 +1,70 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/range/each_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/range/each_rb.html new file mode 100644 index 0000000000..97ebc4d6ba --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/range/each_rb.html @@ -0,0 +1,76 @@ +--- +title: each.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/time_with_zone
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/range/include_range_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/range/include_range_rb.html new file mode 100644 index 0000000000..18db14c8da --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/range/include_range_rb.html @@ -0,0 +1,63 @@ +--- +title: include_range.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/range/compare_range
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/range/include_time_with_zone_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/range/include_time_with_zone_rb.html new file mode 100644 index 0000000000..87079e6931 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/range/include_time_with_zone_rb.html @@ -0,0 +1,76 @@ +--- +title: include_time_with_zone.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/time_with_zone
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/range/overlaps_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/range/overlaps_rb.html new file mode 100644 index 0000000000..93ff5f3fcf --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/range/overlaps_rb.html @@ -0,0 +1,68 @@ +--- +title: overlaps.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/range_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/range_rb.html new file mode 100644 index 0000000000..7a80151536 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/range_rb.html @@ -0,0 +1,71 @@ +--- +title: range.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/range/conversions
  • + +
  • active_support/core_ext/range/compare_range
  • + +
  • active_support/core_ext/range/include_time_with_zone
  • + +
  • active_support/core_ext/range/overlaps
  • + +
  • active_support/core_ext/range/each
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/regexp_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/regexp_rb.html new file mode 100644 index 0000000000..cccedaa166 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/regexp_rb.html @@ -0,0 +1,55 @@ +--- +title: regexp.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/securerandom_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/securerandom_rb.html new file mode 100644 index 0000000000..30cb208bad --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/securerandom_rb.html @@ -0,0 +1,76 @@ +--- +title: securerandom.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/access_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/access_rb.html new file mode 100644 index 0000000000..96e39ff559 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/access_rb.html @@ -0,0 +1,68 @@ +--- +title: access.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/behavior_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/behavior_rb.html new file mode 100644 index 0000000000..5ba5edec42 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/behavior_rb.html @@ -0,0 +1,68 @@ +--- +title: behavior.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/conversions_rb.html new file mode 100644 index 0000000000..0f65f6c6c3 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/conversions_rb.html @@ -0,0 +1,78 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/core_ext/time/calculations
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/exclude_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/exclude_rb.html new file mode 100644 index 0000000000..8d68d46eac --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/exclude_rb.html @@ -0,0 +1,68 @@ +--- +title: exclude.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/filters_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/filters_rb.html new file mode 100644 index 0000000000..f065ee15b2 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/filters_rb.html @@ -0,0 +1,68 @@ +--- +title: filters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/indent_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/indent_rb.html new file mode 100644 index 0000000000..44f8f215ff --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/indent_rb.html @@ -0,0 +1,68 @@ +--- +title: indent.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/inflections_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/inflections_rb.html new file mode 100644 index 0000000000..a5e1239f1b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/inflections_rb.html @@ -0,0 +1,85 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
  • active_support/inflector/transliterate
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/inquiry_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/inquiry_rb.html new file mode 100644 index 0000000000..170e5169f8 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/inquiry_rb.html @@ -0,0 +1,83 @@ +--- +title: inquiry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/string_inquirer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/multibyte_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/multibyte_rb.html new file mode 100644 index 0000000000..f212977be1 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/multibyte_rb.html @@ -0,0 +1,83 @@ +--- +title: multibyte.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/multibyte
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/output_safety_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/output_safety_rb.html new file mode 100644 index 0000000000..9db4b8f730 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/output_safety_rb.html @@ -0,0 +1,101 @@ +--- +title: output_safety.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • erb
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/multibyte/unicode
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/starts_ends_with_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/starts_ends_with_rb.html new file mode 100644 index 0000000000..c441225315 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/starts_ends_with_rb.html @@ -0,0 +1,68 @@ +--- +title: starts_ends_with.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/strip_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/strip_rb.html new file mode 100644 index 0000000000..210720abfd --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/strip_rb.html @@ -0,0 +1,68 @@ +--- +title: strip.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string/zones_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string/zones_rb.html new file mode 100644 index 0000000000..678342ab93 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string/zones_rb.html @@ -0,0 +1,78 @@ +--- +title: zones.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/conversions
  • + +
  • active_support/core_ext/time/zones
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/string_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/string_rb.html new file mode 100644 index 0000000000..1f6408007f --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/string_rb.html @@ -0,0 +1,87 @@ +--- +title: string.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/conversions
  • + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/core_ext/string/multibyte
  • + +
  • active_support/core_ext/string/starts_ends_with
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/core_ext/string/access
  • + +
  • active_support/core_ext/string/behavior
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/core_ext/string/exclude
  • + +
  • active_support/core_ext/string/strip
  • + +
  • active_support/core_ext/string/inquiry
  • + +
  • active_support/core_ext/string/indent
  • + +
  • active_support/core_ext/string/zones
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/time/acts_like_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/time/acts_like_rb.html new file mode 100644 index 0000000000..ef4075484c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/time/acts_like_rb.html @@ -0,0 +1,76 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/acts_like
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/time/calculations_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/time/calculations_rb.html new file mode 100644 index 0000000000..78e16a039b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/time/calculations_rb.html @@ -0,0 +1,93 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/duration
  • + +
  • active_support/core_ext/time/conversions
  • + +
  • active_support/time_with_zone
  • + +
  • active_support/core_ext/time/zones
  • + +
  • active_support/core_ext/date_and_time/calculations
  • + +
  • active_support/core_ext/date/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/time/compatibility_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/time/compatibility_rb.html new file mode 100644 index 0000000000..84ab359bb4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/time/compatibility_rb.html @@ -0,0 +1,78 @@ +--- +title: compatibility.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/date_and_time/compatibility
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/time/conversions_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/time/conversions_rb.html new file mode 100644 index 0000000000..48f29dae75 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/time/conversions_rb.html @@ -0,0 +1,85 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
  • active_support/values/time_zone
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/time/zones_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/time/zones_rb.html new file mode 100644 index 0000000000..13e45788f4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/time/zones_rb.html @@ -0,0 +1,87 @@ +--- +title: zones.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/time_with_zone
  • + +
  • active_support/core_ext/time/acts_like
  • + +
  • active_support/core_ext/date_and_time/zones
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/time_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/time_rb.html new file mode 100644 index 0000000000..f6296d36c8 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/time_rb.html @@ -0,0 +1,71 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/acts_like
  • + +
  • active_support/core_ext/time/calculations
  • + +
  • active_support/core_ext/time/compatibility
  • + +
  • active_support/core_ext/time/conversions
  • + +
  • active_support/core_ext/time/zones
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext/uri_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext/uri_rb.html new file mode 100644 index 0000000000..08b0d62246 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext/uri_rb.html @@ -0,0 +1,78 @@ +--- +title: uri.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • uri
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/core_ext_rb.html b/src/5.2/files/activesupport/lib/active_support/core_ext_rb.html new file mode 100644 index 0000000000..b7c9a422b8 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/core_ext_rb.html @@ -0,0 +1,55 @@ +--- +title: core_ext.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/current_attributes_rb.html b/src/5.2/files/activesupport/lib/active_support/current_attributes_rb.html new file mode 100644 index 0000000000..2536c99a4c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/current_attributes_rb.html @@ -0,0 +1,75 @@ +--- +title: current_attributes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/dependencies/autoload_rb.html b/src/5.2/files/activesupport/lib/active_support/dependencies/autoload_rb.html new file mode 100644 index 0000000000..5d202b05cc --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/dependencies/autoload_rb.html @@ -0,0 +1,78 @@ +--- +title: autoload.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/dependencies/interlock_rb.html b/src/5.2/files/activesupport/lib/active_support/dependencies/interlock_rb.html new file mode 100644 index 0000000000..aae260d74b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/dependencies/interlock_rb.html @@ -0,0 +1,87 @@ +--- +title: interlock.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concurrency/share_lock
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/dependencies_rb.html b/src/5.2/files/activesupport/lib/active_support/dependencies_rb.html new file mode 100644 index 0000000000..72bea22478 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/dependencies_rb.html @@ -0,0 +1,117 @@ +--- +title: dependencies.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • thread
  • + +
  • concurrent/map
  • + +
  • pathname
  • + +
  • active_support/core_ext/module/aliasing
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/module/introspection
  • + +
  • active_support/core_ext/module/anonymous
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/core_ext/load_error
  • + +
  • active_support/core_ext/name_error
  • + +
  • active_support/core_ext/string/starts_ends_with
  • + +
  • active_support/dependencies/interlock
  • + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/deprecation/behaviors_rb.html b/src/5.2/files/activesupport/lib/active_support/deprecation/behaviors_rb.html new file mode 100644 index 0000000000..2f99786878 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/deprecation/behaviors_rb.html @@ -0,0 +1,87 @@ +--- +title: behaviors.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/notifications
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/deprecation/constant_accessor_rb.html b/src/5.2/files/activesupport/lib/active_support/deprecation/constant_accessor_rb.html new file mode 100644 index 0000000000..6767fca433 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/deprecation/constant_accessor_rb.html @@ -0,0 +1,85 @@ +--- +title: constant_accessor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/deprecation/instance_delegator_rb.html b/src/5.2/files/activesupport/lib/active_support/deprecation/instance_delegator_rb.html new file mode 100644 index 0000000000..2cc9799d83 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/deprecation/instance_delegator_rb.html @@ -0,0 +1,85 @@ +--- +title: instance_delegator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/deprecation/method_wrappers_rb.html b/src/5.2/files/activesupport/lib/active_support/deprecation/method_wrappers_rb.html new file mode 100644 index 0000000000..f1c5cf8531 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/deprecation/method_wrappers_rb.html @@ -0,0 +1,87 @@ +--- +title: method_wrappers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/aliasing
  • + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/deprecation/proxy_wrappers_rb.html b/src/5.2/files/activesupport/lib/active_support/deprecation/proxy_wrappers_rb.html new file mode 100644 index 0000000000..fdf158d9cc --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/deprecation/proxy_wrappers_rb.html @@ -0,0 +1,91 @@ +--- +title: proxy_wrappers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/regexp
  • + +
  • active_support/inflector/methods
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/deprecation/reporting_rb.html b/src/5.2/files/activesupport/lib/active_support/deprecation/reporting_rb.html new file mode 100644 index 0000000000..ec48b4ffcb --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/deprecation/reporting_rb.html @@ -0,0 +1,85 @@ +--- +title: reporting.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rbconfig
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/deprecation_rb.html b/src/5.2/files/activesupport/lib/active_support/deprecation_rb.html new file mode 100644 index 0000000000..7c638adf10 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/deprecation_rb.html @@ -0,0 +1,97 @@ +--- +title: deprecation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • singleton
  • + +
  • active_support/deprecation/instance_delegator
  • + +
  • active_support/deprecation/behaviors
  • + +
  • active_support/deprecation/reporting
  • + +
  • active_support/deprecation/constant_accessor
  • + +
  • active_support/deprecation/method_wrappers
  • + +
  • active_support/deprecation/proxy_wrappers
  • + +
  • active_support/core_ext/module/deprecation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/descendants_tracker_rb.html b/src/5.2/files/activesupport/lib/active_support/descendants_tracker_rb.html new file mode 100644 index 0000000000..b243360fe6 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/descendants_tracker_rb.html @@ -0,0 +1,70 @@ +--- +title: descendants_tracker.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/digest_rb.html b/src/5.2/files/activesupport/lib/active_support/digest_rb.html new file mode 100644 index 0000000000..8bc5f6ae32 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/digest_rb.html @@ -0,0 +1,68 @@ +--- +title: digest.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/duration/iso8601_parser_rb.html b/src/5.2/files/activesupport/lib/active_support/duration/iso8601_parser_rb.html new file mode 100644 index 0000000000..dfe7144781 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/duration/iso8601_parser_rb.html @@ -0,0 +1,89 @@ +--- +title: iso8601_parser.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/duration/iso8601_serializer_rb.html b/src/5.2/files/activesupport/lib/active_support/duration/iso8601_serializer_rb.html new file mode 100644 index 0000000000..aca6199220 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/duration/iso8601_serializer_rb.html @@ -0,0 +1,85 @@ +--- +title: iso8601_serializer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/core_ext/hash/transform_values
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/duration_rb.html b/src/5.2/files/activesupport/lib/active_support/duration_rb.html new file mode 100644 index 0000000000..ab8aabbd1a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/duration_rb.html @@ -0,0 +1,91 @@ +--- +title: duration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/conversions
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/object/acts_like
  • + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/deprecation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/encrypted_configuration_rb.html b/src/5.2/files/activesupport/lib/active_support/encrypted_configuration_rb.html new file mode 100644 index 0000000000..7e1b361979 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/encrypted_configuration_rb.html @@ -0,0 +1,91 @@ +--- +title: encrypted_configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
  • active_support/encrypted_file
  • + +
  • active_support/ordered_options
  • + +
  • active_support/core_ext/object/inclusion
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/encrypted_file_rb.html b/src/5.2/files/activesupport/lib/active_support/encrypted_file_rb.html new file mode 100644 index 0000000000..1bc86b53b0 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/encrypted_file_rb.html @@ -0,0 +1,89 @@ +--- +title: encrypted_file.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • active_support/message_encryptor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/evented_file_update_checker_rb.html b/src/5.2/files/activesupport/lib/active_support/evented_file_update_checker_rb.html new file mode 100644 index 0000000000..d0ce380769 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/evented_file_update_checker_rb.html @@ -0,0 +1,91 @@ +--- +title: evented_file_update_checker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • pathname
  • + +
  • concurrent/atomic/atomic_boolean
  • + +
  • listen
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/execution_wrapper_rb.html b/src/5.2/files/activesupport/lib/active_support/execution_wrapper_rb.html new file mode 100644 index 0000000000..35b69db302 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/execution_wrapper_rb.html @@ -0,0 +1,83 @@ +--- +title: execution_wrapper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/executor_rb.html b/src/5.2/files/activesupport/lib/active_support/executor_rb.html new file mode 100644 index 0000000000..37ce4ad64f --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/executor_rb.html @@ -0,0 +1,83 @@ +--- +title: executor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/execution_wrapper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/file_update_checker_rb.html b/src/5.2/files/activesupport/lib/active_support/file_update_checker_rb.html new file mode 100644 index 0000000000..270060c216 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/file_update_checker_rb.html @@ -0,0 +1,83 @@ +--- +title: file_update_checker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/gem_version_rb.html b/src/5.2/files/activesupport/lib/active_support/gem_version_rb.html new file mode 100644 index 0000000000..5bee50f44d --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/gzip_rb.html b/src/5.2/files/activesupport/lib/active_support/gzip_rb.html new file mode 100644 index 0000000000..eba3c8c915 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/gzip_rb.html @@ -0,0 +1,87 @@ +--- +title: gzip.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/hash_with_indifferent_access_rb.html b/src/5.2/files/activesupport/lib/active_support/hash_with_indifferent_access_rb.html new file mode 100644 index 0000000000..9729a10b8c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/hash_with_indifferent_access_rb.html @@ -0,0 +1,85 @@ +--- +title: hash_with_indifferent_access.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/hash/reverse_merge
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/i18n_railtie_rb.html b/src/5.2/files/activesupport/lib/active_support/i18n_railtie_rb.html new file mode 100644 index 0000000000..b70867f70c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/i18n_railtie_rb.html @@ -0,0 +1,67 @@ +--- +title: i18n_railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/file_update_checker
  • + +
  • active_support/core_ext/array/wrap
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/i18n_rb.html b/src/5.2/files/activesupport/lib/active_support/i18n_rb.html new file mode 100644 index 0000000000..4727a72741 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/i18n_rb.html @@ -0,0 +1,71 @@ +--- +title: i18n.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/deep_merge
  • + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • i18n
  • + +
  • active_support/lazy_load_hooks
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/inflections_rb.html b/src/5.2/files/activesupport/lib/active_support/inflections_rb.html new file mode 100644 index 0000000000..5c05f5a2fc --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/inflections_rb.html @@ -0,0 +1,76 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/inflector/inflections_rb.html b/src/5.2/files/activesupport/lib/active_support/inflector/inflections_rb.html new file mode 100644 index 0000000000..2e441fa652 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/inflector/inflections_rb.html @@ -0,0 +1,95 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • active_support/core_ext/array/prepend_and_append
  • + +
  • active_support/core_ext/regexp
  • + +
  • active_support/i18n
  • + +
  • active_support/deprecation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/inflector/methods_rb.html b/src/5.2/files/activesupport/lib/active_support/inflector/methods_rb.html new file mode 100644 index 0000000000..2e6abb891a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/inflector/methods_rb.html @@ -0,0 +1,80 @@ +--- +title: methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflections
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/inflector/transliterate_rb.html b/src/5.2/files/activesupport/lib/active_support/inflector/transliterate_rb.html new file mode 100644 index 0000000000..ac6fa61b5d --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/inflector/transliterate_rb.html @@ -0,0 +1,80 @@ +--- +title: transliterate.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/multibyte
  • + +
  • active_support/i18n
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/inflector_rb.html b/src/5.2/files/activesupport/lib/active_support/inflector_rb.html new file mode 100644 index 0000000000..c6f7ee29cb --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/inflector_rb.html @@ -0,0 +1,77 @@ +--- +title: inflector.rb +layout: default +--- +
+ + +
+
+ +
+ +

in case active_support/inflector is required without the rest of active_support

+ +
+ + + + +

Required Files

+
    + +
  • active_support/inflector/inflections
  • + +
  • active_support/inflector/transliterate
  • + +
  • active_support/inflector/methods
  • + +
  • active_support/inflections
  • + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/json/decoding_rb.html b/src/5.2/files/activesupport/lib/active_support/json/decoding_rb.html new file mode 100644 index 0000000000..bd29802ad4 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/json/decoding_rb.html @@ -0,0 +1,82 @@ +--- +title: decoding.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/json/encoding_rb.html b/src/5.2/files/activesupport/lib/active_support/json/encoding_rb.html new file mode 100644 index 0000000000..40ba80e03a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/json/encoding_rb.html @@ -0,0 +1,80 @@ +--- +title: encoding.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/json
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/json_rb.html b/src/5.2/files/activesupport/lib/active_support/json_rb.html new file mode 100644 index 0000000000..f77a16ce9e --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/json_rb.html @@ -0,0 +1,65 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/json/decoding
  • + +
  • active_support/json/encoding
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/key_generator_rb.html b/src/5.2/files/activesupport/lib/active_support/key_generator_rb.html new file mode 100644 index 0000000000..c85ad82216 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/key_generator_rb.html @@ -0,0 +1,87 @@ +--- +title: key_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/lazy_load_hooks_rb.html b/src/5.2/files/activesupport/lib/active_support/lazy_load_hooks_rb.html new file mode 100644 index 0000000000..cfdaf9cbbd --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/lazy_load_hooks_rb.html @@ -0,0 +1,70 @@ +--- +title: lazy_load_hooks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/log_subscriber/test_helper_rb.html b/src/5.2/files/activesupport/lib/active_support/log_subscriber/test_helper_rb.html new file mode 100644 index 0000000000..f1cc6f1e34 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/log_subscriber/test_helper_rb.html @@ -0,0 +1,91 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
  • active_support/logger
  • + +
  • active_support/notifications
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/log_subscriber_rb.html b/src/5.2/files/activesupport/lib/active_support/log_subscriber_rb.html new file mode 100644 index 0000000000..e334bea486 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/log_subscriber_rb.html @@ -0,0 +1,87 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/logger_rb.html b/src/5.2/files/activesupport/lib/active_support/logger_rb.html new file mode 100644 index 0000000000..6e32400ac6 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/logger_rb.html @@ -0,0 +1,89 @@ +--- +title: logger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/logger_silence
  • + +
  • active_support/logger_thread_safe_level
  • + +
  • logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/logger_silence_rb.html b/src/5.2/files/activesupport/lib/active_support/logger_silence_rb.html new file mode 100644 index 0000000000..03816eef33 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/logger_silence_rb.html @@ -0,0 +1,80 @@ +--- +title: logger_silence.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • concurrent
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/logger_thread_safe_level_rb.html b/src/5.2/files/activesupport/lib/active_support/logger_thread_safe_level_rb.html new file mode 100644 index 0000000000..db6226e2c6 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/logger_thread_safe_level_rb.html @@ -0,0 +1,78 @@ +--- +title: logger_thread_safe_level.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • fiber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/message_encryptor_rb.html b/src/5.2/files/activesupport/lib/active_support/message_encryptor_rb.html new file mode 100644 index 0000000000..2e0b9ea480 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/message_encryptor_rb.html @@ -0,0 +1,95 @@ +--- +title: message_encryptor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • openssl
  • + +
  • base64
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/message_verifier
  • + +
  • active_support/messages/metadata
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/message_verifier_rb.html b/src/5.2/files/activesupport/lib/active_support/message_verifier_rb.html new file mode 100644 index 0000000000..eb70d25dc3 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/message_verifier_rb.html @@ -0,0 +1,95 @@ +--- +title: message_verifier.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • base64
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/security_utils
  • + +
  • active_support/messages/metadata
  • + +
  • active_support/messages/rotator
  • + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/messages/metadata_rb.html b/src/5.2/files/activesupport/lib/active_support/messages/metadata_rb.html new file mode 100644 index 0000000000..46c771650c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/messages/metadata_rb.html @@ -0,0 +1,78 @@ +--- +title: metadata.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/messages/rotation_configuration_rb.html b/src/5.2/files/activesupport/lib/active_support/messages/rotation_configuration_rb.html new file mode 100644 index 0000000000..18d7738822 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/messages/rotation_configuration_rb.html @@ -0,0 +1,70 @@ +--- +title: rotation_configuration.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/messages/rotator_rb.html b/src/5.2/files/activesupport/lib/active_support/messages/rotator_rb.html new file mode 100644 index 0000000000..53f0bef049 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/messages/rotator_rb.html @@ -0,0 +1,76 @@ +--- +title: rotator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/multibyte/chars_rb.html b/src/5.2/files/activesupport/lib/active_support/multibyte/chars_rb.html new file mode 100644 index 0000000000..22f667f382 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/multibyte/chars_rb.html @@ -0,0 +1,93 @@ +--- +title: chars.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/json
  • + +
  • active_support/core_ext/string/access
  • + +
  • active_support/core_ext/string/behavior
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/multibyte/unicode_rb.html b/src/5.2/files/activesupport/lib/active_support/multibyte/unicode_rb.html new file mode 100644 index 0000000000..065c236503 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/multibyte/unicode_rb.html @@ -0,0 +1,81 @@ +--- +title: unicode.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/multibyte_rb.html b/src/5.2/files/activesupport/lib/active_support/multibyte_rb.html new file mode 100644 index 0000000000..adf8f101da --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/multibyte_rb.html @@ -0,0 +1,70 @@ +--- +title: multibyte.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/notifications/fanout_rb.html b/src/5.2/files/activesupport/lib/active_support/notifications/fanout_rb.html new file mode 100644 index 0000000000..c277bd9ca1 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/notifications/fanout_rb.html @@ -0,0 +1,87 @@ +--- +title: fanout.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mutex_m
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/notifications/instrumenter_rb.html b/src/5.2/files/activesupport/lib/active_support/notifications/instrumenter_rb.html new file mode 100644 index 0000000000..bfd4b05340 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/notifications/instrumenter_rb.html @@ -0,0 +1,87 @@ +--- +title: instrumenter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/notifications_rb.html b/src/5.2/files/activesupport/lib/active_support/notifications_rb.html new file mode 100644 index 0000000000..d6091ad3d6 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/notifications_rb.html @@ -0,0 +1,82 @@ +--- +title: notifications.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/notifications/instrumenter
  • + +
  • active_support/notifications/fanout
  • + +
  • active_support/per_thread_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_converter_rb.html new file mode 100644 index 0000000000..32b572cfac --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_converter_rb.html @@ -0,0 +1,86 @@ +--- +title: number_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/big_decimal/conversions
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/i18n
  • + +
  • active_support/core_ext/class/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_currency_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_currency_converter_rb.html new file mode 100644 index 0000000000..7e9b7f3fc8 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_currency_converter_rb.html @@ -0,0 +1,78 @@ +--- +title: number_to_currency_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/numeric/inquiry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_delimited_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_delimited_converter_rb.html new file mode 100644 index 0000000000..3e07a415f0 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_delimited_converter_rb.html @@ -0,0 +1,70 @@ +--- +title: number_to_delimited_converter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_converter_rb.html new file mode 100644 index 0000000000..62e65ba8c8 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_converter_rb.html @@ -0,0 +1,70 @@ +--- +title: number_to_human_converter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_size_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_size_converter_rb.html new file mode 100644 index 0000000000..1d126f4bb9 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_human_size_converter_rb.html @@ -0,0 +1,70 @@ +--- +title: number_to_human_size_converter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_percentage_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_percentage_converter_rb.html new file mode 100644 index 0000000000..315f99e4fe --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_percentage_converter_rb.html @@ -0,0 +1,70 @@ +--- +title: number_to_percentage_converter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_phone_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_phone_converter_rb.html new file mode 100644 index 0000000000..730ed3208b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_phone_converter_rb.html @@ -0,0 +1,70 @@ +--- +title: number_to_phone_converter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_rounded_converter_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_rounded_converter_rb.html new file mode 100644 index 0000000000..fd2579da5d --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/number_to_rounded_converter_rb.html @@ -0,0 +1,70 @@ +--- +title: number_to_rounded_converter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper/rounding_helper_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper/rounding_helper_rb.html new file mode 100644 index 0000000000..fca6ec4de5 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper/rounding_helper_rb.html @@ -0,0 +1,70 @@ +--- +title: rounding_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/number_helper_rb.html b/src/5.2/files/activesupport/lib/active_support/number_helper_rb.html new file mode 100644 index 0000000000..5df9fef840 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/number_helper_rb.html @@ -0,0 +1,70 @@ +--- +title: number_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/option_merger_rb.html b/src/5.2/files/activesupport/lib/active_support/option_merger_rb.html new file mode 100644 index 0000000000..88a9af887e --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/option_merger_rb.html @@ -0,0 +1,76 @@ +--- +title: option_merger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/deep_merge
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/ordered_hash_rb.html b/src/5.2/files/activesupport/lib/active_support/ordered_hash_rb.html new file mode 100644 index 0000000000..4374883c47 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/ordered_hash_rb.html @@ -0,0 +1,83 @@ +--- +title: ordered_hash.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/ordered_options_rb.html b/src/5.2/files/activesupport/lib/active_support/ordered_options_rb.html new file mode 100644 index 0000000000..1eede0e723 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/ordered_options_rb.html @@ -0,0 +1,85 @@ +--- +title: ordered_options.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/blank
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/per_thread_registry_rb.html b/src/5.2/files/activesupport/lib/active_support/per_thread_registry_rb.html new file mode 100644 index 0000000000..1f0cee9d4f --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/per_thread_registry_rb.html @@ -0,0 +1,78 @@ +--- +title: per_thread_registry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/proxy_object_rb.html b/src/5.2/files/activesupport/lib/active_support/proxy_object_rb.html new file mode 100644 index 0000000000..53b440702a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/proxy_object_rb.html @@ -0,0 +1,75 @@ +--- +title: proxy_object.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/rails_rb.html b/src/5.2/files/activesupport/lib/active_support/rails_rb.html new file mode 100644 index 0000000000..eda66c1709 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/rails_rb.html @@ -0,0 +1,85 @@ +--- +title: rails.rb +layout: default +--- +
+ + +
+
+ +
+ +

This is private interface.

+ +

Rails components cherry pick from Active Support as needed, but there are a few features that are used for sure in some way or another and it is not worth putting individual requires absolutely everywhere. Think blank? for example.

+ +

This file is loaded by every Rails component except Active Support itself, but it does not belong to the Rails public interface. It is internal to Rails and can change anytime.

+ +
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/dependencies/autoload
  • + +
  • active_support/concern
  • + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/deprecation
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/railtie_rb.html b/src/5.2/files/activesupport/lib/active_support/railtie_rb.html new file mode 100644 index 0000000000..b04b3a148a --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/railtie_rb.html @@ -0,0 +1,82 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/i18n_railtie
  • + +
  • active_support/core_ext/time/zones
  • + +
  • active_support/core_ext/date/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/reloader_rb.html b/src/5.2/files/activesupport/lib/active_support/reloader_rb.html new file mode 100644 index 0000000000..cb77617167 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/reloader_rb.html @@ -0,0 +1,83 @@ +--- +title: reloader.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/execution_wrapper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/rescuable_rb.html b/src/5.2/files/activesupport/lib/active_support/rescuable_rb.html new file mode 100644 index 0000000000..7c3987b617 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/rescuable_rb.html @@ -0,0 +1,84 @@ +--- +title: rescuable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/security_utils_rb.html b/src/5.2/files/activesupport/lib/active_support/security_utils_rb.html new file mode 100644 index 0000000000..a3125de4f8 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/security_utils_rb.html @@ -0,0 +1,78 @@ +--- +title: security_utils.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • digest/sha2
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/string_inquirer_rb.html b/src/5.2/files/activesupport/lib/active_support/string_inquirer_rb.html new file mode 100644 index 0000000000..f30a1aeb4c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/string_inquirer_rb.html @@ -0,0 +1,75 @@ +--- +title: string_inquirer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/subscriber_rb.html b/src/5.2/files/activesupport/lib/active_support/subscriber_rb.html new file mode 100644 index 0000000000..0037c89ab1 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/subscriber_rb.html @@ -0,0 +1,89 @@ +--- +title: subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/per_thread_registry
  • + +
  • active_support/notifications
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/tagged_logging_rb.html b/src/5.2/files/activesupport/lib/active_support/tagged_logging_rb.html new file mode 100644 index 0000000000..559f918631 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/tagged_logging_rb.html @@ -0,0 +1,91 @@ +--- +title: tagged_logging.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/object/blank
  • + +
  • logger
  • + +
  • active_support/logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/test_case_rb.html b/src/5.2/files/activesupport/lib/active_support/test_case_rb.html new file mode 100644 index 0000000000..50a8509d97 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/test_case_rb.html @@ -0,0 +1,101 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • minitest
  • + +
  • active_support/testing/tagged_logging
  • + +
  • active_support/testing/setup_and_teardown
  • + +
  • active_support/testing/assertions
  • + +
  • active_support/testing/deprecation
  • + +
  • active_support/testing/declarative
  • + +
  • active_support/testing/isolation
  • + +
  • active_support/testing/constant_lookup
  • + +
  • active_support/testing/time_helpers
  • + +
  • active_support/testing/file_fixtures
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/assertions_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/assertions_rb.html new file mode 100644 index 0000000000..35b54bcc05 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/assertions_rb.html @@ -0,0 +1,72 @@ +--- +title: assertions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/autorun_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/autorun_rb.html new file mode 100644 index 0000000000..686d266586 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/autorun_rb.html @@ -0,0 +1,63 @@ +--- +title: autorun.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • minitest
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/constant_lookup_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/constant_lookup_rb.html new file mode 100644 index 0000000000..751abeb402 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/constant_lookup_rb.html @@ -0,0 +1,82 @@ +--- +title: constant_lookup.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/declarative_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/declarative_rb.html new file mode 100644 index 0000000000..dbde48033e --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/declarative_rb.html @@ -0,0 +1,72 @@ +--- +title: declarative.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/deprecation_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/deprecation_rb.html new file mode 100644 index 0000000000..85ceba2e2f --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/deprecation_rb.html @@ -0,0 +1,80 @@ +--- +title: deprecation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/deprecation
  • + +
  • active_support/core_ext/regexp
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/file_fixtures_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/file_fixtures_rb.html new file mode 100644 index 0000000000..98ed90ee05 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/file_fixtures_rb.html @@ -0,0 +1,72 @@ +--- +title: file_fixtures.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/isolation_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/isolation_rb.html new file mode 100644 index 0000000000..26ad7f1f36 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/isolation_rb.html @@ -0,0 +1,88 @@ +--- +title: isolation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • tempfile
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/method_call_assertions_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/method_call_assertions_rb.html new file mode 100644 index 0000000000..47984efd69 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/method_call_assertions_rb.html @@ -0,0 +1,80 @@ +--- +title: method_call_assertions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • minitest/mock
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/setup_and_teardown_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/setup_and_teardown_rb.html new file mode 100644 index 0000000000..c3f96d4d51 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/setup_and_teardown_rb.html @@ -0,0 +1,84 @@ +--- +title: setup_and_teardown.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/stream_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/stream_rb.html new file mode 100644 index 0000000000..30c317e5d0 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/stream_rb.html @@ -0,0 +1,77 @@ +--- +title: stream.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+
    + +
  • IO
  • + +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/tagged_logging_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/tagged_logging_rb.html new file mode 100644 index 0000000000..8bb5d8e405 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/tagged_logging_rb.html @@ -0,0 +1,70 @@ +--- +title: tagged_logging.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/testing/time_helpers_rb.html b/src/5.2/files/activesupport/lib/active_support/testing/time_helpers_rb.html new file mode 100644 index 0000000000..7c60fc728c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/testing/time_helpers_rb.html @@ -0,0 +1,86 @@ +--- +title: time_helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/core_ext/string/strip
  • + +
  • active_support/core_ext/time/calculations
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/time_rb.html b/src/5.2/files/activesupport/lib/active_support/time_rb.html new file mode 100644 index 0000000000..fa5a74364b --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/time_rb.html @@ -0,0 +1,92 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • time
  • + +
  • active_support/core_ext/time
  • + +
  • active_support/core_ext/date
  • + +
  • active_support/core_ext/date_time
  • + +
  • active_support/core_ext/integer/time
  • + +
  • active_support/core_ext/numeric/time
  • + +
  • active_support/core_ext/string/conversions
  • + +
  • active_support/core_ext/string/zones
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/time_with_zone_rb.html b/src/5.2/files/activesupport/lib/active_support/time_with_zone_rb.html new file mode 100644 index 0000000000..6a928e651c --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/time_with_zone_rb.html @@ -0,0 +1,93 @@ +--- +title: time_with_zone.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/duration
  • + +
  • active_support/values/time_zone
  • + +
  • active_support/core_ext/object/acts_like
  • + +
  • active_support/core_ext/date_and_time/compatibility
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/values/time_zone_rb.html b/src/5.2/files/activesupport/lib/active_support/values/time_zone_rb.html new file mode 100644 index 0000000000..3dcb366405 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/values/time_zone_rb.html @@ -0,0 +1,87 @@ +--- +title: time_zone.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • tzinfo
  • + +
  • concurrent/map
  • + +
  • active_support/core_ext/object/blank
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/version_rb.html b/src/5.2/files/activesupport/lib/active_support/version_rb.html new file mode 100644 index 0000000000..226ee45c41 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/version_rb.html @@ -0,0 +1,68 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/xml_mini/jdom_rb.html b/src/5.2/files/activesupport/lib/active_support/xml_mini/jdom_rb.html new file mode 100644 index 0000000000..2be5bbc31d --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/xml_mini/jdom_rb.html @@ -0,0 +1,78 @@ +--- +title: jdom.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • jruby
  • + +
  • active_support/core_ext/object/blank
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/xml_mini/libxml_rb.html b/src/5.2/files/activesupport/lib/active_support/xml_mini/libxml_rb.html new file mode 100644 index 0000000000..44c5a851a9 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/xml_mini/libxml_rb.html @@ -0,0 +1,80 @@ +--- +title: libxml.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • libxml
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/xml_mini/libxmlsax_rb.html b/src/5.2/files/activesupport/lib/active_support/xml_mini/libxmlsax_rb.html new file mode 100644 index 0000000000..df946ef5d0 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/xml_mini/libxmlsax_rb.html @@ -0,0 +1,89 @@ +--- +title: libxmlsax.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • libxml
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/xml_mini/nokogiri_rb.html b/src/5.2/files/activesupport/lib/active_support/xml_mini/nokogiri_rb.html new file mode 100644 index 0000000000..396dba1b47 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/xml_mini/nokogiri_rb.html @@ -0,0 +1,80 @@ +--- +title: nokogiri.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • nokogiri
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/xml_mini/nokogirisax_rb.html b/src/5.2/files/activesupport/lib/active_support/xml_mini/nokogirisax_rb.html new file mode 100644 index 0000000000..e87adf2df1 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/xml_mini/nokogirisax_rb.html @@ -0,0 +1,89 @@ +--- +title: nokogirisax.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • nokogiri
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/xml_mini/rexml_rb.html b/src/5.2/files/activesupport/lib/active_support/xml_mini/rexml_rb.html new file mode 100644 index 0000000000..4dcfd2c1a9 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/xml_mini/rexml_rb.html @@ -0,0 +1,82 @@ +--- +title: rexml.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
  • rexml/document
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/activesupport/lib/active_support/xml_mini_rb.html b/src/5.2/files/activesupport/lib/active_support/xml_mini_rb.html new file mode 100644 index 0000000000..b000b383e7 --- /dev/null +++ b/src/5.2/files/activesupport/lib/active_support/xml_mini_rb.html @@ -0,0 +1,88 @@ +--- +title: xml_mini.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • time
  • + +
  • base64
  • + +
  • bigdecimal
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/core_ext/date_time/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/RDOC_MAIN_rdoc.html b/src/5.2/files/railties/RDOC_MAIN_rdoc.html new file mode 100644 index 0000000000..8a3399f93e --- /dev/null +++ b/src/5.2/files/railties/RDOC_MAIN_rdoc.html @@ -0,0 +1,123 @@ +--- +title: RDOC_MAIN.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Welcome to Rails

+ +

Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.

+ +

Understanding the MVC pattern is key to understanding Rails. MVC divides your application into three layers, each with a specific responsibility.

+ +

The Model layer represents your domain model (such as Account, Product, Person, Post, etc.) and encapsulates the business logic that is specific to your application. In Rails, database-backed model classes are derived from ActiveRecord::Base. Active Record allows you to present the data from database rows as objects and embellish these data objects with business logic methods. You can read more about Active Record in its README. Although most Rails models are backed by a database, models can also be ordinary Ruby classes, or Ruby classes that implement a set of interfaces as provided by the Active Model module. You can read more about Active Model in its README.

+ +

The Controller layer is responsible for handling incoming HTTP requests and providing a suitable response. Usually this means returning HTML, but Rails controllers can also generate XML, JSON, PDFs, mobile-specific views, and more. Controllers load and manipulate models, and render view templates in order to generate the appropriate HTTP response. In Rails, incoming requests are routed by Action Dispatch to an appropriate controller, and controller classes are derived from ActionController::Base. Action Dispatch and Action Controller are bundled together in Action Pack. You can read more about Action Pack in its README.

+ +

The View layer is composed of “templates” that are responsible for providing appropriate representations of your application's resources. Templates can come in a variety of formats, but most view templates are HTML with embedded Ruby code (ERB files). Views are typically rendered to generate a controller response, or to generate the body of an email. In Rails, View generation is handled by Action View. You can read more about Action View in its README.

+ +

Active Record, Active Model, Action Pack, and Action View can each be used independently outside Rails. In addition to that, Rails also comes with Action Mailer (README), a library to generate and send emails; Active Job (README), a framework for declaring jobs and making them run on a variety of queueing backends; Action Cable (README), a framework to integrate WebSockets with a Rails application; Active Storage (README), a library to attach cloud and local files to Rails applications; and Active Support (README), a collection of utility classes and standard library extensions that are useful for Rails, and may also be used independently outside Rails.

+ +

Getting Started

+
  1. +

    Install Rails at the command prompt if you haven't yet:

    + +
    $ gem install rails
    +
    +
  2. +

    At the command prompt, create a new Rails application:

    + +
    $ rails new myapp
    +
    + +

    where “myapp” is the application name.

    +
  3. +

    Change directory to myapp and start the web server:

    + +
    $ cd myapp
    +$ rails server
    +
    + +

    Run with --help or -h for options.

    +
  4. +

    Go to http://localhost:3000 and you'll see: “Yay! You’re on Rails!”

    +
  5. +

    Follow the guidelines to start developing your application. You may find the following resources handy:

    + +
+ +

Contributing

+ +

We encourage you to contribute to Ruby on Rails! Please check out the Contributing to Ruby on Rails guide for guidelines about how to proceed. Join us!

+ +

Trying to report a possible security vulnerability in Rails? Please check out our security policy for guidelines about how to proceed.

+ +

Everyone interacting in Rails and its sub-projects' codebases, issue trackers, chat rooms, and mailing lists is expected to follow the Rails code of conduct.

+ +

License

+ +

Ruby on Rails is released under the MIT License.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/README_rdoc.html b/src/5.2/files/railties/README_rdoc.html new file mode 100644 index 0000000000..0d21117f56 --- /dev/null +++ b/src/5.2/files/railties/README_rdoc.html @@ -0,0 +1,106 @@ +--- +title: README.rdoc +layout: default +--- +
+ + +
+
+ +
+ +

Railties – Gluing the Engine to the Rails

+ +

Railties is responsible for gluing all frameworks together. Overall, it:

+
  • +

    handles the bootstrapping process for a Rails application;

    +
  • +

    manages the rails command line interface;

    +
  • +

    and provides the Rails generators core.

    +
+ +

Download

+ +

The latest version of Railties can be installed with RubyGems:

+
  • +

    gem install railties

    +
+ +

Source code can be downloaded as part of the Rails project on GitHub

+ + +

License

+ +

Railties is released under the MIT license:

+ + +

Support

+ +

API documentation is at

+ + +

Bug reports can be filed for the Ruby on Rails project here:

+ + +

Feature requests should be discussed on the rails-core mailing list here:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/minitest/rails_plugin_rb.html b/src/5.2/files/railties/lib/minitest/rails_plugin_rb.html new file mode 100644 index 0000000000..44786a0c10 --- /dev/null +++ b/src/5.2/files/railties/lib/minitest/rails_plugin_rb.html @@ -0,0 +1,89 @@ +--- +title: rails_plugin.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • rails/test_unit/reporter
  • + +
  • rails/test_unit/runner
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/all_rb.html b/src/5.2/files/railties/lib/rails/all_rb.html new file mode 100644 index 0000000000..9a3529f6f8 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/all_rb.html @@ -0,0 +1,63 @@ +--- +title: all.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/api/task_rb.html b/src/5.2/files/railties/lib/rails/api/task_rb.html new file mode 100644 index 0000000000..9c9ff5504b --- /dev/null +++ b/src/5.2/files/railties/lib/rails/api/task_rb.html @@ -0,0 +1,93 @@ +--- +title: task.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rdoc/task
  • + +
  • rails/api/generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/app_loader_rb.html b/src/5.2/files/railties/lib/rails/app_loader_rb.html new file mode 100644 index 0000000000..52eade02bf --- /dev/null +++ b/src/5.2/files/railties/lib/rails/app_loader_rb.html @@ -0,0 +1,80 @@ +--- +title: app_loader.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • rails/version
  • + +
  • rails/commands
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/app_updater_rb.html b/src/5.2/files/railties/lib/rails/app_updater_rb.html new file mode 100644 index 0000000000..bf416f9476 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/app_updater_rb.html @@ -0,0 +1,84 @@ +--- +title: app_updater.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/app/app_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/application/bootstrap_rb.html b/src/5.2/files/railties/lib/rails/application/bootstrap_rb.html new file mode 100644 index 0000000000..828e05a375 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/application/bootstrap_rb.html @@ -0,0 +1,99 @@ +--- +title: bootstrap.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • active_support/notifications
  • + +
  • active_support/dependencies
  • + +
  • active_support/descendants_tracker
  • + +
  • rails/secrets
  • + +
  • active_support/all
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/application/configuration_rb.html b/src/5.2/files/railties/lib/rails/application/configuration_rb.html new file mode 100644 index 0000000000..56638ffe2a --- /dev/null +++ b/src/5.2/files/railties/lib/rails/application/configuration_rb.html @@ -0,0 +1,107 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/file_update_checker
  • + +
  • rails/engine/configuration
  • + +
  • rails/source_annotation_extractor
  • + +
  • yaml
  • + +
  • erb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/application/default_middleware_stack_rb.html b/src/5.2/files/railties/lib/rails/application/default_middleware_stack_rb.html new file mode 100644 index 0000000000..7d9b54d4b8 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/application/default_middleware_stack_rb.html @@ -0,0 +1,91 @@ +--- +title: default_middleware_stack.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/rack_cache
  • + +
  • rack/cache
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/application/finisher_rb.html b/src/5.2/files/railties/lib/rails/application/finisher_rb.html new file mode 100644 index 0000000000..e39da4ada7 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/application/finisher_rb.html @@ -0,0 +1,83 @@ +--- +title: finisher.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/application/routes_reloader_rb.html b/src/5.2/files/railties/lib/rails/application/routes_reloader_rb.html new file mode 100644 index 0000000000..f76e04bd04 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/application/routes_reloader_rb.html @@ -0,0 +1,87 @@ +--- +title: routes_reloader.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/application_controller_rb.html b/src/5.2/files/railties/lib/rails/application_controller_rb.html new file mode 100644 index 0000000000..e7389a348d --- /dev/null +++ b/src/5.2/files/railties/lib/rails/application_controller_rb.html @@ -0,0 +1,68 @@ +--- +title: application_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/application_rb.html b/src/5.2/files/railties/lib/rails/application_rb.html new file mode 100644 index 0000000000..8f3179a3e4 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/application_rb.html @@ -0,0 +1,109 @@ +--- +title: application.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/key_generator
  • + +
  • active_support/message_verifier
  • + +
  • active_support/encrypted_configuration
  • + +
  • active_support/deprecation
  • + +
  • rails/engine
  • + +
  • rails/secrets
  • + +
  • erb
  • + +
  • pp
  • + +
  • psych/y
  • + +
  • rails/tasks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/backtrace_cleaner_rb.html b/src/5.2/files/railties/lib/rails/backtrace_cleaner_rb.html new file mode 100644 index 0000000000..1daf213ff2 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/backtrace_cleaner_rb.html @@ -0,0 +1,83 @@ +--- +title: backtrace_cleaner.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/backtrace_cleaner
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/cli_rb.html b/src/5.2/files/railties/lib/rails/cli_rb.html new file mode 100644 index 0000000000..a33942c8c7 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/cli_rb.html @@ -0,0 +1,80 @@ +--- +title: cli.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/app_loader
  • + +
  • rails/ruby_version_check
  • + +
  • rails/command
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/code_statistics_calculator_rb.html b/src/5.2/files/railties/lib/rails/code_statistics_calculator_rb.html new file mode 100644 index 0000000000..c832da9cbc --- /dev/null +++ b/src/5.2/files/railties/lib/rails/code_statistics_calculator_rb.html @@ -0,0 +1,55 @@ +--- +title: code_statistics_calculator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/code_statistics_rb.html b/src/5.2/files/railties/lib/rails/code_statistics_rb.html new file mode 100644 index 0000000000..f02fbd9635 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/code_statistics_rb.html @@ -0,0 +1,65 @@ +--- +title: code_statistics.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/code_statistics_calculator
  • + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/command/actions_rb.html b/src/5.2/files/railties/lib/rails/command/actions_rb.html new file mode 100644 index 0000000000..409fe7ff72 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/command/actions_rb.html @@ -0,0 +1,72 @@ +--- +title: actions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/command/base_rb.html b/src/5.2/files/railties/lib/rails/command/base_rb.html new file mode 100644 index 0000000000..0a622c23ae --- /dev/null +++ b/src/5.2/files/railties/lib/rails/command/base_rb.html @@ -0,0 +1,93 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thor
  • + +
  • erb
  • + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • rails/command/actions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/command/behavior_rb.html b/src/5.2/files/railties/lib/rails/command/behavior_rb.html new file mode 100644 index 0000000000..55c918a21a --- /dev/null +++ b/src/5.2/files/railties/lib/rails/command/behavior_rb.html @@ -0,0 +1,78 @@ +--- +title: behavior.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/command/environment_argument_rb.html b/src/5.2/files/railties/lib/rails/command/environment_argument_rb.html new file mode 100644 index 0000000000..ae15cf40be --- /dev/null +++ b/src/5.2/files/railties/lib/rails/command/environment_argument_rb.html @@ -0,0 +1,80 @@ +--- +title: environment_argument.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/command/helpers/editor_rb.html b/src/5.2/files/railties/lib/rails/command/helpers/editor_rb.html new file mode 100644 index 0000000000..6ab9a6d88c --- /dev/null +++ b/src/5.2/files/railties/lib/rails/command/helpers/editor_rb.html @@ -0,0 +1,82 @@ +--- +title: editor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/encrypted_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/command_rb.html b/src/5.2/files/railties/lib/rails/command_rb.html new file mode 100644 index 0000000000..8ef1db2544 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/command_rb.html @@ -0,0 +1,88 @@ +--- +title: command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/dependencies/autoload
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/core_ext/hash/transform_values
  • + +
  • thor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/application/application_command_rb.html b/src/5.2/files/railties/lib/rails/commands/application/application_command_rb.html new file mode 100644 index 0000000000..84eaafd027 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/application/application_command_rb.html @@ -0,0 +1,82 @@ +--- +title: application_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/app/app_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/console/console_command_rb.html b/src/5.2/files/railties/lib/rails/commands/console/console_command_rb.html new file mode 100644 index 0000000000..f90d7b344b --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/console/console_command_rb.html @@ -0,0 +1,91 @@ +--- +title: console_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • irb
  • + +
  • irb/completion
  • + +
  • rails/command/environment_argument
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/credentials/credentials_command_rb.html b/src/5.2/files/railties/lib/rails/commands/credentials/credentials_command_rb.html new file mode 100644 index 0000000000..fd8e13fc2e --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/credentials/credentials_command_rb.html @@ -0,0 +1,90 @@ +--- +title: credentials_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • rails/command/helpers/editor
  • + +
  • rails/generators
  • + +
  • rails/generators/rails/master_key/master_key_generator
  • + +
  • rails/generators
  • + +
  • rails/generators/rails/credentials/credentials_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/dbconsole/dbconsole_command_rb.html b/src/5.2/files/railties/lib/rails/commands/dbconsole/dbconsole_command_rb.html new file mode 100644 index 0000000000..2055b3715f --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/dbconsole/dbconsole_command_rb.html @@ -0,0 +1,89 @@ +--- +title: dbconsole_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command/environment_argument
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/destroy/destroy_command_rb.html b/src/5.2/files/railties/lib/rails/commands/destroy/destroy_command_rb.html new file mode 100644 index 0000000000..5f1c657a5f --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/destroy/destroy_command_rb.html @@ -0,0 +1,78 @@ +--- +title: destroy_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/encrypted/encrypted_command_rb.html b/src/5.2/files/railties/lib/rails/commands/encrypted/encrypted_command_rb.html new file mode 100644 index 0000000000..5fe11e4258 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/encrypted/encrypted_command_rb.html @@ -0,0 +1,92 @@ +--- +title: encrypted_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • active_support
  • + +
  • rails/command/helpers/editor
  • + +
  • rails/generators
  • + +
  • rails/generators/rails/encryption_key_file/encryption_key_file_generator
  • + +
  • rails/generators
  • + +
  • rails/generators/rails/encrypted_file/encrypted_file_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/generate/generate_command_rb.html b/src/5.2/files/railties/lib/rails/commands/generate/generate_command_rb.html new file mode 100644 index 0000000000..4225195e14 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/generate/generate_command_rb.html @@ -0,0 +1,78 @@ +--- +title: generate_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/help/help_command_rb.html b/src/5.2/files/railties/lib/rails/commands/help/help_command_rb.html new file mode 100644 index 0000000000..ceb2e001b7 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/help/help_command_rb.html @@ -0,0 +1,70 @@ +--- +title: help_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/new/new_command_rb.html b/src/5.2/files/railties/lib/rails/commands/new/new_command_rb.html new file mode 100644 index 0000000000..420dbb9d19 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/new/new_command_rb.html @@ -0,0 +1,70 @@ +--- +title: new_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/plugin/plugin_command_rb.html b/src/5.2/files/railties/lib/rails/commands/plugin/plugin_command_rb.html new file mode 100644 index 0000000000..3ebbc20f33 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/plugin/plugin_command_rb.html @@ -0,0 +1,82 @@ +--- +title: plugin_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/plugin/plugin_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/rake/rake_command_rb.html b/src/5.2/files/railties/lib/rails/commands/rake/rake_command_rb.html new file mode 100644 index 0000000000..b8a0d5f424 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/rake/rake_command_rb.html @@ -0,0 +1,78 @@ +--- +title: rake_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rake
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/runner/runner_command_rb.html b/src/5.2/files/railties/lib/rails/commands/runner/runner_command_rb.html new file mode 100644 index 0000000000..60dfa8129c --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/runner/runner_command_rb.html @@ -0,0 +1,70 @@ +--- +title: runner_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/secrets/secrets_command_rb.html b/src/5.2/files/railties/lib/rails/commands/secrets/secrets_command_rb.html new file mode 100644 index 0000000000..cf19646b5b --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/secrets/secrets_command_rb.html @@ -0,0 +1,80 @@ +--- +title: secrets_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • rails/secrets
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/server/server_command_rb.html b/src/5.2/files/railties/lib/rails/commands/server/server_command_rb.html new file mode 100644 index 0000000000..4fbc72dc22 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/server/server_command_rb.html @@ -0,0 +1,101 @@ +--- +title: server_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • optparse
  • + +
  • action_dispatch
  • + +
  • rails
  • + +
  • active_support/deprecation
  • + +
  • active_support/core_ext/string/filters
  • + +
  • rails/dev_caching
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/test/test_command_rb.html b/src/5.2/files/railties/lib/rails/commands/test/test_command_rb.html new file mode 100644 index 0000000000..76fd5a4889 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/test/test_command_rb.html @@ -0,0 +1,82 @@ +--- +title: test_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command
  • + +
  • rails/test_unit/runner
  • + +
  • rails/test_unit/reporter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands/version/version_command_rb.html b/src/5.2/files/railties/lib/rails/commands/version/version_command_rb.html new file mode 100644 index 0000000000..95710c7e57 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands/version/version_command_rb.html @@ -0,0 +1,70 @@ +--- +title: version_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/commands_rb.html b/src/5.2/files/railties/lib/rails/commands_rb.html new file mode 100644 index 0000000000..6305db7b99 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/commands_rb.html @@ -0,0 +1,76 @@ +--- +title: commands.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/configuration_rb.html b/src/5.2/files/railties/lib/rails/configuration_rb.html new file mode 100644 index 0000000000..26fd5c761b --- /dev/null +++ b/src/5.2/files/railties/lib/rails/configuration_rb.html @@ -0,0 +1,91 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/ordered_options
  • + +
  • active_support/core_ext/object
  • + +
  • rails/paths
  • + +
  • rails/rack
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/console/app_rb.html b/src/5.2/files/railties/lib/rails/console/app_rb.html new file mode 100644 index 0000000000..4560409e5b --- /dev/null +++ b/src/5.2/files/railties/lib/rails/console/app_rb.html @@ -0,0 +1,84 @@ +--- +title: app.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/all
  • + +
  • action_controller
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/console/helpers_rb.html b/src/5.2/files/railties/lib/rails/console/helpers_rb.html new file mode 100644 index 0000000000..063719d5ed --- /dev/null +++ b/src/5.2/files/railties/lib/rails/console/helpers_rb.html @@ -0,0 +1,70 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/dev_caching_rb.html b/src/5.2/files/railties/lib/rails/dev_caching_rb.html new file mode 100644 index 0000000000..af0326b4a1 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/dev_caching_rb.html @@ -0,0 +1,76 @@ +--- +title: dev_caching.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/engine/commands_rb.html b/src/5.2/files/railties/lib/rails/engine/commands_rb.html new file mode 100644 index 0000000000..2af9cad380 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/engine/commands_rb.html @@ -0,0 +1,63 @@ +--- +title: commands.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/commands
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/engine/configuration_rb.html b/src/5.2/files/railties/lib/rails/engine/configuration_rb.html new file mode 100644 index 0000000000..a3f54c244a --- /dev/null +++ b/src/5.2/files/railties/lib/rails/engine/configuration_rb.html @@ -0,0 +1,87 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/railtie/configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/engine/railties_rb.html b/src/5.2/files/railties/lib/rails/engine/railties_rb.html new file mode 100644 index 0000000000..3c652b25c4 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/engine/railties_rb.html @@ -0,0 +1,77 @@ +--- +title: railties.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/engine/updater_rb.html b/src/5.2/files/railties/lib/rails/engine/updater_rb.html new file mode 100644 index 0000000000..ae9389455a --- /dev/null +++ b/src/5.2/files/railties/lib/rails/engine/updater_rb.html @@ -0,0 +1,89 @@ +--- +title: updater.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/plugin/plugin_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/engine_rb.html b/src/5.2/files/railties/lib/rails/engine_rb.html new file mode 100644 index 0000000000..1158605683 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/engine_rb.html @@ -0,0 +1,107 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/railtie
  • + +
  • rails/engine/railties
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • pathname
  • + +
  • thread
  • + +
  • rails/console/app
  • + +
  • rails/console/helpers
  • + +
  • rake
  • + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/gem_version_rb.html b/src/5.2/files/railties/lib/rails/gem_version_rb.html new file mode 100644 index 0000000000..eafeca16f5 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/gem_version_rb.html @@ -0,0 +1,70 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/actions/create_migration_rb.html b/src/5.2/files/railties/lib/rails/generators/actions/create_migration_rb.html new file mode 100644 index 0000000000..1f21274107 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/actions/create_migration_rb.html @@ -0,0 +1,82 @@ +--- +title: create_migration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • thor/actions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/actions_rb.html b/src/5.2/files/railties/lib/rails/generators/actions_rb.html new file mode 100644 index 0000000000..ebe6dfcc0a --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/actions_rb.html @@ -0,0 +1,74 @@ +--- +title: actions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/active_model_rb.html b/src/5.2/files/railties/lib/rails/generators/active_model_rb.html new file mode 100644 index 0000000000..c26e0f9322 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/active_model_rb.html @@ -0,0 +1,77 @@ +--- +title: active_model.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/app_base_rb.html b/src/5.2/files/railties/lib/rails/generators/app_base_rb.html new file mode 100644 index 0000000000..112e2a324a --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/app_base_rb.html @@ -0,0 +1,105 @@ +--- +title: app_base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • digest/md5
  • + +
  • active_support/core_ext/string/strip
  • + +
  • rails/version
  • + +
  • open-uri
  • + +
  • uri
  • + +
  • rails/generators
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • bundler
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/base_rb.html b/src/5.2/files/railties/lib/rails/generators/base_rb.html new file mode 100644 index 0000000000..ea0c2e04a7 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/base_rb.html @@ -0,0 +1,85 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thor/group
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/css/assets/assets_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/css/assets/assets_generator_rb.html new file mode 100644 index 0000000000..17a8d5685e --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/css/assets/assets_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: assets_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/css/scaffold/scaffold_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/css/scaffold/scaffold_generator_rb.html new file mode 100644 index 0000000000..fe85f50b34 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/css/scaffold/scaffold_generator_rb.html @@ -0,0 +1,78 @@ +--- +title: scaffold_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/erb/controller/controller_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/erb/controller/controller_generator_rb.html new file mode 100644 index 0000000000..97260a7085 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/erb/controller/controller_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/erb
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/erb/mailer/mailer_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/erb/mailer/mailer_generator_rb.html new file mode 100644 index 0000000000..5738eaa6aa --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/erb/mailer/mailer_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: mailer_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/erb
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/erb/scaffold/scaffold_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/erb/scaffold/scaffold_generator_rb.html new file mode 100644 index 0000000000..9ae010eb99 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/erb/scaffold/scaffold_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: scaffold_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/erb
  • + +
  • rails/generators/resource_helpers
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/erb_rb.html b/src/5.2/files/railties/lib/rails/generators/erb_rb.html new file mode 100644 index 0000000000..39a24ac12f --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/erb_rb.html @@ -0,0 +1,63 @@ +--- +title: erb.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/generated_attribute_rb.html b/src/5.2/files/railties/lib/rails/generators/generated_attribute_rb.html new file mode 100644 index 0000000000..77a7364d21 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/generated_attribute_rb.html @@ -0,0 +1,78 @@ +--- +title: generated_attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/js/assets/assets_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/js/assets/assets_generator_rb.html new file mode 100644 index 0000000000..f46c98a6c7 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/js/assets/assets_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: assets_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/migration_rb.html b/src/5.2/files/railties/lib/rails/generators/migration_rb.html new file mode 100644 index 0000000000..fcd6772a4e --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/migration_rb.html @@ -0,0 +1,84 @@ +--- +title: migration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • rails/generators/actions/create_migration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/model_helpers_rb.html b/src/5.2/files/railties/lib/rails/generators/model_helpers_rb.html new file mode 100644 index 0000000000..6be3de5a43 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/model_helpers_rb.html @@ -0,0 +1,78 @@ +--- +title: model_helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/active_model
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/named_base_rb.html b/src/5.2/files/railties/lib/rails/generators/named_base_rb.html new file mode 100644 index 0000000000..36207e7989 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/named_base_rb.html @@ -0,0 +1,89 @@ +--- +title: named_base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/base
  • + +
  • rails/generators/generated_attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/app/app_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/app/app_generator_rb.html new file mode 100644 index 0000000000..47f104dacc --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/app/app_generator_rb.html @@ -0,0 +1,93 @@ +--- +title: app_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/app_base
  • + +
  • rails/generators/rails/master_key/master_key_generator
  • + +
  • rails/generators/rails/credentials/credentials_generator
  • + +
  • rails/version
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/application_record/application_record_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/application_record/application_record_generator_rb.html new file mode 100644 index 0000000000..ee6a45f5e5 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/application_record/application_record_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: application_record_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/assets/assets_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/assets/assets_generator_rb.html new file mode 100644 index 0000000000..560ce412b4 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/assets/assets_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: assets_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/controller/controller_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/controller/controller_generator_rb.html new file mode 100644 index 0000000000..ef0bb14411 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/controller/controller_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/credentials/credentials_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/credentials/credentials_generator_rb.html new file mode 100644 index 0000000000..20bad709bd --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/credentials/credentials_generator_rb.html @@ -0,0 +1,86 @@ +--- +title: credentials_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/base
  • + +
  • rails/generators/rails/master_key/master_key_generator
  • + +
  • active_support/core_ext/string/strip
  • + +
  • active_support/encrypted_configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator_rb.html new file mode 100644 index 0000000000..74e69bb9b5 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator_rb.html @@ -0,0 +1,84 @@ +--- +title: encrypted_file_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/base
  • + +
  • active_support/core_ext/string/strip
  • + +
  • active_support/encrypted_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator_rb.html new file mode 100644 index 0000000000..8ce60d96bc --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator_rb.html @@ -0,0 +1,84 @@ +--- +title: encryption_key_file_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • rails/generators/base
  • + +
  • active_support/encrypted_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/generator/generator_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/generator/generator_generator_rb.html new file mode 100644 index 0000000000..35f54010f1 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/generator/generator_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: generator_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/helper/helper_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/helper/helper_generator_rb.html new file mode 100644 index 0000000000..f2f4a9ba52 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/helper/helper_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: helper_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/integration_test/integration_test_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/integration_test/integration_test_generator_rb.html new file mode 100644 index 0000000000..e184df0289 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/integration_test/integration_test_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: integration_test_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/master_key/master_key_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/master_key/master_key_generator_rb.html new file mode 100644 index 0000000000..b2c1ecec55 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/master_key/master_key_generator_rb.html @@ -0,0 +1,86 @@ +--- +title: master_key_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • rails/generators/base
  • + +
  • rails/generators/rails/encryption_key_file/encryption_key_file_generator
  • + +
  • active_support/encrypted_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/migration/migration_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/migration/migration_generator_rb.html new file mode 100644 index 0000000000..384084bddd --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/migration/migration_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: migration_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/model/model_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/model/model_generator_rb.html new file mode 100644 index 0000000000..2b75eafa18 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/model/model_generator_rb.html @@ -0,0 +1,78 @@ +--- +title: model_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/model_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/plugin/plugin_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/plugin/plugin_generator_rb.html new file mode 100644 index 0000000000..f3508851eb --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/plugin/plugin_generator_rb.html @@ -0,0 +1,89 @@ +--- +title: plugin_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/rails/app/app_generator
  • + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/resource/resource_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/resource/resource_generator_rb.html new file mode 100644 index 0000000000..e08e02f1e8 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/resource/resource_generator_rb.html @@ -0,0 +1,80 @@ +--- +title: resource_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/resource_helpers
  • + +
  • rails/generators/rails/model/model_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/resource_route/resource_route_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/resource_route/resource_route_generator_rb.html new file mode 100644 index 0000000000..9c04333fb5 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/resource_route/resource_route_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: resource_route_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/scaffold/scaffold_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/scaffold/scaffold_generator_rb.html new file mode 100644 index 0000000000..d8bbff5b03 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/scaffold/scaffold_generator_rb.html @@ -0,0 +1,78 @@ +--- +title: scaffold_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/rails/resource/resource_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator_rb.html new file mode 100644 index 0000000000..b76abdab7f --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator_rb.html @@ -0,0 +1,78 @@ +--- +title: scaffold_controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/resource_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/system_test/system_test_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/system_test/system_test_generator_rb.html new file mode 100644 index 0000000000..705267bca3 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/system_test/system_test_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: system_test_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/rails/task/task_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/rails/task/task_generator_rb.html new file mode 100644 index 0000000000..34dd5dce5a --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/rails/task/task_generator_rb.html @@ -0,0 +1,70 @@ +--- +title: task_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/resource_helpers_rb.html b/src/5.2/files/railties/lib/rails/generators/resource_helpers_rb.html new file mode 100644 index 0000000000..3aca15991b --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/resource_helpers_rb.html @@ -0,0 +1,80 @@ +--- +title: resource_helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/active_model
  • + +
  • rails/generators/model_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_case_rb.html b/src/5.2/files/railties/lib/rails/generators/test_case_rb.html new file mode 100644 index 0000000000..dd2f5a1dba --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_case_rb.html @@ -0,0 +1,93 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/testing/behaviour
  • + +
  • rails/generators/testing/setup_and_teardown
  • + +
  • rails/generators/testing/assertions
  • + +
  • fileutils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/controller/controller_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/controller/controller_generator_rb.html new file mode 100644 index 0000000000..4e2f40f785 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/controller/controller_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/generator/generator_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/generator/generator_generator_rb.html new file mode 100644 index 0000000000..373ad97ffd --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/generator/generator_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: generator_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/helper/helper_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/helper/helper_generator_rb.html new file mode 100644 index 0000000000..e8546883c4 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/helper/helper_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: helper_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/integration/integration_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/integration/integration_generator_rb.html new file mode 100644 index 0000000000..68e126305c --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/integration/integration_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: integration_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/job/job_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/job/job_generator_rb.html new file mode 100644 index 0000000000..6c8d914028 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/job/job_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: job_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/mailer/mailer_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/mailer/mailer_generator_rb.html new file mode 100644 index 0000000000..f2ca0ff257 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/mailer/mailer_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: mailer_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/model/model_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/model/model_generator_rb.html new file mode 100644 index 0000000000..389f459f31 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/model/model_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: model_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/plugin/plugin_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/plugin/plugin_generator_rb.html new file mode 100644 index 0000000000..d003053115 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/plugin/plugin_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: plugin_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator_rb.html new file mode 100644 index 0000000000..0e0d1f0405 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: scaffold_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
  • rails/generators/resource_helpers
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit/system/system_generator_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit/system/system_generator_rb.html new file mode 100644 index 0000000000..b14a36fcd7 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit/system/system_generator_rb.html @@ -0,0 +1,63 @@ +--- +title: system_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/test_unit_rb.html b/src/5.2/files/railties/lib/rails/generators/test_unit_rb.html new file mode 100644 index 0000000000..2aa0958bb8 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/test_unit_rb.html @@ -0,0 +1,63 @@ +--- +title: test_unit.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/testing/assertions_rb.html b/src/5.2/files/railties/lib/rails/generators/testing/assertions_rb.html new file mode 100644 index 0000000000..8dfd41a827 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/testing/assertions_rb.html @@ -0,0 +1,74 @@ +--- +title: assertions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/testing/behaviour_rb.html b/src/5.2/files/railties/lib/rails/generators/testing/behaviour_rb.html new file mode 100644 index 0000000000..85f59dfc26 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/testing/behaviour_rb.html @@ -0,0 +1,96 @@ +--- +title: behaviour.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/hash/reverse_merge
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/testing/stream
  • + +
  • active_support/concern
  • + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators/testing/setup_and_teardown_rb.html b/src/5.2/files/railties/lib/rails/generators/testing/setup_and_teardown_rb.html new file mode 100644 index 0000000000..3072ca0260 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators/testing/setup_and_teardown_rb.html @@ -0,0 +1,74 @@ +--- +title: setup_and_teardown.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/generators_rb.html b/src/5.2/files/railties/lib/rails/generators_rb.html new file mode 100644 index 0000000000..298da9d0d7 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/generators_rb.html @@ -0,0 +1,96 @@ +--- +title: generators.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thor/group
  • + +
  • rails/command
  • + +
  • active_support
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/hash/deep_merge
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/string/indent
  • + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/info_controller_rb.html b/src/5.2/files/railties/lib/rails/info_controller_rb.html new file mode 100644 index 0000000000..06811fc009 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/info_controller_rb.html @@ -0,0 +1,89 @@ +--- +title: info_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/application_controller
  • + +
  • action_dispatch/routing/inspector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/info_rb.html b/src/5.2/files/railties/lib/rails/info_rb.html new file mode 100644 index 0000000000..fc4c8b70a4 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/info_rb.html @@ -0,0 +1,80 @@ +--- +title: info.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/initializable_rb.html b/src/5.2/files/railties/lib/rails/initializable_rb.html new file mode 100644 index 0000000000..9ddbf639ec --- /dev/null +++ b/src/5.2/files/railties/lib/rails/initializable_rb.html @@ -0,0 +1,89 @@ +--- +title: initializable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • tsort
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/mailers_controller_rb.html b/src/5.2/files/railties/lib/rails/mailers_controller_rb.html new file mode 100644 index 0000000000..16d9035a86 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/mailers_controller_rb.html @@ -0,0 +1,91 @@ +--- +title: mailers_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/application_controller
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/paths_rb.html b/src/5.2/files/railties/lib/rails/paths_rb.html new file mode 100644 index 0000000000..138b165703 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/paths_rb.html @@ -0,0 +1,79 @@ +--- +title: paths.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/plugin/test_rb.html b/src/5.2/files/railties/lib/rails/plugin/test_rb.html new file mode 100644 index 0000000000..f232c7e81d --- /dev/null +++ b/src/5.2/files/railties/lib/rails/plugin/test_rb.html @@ -0,0 +1,78 @@ +--- +title: test.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/test_unit/runner
  • + +
  • rails/test_unit/reporter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/rack/logger_rb.html b/src/5.2/files/railties/lib/rails/rack/logger_rb.html new file mode 100644 index 0000000000..ce2ed6fb21 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/rack/logger_rb.html @@ -0,0 +1,97 @@ +--- +title: logger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/conversions
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/log_subscriber
  • + +
  • action_dispatch/http/request
  • + +
  • rack/body_proxy
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/rack_rb.html b/src/5.2/files/railties/lib/rails/rack_rb.html new file mode 100644 index 0000000000..251e4e0b2f --- /dev/null +++ b/src/5.2/files/railties/lib/rails/rack_rb.html @@ -0,0 +1,70 @@ +--- +title: rack.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/railtie/configurable_rb.html b/src/5.2/files/railties/lib/rails/railtie/configurable_rb.html new file mode 100644 index 0000000000..fc0e1f0526 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/railtie/configurable_rb.html @@ -0,0 +1,87 @@ +--- +title: configurable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/railtie/configuration_rb.html b/src/5.2/files/railties/lib/rails/railtie/configuration_rb.html new file mode 100644 index 0000000000..cbad94b400 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/railtie/configuration_rb.html @@ -0,0 +1,87 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/railtie_rb.html b/src/5.2/files/railties/lib/rails/railtie_rb.html new file mode 100644 index 0000000000..105177ca97 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/railtie_rb.html @@ -0,0 +1,91 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/initializable
  • + +
  • active_support/inflector
  • + +
  • active_support/core_ext/module/introspection
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/ruby_version_check_rb.html b/src/5.2/files/railties/lib/rails/ruby_version_check_rb.html new file mode 100644 index 0000000000..0d857cfabc --- /dev/null +++ b/src/5.2/files/railties/lib/rails/ruby_version_check_rb.html @@ -0,0 +1,55 @@ +--- +title: ruby_version_check.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/secrets_rb.html b/src/5.2/files/railties/lib/rails/secrets_rb.html new file mode 100644 index 0000000000..2d11a4665c --- /dev/null +++ b/src/5.2/files/railties/lib/rails/secrets_rb.html @@ -0,0 +1,93 @@ +--- +title: secrets.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
  • active_support/message_encryptor
  • + +
  • active_support/core_ext/string/strip
  • + +
  • erb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/source_annotation_extractor_rb.html b/src/5.2/files/railties/lib/rails/source_annotation_extractor_rb.html new file mode 100644 index 0000000000..c2cdf1ce77 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/source_annotation_extractor_rb.html @@ -0,0 +1,84 @@ +--- +title: source_annotation_extractor.rb +layout: default +--- +
+ + +
+
+ +
+ +

Implements the logic behind the rake tasks for annotations like

+ +
rails notes
+rails notes:optimize
+
+ +

and friends. See rails -T notes and railties/lib/rails/tasks/annotations.rake.

+ +

Annotation objects are triplets :line, :tag, :text that represent the line where the annotation lives, its tag, and its text. Note the filename is not stored.

+ +

Annotations are looked for in comments and modulus whitespace they have to start with the tag optionally followed by a colon. Everything up to the end of the line (or closing ERB comment tag) is considered to be their text.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/tasks_rb.html b/src/5.2/files/railties/lib/rails/tasks_rb.html new file mode 100644 index 0000000000..bb2863f119 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/tasks_rb.html @@ -0,0 +1,63 @@ +--- +title: tasks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rake
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/test_help_rb.html b/src/5.2/files/railties/lib/rails/test_help_rb.html new file mode 100644 index 0000000000..37b4a43014 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/test_help_rb.html @@ -0,0 +1,103 @@ +--- +title: test_help.rb +layout: default +--- +
+ + +
+
+ +
+ +

Make double-sure the RAILS_ENV is not set to production, so fixtures aren't loaded into that environment

+ +
+ + + + +

Required Files

+
    + +
  • active_support/test_case
  • + +
  • action_controller
  • + +
  • action_controller/test_case
  • + +
  • action_dispatch/testing/integration
  • + +
  • rails/generators/test_case
  • + +
  • active_support/testing/autorun
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/version_rb.html b/src/5.2/files/railties/lib/rails/version_rb.html new file mode 100644 index 0000000000..ed80a20322 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails/welcome_controller_rb.html b/src/5.2/files/railties/lib/rails/welcome_controller_rb.html new file mode 100644 index 0000000000..d9e5459a91 --- /dev/null +++ b/src/5.2/files/railties/lib/rails/welcome_controller_rb.html @@ -0,0 +1,76 @@ +--- +title: welcome_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/application_controller
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/5.2/files/railties/lib/rails_rb.html b/src/5.2/files/railties/lib/rails_rb.html new file mode 100644 index 0000000000..a6769ada67 --- /dev/null +++ b/src/5.2/files/railties/lib/rails_rb.html @@ -0,0 +1,102 @@ +--- +title: rails.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/ruby_version_check
  • + +
  • pathname
  • + +
  • active_support
  • + +
  • active_support/dependencies/autoload
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/object/blank
  • + +
  • rails/application
  • + +
  • rails/version
  • + +
  • active_support/railtie
  • + +
  • action_dispatch/railtie
  • + +
  • rails/backtrace_cleaner
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
From 7953137b10f7a68fce1f6fd0b1965ba5f53a4743 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 14:39:39 +0900 Subject: [PATCH 26/42] Bump bootstrap from 4.5 to 4.6 ref. https://getbootstrap.com/docs/4.6/getting-started/introduction/ --- src/_layouts/default.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_layouts/default.html b/src/_layouts/default.html index 6727a89301..13f4d247a6 100644 --- a/src/_layouts/default.html +++ b/src/_layouts/default.html @@ -3,7 +3,7 @@ - + From 122cdd575b32e21f3c31e4f8456a817883535ef1 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 17:36:49 +0900 Subject: [PATCH 27/42] Set navbar-expand to header --- src/_layouts/default.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/_layouts/default.html b/src/_layouts/default.html index 13f4d247a6..a50b161528 100644 --- a/src/_layouts/default.html +++ b/src/_layouts/default.html @@ -21,7 +21,7 @@ -
+ + From 3fe09c819d8cd608a5761dd72fe406eb866e6a46 Mon Sep 17 00:00:00 2001 From: toshimaru Date: Wed, 5 May 2021 17:37:13 +0900 Subject: [PATCH 28/42] Display version selector --- src/_layouts/default.html | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/_layouts/default.html b/src/_layouts/default.html index a50b161528..13f8b8cbc9 100644 --- a/src/_layouts/default.html +++ b/src/_layouts/default.html @@ -29,7 +29,16 @@ @@ -134,6 +146,8 @@

Class

  • ActionCable::RemoteConnections
  • +
  • ActionCable::TestCase
  • + diff --git a/src/classes/ActionCable/Channel.html b/src/classes/ActionCable/Channel.html index 0d6b918223..197912ecab 100644 --- a/src/classes/ActionCable/Channel.html +++ b/src/classes/ActionCable/Channel.html @@ -5,7 +5,7 @@